Browse Source

docs(admin-ui): Add documentation for bulk actions

Michael Bromley 3 years ago
parent
commit
f0b14323ce

+ 90 - 0
docs/content/plugins/extending-the-admin-ui/bulk-actions/_index.md

@@ -0,0 +1,90 @@
+---
+title: 'Bulk Actions'
+weight: 7
+---
+
+# Bulk Actions
+
+Certain list views in the Admin UI support bulk actions. There are a default set of bulk actions that are defined by the Admin UI itself (e.g. delete, assign to channels), but using the `@vendure/ui-devit` package
+you are also able to define your own bulk actions.
+
+{{< figure src="./bulk-actions-screenshot.png" >}} 
+
+Use cases for bulk actions include things like:
+
+- Sending multiple products to a 3rd-party localization service
+- Exporting selected products to csv 
+- Bulk-updating custom field data
+
+## Bulk Action Example
+
+A bulk action must be provided to a [ui-extension shared module]({{< relref "extending-the-admin-ui" >}}#lazy-vs-shared-modules) using the [`registerBulkAction` function]({{< relref "register-bulk-action" >}})
+
+```TypeScript
+import { NgModule } from '@angular/core';
+import { ModalService, registerBulkAction, SharedModule } from '@vendure/admin-ui/core';
+
+@NgModule({
+  imports: [SharedModule],
+  providers: [
+    ProductDataTranslationService,
+      
+    // Here is where we define our bulk action
+    // for sending the selected products to a 3rd-party 
+    // translation API  
+    registerBulkAction({
+      // This tells the Admin UI that this bulk action should be made
+      // available on the product list view.  
+      location: 'product-list',
+      label: 'Send to translation service',
+      icon: 'language',
+      // Here is the logic that is executed when the bulk action menu item
+      // is clicked.  
+      onClick: ({ injector, selection }) => {
+        const modalService = injector.get(ModalService);
+        const translationService = injector.get(ProductDataTranslationService);
+        modalService
+          .dialog({
+            title: `Send ${selection.length} products for translation?`,
+            buttons: [
+              { type: 'secondary', label: 'cancel' },
+              { type: 'primary', label: 'send', returnValue: true },
+            ],
+          })
+          .subscribe(response => {
+            if (response) {
+              translationService.sendForTranslation(selection.map(item => item.productId));
+            }
+          });
+      },
+    }),
+  ],
+})
+export class MyUiExtensionModule {}
+```
+
+## Conditionally displaying bulk actions
+
+Sometimes a bulk action only makes sense in certain circumstances. For example, the "assign to channel" action only makes sense when your server has multiple channels set up.
+
+We can conditionally control the display of a bulk action with the `isVisible` function, which should return a Promise resolving to a boolean:
+
+```TypeScript
+import { registerBulkAction, DataService } from '@vendure/admin-ui/core';
+
+registerBulkAction({
+  location: 'product-list',
+  label: 'Assign to channel',
+  // Only display this action if there are multiple channels
+  isVisible: ({ injector }) => injector.get(DataService).client
+    .userStatus()
+    .mapSingle(({ userStatus }) => 1 < userStatus.channels.length)
+    .toPromise(),
+  // ...  
+});
+```
+
+Related API docs:
+
+- [`registerBulkAction`]({{< relref "register-bulk-action" >}})
+- [`BulkAction`]({{< relref "bulk-action" >}})

BIN
docs/content/plugins/extending-the-admin-ui/bulk-actions/bulk-actions-screenshot.png


+ 30 - 0
packages/admin-ui/src/lib/core/src/providers/bulk-action-registry/bulk-action-types.ts

@@ -116,11 +116,41 @@ export interface BulkAction<ItemType = any, ComponentType = any> {
      *
      * This function will be invoked each time the selection is changed, so try to avoid expensive code
      * running here.
+     *
+     * @example
+     * ```TypeScript
+     * import { registerBulkAction, DataService } from '\@vendure/admin-ui/core';
+     *
+     * registerBulkAction({
+     *   location: 'product-list',
+     *   label: 'Assign to channel',
+     *   // Only display this action if there are multiple channels
+     *   isVisible: ({ injector }) => injector.get(DataService).client
+     *     .userStatus()
+     *     .mapSingle(({ userStatus }) => 1 < userStatus.channels.length)
+     *     .toPromise(),
+     *   // ...
+     * });
+     * ```
      */
     isVisible?: (context: BulkActionFunctionContext<ItemType, ComponentType>) => boolean | Promise<boolean>;
     /**
      * @description
      * Control the display of this item based on the user permissions.
+     *
+     * @example
+     * ```TypeScript
+     * registerBulkAction({
+     *   // Can be specified as a simple string
+     *   requiresPermission: Permission.UpdateProduct,
+     *
+     *   // Or as a function that returns a boolean if permissions are satisfied
+     *   requiresPermission: userPermissions =>
+     *     userPermissions.includes(Permission.UpdateCatalog) ||
+     *     userPermissions.includes(Permission.UpdateProduct),
+     *   // ...
+     * })
+     * ```
      */
     requiresPermission?: string | ((userPermissions: string[]) => boolean);
 }

+ 3 - 0
packages/admin-ui/src/lib/core/src/providers/bulk-action-registry/register-bulk-action.ts

@@ -17,6 +17,9 @@ import { BulkAction } from './bulk-action-types';
  *
  * @example
  * ```TypeScript
+ * import { NgModule } from '\@angular/core';
+ * import { ModalService, registerBulkAction, SharedModule } from '\@vendure/admin-ui/core';
+ *
  * \@NgModule({
  *   imports: [SharedModule],
  *   providers: [