Skip to content

Commit

Permalink
fix(core): Allow removal of all Assets from an entity
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Sep 16, 2019
1 parent 0e624f4 commit 528eb3c
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 27 deletions.
15 changes: 15 additions & 0 deletions packages/core/e2e/collection.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,21 @@ describe('Collection resolver', () => {

expect(updateCollection.assets.map(a => a.id)).toEqual([assets[3].id, assets[0].id]);
});

it('removes all assets', async () => {
const { updateCollection } = await client.query<
UpdateCollection.Mutation,
UpdateCollection.Variables
>(UPDATE_COLLECTION, {
input: {
id: pearCollection.id,
assetIds: [],
},
});

expect(updateCollection.assets).toEqual([]);
expect(updateCollection.featuredAsset).toBeNull();
});
});

it('collection query', async () => {
Expand Down
28 changes: 19 additions & 9 deletions packages/core/src/service/services/asset.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ import { VendureEntity } from '../../entity/base/base.entity';
import { ListQueryBuilder } from '../helpers/list-query-builder/list-query-builder';

export interface EntityWithAssets extends VendureEntity {
featuredAsset: Asset;
featuredAsset: Asset | null;
assets: OrderableAsset[];
}

export interface EntityAssetInput {
assetIds?: ID[] | null;
featuredAssetId?: ID | null;
}

@Injectable()
export class AssetService {
constructor(
Expand Down Expand Up @@ -68,7 +73,7 @@ export class AssetService {
.findOne(entity.id, {
relations: ['featuredAsset'],
});
return entityWithFeaturedAsset && entityWithFeaturedAsset.featuredAsset;
return (entityWithFeaturedAsset && entityWithFeaturedAsset.featuredAsset) || undefined;
}

async getEntityAssets<T extends EntityWithAssets>(entity: T): Promise<Asset[] | undefined> {
Expand All @@ -85,11 +90,13 @@ export class AssetService {
return assets.sort((a, b) => a.position - b.position).map(a => a.asset);
}

async updateFeaturedAsset<T extends EntityWithAssets>(
entity: T,
featuredAssetId?: ID | null,
): Promise<T> {
if (!featuredAssetId) {
async updateFeaturedAsset<T extends EntityWithAssets>(entity: T, input: EntityAssetInput): Promise<T> {
const { assetIds, featuredAssetId } = input;
if (featuredAssetId === null || (assetIds && assetIds.length === 0)) {
entity.featuredAsset = null;
return entity;
}
if (featuredAssetId === undefined) {
return entity;
}
const featuredAsset = await this.findOne(featuredAssetId);
Expand All @@ -102,17 +109,20 @@ export class AssetService {
/**
* Updates the assets / featuredAsset of an entity, ensuring that only valid assetIds are used.
*/
async updateEntityAssets<T extends EntityWithAssets>(entity: T, assetIds?: ID[] | null): Promise<T> {
async updateEntityAssets<T extends EntityWithAssets>(entity: T, input: EntityAssetInput): Promise<T> {
if (!entity.id) {
throw new InternalServerError('error.entity-must-have-an-id');
}
const { assetIds, featuredAssetId } = input;
if (assetIds && assetIds.length) {
const assets = await this.connection.getRepository(Asset).findByIds(assetIds);
const sortedAssets = assetIds
.map(id => assets.find(a => idsAreEqual(a.id, id)))
.filter(notNullOrUndefined);
this.removeExistingOrderableAssets(entity);
await this.removeExistingOrderableAssets(entity);
entity.assets = await this.createOrderableAssets(entity, sortedAssets);
} else if (assetIds && assetIds.length === 0) {
await this.removeExistingOrderableAssets(entity);
}
return entity;
}
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/service/services/collection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,10 @@ export class CollectionService implements OnModuleInit {
}
coll.position = await this.getNextPositionInParent(ctx, input.parentId || undefined);
coll.filters = this.getCollectionFiltersFromInput(input);
await this.assetService.updateFeaturedAsset(coll, input.featuredAssetId);
await this.assetService.updateFeaturedAsset(coll, input);
},
});
await this.assetService.updateEntityAssets(collection, input.assetIds);
await this.assetService.updateEntityAssets(collection, input);
this.applyCollectionFilters(ctx, [collection]);
return assertFound(this.findOne(ctx, collection.id));
}
Expand All @@ -267,8 +267,8 @@ export class CollectionService implements OnModuleInit {
if (input.filters) {
coll.filters = this.getCollectionFiltersFromInput(input);
}
await this.assetService.updateFeaturedAsset(coll, input.featuredAssetId);
await this.assetService.updateEntityAssets(coll, input.assetIds);
await this.assetService.updateFeaturedAsset(coll, input);
await this.assetService.updateEntityAssets(coll, input);
},
});
if (input.filters) {
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/service/services/product-variant.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,14 @@ export class ProductVariantService {
}
variant.product = { id: input.productId } as any;
variant.taxCategory = { id: input.taxCategoryId } as any;
await this.assetService.updateFeaturedAsset(variant, input.featuredAssetId);
await this.assetService.updateFeaturedAsset(variant, input);
},
typeOrmSubscriberData: {
channelId: ctx.channelId,
taxCategoryId: input.taxCategoryId,
},
});
await this.assetService.updateEntityAssets(createdVariant, input.assetIds);
await this.assetService.updateEntityAssets(createdVariant, input);
if (input.stockOnHand != null && input.stockOnHand !== 0) {
await this.stockMovementService.adjustProductVariantStock(
createdVariant.id,
Expand Down Expand Up @@ -227,8 +227,8 @@ export class ProductVariantService {
input.stockOnHand,
);
}
await this.assetService.updateFeaturedAsset(updatedVariant, input.featuredAssetId);
await this.assetService.updateEntityAssets(updatedVariant, input.assetIds);
await this.assetService.updateFeaturedAsset(updatedVariant, input);
await this.assetService.updateEntityAssets(updatedVariant, input);
},
typeOrmSubscriberData: {
channelId: ctx.channelId,
Expand Down
18 changes: 8 additions & 10 deletions packages/core/src/service/services/product.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ export class ProductService {
if (input.facetValueIds) {
p.facetValues = await this.facetValueService.findByIds(input.facetValueIds);
}
await this.assetService.updateFeaturedAsset(p, input.featuredAssetId);
await this.assetService.updateFeaturedAsset(p, input);
},
});
await this.assetService.updateEntityAssets(product, input.assetIds);
await this.assetService.updateEntityAssets(product, input);
this.eventBus.publish(new CatalogModificationEvent(ctx, product));
return assertFound(this.findOne(ctx, product.id));
}
Expand All @@ -127,8 +127,8 @@ export class ProductService {
if (input.facetValueIds) {
p.facetValues = await this.facetValueService.findByIds(input.facetValueIds);
}
await this.assetService.updateFeaturedAsset(p, input.featuredAssetId);
await this.assetService.updateEntityAssets(p, input.assetIds);
await this.assetService.updateFeaturedAsset(p, input);
await this.assetService.updateEntityAssets(p, input);
},
});
this.eventBus.publish(new CatalogModificationEvent(ctx, product));
Expand Down Expand Up @@ -189,12 +189,10 @@ export class ProductService {
}

private async getProductWithOptionGroups(productId: ID): Promise<Product> {
const product = await this.connection
.getRepository(Product)
.findOne(productId, {
relations: ['optionGroups', 'variants', 'variants.options'],
where: { deletedAt: null },
});
const product = await this.connection.getRepository(Product).findOne(productId, {
relations: ['optionGroups', 'variants', 'variants.options'],
where: { deletedAt: null },
});
if (!product) {
throw new EntityNotFoundError('Product', productId);
}
Expand Down

0 comments on commit 528eb3c

Please sign in to comment.