1
0
Эх сурвалжийг харах

feat(server): Implement create and update for Facets

Michael Bromley 7 жил өмнө
parent
commit
704dbf7c01

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
schema.json


+ 1 - 0
server/dev-config.ts

@@ -21,6 +21,7 @@ export const devConfig: VendureConfig = {
         database: 'vendure-dev',
     },
     customFields: {
+        Facet: [{ name: 'searchable', type: 'boolean' }],
         Product: [
             { name: 'infoUrl', type: 'string' },
             { name: 'downloadable', type: 'boolean' },

+ 7 - 0
server/src/api/facet/facet.api.graphql

@@ -3,6 +3,13 @@ type Query {
     facet(id: ID!, languageCode: LanguageCode): Facet
 }
 
+type Mutation {
+    "Create a new Facet"
+    createFacet(input: CreateFacetInput): Facet!
+    "Update an existing Facet"
+    updateFacet(input: UpdateFacetInput): Facet!
+}
+
 type FacetList implements PaginatedList {
     items: [Facet!]!
     totalItems: Int!

+ 25 - 4
server/src/api/facet/facet.resolver.ts

@@ -1,16 +1,15 @@
-import { Query, Resolver } from '@nestjs/graphql';
+import { Mutation, Query, Resolver } from '@nestjs/graphql';
 
 import { PaginatedList } from '../../../../shared/shared-types';
 import { Facet } from '../../entity/facet/facet.entity';
-import { Product } from '../../entity/product/product.entity';
 import { Translated } from '../../locale/locale-types';
-import { ConfigService } from '../../service/config.service';
+import { FacetValueService } from '../../service/facet-value.service';
 import { FacetService } from '../../service/facet.service';
 import { ApplyIdCodec } from '../common/apply-id-codec-decorator';
 
 @Resolver('Facet')
 export class FacetResolver {
-    constructor(private facetService: FacetService) {}
+    constructor(private facetService: FacetService, private facetValueService: FacetValueService) {}
 
     @Query()
     @ApplyIdCodec()
@@ -23,4 +22,26 @@ export class FacetResolver {
     async facet(obj, args): Promise<Translated<Facet> | undefined> {
         return this.facetService.findOne(args.id, args.languageCode);
     }
+
+    @Mutation()
+    @ApplyIdCodec()
+    async createFacet(_, args): Promise<Translated<Facet>> {
+        const { input } = args;
+        const facet = await this.facetService.create(args.input);
+
+        if (input.values && input.values.length) {
+            for (const value of input.values) {
+                const newValue = await this.facetValueService.create(facet, value);
+                facet.values.push(newValue);
+            }
+        }
+        return facet;
+    }
+
+    @Mutation()
+    @ApplyIdCodec()
+    async updateFacet(_, args): Promise<Translated<Facet>> {
+        const { input } = args;
+        return this.facetService.update(args.input);
+    }
 }

+ 2 - 0
server/src/app.module.ts

@@ -25,6 +25,7 @@ import { TranslationUpdaterService } from './locale/translation-updater.service'
 import { AdministratorService } from './service/administrator.service';
 import { ConfigService } from './service/config.service';
 import { CustomerService } from './service/customer.service';
+import { FacetValueService } from './service/facet-value.service';
 import { FacetService } from './service/facet.service';
 import { ProductOptionGroupService } from './service/product-option-group.service';
 import { ProductOptionService } from './service/product-option.service';
@@ -42,6 +43,7 @@ import { ProductService } from './service/product.service';
         ConfigService,
         FacetResolver,
         FacetService,
+        FacetValueService,
         JwtStrategy,
         I18nService,
         PasswordService,

+ 7 - 0
server/src/entity/facet-value/facet-value.dto.ts

@@ -0,0 +1,7 @@
+import { TranslatedInput } from '../../locale/locale-types';
+
+import { FacetValue } from './facet-value.entity';
+
+export interface CreateFacetValueDto extends TranslatedInput<FacetValue> {
+    code: string;
+}

+ 14 - 0
server/src/entity/facet/facet.dto.ts

@@ -0,0 +1,14 @@
+import { TranslatedInput } from '../../locale/locale-types';
+import { CreateFacetValueDto } from '../facet-value/facet-value.dto';
+
+import { Facet } from './facet.entity';
+
+export interface CreateFacetDto extends TranslatedInput<Facet> {
+    code: string;
+    values?: CreateFacetValueDto[];
+}
+
+export interface UpdateFacetDto extends TranslatedInput<Facet> {
+    id: string;
+    code?: string;
+}

+ 1 - 1
server/src/entity/facet/facet.graphql

@@ -26,7 +26,7 @@ input FacetTranslationInput {
 input CreateFacetInput {
     code: String!
     translations: [FacetTranslationInput!]!
-    options: [CreateProductOptionInput!]!
+    values: [CreateFacetValueInput!]
 }
 
 input UpdateFacetInput {

+ 1 - 1
server/src/entity/product-option-group/product-option-group.dto.ts

@@ -10,5 +10,5 @@ export interface CreateProductOptionGroupDto extends TranslatedInput<ProductOpti
 
 export interface UpdateProductOptionGroupDto extends TranslatedInput<ProductOptionGroup> {
     id: string;
-    code: string;
+    code?: string;
 }

+ 52 - 0
server/src/service/facet-value.service.ts

@@ -0,0 +1,52 @@
+import { Injectable } from '@nestjs/common';
+import { InjectConnection } from '@nestjs/typeorm';
+import { Connection } from 'typeorm';
+
+import { ID } from '../../../shared/shared-types';
+import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
+import { assertFound } from '../common/utils';
+import { FacetValueTranslation } from '../entity/facet-value/facet-value-translation.entity';
+import { CreateFacetValueDto } from '../entity/facet-value/facet-value.dto';
+import { FacetValue } from '../entity/facet-value/facet-value.entity';
+import { Facet } from '../entity/facet/facet.entity';
+import { LanguageCode } from '../locale/language-code';
+import { Translated } from '../locale/locale-types';
+import { translateDeep } from '../locale/translate-entity';
+
+@Injectable()
+export class FacetValueService {
+    constructor(@InjectConnection() private connection: Connection) {}
+
+    findAll(lang: LanguageCode): Promise<Array<Translated<FacetValue>>> {
+        return this.connection.manager
+            .find(FacetValue, {
+                relations: ['facet'],
+            })
+            .then(facetValues => facetValues.map(facetValue => translateDeep(facetValue, lang)));
+    }
+
+    findOne(id: ID, lang: LanguageCode): Promise<Translated<FacetValue> | undefined> {
+        return this.connection.manager
+            .findOne(FacetValue, id, {
+                relations: ['facet'],
+            })
+            .then(facetValue => facetValue && translateDeep(facetValue, lang));
+    }
+
+    async create(facet: Facet, createFacetValueDto: CreateFacetValueDto): Promise<Translated<FacetValue>> {
+        const facetValue = new FacetValue(createFacetValueDto);
+        const translations: FacetValueTranslation[] = [];
+
+        for (const input of createFacetValueDto.translations) {
+            const translation = new FacetValueTranslation(input);
+            translations.push(translation);
+            await this.connection.manager.save(translation);
+        }
+
+        facetValue.translations = translations;
+        facetValue.facet = facet;
+        const createdGroup = await this.connection.manager.save(facetValue);
+
+        return assertFound(this.findOne(createdGroup.id, DEFAULT_LANGUAGE_CODE));
+    }
+}

+ 38 - 3
server/src/service/facet.service.ts

@@ -5,6 +5,10 @@ import { Connection } from 'typeorm';
 import { ID, PaginatedList } from '../../../shared/shared-types';
 import { buildListQuery } from '../common/build-list-query';
 import { ListQueryOptions } from '../common/common-types';
+import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
+import { assertFound } from '../common/utils';
+import { FacetTranslation } from '../entity/facet/facet-translation.entity';
+import { CreateFacetDto, UpdateFacetDto } from '../entity/facet/facet.dto';
 import { Facet } from '../entity/facet/facet.entity';
 import { LanguageCode } from '../locale/language-code';
 import { Translated } from '../locale/locale-types';
@@ -23,8 +27,8 @@ export class FacetService {
 
         return buildListQuery(this.connection, Facet, options, relations)
             .getManyAndCount()
-            .then(([products, totalItems]) => {
-                const items = products.map(product => translateDeep(product, lang, ['values']));
+            .then(([facets, totalItems]) => {
+                const items = facets.map(facet => translateDeep(facet, lang, ['values']));
                 return {
                     items,
                     totalItems,
@@ -37,6 +41,37 @@ export class FacetService {
 
         return this.connection.manager
             .findOne(Facet, facetId, { relations })
-            .then(product => product && translateDeep(product, lang, ['values']));
+            .then(facet => facet && translateDeep(facet, lang, ['values']));
+    }
+
+    async create(createFacetDto: CreateFacetDto): Promise<Translated<Facet>> {
+        const facet = new Facet(createFacetDto);
+        const translations: FacetTranslation[] = [];
+
+        for (const input of createFacetDto.translations) {
+            const translation = new FacetTranslation(input);
+            translations.push(translation);
+            await this.connection.manager.save(translation);
+        }
+
+        facet.translations = translations;
+        const createdFacet = await this.connection.manager.save(facet);
+
+        return assertFound(this.findOne(createdFacet.id, DEFAULT_LANGUAGE_CODE));
+    }
+
+    async update(updateFacetDto: UpdateFacetDto): Promise<Translated<Facet>> {
+        const existingTranslations = await this.connection.getRepository(FacetTranslation).find({
+            where: { base: updateFacetDto.id },
+            relations: ['base'],
+        });
+
+        const translationUpdater = this.translationUpdaterService.create(FacetTranslation);
+        const diff = translationUpdater.diff(existingTranslations, updateFacetDto.translations);
+
+        const facet = await translationUpdater.applyDiff(new Facet(updateFacetDto), diff);
+        await this.connection.manager.save(facet);
+
+        return assertFound(this.findOne(facet.id, DEFAULT_LANGUAGE_CODE));
     }
 }

+ 2 - 2
server/src/service/product-option.service.ts

@@ -22,7 +22,7 @@ export class ProductOptionService {
             .find(ProductOption, {
                 relations: ['group'],
             })
-            .then(groups => groups.map(group => translateDeep(group, lang)));
+            .then(options => options.map(option => translateDeep(option, lang)));
     }
 
     findOne(id: ID, lang: LanguageCode): Promise<Translated<ProductOption> | undefined> {
@@ -30,7 +30,7 @@ export class ProductOptionService {
             .findOne(ProductOption, id, {
                 relations: ['group'],
             })
-            .then(group => group && translateDeep(group, lang));
+            .then(option => option && translateDeep(option, lang));
     }
 
     async create(

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно