From 05c284370f4d9ce4a5c7808716a6a35af30a2a82 Mon Sep 17 00:00:00 2001 From: Cris Rockwell Date: Tue, 25 Aug 2026 18:59:20 -0400 Subject: [PATCH 1/2] ASSETS-75093: Document combined aem/assets/assetsview/1 extension point Present aem/assets/assetsview/1 as the unified extension point across the AEM Assets View docs (overview, API landing, common concepts, browse/details pages, step-by-step development, and troubleshooting). - Add a dedicated Header Menu page and move the shared `headerMenu` namespace reference off the Browse and Details pages, which now link to it - Update Code Generation to the @adobe/aem-assets-assetsview-ext-tpl template and remove the browse/details templates from the `aio app init` output - Fix malformed blockquote code fences in Code Generation - Note the standalone browse/1 and details/1 extension points remain supported for existing extensions Co-Authored-By: Claude Opus 4.8 --- src/pages/config.md | 1 + .../aem-assets-view/api/browse-view/index.md | 262 ++-------------- .../aem-assets-view/api/commons/index.md | 37 ++- .../aem-assets-view/api/details-view/index.md | 142 ++------- .../add-custom-action.jpg | Bin .../aem-assets-view/api/header-menu/index.md | 285 ++++++++++++++++++ .../services/aem-assets-view/api/index.md | 25 +- .../aem-assets-view/code-generation/index.md | 60 ++-- .../services/aem-assets-view/debug/index.md | 6 +- .../extension-development/index.md | 31 +- src/pages/services/aem-assets-view/index.md | 4 +- 11 files changed, 431 insertions(+), 422 deletions(-) rename src/pages/services/aem-assets-view/api/{browse-view => header-menu}/add-custom-action.jpg (100%) create mode 100644 src/pages/services/aem-assets-view/api/header-menu/index.md diff --git a/src/pages/config.md b/src/pages/config.md index 32841bc1..b6bf9ce6 100644 --- a/src/pages/config.md +++ b/src/pages/config.md @@ -52,6 +52,7 @@ - [Common Concepts](/services/aem-assets-view/api/commons/index.md) - [Browse View](/services/aem-assets-view/api/browse-view/index.md) - [Details View](/services/aem-assets-view/api/details-view/index.md) + - [Header Menu](/services/aem-assets-view/api/header-menu/index.md) - [Step-by-step Extension Development](/services/aem-assets-view/extension-development/index.md) - [Code Generation](/services/aem-assets-view/code-generation/index.md) - [Troubleshooting](/services/aem-assets-view/debug/index.md) diff --git a/src/pages/services/aem-assets-view/api/browse-view/index.md b/src/pages/services/aem-assets-view/api/browse-view/index.md index 55788de4..533950bd 100644 --- a/src/pages/services/aem-assets-view/api/browse-view/index.md +++ b/src/pages/services/aem-assets-view/api/browse-view/index.md @@ -36,11 +36,15 @@ Browse View are selected. **Header menu** is the set of buttons at the top right of the browse screen. Custom buttons may be added to the header menu between the ellipses menu and the default header menu buttons. ![header menu](header-menu.png) -Extensions should use the `aem/assets/browse/1` extension point to utilize extensibility services of the Browse View. +Extensions should use the unified `aem/assets/assetsview/1` extension point to utilize extensibility services of the +Browse View. The standalone `aem/assets/browse/1` extension point remains supported for existing extensions, but new +extensions should use `aem/assets/assetsview/1`, which also lets the same extension customize the +[Details View](../details-view/index.md). Regardless of the extension point, the Browse View capabilities are provided +through the same `actionBar`, `quickActions`, and `headerMenu` namespaces described below. An extension needs to implement both `actionBar` and `quickActions` namespace to be recognized by Assets View. -The `headerMenu` namespace is optional for browse extensions. -If you implement `headerMenu`, all of its methods are optional: `getButtons`, `getHiddenButtonIds`, and `overrideButton`. Implement only the methods your extension needs. +Header menu buttons are customized through the optional, cross-cutting `headerMenu` namespace, documented on the +dedicated [Header Menu](../header-menu/index.md) page. ## Custom ActionBar actions and QuickActions menu actions @@ -58,13 +62,10 @@ Using the [`quickActions`](#quickactions-namespace) namespace, built-in QuickAct selected asset. ## Custom header menu buttons -This extensibility feature allows context-aware customization of the header menu buttons. -Using the [`headerMenu`](#headermenu-namespace) namespace, you can add custom header menu buttons before built-in header menu buttons, hide built-in header menu buttons by id (removing them from the header menu), and override built-in header menu button clicks so the default handler does not run or runs conditionally. - -In this example, a custom button is added to the header menu before the list of built-in header menu buttons. - -![header menu buttons](add-custom-action.jpg) +Browse extensions can add, hide, or override header menu buttons using the `headerMenu` namespace. Because header menu +behavior is shared between the Browse View and the Details View, it is documented on the dedicated +[Header Menu](../header-menu/index.md) page, together with the built-in header menu button ids for each browsing context. ## API Reference @@ -74,7 +75,7 @@ to the extension and the API provided by the extension to the AEM Assets View ho ### Host API Reference In addition to the [Common API](../commons/index.md) provided by AEM Assets View to all extensions, -the host application provides the following definitions that are specific to the `aem/assets/browse/1` extension point: [`actionBar`](#actionbar-namespace), [`quickActions`](#quickactions-namespace) and [`headerMenu`](#headermenu-namespace) namespaces. +the host application provides the following definitions that are specific to the Browse View: [`actionBar`](#actionbar-namespace) and [`quickActions`](#quickactions-namespace) namespaces. Header menu customization is available through the shared [`headerMenu`](../header-menu/index.md) namespace. #### Browsing context @@ -105,29 +106,13 @@ action ids of actions that can be hidden: | `search` | "edit", "openInExpress", "reprocess", "copy", "move", "rename", "bulkRename", "managePermissions", "delete", "publish", "download", "share" | | `trash` | "delete" | -#### Built-in header menu buttons - -Browse extensions use the [`headerMenu`](#headermenu-namespace) namespace to customize header menu buttons in the top bar. -Depending on context and extension point, the host exposes the following built-in header menu button ids that can be hidden or overridden. - -| Context | Header menu button IDs that can be hidden or overridden | -|------------|------------| -| `assets` | "createFolder", "addAssets" | -| `collections` | "createCollection", "addToCollection", "editSmartCollection" | -| `recent` | — | -| `search` | — | -| `trash` | — | - -In `recent`, `search`, and `trash`, there are no built-in header menu buttons to hide, but extensions can still add custom header menu buttons via [`getButtons`](#headermenu-namespace). - ### Extension API Reference -The extension definition object passed by the extension to the `register()` function defines the [`actionBar`](#actionbar-namespace), [`quickActions`](#quickActions-namespace) and [`headerMenu`](#headermenu-namespace) namespaces. +The extension definition object passed by the extension to the `register()` function defines the [`actionBar`](#actionbar-namespace) and [`quickActions`](#quickactions-namespace) namespaces. For header menu customization, see the [Header Menu](../header-menu/index.md) page. The methods in these namespaces provide the capabilities to - Add custom actions to the ActionBar - Hide or customize built-in actions in the ActionBar and QuickActions -- Add custom header menu buttons, and optionally hide or override built-in header menu buttons @@ -283,130 +268,19 @@ overrideBuiltInAction: ({ actionId, context, resource }) => { }, ``` -#### headerMenu namespace - -The `headerMenu` namespace supports adding custom header menu buttons in the browse view header menu and optionally hiding and overriding built-in header menu buttons. - -`headerMenu` behavior is shared between Browse View and Details View. If an extension implements `headerMenu` in either `aem/assets/browse/1` or `aem/assets/details/1`, those methods are used for header menu handling in both screens. The built-in button set and button ids still differ by screen/context, so use the appropriate ids from each page's [Built-in header menu buttons](#built-in-header-menu-buttons) table. - -All `headerMenu` methods are optional: - -- `getButtons({ context, resource })` — optional -- `getHiddenButtonIds({ context, resource })` — optional -- `overrideButton({ buttonId, context, resource })` — optional - - -`getButtons({ context, resource })` - -**Description:** Returns an array of custom header menu button definitions that will be added to the application's header menu. These buttons are rendered alongside built-in header menu buttons and provide a way for extensions to add custom functionality accessible from the header menu on browse screens. - -**Parameters:** -- context (`string`): current [browsing context](#browsing-context). -- resource (`object`): Information about the current location being browsed - - id (`string`): The unique identifier of the current location - - path (`string`): The path of the current location - - In contexts that do not support a notion of active resource, like `'trash'`, `'search'` or `'recent'`, the `resource` argument will be `undefined`. - For `'assets'` and `'collections'` context, the `resource` is a JSON object with `id` and `path`, even for the root folder. - -**Returns:** (`array`) An array of button configuration objects, where each object contains: -- id (`string`): Unique identifier for the button within the extension -- label (`string`): Display text for the button -- icon (`string`): Name of the [React-Spectrum workflow icon](https://react-spectrum.adobe.com/react-spectrum/workflow-icons.html#available-icons) -- onClick (`function`): Callback function executed when the header menu button is clicked; receives `{ context, resource }` -- variant (`string`, optional): Button visual style, defaults to `'primary'` - - Supported values: `'accent'`, `'primary'`, `'secondary'`, `'negative'` - -**Example:** - -```javascript -headerMenu: { - async getButtons({ context, resource }) { - if (context !== 'assets') { - return []; - } - return [ - { - id: 'export-metadata', - label: 'Export Metadata', - icon: 'Download', - variant: 'secondary', - onClick: async ({ context, resource }) => { - // Custom logic - }, - }, - { - id: 'custom-workflow', - label: 'Start Workflow', - icon: 'Workflow', - onClick: async ({ context, resource }) => { - // Custom logic - }, - }, - ]; - }, -}, -``` - -`getHiddenButtonIds({ context, resource })` - -**Description:** Returns an array of [built-in header menu button ids](#built-in-header-menu-buttons) that should be hidden. - -The host calls this method when the browse location or context changes. Extension code should return quickly; avoid slow or blocking work (for example backend calls), because the host may wait on the result before rendering header menu buttons. - -**Parameters:** -- context (`string`): current [browsing context](#browsing-context). -- resource (`object`): Same semantics as for [`getButtons`](#headermenu-namespace). - -**Returns:** (`array`) An array of built-in header menu button ids to hide, or an empty array if none should be hidden. - -**Example:** - -```js -getHiddenButtonIds: ({ context, resource }) => { - if (context === 'assets') { - return ['createFolder']; - } - return []; -}, -``` - -`overrideButton({ buttonId, context, resource })` - -**Description:** Return `true` if the extension handled the click and the built-in header menu button handler should **not** run. Return `false` to let the Host run the default behavior. - -**Parameters:** -- buttonId (`string`): Built-in header menu button id from [Built-in header menu buttons](#built-in-header-menu-buttons). -- context (`string`): current [browsing context](#browsing-context). -- resource (`object`): Same semantics as for [`getButtons`](#headermenu-namespace). - -**Returns:** (`boolean`) `false` for the Host to use the built-in handler, `true` to skip the built-in handler. - -**Example:** - -```js -overrideButton: ({ buttonId, context, resource }) => { - if (buttonId === 'addAssets') { - // Custom handling; skip built-in handler - return true; - } - return false; -}, -``` - - ## Examples -These code snippets demonstrate how to add a custom action to the ActionBar, add buttons to the header menu, -hide built-in actions or override built-in action handlers from the ActionBar and QuickActions menu, and optionally -hide or override built-in header menu buttons in the Browse View. (The examples below serve illustrative purposes thus omit -certain import statements and other non-important parts.) +These code snippets demonstrate how to add a custom action to the ActionBar and +hide built-in actions or override built-in action handlers from the ActionBar and QuickActions menu in the Browse View. +(The examples below serve illustrative purposes thus omit certain import statements and other non-important parts.) +For header menu button examples, see the [Header Menu](../header-menu/index.md) page. The ExtensionRegistration component initializes the extension registration process by calling the `register()` function provided by the `@adobe/uix-guest` library. The objects passed to the `register()` function describe the extension and its capabilities. In particular, it declares -that the extension uses the `actionBar` and `quickActions` namespaces with their required methods, and may include the -optional `headerMenu` namespace. All `headerMenu` methods are optional; implement `getButtons`, `getHiddenButtonIds`, and/or `overrideButton` as needed. +that the extension uses the `actionBar` and `quickActions` namespaces with their required methods. Header menu buttons +are declared through the optional [`headerMenu`](../header-menu/index.md) namespace. This example demonstrates the minimal set of namespaces and methods required for a browse extension to be recognized by the Host application. @@ -436,17 +310,6 @@ function ExtensionRegistration() { return false; }, }, - headerMenu: { - async getButtons({ context, resource }) { - return []; - }, - async getHiddenButtonIds({ context, resource }) { - return []; - }, - async overrideButton({ buttonId, context, resource }) { - return false; - }, - }, }, }); }; @@ -687,90 +550,7 @@ function ExtensionRegistration() { } ``` -### Example of hiding built-in header menu buttons - -In this example, the built-in **Create folder** header menu button (`createFolder`) is hidden in the `assets` context. - -```js -function ExtensionRegistration() { - const init = async () => { - const guestConnection = await register({ - id: extensionId, - methods: { - actionBar: { - // ... - }, - quickActions: { - // ... - }, - headerMenu: { - async getButtons({ context, resource }) { - return []; - }, - async getHiddenButtonIds({ context, resource }) { - if (context === 'assets') { - return ['createFolder']; - } - return []; - }, - async overrideButton({ buttonId, context, resource }) { - return false; - }, - }, - }, - }); - }; - init().catch(console.error); - - return IFrame for integration with Host (AEM Assets View)...; -} - -export default ExtensionRegistration; -``` - -### Example of overriding a built-in header menu button - -In this example, when the user activates the **Add assets** header menu button (`addAssets`), the extension runs custom logic -and skips the Host's default handler by returning `true`. - -```js -function ExtensionRegistration() { - const init = async () => { - const guestConnection = await register({ - id: extensionId, - methods: { - actionBar: { - // ... - }, - quickActions: { - // ... - }, - headerMenu: { - async getButtons({ context, resource }) { - return []; - }, - async getHiddenButtonIds({ context, resource }) { - return []; - }, - async overrideButton({ buttonId, context, resource }) { - if (buttonId === 'addAssets') { - // Custom upload or validation flow - return true; - } - return false; - }, - }, - }, - }); - }; - init().catch(console.error); - - return IFrame for integration with Host (AEM Assets View)...; -} - -export default ExtensionRegistration; -``` - -To open a custom dialog from custom ActionBar actions, QuickActions menu actions, or header menu buttons, refer to the +To open a custom dialog from custom ActionBar actions or QuickActions menu actions, refer to the [Modal API](../commons/index.md#modal-api) provided by AEM Assets View to all extensions for implementation of -dialog management. +dialog management. For header menu button examples — including hiding and overriding built-in header menu buttons — +see the [Header Menu](../header-menu/index.md) page. diff --git a/src/pages/services/aem-assets-view/api/commons/index.md b/src/pages/services/aem-assets-view/api/commons/index.md index 7952e0c9..f954f935 100644 --- a/src/pages/services/aem-assets-view/api/commons/index.md +++ b/src/pages/services/aem-assets-view/api/commons/index.md @@ -21,15 +21,15 @@ You can provide documentation feedback by clicking "Log an issue". ## Extension Point -AEM Assets View has an `aem/assets/details/1` [extension point](https://developer.adobe.com/app-builder/docs/guides/extensions/) -that allows you to extend its functionality in the Details View. +AEM Assets View has a unified `aem/assets/assetsview/1` [extension point](https://developer.adobe.com/app-builder/docs/guides/extensions/) +that allows you to extend its functionality in both the Browse View and the Details View from a single extension. To declare it to be used by your extension, you need to add the following configuration to your `app.config.yaml` at the root of your extension: ```yaml extensions: - aem/assets/details/1: - $include: src/aem-assets-details-1/ext.config.yaml + aem/assets/assetsview/1: + $include: src/aem-assets-assetsview-1/ext.config.yaml ``` Here is an example of `ext.config.yaml` file: @@ -42,7 +42,11 @@ actions: actions web: web-src ``` -More **extension points** may be added in future releases to add extensibility features to other parts of the AEM Assets View. + + +The standalone `aem/assets/browse/1` and `aem/assets/details/1` extension points remain supported for existing +extensions, but new extensions should use the unified `aem/assets/assetsview/1` extension point. It exposes the same +namespaces and methods, so a single extension can customize both screens without registering multiple extension points. ## Extension Registration @@ -59,10 +63,14 @@ Extension registration data must include: View and extension and is needed if extension provides custom UI. - `methods` - objects with the extension APIs exposed to the AEM Assets View. All methods are grouped into **namespaces** that represent more granular areas of AEM Assets View functionality within the extension point. -Currently, only the following **namespace** is available: - - `detailSidePanel`, that allows to add custom side panels in the Details View +The following **namespaces** are available under the unified `aem/assets/assetsview/1` extension point: + - `actionBar`, that allows adding, hiding, or overriding [ActionBar actions](../browse-view/index.md#actionbar-namespace) in the Browse View + - `quickActions`, that allows hiding or overriding [QuickActions menu actions](../browse-view/index.md#quickactions-namespace) in the Browse View + - `detailSidePanel`, that allows adding [custom side panels](../details-view/index.md#detailsidepanel-namespace) in the Details View + - `headerMenu`, that allows adding, hiding, or overriding [header menu buttons](../header-menu/index.md) in the Browse View and the Details View -More **namespaces** may be added in future releases to add more extensibility features within the Details View. +Implement only the namespaces your extension needs. A single extension can mix Browse View and Details View +namespaces in one `register()` call. ```js import { register } from '@adobe/uix-guest'; @@ -72,6 +80,13 @@ import { register } from '@adobe/uix-guest'; const guestConnection = await register({ id: 'extension-id', methods: { + // Browse View + actionBar: { + getActions() { + // .. + } + }, + // Details View detailSidePanel: { getPanels() { // .. @@ -83,9 +98,9 @@ import { register } from '@adobe/uix-guest'; ``` ## Building Extension UI -The `aem/assets/details/1` extension point and its `detailSidePanel` **namespace** requires UI extension to provide -its own interface for the custom side panel. This interface should be implemented as a separate entry point within the extension -web application. +Namespaces that render extension content — such as `detailSidePanel` (custom side panels) and the `modal` dialogs used +by ActionBar actions, QuickActions, and header menu buttons — require the UI extension to provide its own interface. +This interface should be implemented as a separate entry point within the extension web application. Normally this interface needs data from the AEM Assets View or needs to trigger certain action within the host application. To support this the interface page should establish its own connection with AEM Assets View using the `attach()` function diff --git a/src/pages/services/aem-assets-view/api/details-view/index.md b/src/pages/services/aem-assets-view/api/details-view/index.md index b27fcdd3..97863108 100644 --- a/src/pages/services/aem-assets-view/api/details-view/index.md +++ b/src/pages/services/aem-assets-view/api/details-view/index.md @@ -20,16 +20,18 @@ To get access to Assets View UI extensibility, You can provide documentation feedback by clicking "Log an issue". -Extensions should use the `aem/assets/details/1` extension point to utilize extensibility services of the Details View. +Extensions should use the unified `aem/assets/assetsview/1` extension point to utilize extensibility services of the +Details View. The standalone `aem/assets/details/1` extension point remains supported for existing extensions, but new +extensions should use `aem/assets/assetsview/1`, which also lets the same extension customize the +[Browse View](../browse-view/index.md). Regardless of the extension point, the Details View capabilities are provided +through the `detailSidePanel` namespace described below and the shared [`headerMenu`](../header-menu/index.md) namespace. ## Custom header menu buttons in Details View -The Details View header menu includes built-in buttons (for example "Assign tasks" and "Download"). - -Using the optional [`headerMenu`](#headermenu-namespace) namespace, a details extension can add custom header menu buttons, hide built-in header menu buttons by id (removing them from the header menu), and override built-in header menu button clicks so the default handler does not run. -If you implement `headerMenu`, all of its methods are optional: `getButtons`, `getHiddenButtonIds`, and `overrideButton`. Implement only the methods your extension needs. - -Built-in header menu button ids for the Details View (`aem/assets/details/1`) are listed in the [Built-in header menu buttons](#built-in-header-menu-buttons) table below. +The Details View header menu includes built-in buttons (for example "Assign tasks" and "Download"). A details extension +can add, hide, or override header menu buttons using the `headerMenu` namespace. Because header menu behavior is shared +between the Browse View and the Details View, it is documented on the dedicated [Header Menu](../header-menu/index.md) +page, together with the built-in header menu button ids for the `details` context. ## Custom side panels @@ -54,8 +56,9 @@ to the extension and the API provided by the extension to the AEM Assets View ho ### Host API Reference In addition to the [Common API](../commons/index.md) provided by AEM Assets View to all extensions, -the host application provides the following API specific to the `aem/assets/details/1` extension point, -the [`detailSidePanel`](#detailsidepanel-namespace) namespace, and the optional [`headerMenu`](#headermenu-namespace) namespace. +the host application provides the following API specific to the Details View, the +[`detailSidePanel`](#detailsidepanel-namespace) namespace. Header menu customization is available through the shared +[`headerMenu`](../header-menu/index.md) namespace. `details.getCurrentResourceInfo()` @@ -72,7 +75,7 @@ const { path, id } = await guestConnection.host.details.getCurrentResourceInfo() ### Extension API Reference -The extension definition object passed by the extension to the `register()` function defines the [`detailSidePanel`](#detailsidepanel-namespace) namespace and may optionally define the [`headerMenu`](#headermenu-namespace) namespace. +The extension definition object passed by the extension to the `register()` function defines the [`detailSidePanel`](#detailsidepanel-namespace) namespace. For header menu customization, see the [Header Menu](../header-menu/index.md) page. #### detailSidePanel namespace @@ -94,89 +97,6 @@ Each array element is a custom panel descriptor that is a JSON with the followin - `contentUrl` (`string`): Relative root to the panel's content. - `reloadOnThemeChange` (`boolean`): Whether to reload custom panel when application theme changes. -#### Built-in header menu buttons - -Details extensions use the [`headerMenu`](#headermenu-namespace) namespace to customize header menu buttons in the top bar. -The host exposes the following built-in header menu button ids that can be hidden or overridden. - -| Context | Header menu button IDs that can be hidden or overridden | -|------------|------------| -| `details` | "assignTasks", "download" | - -#### headerMenu namespace - -The `headerMenu` namespace supports adding custom **header menu buttons** in the Details View header menu and optionally hiding and overriding built-in header menu buttons there. - -`headerMenu` behavior is shared between Browse View and Details View. If an extension implements `headerMenu` in either `aem/assets/browse/1` or `aem/assets/details/1`, those methods are used for header menu handling in both screens. The built-in button set and button ids still differ by screen/context, so use the appropriate ids from each page's [Built-in header menu buttons](#built-in-header-menu-buttons) table. - -All `headerMenu` methods are optional: - -- `getButtons({ context, resource })` — optional -- `getHiddenButtonIds({ context, resource })` — optional -- `overrideButton({ buttonId, context, resource })` — optional - -For example, you can implement only `getHiddenButtonIds` or `overrideButton` without implementing `getButtons`. - -`resource` describes the asset or folder currently shown in the Details View (see [`details.getCurrentResourceInfo()`](#host-api-reference)). - -`getButtons({ context, resource })` - -**Description:** Returns an array of custom header menu button definitions that will be added to the Details View header menu. These buttons are rendered alongside built-in header menu buttons and let extensions surface actions in the header menu while viewing an asset or folder. - -**Parameters:** -- context (`string`): Current context for the Details View, as communicated by the Host. -- resource (`object`): The asset or folder currently shown in the Details View. - - id (`string`): Resource URN. - - path (`string`): Resource path. - - Matches the object returned by [`details.getCurrentResourceInfo()`](#host-api-reference). - -**Returns:** (`array`) An array of button configuration objects. Each object contains: -- id (`string`): Unique identifier for the button within the extension -- label (`string`): Display text for the button -- icon (`string`): Name of the [React-Spectrum workflow icon](https://react-spectrum.adobe.com/react-spectrum/workflow-icons.html#available-icons) -- onClick (`function`): Callback when the header menu button is clicked; receives `{ context, resource }` -- variant (`string`, optional): Button visual style, defaults to `'primary'` - - Supported values: `'accent'`, `'primary'`, `'secondary'`, `'negative'` - -**Example:** - -```javascript -headerMenu: { - async getButtons({ context, resource }) { - return [ - { - id: 'details-export', - label: 'Export', - icon: 'Download', - variant: 'secondary', - onClick: async ({ context, resource }) => { - // resource is the asset or folder open in Details View - }, - }, - ]; - }, -}, -``` - -`getHiddenButtonIds({ context, resource })` - -**Description:** Returns an array of built-in header menu button ids to hide in the Details View. Supported ids are those listed for the `details` context in [Built-in header menu buttons](#built-in-header-menu-buttons). - -The host calls this method when the asset or context relevant to the header menu changes. Return quickly; avoid slow or blocking work while the host resolves header menu button visibility. - -**Returns:** (`array`) An array of built-in header menu button ids to hide, or an empty array if none should be hidden. - -`overrideButton({ buttonId, context, resource })` - -**Description:** Return `true` if the extension handled the click and the built-in header menu button handler should **not** run. Return `false` to let the Host run the default behavior. - -**Parameters:** -- buttonId (`string`): Built-in header menu button id for the Details View; must be one of the ids listed for the `details` context in [Built-in header menu buttons](#built-in-header-menu-buttons). - -**Returns:** (`boolean`) `false` for the Host to use the built-in handler, `true` to skip the built-in handler. - - - ## Example of adding custom side panels These code snippets demonstrate how to create a custom side panel using UIX SDK library and add it to the side rail @@ -226,8 +146,8 @@ The `ExtensionRegistration` component initializes the extension registration pro provided by the `@adobe/uix-guest` library. The objects passed to the `register()` function describe the extension and its capabilities. In particular, it declares that the -extension uses the `detailSidePanel` namespace and its `getPanels` method, and may include the optional `headerMenu` namespace. -For `headerMenu`, all methods are optional; this example stubs out `getButtons`, `getHiddenButtonIds`, and `overrideButton`. +extension uses the `detailSidePanel` namespace and its `getPanels` method. A details extension can also declare the shared +[`headerMenu`](../header-menu/index.md) namespace in the same `register()` call to customize header menu buttons. ```js function ExtensionRegistration() { @@ -249,17 +169,6 @@ function ExtensionRegistration() { ]; }, }, - headerMenu: { - async getButtons({ context, resource }) { - return []; - }, - async getHiddenButtonIds({ context, resource }) { - return []; - }, - async overrideButton({ buttonId, context, resource }) { - return false; - }, - }, }, }); }; @@ -271,25 +180,8 @@ function ExtensionRegistration() { export default ExtensionRegistration; ``` -To hide or override built-in header menu buttons in the Details View, add `getHiddenButtonIds` and/or `overrideButton` (and `getButtons` if you add custom buttons). For example, hide the built-in **Download** header menu button and take over the **Assign tasks** click (skipping the Host handler when you return `true`): - -```js -headerMenu: { - async getButtons({ context, resource }) { - return []; - }, - async getHiddenButtonIds({ context, resource }) { - return ['download']; - }, - async overrideButton({ buttonId, context, resource }) { - if (buttonId === 'assignTasks') { - // Custom assign-tasks flow; skip built-in handler - return true; - } - return false; - }, -}, -``` +To add, hide, or override header menu buttons in the Details View — including a worked example that hides the built-in +**Download** button and takes over the **Assign tasks** click — see the [Header Menu](../header-menu/index.md) page. The `PanelExtensionTemplate` component is responsible for rendering the custom panel content. It uses the `attach()` function provided by the `@adobe/uix-guest` library to establish a connection with the AEM Assets View and uses this connection object to diff --git a/src/pages/services/aem-assets-view/api/browse-view/add-custom-action.jpg b/src/pages/services/aem-assets-view/api/header-menu/add-custom-action.jpg similarity index 100% rename from src/pages/services/aem-assets-view/api/browse-view/add-custom-action.jpg rename to src/pages/services/aem-assets-view/api/header-menu/add-custom-action.jpg diff --git a/src/pages/services/aem-assets-view/api/header-menu/index.md b/src/pages/services/aem-assets-view/api/header-menu/index.md new file mode 100644 index 00000000..61f8f9d5 --- /dev/null +++ b/src/pages/services/aem-assets-view/api/header-menu/index.md @@ -0,0 +1,285 @@ +--- +title: Header Menu - AEM Assets View Extensibility +description: Learn how to add, hide, and override header menu buttons in AEM Assets View +contributors: + - https://github.com/AdobeDocs/uix +--- + +# Header Menu + +The **header menu** is the set of buttons at the top right of AEM Assets View. Using the `headerMenu` namespace, +an extension can add custom header menu buttons, hide built-in header menu buttons by id (removing them from the +header menu), and override built-in header menu button clicks so the default handler does not run. + + + +UI Extensibility is supported in Assets Ultimate only. + + + +To get access to Assets View UI extensibility, +[create and submit an Adobe Customer Support case](https://helpx.adobe.com/enterprise/using/support-for-experience-cloud.html). +You can provide documentation feedback by clicking "Log an issue". + +## A namespace shared across screens + +Unlike the [`actionBar`](../browse-view/index.md#actionbar-namespace) and [`quickActions`](../browse-view/index.md#quickactions-namespace) +namespaces (specific to the [Browse View](../browse-view/index.md)) and the +[`detailSidePanel`](../details-view/index.md#detailsidepanel-namespace) namespace (specific to the +[Details View](../details-view/index.md)), the `headerMenu` namespace is **shared between the Browse View and the +Details View**. When an extension implements `headerMenu` (under the unified `aem/assets/assetsview/1` extension point, +or a standalone `aem/assets/browse/1` or `aem/assets/details/1` extension point), those methods are used for header +menu handling on both screens. + +The built-in button set and button ids differ by screen and context, so use the appropriate ids from the +[Built-in header menu buttons](#built-in-header-menu-buttons) tables below. The meaning of the `context` and `resource` +arguments passed to the methods also depends on the screen — see [Method arguments by screen](#method-arguments-by-screen). + +In the Browse View, custom buttons are added to the header menu between the ellipses menu and the default header menu buttons. + +![header menu buttons](add-custom-action.jpg) + +## Built-in header menu buttons + +The host exposes the following built-in header menu button ids that can be hidden or overridden through the +[`headerMenu` methods](#extension-api-reference). + +**Browse View** ([browsing context](../browse-view/index.md#browsing-context)): + +| Context | Header menu button IDs that can be hidden or overridden | +|------------|------------| +| `assets` | "createFolder", "addAssets" | +| `collections` | "createCollection", "addToCollection", "editSmartCollection" | +| `recent` | — | +| `search` | — | +| `trash` | — | + +In `recent`, `search`, and `trash`, there are no built-in header menu buttons to hide, but extensions can still add +custom header menu buttons via [`getButtons`](#extension-api-reference). + +**Details View** (the `details` context): + +| Context | Header menu button IDs that can be hidden or overridden | +|------------|------------| +| `details` | "assignTasks", "download" | + +## Method arguments by screen + +All `headerMenu` methods receive a `context` and, for `getButtons`/`getHiddenButtonIds`/`overrideButton`, a `resource`. +Their meaning depends on the screen the header menu is being rendered on: + +| Argument | Browse View | Details View | +|------------|------------|------------| +| `context` | The current [browsing context](../browse-view/index.md#browsing-context): `assets`, `collections`, `recent`, `search`, or `trash`. | `details`. | +| `resource` | Information about the current location being browsed (`id`, `path`). In contexts without a notion of active resource (`trash`, `search`, `recent`), `resource` is `undefined`. In `assets` and `collections`, it is an object with `id` and `path`, even for the root folder. | The asset or folder currently shown in the Details View (`id`, `path`), matching [`details.getCurrentResourceInfo()`](../details-view/index.md#host-api-reference). | + +## Extension API Reference + +The `headerMenu` namespace supports adding custom header menu buttons and, optionally, hiding and overriding built-in +header menu buttons. All of its methods are optional — implement only the ones your extension needs: + +- `getButtons({ context, resource })` — optional +- `getHiddenButtonIds({ context, resource })` — optional +- `overrideButton({ buttonId, context, resource })` — optional + +For example, you can implement only `getHiddenButtonIds` or `overrideButton` without implementing `getButtons`. + +### getButtons({ context, resource }) + +**Description:** Returns an array of custom header menu button definitions that are added to the application's header +menu. These buttons are rendered alongside built-in header menu buttons and let extensions surface actions in the header +menu. + +**Parameters:** +- context (`string`): current context (see [Method arguments by screen](#method-arguments-by-screen)). +- resource (`object`): information about the current location or asset (see [Method arguments by screen](#method-arguments-by-screen)). + +**Returns:** (`array`) An array of button configuration objects, where each object contains: +- id (`string`): Unique identifier for the button within the extension +- label (`string`): Display text for the button +- icon (`string`): Name of the [React-Spectrum workflow icon](https://react-spectrum.adobe.com/react-spectrum/workflow-icons.html#available-icons) +- onClick (`function`): Callback function executed when the header menu button is clicked; receives `{ context, resource }` +- variant (`string`, optional): Button visual style, defaults to `'primary'` + - Supported values: `'accent'`, `'primary'`, `'secondary'`, `'negative'` + +**Example:** + +```javascript +headerMenu: { + async getButtons({ context, resource }) { + if (context !== 'assets') { + return []; + } + return [ + { + id: 'export-metadata', + label: 'Export Metadata', + icon: 'Download', + variant: 'secondary', + onClick: async ({ context, resource }) => { + // Custom logic + }, + }, + { + id: 'custom-workflow', + label: 'Start Workflow', + icon: 'Workflow', + onClick: async ({ context, resource }) => { + // Custom logic + }, + }, + ]; + }, +}, +``` + +### getHiddenButtonIds({ context, resource }) + +**Description:** Returns an array of [built-in header menu button ids](#built-in-header-menu-buttons) that should be hidden. + +The host calls this method when the location, asset, or context relevant to the header menu changes. Extension code +should return quickly; avoid slow or blocking work (for example backend calls), because the host may wait on the result +before rendering header menu buttons. + +**Parameters:** +- context (`string`): current context (see [Method arguments by screen](#method-arguments-by-screen)). +- resource (`object`): information about the current location or asset (see [Method arguments by screen](#method-arguments-by-screen)). + +**Returns:** (`array`) An array of built-in header menu button ids to hide, or an empty array if none should be hidden. + +**Example:** + +```js +getHiddenButtonIds: ({ context, resource }) => { + if (context === 'assets') { + return ['createFolder']; + } + return []; +}, +``` + +### overrideButton({ buttonId, context, resource }) + +**Description:** Return `true` if the extension handled the click and the built-in header menu button handler should +**not** run. Return `false` to let the Host run the default behavior. + +**Parameters:** +- buttonId (`string`): Built-in header menu button id from [Built-in header menu buttons](#built-in-header-menu-buttons). +- context (`string`): current context (see [Method arguments by screen](#method-arguments-by-screen)). +- resource (`object`): information about the current location or asset (see [Method arguments by screen](#method-arguments-by-screen)). + +**Returns:** (`boolean`) `false` for the Host to use the built-in handler, `true` to skip the built-in handler. + +**Example:** + +```js +overrideButton: ({ buttonId, context, resource }) => { + if (buttonId === 'addAssets') { + // Custom handling; skip built-in handler + return true; + } + return false; +}, +``` + +## Examples + +These code snippets demonstrate how to add, hide, and override header menu buttons. (The examples below serve +illustrative purposes thus omit certain `import` statements and other non-important parts.) In a combined extension, +the `headerMenu` namespace is declared alongside the Browse View (`actionBar`, `quickActions`) and Details View +(`detailSidePanel`) namespaces in the same `register()` call. + +### Example of adding a custom header menu button + +In this example, an **Export Metadata** button is added to the header menu in the `assets` context. + +```js +function ExtensionRegistration() { + const init = async () => { + const guestConnection = await register({ + id: extensionId, + methods: { + // other namespaces (actionBar, quickActions, detailSidePanel) ... + headerMenu: { + async getButtons({ context, resource }) { + if (context !== 'assets') { + return []; + } + return [ + { + id: 'export-metadata', + label: 'Export Metadata', + icon: 'Download', + variant: 'secondary', + onClick: async ({ context, resource }) => { + // Custom logic + }, + }, + ]; + }, + }, + }, + }); + }; + init().catch(console.error); + + return IFrame for integration with Host (AEM Assets View)...; +} + +export default ExtensionRegistration; +``` + +### Example of hiding a built-in header menu button + +In this example, the built-in **Create folder** header menu button (`createFolder`) is hidden in the `assets` context. + +```js +headerMenu: { + async getHiddenButtonIds({ context, resource }) { + if (context === 'assets') { + return ['createFolder']; + } + return []; + }, +}, +``` + +### Example of overriding a built-in header menu button + +In this example, when the user activates the **Add assets** header menu button (`addAssets`), the extension runs custom +logic and skips the Host's default handler by returning `true`. + +```js +headerMenu: { + async overrideButton({ buttonId, context, resource }) { + if (buttonId === 'addAssets') { + // Custom upload or validation flow + return true; + } + return false; + }, +}, +``` + +### Example in the Details View + +In the Details View, hide the built-in **Download** header menu button and take over the **Assign tasks** click +(skipping the Host handler when you return `true`): + +```js +headerMenu: { + async getHiddenButtonIds({ context, resource }) { + return ['download']; + }, + async overrideButton({ buttonId, context, resource }) { + if (buttonId === 'assignTasks') { + // Custom assign-tasks flow; skip built-in handler + return true; + } + return false; + }, +}, +``` + +To open a custom dialog from a header menu button, refer to the [Modal API](../commons/index.md#modal-api) provided by +AEM Assets View to all extensions for implementation of dialog management. diff --git a/src/pages/services/aem-assets-view/api/index.md b/src/pages/services/aem-assets-view/api/index.md index bc4abb43..d0510580 100644 --- a/src/pages/services/aem-assets-view/api/index.md +++ b/src/pages/services/aem-assets-view/api/index.md @@ -7,7 +7,7 @@ contributors: # The AEM Assets View Extension Points -This section covers the utilization of existing extension points, extension registration, and common methods that can be used in any application that leverages extension points for service customization. +This section covers the utilization of the extension points, extension registration, and common methods that can be used in any application that leverages extension points for service customization. @@ -19,6 +19,29 @@ To get access to Assets View UI extensibility, [create and submit an Adobe Customer Support case](https://helpx.adobe.com/enterprise/using/support-for-experience-cloud.html). You can provide documentation feedback by clicking "Log an issue". +## A single extension point for Assets View + +AEM Assets View provides a unified extension point, `aem/assets/assetsview/1`, that combines Browse View and +Details View extensibility. A single extension registered under `aem/assets/assetsview/1` can customize both +screens — for example, adding an ActionBar action in the Browse View and a side panel in the Details View — from +one App Builder extension, one deployment, and one `register()` call. + +The extensibility APIs are organized into **namespaces**, each covering a granular area of Assets View functionality: + +| Namespace | Screen | Purpose | +|------------|------------|------------| +| [`actionBar`](browse-view/index.md#actionbar-namespace) | Browse View | Add, hide, or override ActionBar actions | +| [`quickActions`](browse-view/index.md#quickactions-namespace) | Browse View | Hide or override QuickActions menu actions | +| [`detailSidePanel`](details-view/index.md#detailsidepanel-namespace) | Details View | Add custom side panels to the side rail | +| [`headerMenu`](header-menu/index.md) | Browse View and Details View | Add, hide, or override header menu buttons | + +Implement only the namespaces your extension needs. The pages below describe each namespace and its methods in detail. + + + +The standalone `aem/assets/browse/1` and `aem/assets/details/1` extension points remain supported for existing +extensions, but new extensions should use the unified `aem/assets/assetsview/1` extension point. + [Common Concepts in Creating Extensions](commons/index.md) diff --git a/src/pages/services/aem-assets-view/code-generation/index.md b/src/pages/services/aem-assets-view/code-generation/index.md index 13be600e..30c846f0 100644 --- a/src/pages/services/aem-assets-view/code-generation/index.md +++ b/src/pages/services/aem-assets-view/code-generation/index.md @@ -1,15 +1,16 @@ --- -title: Code Generation Guide - Details View Extensibility in AEM Assets View +title: Code Generation Guide - AEM Assets View Extensibility description: Learn how to generate base structure of AEM Assets View Extension. contributors: - https://github.com/AdobeDocs/uix --- -# Code Generation for the Details View Extension in AEM Assets View +# Code Generation for the AEM Assets View Extension -The [Asset Browse extension Template](https://github.com/adobe/aem-assets-browse-ext-tpl) and -[Asset Details extension Template](https://github.com/adobe/aem-assets-details-ext-tpl) for the AEM Assets View help developers -to bootstrap their App Builder apps when using the [AIO CLI](https://github.com/adobe/aio-cli) and generates basic extension structure and all required code. +The [Assets View extension Template](https://github.com/adobe/aem-assets-assetsview-ext-tpl) for the AEM Assets View helps +developers to bootstrap their App Builder apps when using the [AIO CLI](https://github.com/adobe/aio-cli) and generates +basic extension structure and all required code. It scaffolds the unified `aem/assets/assetsview/1` extension point, so a +single generated extension can customize both the Browse View and the Details View. @@ -74,7 +75,7 @@ Create a directory and run the following commands from that directory: Only Templates Supported By My Org ``` -4. Use the spacebar to select the template named `@adobe/aem-assets-details-ext-tpl` (Template for an AIO CLI App Builder plugin that generates code for a UI extension in the Asset Details section of the AEM Assets View). +4. Use the spacebar to select the template named `@adobe/aem-assets-assetsview-ext-tpl` (Template for an AIO CLI App Builder plugin that generates code for a UI extension of the AEM Assets View, combining Browse View and Details View extensibility). ```shell ➜ demo-extension-project % aio app init @@ -84,9 +85,7 @@ Create a directory and run the following commands from that directory: ✔ Downloaded the list of templates ? Choose the template(s) to install: | | Template | Description | Extension Point | Categories | - |----|-----------------------------------------|------------------------------------------------------------|---------------------------|----------------------| - | ◯ | @adobe/aem-assets-browse-ext-tpl * | Asset Browse extension Template for the AEM Assets View | aem/assets/browse/1 | action, ui | - | ❯◉ | @adobe/aem-assets-details-ext-tpl * | Asset Details extension Template for the AEM Assets View | aem/assets/details/1 | action, ui | + | ❯◉ | @adobe/aem-assets-assetsview-ext-tpl * | Assets View extension Template for the AEM Assets View | aem/assets/assetsview/1 | action, ui | | ◯ | @adobe/generator-app-api-mesh * | Extensibility template for Adobe API Mesh, for App Builder | N/A | action, graphql-mesh | | ◯ | @adobe/generator-app-excshell * | Extensibility template for generator-aio-app | dx/excshell/1 | action, ui | | - | @adobe/generator-app-asset-compute * | Extensibility template for generator-aio-app | dx/asset-compute/worker/1 | action | @@ -95,22 +94,23 @@ Create a directory and run the following commands from that directory: ... - ✔ Installed npm package @adobe/aem-assets-details-ext-tpl - ℹ Running template @adobe/aem-assets-details-ext-tpl + ✔ Installed npm package @adobe/aem-assets-assetsview-ext-tpl + ℹ Running template @adobe/aem-assets-assetsview-ext-tpl - Overview of the Asset Details extension Template for the AEM Assets View: + Overview of the Assets View extension Template for the AEM Assets View: - * You have the option to generate boilerplate code for your extensible side panel. + * You have the option to generate boilerplate code for a Details View side panel and/or a Browse View ActionBar action. * You can get help regarding documentation at any time from the menu. * An App Builder project will be created with Node.js packages pre-configured. ``` -> If you are experienced user you may also simplify process of template selection by running the command +If you are experienced user you may also simplify process of template selection by running the command: -> ```shell -aio app init --template=@adobe/aem-assets-details-ext-tpl +```shell +aio app init --template=@adobe/aem-assets-assetsview-ext-tpl +``` -> At this point Asset Details extension Template for the AEM Assets View is added to your project and ready to use. +At this point the Assets View extension Template for the AEM Assets View is added to your project and ready to use. ## Provide basic information about extension @@ -129,7 +129,9 @@ aio app init --template=@adobe/aem-assets-details-ext-tpl ```shell ? What would you like to do next? (Use arrow keys) ────────────── - Add a side panel to the Details View + Add a side panel to the Details View + Add an action to the ActionBar + Add a button to the header menu Add server-side handler ────────────── ❯ I'm done @@ -138,41 +140,45 @@ aio app init --template=@adobe/aem-assets-details-ext-tpl ### Novice, explore what is possible -> 6.1. If you are only starting with exploring UI Extensibility feel no hesitation to choose `I don't know`. +6.1. If you are only starting with exploring UI Extensibility feel no hesitation to choose `I don't know`. -> ```shell +```shell ? What would you like to do next? I don't know ? What about this then? (Use arrow keys) ────────────── ❯ Find some help ────────────── Go back +``` -> `Find some help` displays list of useful links. +`Find some help` displays list of useful links. ### Seasoned developer, choose what you need -> 6.2. If you already know what you want to do, start add features to you extensions by selecting items from the main part of the menu. Each part correspond to single Extension Point in AEM Assets View. +6.2. If you already know what you want to do, start add features to you extensions by selecting items from the main part of the menu. Each item corresponds to a capability of the unified `aem/assets/assetsview/1` extension point — a Details View side panel, a Browse View ActionBar action, or a header menu button. You can add as many of each as you need. -> ```shell +```shell ? What would you like to do next? Add a side panel to the Details View ? Please provide tooltip for the side panel icon: Demo panel icon ? Please provide title for the side panel: Demo panel ? Please select React Spectrum icon for the side panel: Extension +``` -> In addition, if your extension requires server-to-server communication add as many server-side handlers as you need. -> ```shell +In addition, if your extension requires server-to-server communication add as many server-side handlers as you need. + +```shell ? What would you like to do next? Add server-side handler ? Adobe I/O Runtime lets you invoke serverless code on demand. How would you like to name this action? export-to-remote-service +``` ### Experts, have full control -> 6.3. If you know what you are doing and want to tweak implementation on low level hit `I'm done` as first answer and you will get bare bone project structure. +6.3. If you know what you are doing and want to tweak implementation on low level hit `I'm done` as first answer and you will get bare bone project structure. ## Add business logic 7. After you choose `I'm done` template starts installation of project's package dependencies and generates code. At this point you already have fully functional UI Extension and it's time to add functionality that you business needs. -The best place to start is navigating directly to `src/aem-assets-details-1/web-src/src/components/ExtensionRegistration.js` +The best place to start is navigating directly to `src/aem-assets-assetsview-1/web-src/src/components/ExtensionRegistration.js` which contains code that defines capabilities of the extension and provides information to the AEM Assets View when and how extension should be invoked. diff --git a/src/pages/services/aem-assets-view/debug/index.md b/src/pages/services/aem-assets-view/debug/index.md index 72c57fa1..82bf2186 100644 --- a/src/pages/services/aem-assets-view/debug/index.md +++ b/src/pages/services/aem-assets-view/debug/index.md @@ -47,7 +47,7 @@ To view your deployed application in the Experience Cloud shell: -> https://experience.adobe.com/?devMode=true#/custom-apps/?localDevUrl=https://localhost:9080 Your actions: web actions: - -> https://localhost:9080/api/v1/web/aem-assets-details-1/my-action + -> https://localhost:9080/api/v1/web/aem-assets-assetsview-1/my-action non-web actions: press CTRL+C to terminate the dev environment 2024-10-16T13:53:10.658Z [serve] info: server running on port : 9080 @@ -140,8 +140,8 @@ for the same extension point by separating them with a comma. **Example:** -`ext.aem%2fassets%2fdetails%2f1=https://localhost:9080` loads locally running extension from `https://localhost:9080` -and applies it to the `aem/assets/details/1` extension point. +`ext.aem%2fassets%2fassetsview%2f1=https://localhost:9080` loads locally running extension from `https://localhost:9080` +and applies it to the `aem/assets/assetsview/1` extension point. The `ext=` parameter can also be used without specifying the extension point ID: ``` diff --git a/src/pages/services/aem-assets-view/extension-development/index.md b/src/pages/services/aem-assets-view/extension-development/index.md index 0bbbce90..e77800a7 100644 --- a/src/pages/services/aem-assets-view/extension-development/index.md +++ b/src/pages/services/aem-assets-view/extension-development/index.md @@ -21,10 +21,15 @@ You can provide documentation feedback by clicking "Log an issue". ## About application -This example application will use the [Details View extension point](../api/details-view/index.md). It will render +This example application will use the unified `aem/assets/assetsview/1` extension point and the +[Details View](../api/details-view/index.md) `detailSidePanel` namespace. It will render a custom icon in the side panel rail only if the selected asset has the "jpeg" extension. When the user clicks on the icon, the extension will display a custom panel with a button. Clicking the button will display a toast message with the asset's path. +Because it uses the unified extension point, the same extension could also customize the +[Browse View](../api/browse-view/index.md) — for example, adding an ActionBar action — by declaring the corresponding +namespaces in the same `register()` call. This guide focuses on a single Details View side panel to keep the example concise. + More information about AEM Assets View extension points can be found at [AEM Assets View Extension Points](../api/index.md). ## Create a project in Adobe Developer Console @@ -114,7 +119,7 @@ More details are described in [Local environment set up](../../../guides/local-e ## Initialize your extension using the AIO CLI and generate a base structure from the template First, we need to [sign in from CLI](https://developer.adobe.com/app-builder/docs/getting_started/first_app/#3-signing-in-from-cli) and bootstrap our project. -Please complete all the steps described in [Code Generation for the Details View Extension in AEM Assets View](../code-generation/index.md). +Please complete all the steps described in [Code Generation for the AEM Assets View Extension](../code-generation/index.md). For the purposes of this guide, we will use - `Asset Info Extension` as the extension name and description @@ -139,7 +144,7 @@ of a UI Extension that implements [extension points](https://developer.adobe.com |-- package-lock.json |-- package.json `-- src - `-- aem-assets-details-1 + `-- aem-assets-assetsview-1 |-- ext.config.yaml `-- web-src |-- index.html @@ -157,8 +162,8 @@ of a UI Extension that implements [extension points](https://developer.adobe.com ```yaml # app.config.yaml extensions: - aem/assets/details/1: - $include: src/aem-assets-details-1/ext.config.yaml + aem/assets/assetsview/1: + $include: src/aem-assets-assetsview-1/ext.config.yaml ``` If necessary, you can find other bootstrap options in [Bootstrapping new App using the CLI](https://developer.adobe.com/app-builder/docs/getting_started/first_app/#4-bootstrapping-new-app-using-the-cli). @@ -167,7 +172,7 @@ If necessary, you can find other bootstrap options in [Bootstrapping new App usi ### Routing -The root component `src/aem-assets-details-1/web-src/src/components/App.js` contains the routing of our application. It defines three routes: +The root component `src/aem-assets-assetsview-1/web-src/src/components/App.js` contains the routing of our application. It defines three routes: - the first two are the default routes which trigger the `ExtensionRegistration` component responsible for initial extension registration within the AEM Assets View application. - the `asset-info` route which invokes the `PanelAssetInfo` component responsible for rendering the @@ -222,7 +227,7 @@ Please note that your code may slightly differ from the given example depending ### Extension registration -This logic component `src/aem-assets-view-1/web-src/src/components/ExtensionRegistration.js` registers our extension +This logic component `src/aem-assets-assetsview-1/web-src/src/components/ExtensionRegistration.js` registers our extension with the host AEM instance as soon as it loads, so they can share data and communicate with each other. ```js @@ -287,7 +292,7 @@ Note that we have to `await` the `getCurrentResourceInfo()` method call to get t ### Custom panel -The `src/aem-assets-details-1/web-src/src/components/PanelAssetInfo.js` component is responsible for rendering the custom panel content. +The `src/aem-assets-assetsview-1/web-src/src/components/PanelAssetInfo.js` component is responsible for rendering the custom panel content. ```js import React, { useState, useEffect } from 'react'; @@ -402,17 +407,17 @@ After that, we build and deploy the frontend files/assets: ```shell aio app deploy - no backend or a build already exists, skipping action build for 'aem/assets/details/1' -✔ Building web assets for 'aem/assets/details/1' -no backend, skipping action deploy 'aem/assets/details/1' -✔ Deploying web assets for 'aem/assets/details/1' + no backend or a build already exists, skipping action build for 'aem/assets/assetsview/1' +✔ Building web assets for 'aem/assets/assetsview/1' +no backend, skipping action deploy 'aem/assets/assetsview/1' +✔ Deploying web assets for 'aem/assets/assetsview/1' To view your deployed application: -> https://123456-yournamespace-stage.adobeio-static.net/index.html To view your deployed application in the Experience Cloud shell: -> https://experience.adobe.com/?devMode=true#/custom-apps/?localDevUrl=https://123456-yournamespace-stage.adobeio-static.net/index.html For a developer preview of your UI extension in the AEM Assets View environment, follow the URL: -> https://experience.adobe.com/aem/extension-manager/preview/ -New Extension Point(s) in Workspace 'Stage': 'aem/assets/details/1' +New Extension Point(s) in Workspace 'Stage': 'aem/assets/assetsview/1' Successful deployment 🏄 ``` diff --git a/src/pages/services/aem-assets-view/index.md b/src/pages/services/aem-assets-view/index.md index 64434066..0d331983 100644 --- a/src/pages/services/aem-assets-view/index.md +++ b/src/pages/services/aem-assets-view/index.md @@ -24,5 +24,7 @@ You can provide documentation feedback by clicking "Log an issue". UI Extensibility allows 3rd party developers to extend and customize AEM Assets View with modern front-end technology stack with JavaScript, Node.js and React. -In this section, you will find the available [extension points](api/index.md) and examples of how to utilize them. +AEM Assets View exposes a single, unified extension point, `aem/assets/assetsview/1`, that lets one extension +customize both the Browse View and the Details View. In this section, you will find the available +[extension points](api/index.md) and examples of how to utilize them. From f3913a71031b3ad858a3ffcdf2cccfadb8cfda68 Mon Sep 17 00:00:00 2001 From: Cris Rockwell Date: Wed, 26 Aug 2026 10:24:27 -0400 Subject: [PATCH 2/2] Fix MDX lint errors: backtick headerMenu method-signature headings The three method headings in the Header Menu page contained unescaped curly braces ({ context, resource }), which MDX parses as JSX expressions and the devsite linter rejects. Wrap the signatures in backticks, matching the method-heading convention used by the sibling API pages (e.g. modal). Co-Authored-By: Claude Opus 4.8 --- src/pages/services/aem-assets-view/api/header-menu/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/services/aem-assets-view/api/header-menu/index.md b/src/pages/services/aem-assets-view/api/header-menu/index.md index 61f8f9d5..7947bc3a 100644 --- a/src/pages/services/aem-assets-view/api/header-menu/index.md +++ b/src/pages/services/aem-assets-view/api/header-menu/index.md @@ -84,7 +84,7 @@ header menu buttons. All of its methods are optional — implement only the ones For example, you can implement only `getHiddenButtonIds` or `overrideButton` without implementing `getButtons`. -### getButtons({ context, resource }) +### `getButtons({ context, resource })` **Description:** Returns an array of custom header menu button definitions that are added to the application's header menu. These buttons are rendered alongside built-in header menu buttons and let extensions surface actions in the header @@ -133,7 +133,7 @@ headerMenu: { }, ``` -### getHiddenButtonIds({ context, resource }) +### `getHiddenButtonIds({ context, resource })` **Description:** Returns an array of [built-in header menu button ids](#built-in-header-menu-buttons) that should be hidden. @@ -158,7 +158,7 @@ getHiddenButtonIds: ({ context, resource }) => { }, ``` -### overrideButton({ buttonId, context, resource }) +### `overrideButton({ buttonId, context, resource })` **Description:** Return `true` if the extension handled the click and the built-in header menu button handler should **not** run. Return `false` to let the Host run the default behavior.