Browse Source

refactor(admin-ui): Create findTranslation utility

Michael Bromley 5 years ago
parent
commit
cf2604d4c7

+ 3 - 2
packages/admin-ui/src/lib/catalog/src/components/collection-detail/collection-detail.component.ts

@@ -21,6 +21,7 @@ import {
     CustomFieldConfig,
     DataService,
     encodeConfigArgValue,
+    findTranslation,
     getConfigArgValue,
     LanguageCode,
     ModalService,
@@ -105,7 +106,7 @@ export class CollectionDetailComponent
             .pipe(take(1))
             .subscribe(([entity, languageCode]) => {
                 const slugControl = this.detailForm.get(['slug']);
-                const currentTranslation = entity.translations.find(t => t.languageCode === languageCode);
+                const currentTranslation = findTranslation(entity, languageCode);
                 const currentSlugIsEmpty = !currentTranslation || !currentTranslation.slug;
                 if (slugControl && slugControl.pristine && currentSlugIsEmpty) {
                     slugControl.setValue(normalizeString(`${nameValue}`, '-'));
@@ -223,7 +224,7 @@ export class CollectionDetailComponent
      * Sets the values of the form on changes to the category or current language.
      */
     protected setFormValues(entity: Collection.Fragment, languageCode: LanguageCode) {
-        const currentTranslation = entity.translations.find(t => t.languageCode === languageCode);
+        const currentTranslation = findTranslation(entity, languageCode);
 
         this.detailForm.patchValue({
             name: currentTranslation ? currentTranslation.name : '',

+ 3 - 3
packages/admin-ui/src/lib/catalog/src/components/facet-detail/facet-detail.component.ts

@@ -11,6 +11,7 @@ import {
     DataService,
     DeletionResult,
     FacetWithValues,
+    findTranslation,
     LanguageCode,
     ModalService,
     NotificationService,
@@ -269,7 +270,7 @@ export class FacetDetailComponent
      * Sets the values of the form on changes to the facet or current language.
      */
     protected setFormValues(facet: FacetWithValues.Fragment, languageCode: LanguageCode) {
-        const currentTranslation = facet.translations.find(t => t.languageCode === languageCode);
+        const currentTranslation = findTranslation(facet, languageCode);
 
         this.detailForm.patchValue({
             facet: {
@@ -299,8 +300,7 @@ export class FacetDetailComponent
         currentValuesFormArray.clear();
         this.values = [...facet.values];
         facet.values.forEach((value, i) => {
-            const valueTranslation =
-                value.translations && value.translations.find(t => t.languageCode === languageCode);
+            const valueTranslation = findTranslation(value, languageCode);
             const group = {
                 id: value.id,
                 code: value.code,

+ 4 - 3
packages/admin-ui/src/lib/catalog/src/components/product-detail/product-detail.component.ts

@@ -10,6 +10,7 @@ import {
     CustomFieldConfig,
     DataService,
     FacetWithValues,
+    findTranslation,
     flattenFacetValues,
     GlobalFlag,
     IGNORE_CAN_DEACTIVATE_GUARD,
@@ -327,7 +328,7 @@ export class ProductDetailComponent
             .pipe(take(1))
             .subscribe(([entity, languageCode]) => {
                 const slugControl = this.detailForm.get(['product', 'slug']);
-                const currentTranslation = entity.translations.find(t => t.languageCode === languageCode);
+                const currentTranslation = findTranslation(entity, languageCode);
                 const currentSlugIsEmpty = !currentTranslation || !currentTranslation.slug;
                 if (slugControl && slugControl.pristine && currentSlugIsEmpty) {
                     slugControl.setValue(normalizeString(`${nameValue}`, '-'));
@@ -530,7 +531,7 @@ export class ProductDetailComponent
      * Sets the values of the form on changes to the product or current language.
      */
     protected setFormValues(product: ProductWithVariants.Fragment, languageCode: LanguageCode) {
-        const currentTranslation = product.translations.find(t => t.languageCode === languageCode);
+        const currentTranslation = findTranslation(product, languageCode);
         this.detailForm.patchValue({
             product: {
                 enabled: product.enabled,
@@ -559,7 +560,7 @@ export class ProductDetailComponent
 
         const variantsFormArray = this.detailForm.get('variants') as FormArray;
         product.variants.forEach((variant, i) => {
-            const variantTranslation = variant.translations.find(t => t.languageCode === languageCode);
+            const variantTranslation = findTranslation(variant, languageCode);
             const facetValueIds = variant.facetValues.map(fv => fv.id);
             const group: VariantFormValue = {
                 id: variant.id,

+ 11 - 14
packages/admin-ui/src/lib/catalog/src/providers/product-detail/product-detail.service.ts

@@ -5,6 +5,7 @@ import {
     DataService,
     DeletionResult,
     FacetWithValues,
+    findTranslation,
     LanguageCode,
     ProductWithVariants,
     UpdateProductInput,
@@ -162,13 +163,11 @@ export class ProductDetailService {
         if (productInput) {
             updateOperations.push(this.dataService.product.updateProduct(productInput));
 
-            const productOldName = product.translations?.find(t => t.languageCode === languageCode)?.name;
-            const productNewName = productInput.translations?.find(t => t.languageCode === languageCode)
-                ?.name;
+            const productOldName = findTranslation(product, languageCode)?.name;
+            const productNewName = findTranslation(productInput, languageCode)?.name;
             if (productOldName && productNewName && autoUpdate) {
                 for (const variant of product.variants) {
-                    const currentVariantName =
-                        variant.translations.find(t => t.languageCode === languageCode)?.name || '';
+                    const currentVariantName = findTranslation(variant, languageCode)?.name || '';
                     let variantInput: UpdateProductVariantInput;
                     const existingVariantInput = updateVariantsInput.find(i => i.id === variant.id);
                     if (existingVariantInput) {
@@ -180,9 +179,7 @@ export class ProductDetailService {
                         };
                         updateVariantsInput.push(variantInput);
                     }
-                    const variantTranslation = variantInput.translations?.find(
-                        t => t.languageCode === languageCode,
-                    );
+                    const variantTranslation = findTranslation(variantInput, languageCode);
                     if (variantTranslation) {
                         variantTranslation.name = replaceLast(
                             variantTranslation.name,
@@ -208,7 +205,7 @@ export class ProductDetailService {
         if (input.autoUpdate) {
             // Update any ProductVariants' names which include the option name
             let oldOptionName: string | undefined;
-            const newOptionName = input.translations?.find(t => t.languageCode === languageCode)?.name;
+            const newOptionName = findTranslation(input, languageCode)?.name;
             if (!newOptionName) {
                 updateProductVariantNames$ = of([]);
             }
@@ -216,12 +213,12 @@ export class ProductDetailService {
             for (const variant of product.variants) {
                 if (variant.options.map(o => o.id).includes(input.id)) {
                     if (!oldOptionName) {
-                        oldOptionName = variant.options
-                            .find(o => o.id === input.id)
-                            ?.translations.find(t => t.languageCode === languageCode)?.name;
+                        oldOptionName = findTranslation(
+                            variant.options.find(o => o.id === input.id),
+                            languageCode,
+                        )?.name;
                     }
-                    const variantName =
-                        variant.translations.find(t => t.languageCode === languageCode)?.name || '';
+                    const variantName = findTranslation(variant, languageCode)?.name || '';
                     if (oldOptionName && newOptionName && variantName.includes(oldOptionName)) {
                         variantsToUpdate.push({
                             id: variant.id,

+ 3 - 1
packages/admin-ui/src/lib/core/src/common/utilities/create-updated-translatable.ts

@@ -3,6 +3,8 @@ import { assertNever } from '@vendure/common/lib/shared-utils';
 
 import { CustomFieldConfig, LanguageCode } from '../generated-types';
 
+import { findTranslation } from './find-translation';
+
 export interface TranslatableUpdateOptions<T extends { translations: any[] } & MayHaveCustomFields> {
     translatable: T;
     updatedFields: { [key: string]: any };
@@ -25,7 +27,7 @@ export function createUpdatedTranslatable<T extends { translations: any[] } & Ma
 ): T {
     const { translatable, updatedFields, languageCode, customFieldConfig, defaultTranslation } = options;
     const currentTranslation =
-        translatable.translations.find(t => t.languageCode === languageCode) || defaultTranslation;
+        findTranslation(translatable, languageCode) || defaultTranslation || ({} as any);
     const index = translatable.translations.indexOf(currentTranslation);
     const newTranslation = patchObject(currentTranslation, updatedFields);
     const newCustomFields: CustomFieldsObject = {};

+ 17 - 0
packages/admin-ui/src/lib/core/src/common/utilities/find-translation.ts

@@ -0,0 +1,17 @@
+import { LanguageCode } from '../generated-types';
+
+export type Translation<T> = T & { languageCode: LanguageCode };
+export type PossiblyTranslatable<T> = { translations?: Array<Translation<T>> | null };
+export type TranslationOf<E> = E extends PossiblyTranslatable<infer U> ? U : undefined;
+
+/**
+ * @description
+ * Given a translatable entity, returns the translation in the specified LanguageCode if
+ * one exists.
+ */
+export function findTranslation<E extends PossiblyTranslatable<any>>(
+    entity: E | undefined,
+    languageCode: LanguageCode,
+): TranslationOf<E> | undefined {
+    return (entity?.translations || []).find(t => t.languageCode === languageCode);
+}

+ 1 - 0
packages/admin-ui/src/lib/core/src/public_api.ts

@@ -14,6 +14,7 @@ export * from './common/introspection-result';
 export * from './common/language-translation-strings';
 export * from './common/utilities/configurable-operation-utils';
 export * from './common/utilities/create-updated-translatable';
+export * from './common/utilities/find-translation';
 export * from './common/utilities/flatten-facet-values';
 export * from './common/utilities/get-default-ui-language';
 export * from './common/utilities/interpolate-description';

+ 2 - 1
packages/admin-ui/src/lib/settings/src/components/country-detail/country-detail.component.ts

@@ -8,6 +8,7 @@ import {
     CreateCountryInput,
     createUpdatedTranslatable,
     DataService,
+    findTranslation,
     LanguageCode,
     NotificationService,
     ServerConfigService,
@@ -126,7 +127,7 @@ export class CountryDetailComponent
     }
 
     protected setFormValues(country: Country, languageCode: LanguageCode): void {
-        const currentTranslation = country.translations.find(t => t.languageCode === languageCode);
+        const currentTranslation = findTranslation(country, languageCode);
 
         this.detailForm.patchValue({
             code: country.code,

+ 2 - 1
packages/admin-ui/src/lib/settings/src/components/shipping-method-detail/shipping-method-detail.component.ts

@@ -11,6 +11,7 @@ import {
     createUpdatedTranslatable,
     CustomFieldConfig,
     DataService,
+    findTranslation,
     GetActiveChannel,
     getConfigArgValue,
     LanguageCode,
@@ -298,7 +299,7 @@ export class ShippingMethodDetailComponent
     }
 
     protected setFormValues(shippingMethod: ShippingMethod.Fragment, languageCode: LanguageCode): void {
-        const currentTranslation = shippingMethod.translations.find(t => t.languageCode === languageCode);
+        const currentTranslation = findTranslation(shippingMethod, languageCode);
         this.detailForm.patchValue({
             name: currentTranslation?.name ?? '',
             description: currentTranslation?.description ?? '',