Skip to content

Commit

Permalink
feat(core): Implement deleteAssets mutation
Browse files Browse the repository at this point in the history
Relates to #380
  • Loading branch information
michaelbromley committed Jul 2, 2020
1 parent a4e132a commit 6f12014
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,8 @@ export type Mutation = {
updateAsset: Asset;
/** Delete an Asset */
deleteAsset: DeletionResponse;
/** Delete multiple Assets */
deleteAssets: DeletionResponse;
login: LoginResult;
logout: Scalars['Boolean'];
/** Create a new Channel */
Expand Down Expand Up @@ -1934,6 +1936,11 @@ export type MutationDeleteAssetArgs = {
force?: Maybe<Scalars['Boolean']>;
};

export type MutationDeleteAssetsArgs = {
ids: Array<Scalars['ID']>;
force?: Maybe<Scalars['Boolean']>;
};

export type MutationLoginArgs = {
username: Scalars['String'];
password: Scalars['String'];
Expand Down
8 changes: 8 additions & 0 deletions packages/common/src/generated-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1766,6 +1766,8 @@ export type Mutation = {
updateAsset: Asset;
/** Delete an Asset */
deleteAsset: DeletionResponse;
/** Delete multiple Assets */
deleteAssets: DeletionResponse;
login: LoginResult;
logout: Scalars['Boolean'];
/** Create a new Channel */
Expand Down Expand Up @@ -1940,6 +1942,12 @@ export type MutationDeleteAssetArgs = {
};


export type MutationDeleteAssetsArgs = {
ids: Array<Scalars['ID']>;
force?: Maybe<Scalars['Boolean']>;
};


export type MutationLoginArgs = {
username: Scalars['String'];
password: Scalars['String'];
Expand Down
7 changes: 7 additions & 0 deletions packages/core/e2e/graphql/generated-e2e-admin-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,8 @@ export type Mutation = {
updateAsset: Asset;
/** Delete an Asset */
deleteAsset: DeletionResponse;
/** Delete multiple Assets */
deleteAssets: DeletionResponse;
login: LoginResult;
logout: Scalars['Boolean'];
/** Create a new Channel */
Expand Down Expand Up @@ -1934,6 +1936,11 @@ export type MutationDeleteAssetArgs = {
force?: Maybe<Scalars['Boolean']>;
};

export type MutationDeleteAssetsArgs = {
ids: Array<Scalars['ID']>;
force?: Maybe<Scalars['Boolean']>;
};

export type MutationLoginArgs = {
username: Scalars['String'];
password: Scalars['String'];
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/api/resolvers/admin/asset.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import {
MutationCreateAssetsArgs,
MutationDeleteAssetArgs,
MutationDeleteAssetsArgs,
MutationUpdateAssetArgs,
Permission,
QueryAssetArgs,
Expand Down Expand Up @@ -53,6 +54,12 @@ export class AssetResolver {
@Mutation()
@Allow(Permission.DeleteCatalog)
async deleteAsset(@Ctx() ctx: RequestContext, @Args() { id, force }: MutationDeleteAssetArgs) {
return this.assetService.delete(ctx, id, force || undefined);
return this.assetService.delete(ctx, [id], force || undefined);
}

@Mutation()
@Allow(Permission.DeleteCatalog)
async deleteAssets(@Ctx() ctx: RequestContext, @Args() { ids, force }: MutationDeleteAssetsArgs) {
return this.assetService.delete(ctx, ids, force || undefined);
}
}
2 changes: 2 additions & 0 deletions packages/core/src/api/schema/admin-api/asset.api.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ type Mutation {
updateAsset(input: UpdateAssetInput!): Asset!
"Delete an Asset"
deleteAsset(id: ID!, force: Boolean): DeletionResponse!
"Delete multiple Assets"
deleteAssets(ids: [ID!]!, force: Boolean): DeletionResponse!
}

# generated by generateListOptions function
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"unexpected-password-on-registration": "Do not provide a password when `authOptions.requireVerification` is set to \"true\""
},
"message": {
"asset-to-be-deleted-is-featured": "The selected Asset is featured by {products, plural, =0 {} one {1 Product} other {# Products}}{variants, plural, =0 {} one { 1 ProductVariant} other { # ProductVariants}}{collections, plural, =0 {} one { 1 Collection} other { # Collections}}",
"asset-to-be-deleted-is-featured": "The selected {assetCount, plural, one {Asset is} other {Assets are}} featured by {products, plural, =0 {} one {1 Product} other {# Products}} {variants, plural, =0 {} one { 1 ProductVariant} other { # ProductVariants}} {collections, plural, =0 {} one { 1 Collection} other { # Collections}}",
"country-used-in-addresses": "The selected Country cannot be deleted as it is used in {count, plural, one {1 Address} other {# Addresses}}",
"facet-force-deleted": "The Facet was deleted and its FacetValues were removed from {products, plural, =0 {} one {1 Product} other {# Products}}{both, select, both { , } single {}}{variants, plural, =0 {} one {1 ProductVariant} other {# ProductVariants}}",
"facet-used": "The selected Facet includes FacetValues which are assigned to {products, plural, =0 {} one {1 Product} other {# Products}}{both, select, both { , } single {}}{variants, plural, =0 {} one {1 ProductVariant} other {# ProductVariants}}",
Expand Down
47 changes: 30 additions & 17 deletions packages/core/src/service/services/asset.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,31 +155,44 @@ export class AssetService {
return updatedAsset;
}

async delete(ctx: RequestContext, id: ID, force: boolean = false): Promise<DeletionResponse> {
const asset = await getEntityOrThrow(this.connection, Asset, id);
const usages = await this.findAssetUsages(asset);
const hasUsages = !!(usages.products.length || usages.variants.length || usages.collections.length);
async delete(ctx: RequestContext, ids: ID[], force: boolean = false): Promise<DeletionResponse> {
const assets = await this.connection.getRepository(Asset).findByIds(ids);
const usageCount = {
products: 0,
variants: 0,
collections: 0,
};
for (const asset of assets) {
const usages = await this.findAssetUsages(asset);
usageCount.products += usages.products.length;
usageCount.variants += usages.variants.length;
usageCount.collections += usages.collections.length;
}
const hasUsages = !!(usageCount.products || usageCount.variants || usageCount.collections);
if (hasUsages && !force) {
return {
result: DeletionResult.NOT_DELETED,
message: ctx.translate('message.asset-to-be-deleted-is-featured', {
products: usages.products.length,
variants: usages.variants.length,
collections: usages.collections.length,
assetCount: assets.length,
products: usageCount.products,
variants: usageCount.variants,
collections: usageCount.collections,
}),
};
}
// Create a new asset so that the id is still available
// after deletion (the .remove() method sets it to undefined)
const deletedAsset = new Asset(asset);
await this.connection.getRepository(Asset).remove(asset);
try {
await this.configService.assetOptions.assetStorageStrategy.deleteFile(asset.source);
await this.configService.assetOptions.assetStorageStrategy.deleteFile(asset.preview);
} catch (e) {
Logger.error(`error.could-not-delete-asset-file`, undefined, e.stack);
for (const asset of assets) {
// Create a new asset so that the id is still available
// after deletion (the .remove() method sets it to undefined)
const deletedAsset = new Asset(asset);
await this.connection.getRepository(Asset).remove(asset);
try {
await this.configService.assetOptions.assetStorageStrategy.deleteFile(asset.source);
await this.configService.assetOptions.assetStorageStrategy.deleteFile(asset.preview);
} catch (e) {
Logger.error(`error.could-not-delete-asset-file`, undefined, e.stack);
}
this.eventBus.publish(new AssetEvent(ctx, deletedAsset, 'deleted'));
}
this.eventBus.publish(new AssetEvent(ctx, deletedAsset, 'deleted'));
return {
result: DeletionResult.DELETED,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,8 @@ export type Mutation = {
updateAsset: Asset;
/** Delete an Asset */
deleteAsset: DeletionResponse;
/** Delete multiple Assets */
deleteAssets: DeletionResponse;
login: LoginResult;
logout: Scalars['Boolean'];
/** Create a new Channel */
Expand Down Expand Up @@ -1934,6 +1936,11 @@ export type MutationDeleteAssetArgs = {
force?: Maybe<Scalars['Boolean']>;
};

export type MutationDeleteAssetsArgs = {
ids: Array<Scalars['ID']>;
force?: Maybe<Scalars['Boolean']>;
};

export type MutationLoginArgs = {
username: Scalars['String'];
password: Scalars['String'];
Expand Down
2 changes: 1 addition & 1 deletion schema-admin.json

Large diffs are not rendered by default.

0 comments on commit 6f12014

Please sign in to comment.