Просмотр исходного кода

feat(core): Add bulk collection delete mutation

Relates to #853
Michael Bromley 3 лет назад
Родитель
Сommit
98b4c573fc

+ 7 - 0
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts

@@ -2296,6 +2296,8 @@ export type Mutation = {
   updateCollection: Collection;
   /** Delete a Collection and all of its descendants */
   deleteCollection: DeletionResponse;
+  /** Delete a Collection and all of its descendants */
+  deleteCollections: Array<DeletionResponse>;
   /** Move a Collection to a different parent or index */
   moveCollection: Collection;
   /** Assigns Collections to the specified Channel */
@@ -2577,6 +2579,11 @@ export type MutationDeleteCollectionArgs = {
 };
 
 
+export type MutationDeleteCollectionsArgs = {
+  ids: Array<Scalars['ID']>;
+};
+
+
 export type MutationMoveCollectionArgs = {
   input: MoveCollectionInput;
 };

+ 7 - 0
packages/common/src/generated-types.ts

@@ -2373,6 +2373,8 @@ export type Mutation = {
   updateCollection: Collection;
   /** Delete a Collection and all of its descendants */
   deleteCollection: DeletionResponse;
+  /** Delete a Collection and all of its descendants */
+  deleteCollections: Array<DeletionResponse>;
   /** Move a Collection to a different parent or index */
   moveCollection: Collection;
   /** Assigns Collections to the specified Channel */
@@ -2654,6 +2656,11 @@ export type MutationDeleteCollectionArgs = {
 };
 
 
+export type MutationDeleteCollectionsArgs = {
+  ids: Array<Scalars['ID']>;
+};
+
+
 export type MutationMoveCollectionArgs = {
   input: MoveCollectionInput;
 };

+ 82 - 1
packages/core/e2e/collection.e2e-spec.ts

@@ -10,7 +10,7 @@ import gql from 'graphql-tag';
 import path from 'path';
 
 import { initialData } from '../../../e2e-common/e2e-initial-data';
-import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
+import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
 import { pick } from '../../common/lib/pick';
 import { productIdCollectionFilter, variantIdCollectionFilter } from '../src/index';
 
@@ -29,6 +29,9 @@ import {
     CreateCollectionSelectVariants,
     CurrencyCode,
     DeleteCollection,
+    DeleteCollectionsBulk,
+    DeleteCollectionsBulkMutation,
+    DeleteCollectionsBulkMutationVariables,
     DeleteProduct,
     DeleteProductVariant,
     DeletionResult,
@@ -38,6 +41,8 @@ import {
     GetCollectionBreadcrumbs,
     GetCollectionListAdminQuery,
     GetCollectionListAdminQueryVariables,
+    GetCollectionListQuery,
+    GetCollectionListQueryVariables,
     GetCollectionNestedParents,
     GetCollectionProducts,
     GetCollections,
@@ -2178,6 +2183,73 @@ describe('Collection resolver', () => {
         });
     });
 
+    describe('deleteCollections (multiple)', () => {
+        let top: CollectionFragment;
+        let child: CollectionFragment;
+        let grandchild: CollectionFragment;
+        beforeAll(async () => {
+            async function createNewCollection(name: string, parentId?: string) {
+                const { createCollection } = await adminClient.query<
+                    CreateCollectionMutation,
+                    CreateCollectionMutationVariables
+                >(CREATE_COLLECTION, {
+                    input: {
+                        translations: [
+                            {
+                                languageCode: LanguageCode.en,
+                                name,
+                                description: '',
+                                slug: name,
+                            },
+                        ],
+                        filters: [],
+                    },
+                });
+                return createCollection;
+            }
+
+            top = await createNewCollection('top');
+            child = await createNewCollection('child', top.id);
+            grandchild = await createNewCollection('grandchild', child.id);
+        });
+
+        it('deletes all selected collections', async () => {
+            const { collections: before } = await adminClient.query<
+                GetCollectionListQuery,
+                GetCollectionListQueryVariables
+            >(GET_COLLECTION_LIST);
+
+            expect(before.items.map(pick(['id', 'name'])).sort(sortById)).toEqual([
+                { id: 'T_28', name: 'top' },
+                { id: 'T_29', name: 'child' },
+                { id: 'T_30', name: 'grandchild' },
+                { id: 'T_8', name: 'Accessories' },
+            ]);
+
+            const { deleteCollections } = await adminClient.query<
+                DeleteCollectionsBulkMutation,
+                DeleteCollectionsBulkMutationVariables
+            >(DELETE_COLLECTIONS_BULK, {
+                ids: [top.id, child.id, grandchild.id],
+            });
+
+            expect(deleteCollections).toEqual([
+                { result: DeletionResult.DELETED, message: null },
+                { result: DeletionResult.DELETED, message: null },
+                { result: DeletionResult.DELETED, message: null },
+            ]);
+
+            const { collections: after } = await adminClient.query<
+                GetCollectionListQuery,
+                GetCollectionListQueryVariables
+            >(GET_COLLECTION_LIST);
+
+            expect(after.items.map(pick(['id', 'name'])).sort(sortById)).toEqual([
+                { id: 'T_8', name: 'Accessories' },
+            ]);
+        });
+    });
+
     function getFacetValueId(code: string): string {
         const match = facetValues.find(fv => fv.code === code);
         if (!match) {
@@ -2384,3 +2456,12 @@ const REMOVE_COLLECTIONS_FROM_CHANNEL = gql`
     }
     ${COLLECTION_FRAGMENT}
 `;
+
+const DELETE_COLLECTIONS_BULK = gql`
+    mutation DeleteCollectionsBulk($ids: [ID!]!) {
+        deleteCollections(ids: $ids) {
+            message
+            result
+        }
+    }
+`;

+ 20 - 0
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -2296,6 +2296,8 @@ export type Mutation = {
   updateCollection: Collection;
   /** Delete a Collection and all of its descendants */
   deleteCollection: DeletionResponse;
+  /** Delete a Collection and all of its descendants */
+  deleteCollections: Array<DeletionResponse>;
   /** Move a Collection to a different parent or index */
   moveCollection: Collection;
   /** Assigns Collections to the specified Channel */
@@ -2577,6 +2579,11 @@ export type MutationDeleteCollectionArgs = {
 };
 
 
+export type MutationDeleteCollectionsArgs = {
+  ids: Array<Scalars['ID']>;
+};
+
+
 export type MutationMoveCollectionArgs = {
   input: MoveCollectionInput;
 };
@@ -5539,6 +5546,13 @@ export type RemoveCollectionsFromChannelMutationVariables = Exact<{
 
 export type RemoveCollectionsFromChannelMutation = { removeCollectionsFromChannel: Array<CollectionFragment> };
 
+export type DeleteCollectionsBulkMutationVariables = Exact<{
+  ids: Array<Scalars['ID']> | Scalars['ID'];
+}>;
+
+
+export type DeleteCollectionsBulkMutation = { deleteCollections: Array<Pick<DeletionResponse, 'message' | 'result'>> };
+
 export type GetCheckersQueryVariables = Exact<{ [key: string]: never; }>;
 
 
@@ -7654,6 +7668,12 @@ export namespace RemoveCollectionsFromChannel {
   export type RemoveCollectionsFromChannel = NonNullable<(NonNullable<RemoveCollectionsFromChannelMutation['removeCollectionsFromChannel']>)[number]>;
 }
 
+export namespace DeleteCollectionsBulk {
+  export type Variables = DeleteCollectionsBulkMutationVariables;
+  export type Mutation = DeleteCollectionsBulkMutation;
+  export type DeleteCollections = NonNullable<(NonNullable<DeleteCollectionsBulkMutation['deleteCollections']>)[number]>;
+}
+
 export namespace GetCheckers {
   export type Variables = GetCheckersQueryVariables;
   export type Query = GetCheckersQuery;

+ 16 - 3
packages/core/src/api/resolvers/admin/collection.resolver.ts

@@ -1,10 +1,13 @@
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import {
     ConfigurableOperationDefinition,
-    DeletionResponse, MutationAssignCollectionsToChannelArgs,
+    DeletionResponse,
+    MutationAssignCollectionsToChannelArgs,
     MutationCreateCollectionArgs,
     MutationDeleteCollectionArgs,
-    MutationMoveCollectionArgs, MutationRemoveCollectionsFromChannelArgs,
+    MutationDeleteCollectionsArgs,
+    MutationMoveCollectionArgs,
+    MutationRemoveCollectionsFromChannelArgs,
     MutationUpdateCollectionArgs,
     Permission,
     QueryCollectionArgs,
@@ -138,6 +141,16 @@ export class CollectionResolver {
         return this.collectionService.delete(ctx, args.id);
     }
 
+    @Transaction()
+    @Mutation()
+    @Allow(Permission.DeleteCatalog, Permission.DeleteCollection)
+    async deleteCollections(
+        @Ctx() ctx: RequestContext,
+        @Args() args: MutationDeleteCollectionsArgs,
+    ): Promise<DeletionResponse[]> {
+        return Promise.all(args.ids.map(id => this.collectionService.delete(ctx, id)));
+    }
+
     /**
      * Encodes any entity IDs used in the filter arguments.
      */
@@ -158,7 +171,7 @@ export class CollectionResolver {
         @Ctx() ctx: RequestContext,
         @Args() args: MutationAssignCollectionsToChannelArgs,
     ): Promise<Array<Translated<Collection>>> {
-        return await this.collectionService.assignCollectionsToChannel(ctx,args.input);
+        return await this.collectionService.assignCollectionsToChannel(ctx, args.input);
     }
 
     @Transaction()

+ 3 - 0
packages/core/src/api/schema/admin-api/collection.api.graphql

@@ -17,6 +17,9 @@ type Mutation {
     "Delete a Collection and all of its descendants"
     deleteCollection(id: ID!): DeletionResponse!
 
+    "Delete multiple Collections and all of their descendants"
+    deleteCollections(ids: [ID!]!): [DeletionResponse!]!
+
     "Move a Collection to a different parent or index"
     moveCollection(input: MoveCollectionInput!): Collection!
 

+ 7 - 0
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts

@@ -2296,6 +2296,8 @@ export type Mutation = {
   updateCollection: Collection;
   /** Delete a Collection and all of its descendants */
   deleteCollection: DeletionResponse;
+  /** Delete a Collection and all of its descendants */
+  deleteCollections: Array<DeletionResponse>;
   /** Move a Collection to a different parent or index */
   moveCollection: Collection;
   /** Assigns Collections to the specified Channel */
@@ -2577,6 +2579,11 @@ export type MutationDeleteCollectionArgs = {
 };
 
 
+export type MutationDeleteCollectionsArgs = {
+  ids: Array<Scalars['ID']>;
+};
+
+
 export type MutationMoveCollectionArgs = {
   input: MoveCollectionInput;
 };

+ 7 - 0
packages/payments-plugin/e2e/graphql/generated-admin-types.ts

@@ -2296,6 +2296,8 @@ export type Mutation = {
   updateCollection: Collection;
   /** Delete a Collection and all of its descendants */
   deleteCollection: DeletionResponse;
+  /** Delete a Collection and all of its descendants */
+  deleteCollections: Array<DeletionResponse>;
   /** Move a Collection to a different parent or index */
   moveCollection: Collection;
   /** Assigns Collections to the specified Channel */
@@ -2577,6 +2579,11 @@ export type MutationDeleteCollectionArgs = {
 };
 
 
+export type MutationDeleteCollectionsArgs = {
+  ids: Array<Scalars['ID']>;
+};
+
+
 export type MutationMoveCollectionArgs = {
   input: MoveCollectionInput;
 };

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
schema-admin.json


Некоторые файлы не были показаны из-за большого количества измененных файлов