Browse Source

feat(admin-ui): Add quick jump for easier variants nav

Michael Bromley 2 years ago
parent
commit
fd45482ab8
22 changed files with 136 additions and 28 deletions
  1. 18 18
      packages/admin-ui/i18n-coverage.json
  2. 3 1
      packages/admin-ui/src/lib/catalog/src/catalog.module.ts
  3. 16 9
      packages/admin-ui/src/lib/catalog/src/components/product-variant-detail/product-variant-detail.component.html
  4. 5 0
      packages/admin-ui/src/lib/catalog/src/components/product-variant-detail/product-variant-detail.component.scss
  5. 15 0
      packages/admin-ui/src/lib/catalog/src/components/product-variant-quick-jump/product-variant-quick-jump.component.html
  6. 0 0
      packages/admin-ui/src/lib/catalog/src/components/product-variant-quick-jump/product-variant-quick-jump.component.scss
  7. 58 0
      packages/admin-ui/src/lib/catalog/src/components/product-variant-quick-jump/product-variant-quick-jump.component.ts
  8. 7 0
      packages/admin-ui/src/lib/core/src/common/generated-types.ts
  9. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/cs.json
  10. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/de.json
  11. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/en.json
  12. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/es.json
  13. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/fr.json
  14. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/it.json
  15. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/pl.json
  16. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json
  17. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/pt_PT.json
  18. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/ru.json
  19. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/uk.json
  20. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json
  21. 1 0
      packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json
  22. 1 0
      packages/admin-ui/src/lib/static/styles/global/_forms.scss

+ 18 - 18
packages/admin-ui/i18n-coverage.json

@@ -1,69 +1,69 @@
 {
-  "generatedOn": "2023-05-29T10:50:35.826Z",
-  "lastCommit": "e6c8f0ca21f187e49a4dbc7cc59b6522dc19865f",
+  "generatedOn": "2023-05-29T11:32:35.039Z",
+  "lastCommit": "f01a9ce747a897c4a07219c4713d3f3d8c6d405e",
   "translationStatus": {
     "cs": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 550,
       "percentage": 77
     },
     "de": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 533,
       "percentage": 75
     },
     "en": {
-      "tokenCount": 713,
-      "translatedCount": 709,
-      "percentage": 99
+      "tokenCount": 714,
+      "translatedCount": 711,
+      "percentage": 100
     },
     "es": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 575,
       "percentage": 81
     },
     "fr": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 570,
       "percentage": 80
     },
     "it": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 574,
-      "percentage": 81
+      "percentage": 80
     },
     "pl": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 384,
       "percentage": 54
     },
     "pt_BR": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 548,
       "percentage": 77
     },
     "pt_PT": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 583,
       "percentage": 82
     },
     "ru": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 573,
       "percentage": 80
     },
     "uk": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 573,
       "percentage": 80
     },
     "zh_Hans": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 519,
       "percentage": 73
     },
     "zh_Hant": {
-      "tokenCount": 713,
+      "tokenCount": 714,
       "translatedCount": 364,
       "percentage": 51
     }

+ 3 - 1
packages/admin-ui/src/lib/catalog/src/catalog.module.ts

@@ -62,6 +62,7 @@ import { ProductVariantsEditorComponent } from './components/product-variants-ed
 import { ProductVariantsTableComponent } from './components/product-variants-table/product-variants-table.component';
 import { UpdateProductOptionDialogComponent } from './components/update-product-option-dialog/update-product-option-dialog.component';
 import { VariantPriceDetailComponent } from './components/variant-price-detail/variant-price-detail.component';
+import { ProductVariantQuickJumpComponent } from './components/product-variant-quick-jump/product-variant-quick-jump.component';
 
 const CATALOG_COMPONENTS = [
     ProductListComponent,
@@ -103,6 +104,7 @@ const CATALOG_COMPONENTS = [
         ...CATALOG_COMPONENTS,
         CreateProductVariantDialogComponent,
         CreateProductOptionGroupDialogComponent,
+        ProductVariantQuickJumpComponent,
     ],
     providers: [
         {
@@ -174,7 +176,7 @@ export class CatalogModule {
                         link: ['/catalog', 'products', entity?.product.id],
                     },
                     {
-                        label: `${entity?.name}`,
+                        label: `${entity?.name} (${entity?.sku})`,
                         link: ['variants', entity?.id],
                     },
                 ],

+ 16 - 9
packages/admin-ui/src/lib/catalog/src/components/product-variant-detail/product-variant-detail.component.html

@@ -1,13 +1,16 @@
 <vdr-page-block>
     <vdr-action-bar>
-        <vdr-ab-left>
-            <div class="flex clr-flex-row"></div>
-            <vdr-language-selector
-                [disabled]="isNew$ | async"
-                [availableLanguageCodes]="availableLanguages$ | async"
-                [currentLanguageCode]="languageCode$ | async"
-                (languageCodeChange)="setLanguage($event)"
-            ></vdr-language-selector>
+        <vdr-ab-left [grow]="true">
+            <div class="flex center">
+                <vdr-language-selector
+                    class="mr-2"
+                    [disabled]="isNew$ | async"
+                    [availableLanguageCodes]="availableLanguages$ | async"
+                    [currentLanguageCode]="languageCode$ | async"
+                    (languageCodeChange)="setLanguage($event)"
+                ></vdr-language-selector>
+                <vdr-product-variant-quick-jump [productId]="entity?.product.id" />
+            </div>
         </vdr-ab-left>
 
         <vdr-ab-right>
@@ -56,7 +59,11 @@
                     </vdr-chip>
                 </div>
                 <div>
-                    <a [routerLink]="['../../', 'options']" class="button" *vdrIfPermissions="updatePermissions">
+                    <a
+                        [routerLink]="['../../', 'options']"
+                        class="button"
+                        *vdrIfPermissions="updatePermissions"
+                    >
                         <clr-icon shape="pencil"></clr-icon>
                         {{ 'catalog.edit-options' | translate }}
                     </a>

+ 5 - 0
packages/admin-ui/src/lib/catalog/src/components/product-variant-detail/product-variant-detail.component.scss

@@ -3,3 +3,8 @@
     flex-wrap: wrap;
     gap: 3px;
 }
+
+vdr-product-variant-quick-jump {
+    flex: 1;
+    margin-right: calc(var(--space-unit) * 2);
+}

+ 15 - 0
packages/admin-ui/src/lib/catalog/src/components/product-variant-quick-jump/product-variant-quick-jump.component.html

@@ -0,0 +1,15 @@
+<ng-select
+    *ngIf="(variants$ | async)?.length > 1"
+    [items]="variants$ | async"
+    appendTo="body"
+    bindValue="id"
+    [(ngModel)]="selectedVariantId"
+    [searchFn]="searchFn"
+    [clearable]="false"
+    [placeholder]="'catalog.quick-jump-placeholder' | translate"
+    (change)="onSelect($event)"
+>
+    <ng-template ng-option-tmp let-item="item" let-index="index" let-search="searchTerm">
+        {{ item.name }} ({{ item.sku }})
+    </ng-template>
+</ng-select>

+ 0 - 0
packages/admin-ui/src/lib/catalog/src/components/product-variant-quick-jump/product-variant-quick-jump.component.scss


+ 58 - 0
packages/admin-ui/src/lib/catalog/src/components/product-variant-quick-jump/product-variant-quick-jump.component.ts

@@ -0,0 +1,58 @@
+import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import {
+    DataService,
+    GetProductVariantsQuickJumpDocument,
+    GetProductVariantsQuickJumpQuery,
+} from '@vendure/admin-ui/core';
+import { gql } from 'apollo-angular';
+import { Observable } from 'rxjs';
+
+const GET_PRODUCT_VARIANTS_QUICK_JUMP = gql`
+    query GetProductVariantsQuickJump($id: ID!) {
+        product(id: $id) {
+            id
+            variants {
+                id
+                name
+                sku
+            }
+        }
+    }
+`;
+
+@Component({
+    selector: 'vdr-product-variant-quick-jump',
+    templateUrl: './product-variant-quick-jump.component.html',
+    styleUrls: ['./product-variant-quick-jump.component.scss'],
+    changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class ProductVariantQuickJumpComponent implements OnInit {
+    @Input() productId: string;
+    selectedVariantId: string | undefined;
+    variants$: Observable<NonNullable<GetProductVariantsQuickJumpQuery['product']>['variants']>;
+    constructor(private dataService: DataService, private router: Router) {}
+
+    ngOnInit() {
+        this.variants$ = this.dataService
+            .query(GetProductVariantsQuickJumpDocument, {
+                id: this.productId,
+            })
+            .mapSingle(data => data.product?.variants ?? []);
+    }
+
+    searchFn = (
+        term: string,
+        item: NonNullable<GetProductVariantsQuickJumpQuery['product']>['variants'][number],
+    ) =>
+        item.name.toLowerCase().includes(term.toLowerCase()) ||
+        item.sku.toLowerCase().includes(term.toLowerCase());
+
+    onSelect(item?: NonNullable<GetProductVariantsQuickJumpQuery['product']>['variants'][number]) {
+        if (item) {
+            this.router
+                .navigate(['catalog', 'products', this.productId, 'variants', item.id])
+                .then(() => (this.selectedVariantId = undefined));
+        }
+    }
+}

File diff suppressed because it is too large
+ 7 - 0
packages/admin-ui/src/lib/core/src/common/generated-types.ts


+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/cs.json

@@ -148,6 +148,7 @@
     "product-variants": "Varianty produktu",
     "products": "",
     "public": "Veřejný",
+    "quick-jump-placeholder": "",
     "reindex-error": "Při regeneraci vyhledávacího indexu došlo k chybě",
     "reindex-successful": "Zaindexováno: {count, plural, one {varianta produktu} other {{count} variant produktu}} během {time}ms",
     "reindexing": "Regenerovat vyhledávací index",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/de.json

@@ -148,6 +148,7 @@
     "product-variants": "Produktvarianten",
     "products": "",
     "public": "Öffentlich",
+    "quick-jump-placeholder": "",
     "reindex-error": "Beim Neuaufbau des Suchindex ist ein Fehler aufgetreten",
     "reindex-successful": "{count, plural, one {Produktvariante} other {{count} Produktvarianten}} indiziert in {time}ms",
     "reindexing": "Suchindex wird neu aufgebaut",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/en.json

@@ -148,6 +148,7 @@
     "product-variants": "Product variants",
     "products": "Products",
     "public": "Public",
+    "quick-jump-placeholder": "Quick jump to variant",
     "reindex-error": "An error occurred while rebuilding search index",
     "reindex-successful": "Indexed {count, plural, one {product variant} other {{count} product variants}} in {time}ms",
     "reindexing": "Rebuilding search index",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/es.json

@@ -148,6 +148,7 @@
     "product-variants": "Variantes de producto",
     "products": "",
     "public": "Público",
+    "quick-jump-placeholder": "",
     "reindex-error": "Ha ocurrido un error reconstruyendo el índice de búsqueda",
     "reindex-successful": "Indexado {count, plural, one {variante} other {{count} variantes}} en {time}ms",
     "reindexing": "Reconstruyendo índice de búsqueda",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/fr.json

@@ -148,6 +148,7 @@
     "product-variants": "Variations du produit",
     "products": "",
     "public": "Public",
+    "quick-jump-placeholder": "",
     "reindex-error": "Une erreur s'est produite lors de la reconstruction de l'index de recherche",
     "reindex-successful": "Indexation {count, plural, one {d'une variation de produit} other {de {count} variations de produit}} en {time} ms",
     "reindexing": "Reconstruction de l'index de recherche",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/it.json

@@ -148,6 +148,7 @@
     "product-variants": "Varianti del Prodotto",
     "products": "",
     "public": "Pubblico",
+    "quick-jump-placeholder": "",
     "reindex-error": "Si è verificato un errore nella ricostruzione dell'indice di ricerca",
     "reindex-successful": "{count, plural, one {Indicizzata una variante prodotto} other {Indicizzate {count} varianti prodotto}} in {time}ms",
     "reindexing": "Ricostruzione indice",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/pl.json

@@ -148,6 +148,7 @@
     "product-variants": "Warianty produktu",
     "products": "",
     "public": "",
+    "quick-jump-placeholder": "",
     "reindex-error": "Wystąpił błąd podczas przebudowania indeksów",
     "reindex-successful": "Zaindeksowano {count, plural, one {wariant produktu} other {{count} wariantów produktu}} w {time}ms",
     "reindexing": "Przebudowuje indeksy wyszukiwania",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json

@@ -148,6 +148,7 @@
     "product-variants": "Variações do produto",
     "products": "",
     "public": "Público",
+    "quick-jump-placeholder": "",
     "reindex-error": "Ocorreu um erro ao recriar o índice de pesquisa",
     "reindex-successful": "Indexado {count, plural, one {product variant} other {{count} product variants}} em {time}ms",
     "reindexing": "Reconstruindo o índice de pesquisa",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/pt_PT.json

@@ -148,6 +148,7 @@
     "product-variants": "Variações do produto",
     "products": "",
     "public": "Público",
+    "quick-jump-placeholder": "",
     "reindex-error": "Ocorreu um erro ao reconstruir o índice de pesquisa",
     "reindex-successful": "{count, plural, one {Variante do produto indexada} other {{count} variantes de produtos indexadas}} em {time}ms",
     "reindexing": "A reconstruir o índice de pesquisa",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/ru.json

@@ -148,6 +148,7 @@
     "product-variants": "Вариант товара",
     "products": "",
     "public": "Публичный",
+    "quick-jump-placeholder": "",
     "reindex-error": "Произошла ошибка при перестройке индекса поиска",
     "reindex-successful": "Проиндексировано {count, plural, one {вариант товара} other {{count} вариантов товара}} за {time}мс",
     "reindexing": "Перестройка поискового индекса",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/uk.json

@@ -148,6 +148,7 @@
     "product-variants": "Варіант товару",
     "products": "",
     "public": "Публічний",
+    "quick-jump-placeholder": "",
     "reindex-error": "Помилка при перебудові індексу пошуку",
     "reindex-successful": "Проіндексовано {count, plural, one {варіант товару} other {{count} варіантів товару}} за {time}мс",
     "reindexing": "Перебудова пошукового індексу",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json

@@ -148,6 +148,7 @@
     "product-variants": "商品规格",
     "products": "",
     "public": "公开",
+    "quick-jump-placeholder": "",
     "reindex-error": "重建索引失败",
     "reindex-successful": "已成功重建{count}个产品索引,耗时{time}毫秒",
     "reindexing": "正在重建搜索索引",

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json

@@ -148,6 +148,7 @@
     "product-variants": "商品規格",
     "products": "",
     "public": "公開",
+    "quick-jump-placeholder": "",
     "reindex-error": "重建索引失敗",
     "reindex-successful": "已成功重建{count}個產品索引,耗时{time}毫秒",
     "reindexing": "正在重建搜索索引",

+ 1 - 0
packages/admin-ui/src/lib/static/styles/global/_forms.scss

@@ -130,6 +130,7 @@ select {
     .ng-value {
         margin: 0 6px 0 0;
         background-color: var(--color-form-input-bg) !important;
+        color: var(--color-text-100) !important;
     }
     .ng-input {
         margin: 0;

Some files were not shown because too many files changed in this diff