@vendure/admin-ui 1.5.1 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/bundles/vendure-admin-ui-catalog.umd.js +206 -172
  2. package/bundles/vendure-admin-ui-catalog.umd.js.map +1 -1
  3. package/bundles/vendure-admin-ui-core.umd.js +1790 -1300
  4. package/bundles/vendure-admin-ui-core.umd.js.map +1 -1
  5. package/bundles/vendure-admin-ui-dashboard.umd.js +3 -3
  6. package/bundles/vendure-admin-ui-dashboard.umd.js.map +1 -1
  7. package/bundles/vendure-admin-ui-login.umd.js +2 -2
  8. package/bundles/vendure-admin-ui-login.umd.js.map +1 -1
  9. package/bundles/vendure-admin-ui-marketing.umd.js +1 -1
  10. package/bundles/vendure-admin-ui-marketing.umd.js.map +1 -1
  11. package/bundles/vendure-admin-ui-order.umd.js +3 -3
  12. package/bundles/vendure-admin-ui-order.umd.js.map +1 -1
  13. package/catalog/components/collection-contents/collection-contents.component.d.ts +7 -2
  14. package/catalog/components/collection-detail/collection-detail.component.d.ts +12 -4
  15. package/catalog/components/collection-list/collection-list.component.d.ts +2 -0
  16. package/catalog/components/collection-tree/array-to-tree.d.ts +1 -1
  17. package/catalog/components/collection-tree/collection-tree-node.component.d.ts +5 -1
  18. package/catalog/components/collection-tree/collection-tree.component.d.ts +1 -0
  19. package/catalog/providers/product-detail/product-detail.service.d.ts +2 -2
  20. package/catalog/public_api.d.ts +0 -1
  21. package/catalog/vendure-admin-ui-catalog.metadata.json +1 -1
  22. package/core/common/generated-types.d.ts +32 -3
  23. package/core/common/utilities/selection-manager.d.ts +23 -0
  24. package/core/common/version.d.ts +1 -1
  25. package/core/components/app-shell/app-shell.component.d.ts +1 -0
  26. package/core/data/definitions/collection-definitions.d.ts +1 -0
  27. package/core/data/providers/collection-data.service.d.ts +6 -2
  28. package/core/providers/local-storage/local-storage.service.d.ts +1 -0
  29. package/core/public_api.d.ts +5 -0
  30. package/core/shared/components/asset-gallery/asset-gallery.component.d.ts +21 -6
  31. package/core/shared/components/configurable-input/configurable-input.component.d.ts +7 -2
  32. package/core/shared/components/product-multi-selector-dialog/product-multi-selector-dialog.component.d.ts +35 -0
  33. package/{catalog → core/shared}/components/product-search-input/product-search-input.component.d.ts +1 -1
  34. package/core/shared/components/select-toggle/select-toggle.component.d.ts +1 -0
  35. package/core/shared/dynamic-form-inputs/combination-mode-form-input/combination-mode-form-input.component.d.ts +25 -0
  36. package/core/shared/dynamic-form-inputs/product-multi-selector-form-input/product-multi-selector-form-input.component.d.ts +20 -0
  37. package/core/shared/dynamic-form-inputs/register-dynamic-input-components.d.ts +3 -1
  38. package/core/shared/dynamic-form-inputs/relation-form-input/asset/relation-asset-input.component.d.ts +5 -2
  39. package/core/vendure-admin-ui-core.metadata.json +1 -1
  40. package/dashboard/vendure-admin-ui-dashboard.metadata.json +1 -1
  41. package/esm2015/catalog/catalog.module.js +1 -3
  42. package/esm2015/catalog/components/assets/assets.component.js +1 -1
  43. package/esm2015/catalog/components/collection-contents/collection-contents.component.js +51 -14
  44. package/esm2015/catalog/components/collection-detail/collection-detail.component.js +67 -29
  45. package/esm2015/catalog/components/collection-list/collection-list.component.js +30 -4
  46. package/esm2015/catalog/components/collection-tree/array-to-tree.js +3 -3
  47. package/esm2015/catalog/components/collection-tree/collection-tree-node.component.js +27 -4
  48. package/esm2015/catalog/components/collection-tree/collection-tree.component.js +4 -2
  49. package/esm2015/catalog/components/product-detail/product-detail.component.js +1 -1
  50. package/esm2015/catalog/components/product-list/product-list.component.js +3 -3
  51. package/esm2015/catalog/components/product-variants-list/product-variants-list.component.js +1 -1
  52. package/esm2015/catalog/public_api.js +1 -2
  53. package/esm2015/core/app.component.module.js +1 -1
  54. package/esm2015/core/common/base-detail.component.js +1 -1
  55. package/esm2015/core/common/deactivate-aware.js +1 -1
  56. package/esm2015/core/common/generated-types.js +1 -1
  57. package/esm2015/core/common/introspection-result.js +255 -189
  58. package/esm2015/core/common/utilities/configurable-operation-utils.js +22 -4
  59. package/esm2015/core/common/utilities/selection-manager.js +64 -0
  60. package/esm2015/core/common/version.js +2 -2
  61. package/esm2015/core/components/app-shell/app-shell.component.js +4 -3
  62. package/esm2015/core/core.module.js +1 -1
  63. package/esm2015/core/data/definitions/collection-definitions.js +18 -1
  64. package/esm2015/core/data/definitions/order-definitions.js +431 -430
  65. package/esm2015/core/data/definitions/shared-definitions.js +29 -28
  66. package/esm2015/core/data/providers/collection-data.service.js +5 -2
  67. package/esm2015/core/providers/local-storage/local-storage.service.js +1 -1
  68. package/esm2015/core/public_api.js +6 -1
  69. package/esm2015/core/shared/components/asset-gallery/asset-gallery.component.js +24 -42
  70. package/esm2015/core/shared/components/asset-preview/asset-preview.component.js +4 -4
  71. package/esm2015/core/shared/components/configurable-input/configurable-input.component.js +13 -3
  72. package/esm2015/core/shared/components/help-tooltip/help-tooltip.component.js +1 -1
  73. package/esm2015/core/shared/components/product-multi-selector-dialog/product-multi-selector-dialog.component.js +129 -0
  74. package/esm2015/core/shared/components/product-search-input/product-search-input.component.js +104 -0
  75. package/esm2015/core/shared/components/rich-text-editor/rich-text-editor.component.js +1 -1
  76. package/esm2015/core/shared/components/select-toggle/select-toggle.component.js +5 -3
  77. package/esm2015/core/shared/dynamic-form-inputs/combination-mode-form-input/combination-mode-form-input.component.js +45 -0
  78. package/esm2015/core/shared/dynamic-form-inputs/product-multi-selector-form-input/product-multi-selector-form-input.component.js +53 -0
  79. package/esm2015/core/shared/dynamic-form-inputs/register-dynamic-input-components.js +5 -1
  80. package/esm2015/core/shared/dynamic-form-inputs/relation-form-input/asset/relation-asset-input.component.js +8 -7
  81. package/esm2015/core/shared/dynamic-form-inputs/select-form-input/select-form-input.component.js +1 -1
  82. package/esm2015/core/shared/shared.module.js +9 -1
  83. package/esm2015/dashboard/components/dashboard/dashboard.component.js +1 -1
  84. package/esm2015/dashboard/components/dashboard-widget/dashboard-widget.component.js +2 -2
  85. package/esm2015/dashboard/widgets/order-summary-widget/order-summary-widget.component.js +1 -1
  86. package/esm2015/login/components/login/login.component.js +3 -3
  87. package/esm2015/marketing/components/promotion-detail/promotion-detail.component.js +2 -2
  88. package/esm2015/order/components/order-editor/order-editor.component.js +1 -1
  89. package/esm2015/order/components/order-list/order-list.component.js +2 -2
  90. package/esm2015/order/components/order-table/order-table.component.js +1 -1
  91. package/fesm2015/vendure-admin-ui-catalog.js +181 -157
  92. package/fesm2015/vendure-admin-ui-catalog.js.map +1 -1
  93. package/fesm2015/vendure-admin-ui-core.js +2611 -2129
  94. package/fesm2015/vendure-admin-ui-core.js.map +1 -1
  95. package/fesm2015/vendure-admin-ui-dashboard.js +3 -3
  96. package/fesm2015/vendure-admin-ui-dashboard.js.map +1 -1
  97. package/fesm2015/vendure-admin-ui-login.js +2 -2
  98. package/fesm2015/vendure-admin-ui-login.js.map +1 -1
  99. package/fesm2015/vendure-admin-ui-marketing.js +1 -1
  100. package/fesm2015/vendure-admin-ui-marketing.js.map +1 -1
  101. package/fesm2015/vendure-admin-ui-order.js +3 -3
  102. package/fesm2015/vendure-admin-ui-order.js.map +1 -1
  103. package/login/vendure-admin-ui-login.metadata.json +1 -1
  104. package/marketing/vendure-admin-ui-marketing.metadata.json +1 -1
  105. package/order/vendure-admin-ui-order.metadata.json +1 -1
  106. package/package.json +5 -5
  107. package/static/i18n-messages/cs.json +9 -0
  108. package/static/i18n-messages/de.json +9 -0
  109. package/static/i18n-messages/en.json +10 -1
  110. package/static/i18n-messages/es.json +9 -0
  111. package/static/i18n-messages/fr.json +9 -0
  112. package/static/i18n-messages/it.json +9 -0
  113. package/static/i18n-messages/pl.json +9 -0
  114. package/static/i18n-messages/pt_BR.json +9 -0
  115. package/static/i18n-messages/pt_PT.json +9 -0
  116. package/static/i18n-messages/ru.json +9 -0
  117. package/static/i18n-messages/uk.json +9 -0
  118. package/static/i18n-messages/zh_Hans.json +9 -0
  119. package/static/i18n-messages/zh_Hant.json +9 -0
  120. package/static/styles/global/_forms.scss +4 -5
  121. package/static/styles/global/_overrides.scss +10 -0
  122. package/static/styles/theme/default.scss +13 -1
  123. package/static/theme.min.css +1 -1
  124. package/esm2015/catalog/components/product-search-input/product-search-input.component.js +0 -104
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/router'), require('@vendure/admin-ui/core'), require('@biesbjerg/ngx-translate-extract-marker'), require('rxjs/operators'), require('@angular/forms'), require('rxjs'), require('@vendure/common/lib/normalize-string'), require('@vendure/common/lib/shared-utils'), require('@vendure/common/lib/generated-shop-types'), require('@angular/common'), require('@vendure/common/lib/shared-constants'), require('@vendure/common/lib/unique'), require('@vendure/common/lib/pick'), require('@angular/cdk/drag-drop'), require('@ng-select/ng-select')) :
3
- typeof define === 'function' && define.amd ? define('@vendure/admin-ui/catalog', ['exports', '@angular/core', '@angular/router', '@vendure/admin-ui/core', '@biesbjerg/ngx-translate-extract-marker', 'rxjs/operators', '@angular/forms', 'rxjs', '@vendure/common/lib/normalize-string', '@vendure/common/lib/shared-utils', '@vendure/common/lib/generated-shop-types', '@angular/common', '@vendure/common/lib/shared-constants', '@vendure/common/lib/unique', '@vendure/common/lib/pick', '@angular/cdk/drag-drop', '@ng-select/ng-select'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.vendure = global.vendure || {}, global.vendure['admin-ui'] = global.vendure['admin-ui'] || {}, global.vendure['admin-ui'].catalog = {}), global.ng.core, global.ng.router, global.vendure['admin-ui'].core, global.ngxTranslateExtractMarker, global.rxjs.operators, global.ng.forms, global.rxjs, global.normalizeString, global.sharedUtils, global.generatedShopTypes, global.ng.common, global.sharedConstants, global.unique, global.pick, global.ng.cdk.dragDrop, global.ngSelect));
5
- }(this, (function (exports, i0, i1, i2, ngxTranslateExtractMarker, operators, forms, rxjs, normalizeString, sharedUtils, generatedShopTypes, common, sharedConstants, unique, pick, dragDrop, ngSelect) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/router'), require('@vendure/admin-ui/core'), require('@biesbjerg/ngx-translate-extract-marker'), require('rxjs/operators'), require('@angular/forms'), require('rxjs'), require('@vendure/common/lib/normalize-string'), require('@vendure/common/lib/shared-utils'), require('@vendure/common/lib/generated-shop-types'), require('@angular/common'), require('@vendure/common/lib/shared-constants'), require('@vendure/common/lib/unique'), require('@vendure/common/lib/pick'), require('@angular/cdk/drag-drop')) :
3
+ typeof define === 'function' && define.amd ? define('@vendure/admin-ui/catalog', ['exports', '@angular/core', '@angular/router', '@vendure/admin-ui/core', '@biesbjerg/ngx-translate-extract-marker', 'rxjs/operators', '@angular/forms', 'rxjs', '@vendure/common/lib/normalize-string', '@vendure/common/lib/shared-utils', '@vendure/common/lib/generated-shop-types', '@angular/common', '@vendure/common/lib/shared-constants', '@vendure/common/lib/unique', '@vendure/common/lib/pick', '@angular/cdk/drag-drop'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.vendure = global.vendure || {}, global.vendure['admin-ui'] = global.vendure['admin-ui'] || {}, global.vendure['admin-ui'].catalog = {}), global.ng.core, global.ng.router, global.vendure['admin-ui'].core, global.ngxTranslateExtractMarker, global.rxjs.operators, global.ng.forms, global.rxjs, global.normalizeString, global.sharedUtils, global.generatedShopTypes, global.ng.common, global.sharedConstants, global.unique, global.pick, global.ng.cdk.dragDrop));
5
+ }(this, (function (exports, i0, i1, i2, ngxTranslateExtractMarker, operators, forms, rxjs, normalizeString, sharedUtils, generatedShopTypes, common, sharedConstants, unique, pick, dragDrop) { 'use strict';
6
6
 
7
7
  function _interopNamespace(e) {
8
8
  if (e && e.__esModule) return e;
@@ -564,17 +564,22 @@
564
564
 
565
565
  var CollectionDetailComponent = /** @class */ (function (_super) {
566
566
  __extends(CollectionDetailComponent, _super);
567
- function CollectionDetailComponent(router, route, serverConfigService, changeDetector, dataService, formBuilder, notificationService, modalService) {
568
- var _this = _super.call(this, route, router, serverConfigService, dataService) || this;
567
+ function CollectionDetailComponent(router, route, serverConfigService, changeDetector, dataService, formBuilder, notificationService, modalService, localStorageService) {
568
+ var _this = this;
569
+ var _a;
570
+ _this = _super.call(this, route, router, serverConfigService, dataService) || this;
569
571
  _this.changeDetector = changeDetector;
570
572
  _this.dataService = dataService;
571
573
  _this.formBuilder = formBuilder;
572
574
  _this.notificationService = notificationService;
573
575
  _this.modalService = modalService;
576
+ _this.localStorageService = localStorageService;
574
577
  _this.assetChanges = {};
575
578
  _this.filters = [];
576
579
  _this.allFilters = [];
580
+ _this.livePreview = false;
577
581
  _this.updatePermission = [i2.Permission.UpdateCatalog, i2.Permission.UpdateCollection];
582
+ _this.filterRemoved$ = new rxjs.Subject();
578
583
  _this.customFields = _this.getCustomFieldConfig('Collection');
579
584
  _this.detailForm = _this.formBuilder.group({
580
585
  name: ['', forms.Validators.required],
@@ -587,6 +592,7 @@
587
592
  return (Object.assign(Object.assign({}, hash), (_c = {}, _c[field.name] = '', _c)));
588
593
  }, {})),
589
594
  });
595
+ _this.livePreview = (_a = _this.localStorageService.get('livePreviewCollectionContents')) !== null && _a !== void 0 ? _a : false;
590
596
  return _this;
591
597
  }
592
598
  CollectionDetailComponent.prototype.ngOnInit = function () {
@@ -595,12 +601,42 @@
595
601
  this.dataService.collection.getCollectionFilters().single$.subscribe(function (res) {
596
602
  _this.allFilters = res.collectionFilters;
597
603
  });
604
+ var filtersFormArray = this.detailForm.get('filters');
605
+ this.updatedFilters$ = rxjs.merge(filtersFormArray.statusChanges, this.filterRemoved$).pipe(operators.debounceTime(200), operators.filter(function () { return filtersFormArray.touched; }), operators.map(function () { return _this.mapOperationsToInputs(_this.filters, filtersFormArray.value).filter(function (_filter) {
606
+ var e_1, _c;
607
+ try {
608
+ // ensure all the arguments have valid values. E.g. a newly-added
609
+ // filter will not yet have valid values
610
+ for (var _d = __values(_filter.arguments), _e = _d.next(); !_e.done; _e = _d.next()) {
611
+ var arg = _e.value;
612
+ if (arg.value === '') {
613
+ return false;
614
+ }
615
+ }
616
+ }
617
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
618
+ finally {
619
+ try {
620
+ if (_e && !_e.done && (_c = _d.return)) _c.call(_d);
621
+ }
622
+ finally { if (e_1) throw e_1.error; }
623
+ }
624
+ return true;
625
+ }); }));
626
+ this.parentId$ = this.route.paramMap.pipe(operators.map(function (pm) { return pm.get('parentId') || undefined; }), operators.switchMap(function (parentId) {
627
+ if (parentId) {
628
+ return rxjs.of(parentId);
629
+ }
630
+ else {
631
+ return _this.entity$.pipe(operators.map(function (collection) { var _a; return (_a = collection.parent) === null || _a === void 0 ? void 0 : _a.id; }));
632
+ }
633
+ }));
598
634
  };
599
635
  CollectionDetailComponent.prototype.ngOnDestroy = function () {
600
636
  this.destroy();
601
637
  };
602
- CollectionDetailComponent.prototype.getFilterDefinition = function (filter) {
603
- return this.allFilters.find(function (f) { return f.code === filter.code; });
638
+ CollectionDetailComponent.prototype.getFilterDefinition = function (_filter) {
639
+ return this.allFilters.find(function (f) { return f.code === _filter.code; });
604
640
  };
605
641
  CollectionDetailComponent.prototype.assetsChanged = function () {
606
642
  return !!Object.values(this.assetChanges).length;
@@ -624,28 +660,27 @@
624
660
  };
625
661
  CollectionDetailComponent.prototype.addFilter = function (collectionFilter) {
626
662
  var filtersArray = this.detailForm.get('filters');
627
- var index = filtersArray.value.findIndex(function (o) { return o.code === collectionFilter.code; });
628
- if (index === -1) {
629
- var argsHash = collectionFilter.args.reduce(function (output, arg) {
630
- var _c;
631
- return (Object.assign(Object.assign({}, output), (_c = {}, _c[arg.name] = i2.getConfigArgValue(arg.value), _c)));
632
- }, {});
633
- filtersArray.push(this.formBuilder.control({
634
- code: collectionFilter.code,
635
- args: argsHash,
636
- }));
637
- this.filters.push({
638
- code: collectionFilter.code,
639
- args: collectionFilter.args.map(function (a) { return ({ name: a.name, value: i2.getConfigArgValue(a.value) }); }),
640
- });
641
- }
663
+ var argsHash = collectionFilter.args.reduce(function (output, arg) {
664
+ var _c;
665
+ return (Object.assign(Object.assign({}, output), (_c = {}, _c[arg.name] = i2.getConfigArgValue(arg.value), _c)));
666
+ }, {});
667
+ filtersArray.push(this.formBuilder.control({
668
+ code: collectionFilter.code,
669
+ args: argsHash,
670
+ }));
671
+ this.filters.push({
672
+ code: collectionFilter.code,
673
+ args: collectionFilter.args.map(function (a) { return ({ name: a.name, value: i2.getConfigArgValue(a.value) }); }),
674
+ });
642
675
  };
643
- CollectionDetailComponent.prototype.removeFilter = function (collectionFilter) {
676
+ CollectionDetailComponent.prototype.removeFilter = function (index) {
644
677
  var filtersArray = this.detailForm.get('filters');
645
- var index = filtersArray.value.findIndex(function (o) { return o.code === collectionFilter.code; });
646
678
  if (index !== -1) {
647
679
  filtersArray.removeAt(index);
680
+ filtersArray.markAsDirty();
681
+ filtersArray.markAsTouched();
648
682
  this.filters.splice(index, 1);
683
+ this.filterRemoved$.next();
649
684
  }
650
685
  };
651
686
  CollectionDetailComponent.prototype.create = function () {
@@ -702,6 +737,13 @@
702
737
  CollectionDetailComponent.prototype.canDeactivate = function () {
703
738
  return _super.prototype.canDeactivate.call(this) && !this.assetChanges.assets && !this.assetChanges.featuredAsset;
704
739
  };
740
+ CollectionDetailComponent.prototype.toggleLivePreview = function () {
741
+ this.livePreview = !this.livePreview;
742
+ this.localStorageService.set('livePreviewCollectionContents', this.livePreview);
743
+ };
744
+ CollectionDetailComponent.prototype.trackByFn = function (index, item) {
745
+ return JSON.stringify(item);
746
+ };
705
747
  /**
706
748
  * Sets the values of the form on changes to the category or current language.
707
749
  */
@@ -714,7 +756,12 @@
714
756
  description: currentTranslation ? currentTranslation.description : '',
715
757
  visible: !entity.isPrivate,
716
758
  });
717
- entity.filters.forEach(function (f) { return _this.addFilter(f); });
759
+ var formArray = this.detailForm.get('filters');
760
+ if (formArray.length !== entity.filters.length) {
761
+ formArray.clear();
762
+ this.filters = [];
763
+ entity.filters.forEach(function (f) { return _this.addFilter(f); });
764
+ }
718
765
  if (this.customFields.length) {
719
766
  this.setCustomFieldFormValues(this.customFields, this.detailForm.get(['customFields']), entity, currentTranslation);
720
767
  }
@@ -746,10 +793,13 @@
746
793
  return operations.map(function (o, i) {
747
794
  return {
748
795
  code: o.code,
749
- arguments: Object.values(formValueOperations[i].args).map(function (value, j) { return ({
750
- name: o.args[j].name,
751
- value: i2.encodeConfigArgValue(value),
752
- }); }),
796
+ arguments: Object.entries(formValueOperations[i].args).map(function (_c, j) {
797
+ var _d = __read(_c, 2), name = _d[0], value = _d[1];
798
+ return {
799
+ name: name,
800
+ value: i2.encodeConfigArgValue(value),
801
+ };
802
+ }),
753
803
  };
754
804
  });
755
805
  };
@@ -758,9 +808,9 @@
758
808
  CollectionDetailComponent.decorators = [
759
809
  { type: i0.Component, args: [{
760
810
  selector: 'vdr-collection-detail',
761
- template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <vdr-entity-info [entity]=\"entity$ | async\"></vdr-entity-info>\r\n <vdr-language-selector\r\n [disabled]=\"isNew$ | async\"\r\n [availableLanguageCodes]=\"availableLanguages$ | async\"\r\n [currentLanguageCode]=\"languageCode$ | async\"\r\n (languageCodeChange)=\"setLanguage($event)\"\r\n ></vdr-language-selector>\r\n </vdr-ab-left>\r\n\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"collection-detail\"></vdr-action-bar-items>\r\n <button\r\n class=\"btn btn-primary\"\r\n *ngIf=\"isNew$ | async; else updateButton\"\r\n (click)=\"create()\"\r\n [disabled]=\"detailForm.invalid || detailForm.pristine\"\r\n >\r\n {{ 'common.create' | translate }}\r\n </button>\r\n <ng-template #updateButton>\r\n <button\r\n *vdrIfPermissions=\"updatePermission\"\r\n class=\"btn btn-primary\"\r\n (click)=\"save()\"\r\n [disabled]=\"(detailForm.invalid || detailForm.pristine) && !assetsChanged()\"\r\n >\r\n {{ 'common.update' | translate }}\r\n </button>\r\n </ng-template>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<form class=\"form\" [formGroup]=\"detailForm\" *ngIf=\"entity$ | async as category\">\r\n <div class=\"clr-row\">\r\n <div class=\"clr-col\">\r\n <vdr-form-field [label]=\"'catalog.visibility' | translate\" for=\"visibility\">\r\n <clr-toggle-wrapper>\r\n <input\r\n type=\"checkbox\"\r\n clrToggle\r\n formControlName=\"visible\"\r\n id=\"visibility\"\r\n [vdrDisabled]=\"!(updatePermission | hasPermission)\"\r\n />\r\n <label class=\"visible-toggle\">\r\n <ng-container *ngIf=\"detailForm.value.visible; else private\">{{ 'catalog.public' | translate }}</ng-container>\r\n <ng-template #private>{{ 'catalog.private' | translate }}</ng-template>\r\n </label>\r\n </clr-toggle-wrapper>\r\n </vdr-form-field>\r\n <vdr-form-field [label]=\"'common.name' | translate\" for=\"name\">\r\n <input\r\n id=\"name\"\r\n type=\"text\"\r\n formControlName=\"name\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n (input)=\"updateSlug($event.target.value)\"\r\n />\r\n </vdr-form-field>\r\n <vdr-form-field\r\n [label]=\"'catalog.slug' | translate\"\r\n for=\"slug\"\r\n [errors]=\"{ pattern: ('catalog.slug-pattern-error' | translate) }\"\r\n >\r\n <input\r\n id=\"slug\"\r\n type=\"text\"\r\n formControlName=\"slug\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n />\r\n </vdr-form-field>\r\n <vdr-rich-text-editor\r\n formControlName=\"description\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n [label]=\"'common.description' | translate\"\r\n ></vdr-rich-text-editor>\r\n\r\n <section formGroupName=\"customFields\" *ngIf=\"customFields.length\">\r\n <label>{{ 'common.custom-fields' | translate }}</label>\r\n <vdr-tabbed-custom-fields\r\n entityName=\"Collection\"\r\n [customFields]=\"customFields\"\r\n [customFieldsFormGroup]=\"detailForm.get(['customFields'])\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n ></vdr-tabbed-custom-fields>\r\n </section>\r\n <vdr-custom-detail-component-host\r\n locationId=\"collection-detail\"\r\n [entity$]=\"entity$\"\r\n [detailForm]=\"detailForm\"\r\n ></vdr-custom-detail-component-host>\r\n </div>\r\n <div class=\"clr-col-md-auto\">\r\n <vdr-assets\r\n [assets]=\"category.assets\"\r\n [featuredAsset]=\"category.featuredAsset\"\r\n [updatePermissions]=\"updatePermission\"\r\n (change)=\"assetChanges = $event\"\r\n ></vdr-assets>\r\n </div>\r\n </div>\r\n <div class=\"clr-row\" formArrayName=\"filters\">\r\n <div class=\"clr-col\">\r\n <label>{{ 'catalog.filters' | translate }}</label>\r\n <ng-container *ngFor=\"let filter of filters; index as i\">\r\n <vdr-configurable-input\r\n (remove)=\"removeFilter($event)\"\r\n [operation]=\"filter\"\r\n [operationDefinition]=\"getFilterDefinition(filter)\"\r\n [formControlName]=\"i\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n ></vdr-configurable-input>\r\n </ng-container>\r\n\r\n <div *vdrIfPermissions=\"updatePermission\">\r\n <vdr-dropdown>\r\n <button class=\"btn btn-outline\" vdrDropdownTrigger>\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'marketing.add-condition' | translate }}\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-left\">\r\n <button\r\n *ngFor=\"let filter of allFilters\"\r\n type=\"button\"\r\n vdrDropdownItem\r\n (click)=\"addFilter(filter)\"\r\n >\r\n {{ filter.description }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </div>\r\n </div>\r\n <div class=\"clr-col\">\r\n <vdr-collection-contents [collectionId]=\"id\" #collectionContents>\r\n <ng-template let-count>\r\n <div class=\"contents-title\">\r\n {{ 'catalog.collection-contents' | translate }} ({{\r\n 'common.results-count' | translate: { count: count }\r\n }})\r\n </div>\r\n </ng-template>\r\n </vdr-collection-contents>\r\n </div>\r\n </div>\r\n</form>\r\n",
811
+ template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <vdr-entity-info [entity]=\"entity$ | async\"></vdr-entity-info>\r\n <vdr-language-selector\r\n [disabled]=\"isNew$ | async\"\r\n [availableLanguageCodes]=\"availableLanguages$ | async\"\r\n [currentLanguageCode]=\"languageCode$ | async\"\r\n (languageCodeChange)=\"setLanguage($event)\"\r\n ></vdr-language-selector>\r\n </vdr-ab-left>\r\n\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"collection-detail\"></vdr-action-bar-items>\r\n <button\r\n class=\"btn btn-primary\"\r\n *ngIf=\"isNew$ | async; else updateButton\"\r\n (click)=\"create()\"\r\n [disabled]=\"detailForm.invalid || detailForm.pristine\"\r\n >\r\n {{ 'common.create' | translate }}\r\n </button>\r\n <ng-template #updateButton>\r\n <button\r\n *vdrIfPermissions=\"updatePermission\"\r\n class=\"btn btn-primary\"\r\n (click)=\"save()\"\r\n [disabled]=\"(detailForm.invalid || detailForm.pristine) && !assetsChanged()\"\r\n >\r\n {{ 'common.update' | translate }}\r\n </button>\r\n </ng-template>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<form class=\"form\" [formGroup]=\"detailForm\" *ngIf=\"entity$ | async as category\">\r\n <div class=\"clr-row\">\r\n <div class=\"clr-col\">\r\n <vdr-form-field [label]=\"'catalog.visibility' | translate\" for=\"visibility\">\r\n <clr-toggle-wrapper>\r\n <input\r\n type=\"checkbox\"\r\n clrToggle\r\n formControlName=\"visible\"\r\n id=\"visibility\"\r\n [vdrDisabled]=\"!(updatePermission | hasPermission)\"\r\n />\r\n <label class=\"visible-toggle\">\r\n <ng-container *ngIf=\"detailForm.value.visible; else private\">{{\r\n 'catalog.public' | translate\r\n }}</ng-container>\r\n <ng-template #private>{{ 'catalog.private' | translate }}</ng-template>\r\n </label>\r\n </clr-toggle-wrapper>\r\n </vdr-form-field>\r\n <vdr-form-field [label]=\"'common.name' | translate\" for=\"name\">\r\n <input\r\n id=\"name\"\r\n type=\"text\"\r\n formControlName=\"name\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n (input)=\"updateSlug($event.target.value)\"\r\n />\r\n </vdr-form-field>\r\n <vdr-form-field\r\n [label]=\"'catalog.slug' | translate\"\r\n for=\"slug\"\r\n [errors]=\"{ pattern: ('catalog.slug-pattern-error' | translate) }\"\r\n >\r\n <input\r\n id=\"slug\"\r\n type=\"text\"\r\n formControlName=\"slug\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n />\r\n </vdr-form-field>\r\n <vdr-rich-text-editor\r\n formControlName=\"description\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n [label]=\"'common.description' | translate\"\r\n ></vdr-rich-text-editor>\r\n\r\n <section formGroupName=\"customFields\" *ngIf=\"customFields.length\">\r\n <label>{{ 'common.custom-fields' | translate }}</label>\r\n <vdr-tabbed-custom-fields\r\n entityName=\"Collection\"\r\n [customFields]=\"customFields\"\r\n [customFieldsFormGroup]=\"detailForm.get(['customFields'])\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n ></vdr-tabbed-custom-fields>\r\n </section>\r\n <vdr-custom-detail-component-host\r\n locationId=\"collection-detail\"\r\n [entity$]=\"entity$\"\r\n [detailForm]=\"detailForm\"\r\n ></vdr-custom-detail-component-host>\r\n </div>\r\n <div class=\"clr-col-md-auto\">\r\n <vdr-assets\r\n [assets]=\"category.assets\"\r\n [featuredAsset]=\"category.featuredAsset\"\r\n [updatePermissions]=\"updatePermission\"\r\n (change)=\"assetChanges = $event\"\r\n ></vdr-assets>\r\n </div>\r\n </div>\r\n <div class=\"clr-row\" formArrayName=\"filters\">\r\n <div class=\"clr-col\">\r\n <label>{{ 'catalog.filters' | translate }}</label>\r\n <ng-container *ngFor=\"let filter of filters; index as i; trackBy:trackByFn\">\r\n <vdr-configurable-input\r\n (remove)=\"removeFilter(i)\"\r\n [position]=\"i\"\r\n [operation]=\"filter\"\r\n [operationDefinition]=\"getFilterDefinition(filter)\"\r\n [formControlName]=\"i\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n ></vdr-configurable-input>\r\n </ng-container>\r\n\r\n <div *vdrIfPermissions=\"updatePermission\">\r\n <vdr-dropdown>\r\n <button class=\"btn btn-outline\" vdrDropdownTrigger>\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'marketing.add-condition' | translate }}\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-left\">\r\n <button\r\n *ngFor=\"let filter of allFilters\"\r\n type=\"button\"\r\n vdrDropdownItem\r\n (click)=\"addFilter(filter)\"\r\n >\r\n {{ filter.description }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </div>\r\n </div>\r\n <div class=\"clr-col\">\r\n <vdr-collection-contents\r\n [collectionId]=\"id\"\r\n [parentId]=\"parentId$ | async\"\r\n [updatedFilters]=\"updatedFilters$ | async\"\r\n [previewUpdatedFilters]=\"livePreview\"\r\n #collectionContents\r\n >\r\n <ng-template let-count>\r\n <div class=\"contents-title\">\r\n {{ 'catalog.collection-contents' | translate }} ({{\r\n 'common.results-count' | translate: { count: count }\r\n }})\r\n </div>\r\n <clr-checkbox-wrapper [class.disabled]=\"detailForm.get('filters')?.pristine\">\r\n <input\r\n type=\"checkbox\"\r\n clrCheckbox\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n [disabled]=\"detailForm.get('filters')?.pristine\"\r\n [ngModel]=\"livePreview\"\r\n (ngModelChange)=\"toggleLivePreview()\"\r\n />\r\n <label>{{ 'catalog.live-preview-contents' | translate }}</label>\r\n </clr-checkbox-wrapper>\r\n </ng-template>\r\n </vdr-collection-contents>\r\n </div>\r\n </div>\r\n</form>\r\n",
762
812
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
763
- styles: [".visible-toggle{margin-top:-3px!important}\n"]
813
+ styles: [".visible-toggle{margin-top:-3px!important}clr-checkbox-wrapper{transition:opacity .3s}clr-checkbox-wrapper.disabled{opacity:.5}\n"]
764
814
  },] }
765
815
  ];
766
816
  CollectionDetailComponent.ctorParameters = function () { return [
@@ -771,7 +821,8 @@
771
821
  { type: i2.DataService },
772
822
  { type: forms.FormBuilder },
773
823
  { type: i2.NotificationService },
774
- { type: i2.ModalService }
824
+ { type: i2.ModalService },
825
+ { type: i2.LocalStorageService }
775
826
  ]; };
776
827
  CollectionDetailComponent.propDecorators = {
777
828
  contentsComponent: [{ type: i0.ViewChild, args: ['collectionContents',] }]
@@ -787,15 +838,19 @@
787
838
  this.serverConfigService = serverConfigService;
788
839
  this.filterTermControl = new forms.FormControl('');
789
840
  this.expandAll = false;
841
+ this.expandedIds = [];
790
842
  this.destroy$ = new rxjs.Subject();
791
843
  }
792
844
  CollectionListComponent.prototype.ngOnInit = function () {
793
845
  var _this = this;
846
+ var _a, _b;
794
847
  this.queryResult = this.dataService.collection.getCollections(1000, 0).refetchOnChannelChange();
795
848
  this.items$ = this.queryResult.mapStream(function (data) { return data.collections.items; }).pipe(operators.shareReplay(1));
796
849
  this.activeCollectionId$ = this.route.paramMap.pipe(operators.map(function (pm) { return pm.get('contents'); }), operators.distinctUntilChanged());
797
- this.activeCollectionTitle$ = rxjs.combineLatest(this.activeCollectionId$, this.items$).pipe(operators.map(function (_a) {
798
- var _b = __read(_a, 2), id = _b[0], collections = _b[1];
850
+ this.expandedIds = (_b = (_a = this.route.snapshot.queryParamMap.get('expanded')) === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
851
+ this.expandAll = this.route.snapshot.queryParamMap.get('expanded') === 'all';
852
+ this.activeCollectionTitle$ = rxjs.combineLatest(this.activeCollectionId$, this.items$).pipe(operators.map(function (_c) {
853
+ var _d = __read(_c, 2), id = _d[0], collections = _d[1];
799
854
  if (id) {
800
855
  var match = collections.find(function (c) { return c.id === id; });
801
856
  return match ? match.name : '';
@@ -805,20 +860,41 @@
805
860
  this.availableLanguages$ = this.serverConfigService.getAvailableLanguages();
806
861
  this.contentLanguage$ = this.dataService.client
807
862
  .uiState()
808
- .mapStream(function (_a) {
809
- var uiState = _a.uiState;
863
+ .mapStream(function (_c) {
864
+ var uiState = _c.uiState;
810
865
  return uiState.contentLanguage;
811
866
  })
812
867
  .pipe(operators.tap(function () { return _this.refresh(); }));
813
868
  this.filterTermControl.valueChanges
814
869
  .pipe(operators.debounceTime(250), operators.takeUntil(this.destroy$))
870
+ .subscribe(function (term) {
871
+ _this.router.navigate(['./'], {
872
+ queryParams: {
873
+ q: term || undefined,
874
+ },
875
+ queryParamsHandling: 'merge',
876
+ relativeTo: _this.route,
877
+ });
878
+ });
879
+ this.route.queryParamMap
880
+ .pipe(operators.map(function (qpm) { return qpm.get('q'); }), operators.distinctUntilChanged(), operators.takeUntil(this.destroy$))
815
881
  .subscribe(function () { return _this.refresh(); });
882
+ this.filterTermControl.patchValue(this.route.snapshot.queryParamMap.get('q'));
816
883
  };
817
884
  CollectionListComponent.prototype.ngOnDestroy = function () {
818
885
  this.queryResult.completed$.next();
819
886
  this.destroy$.next(undefined);
820
887
  this.destroy$.complete();
821
888
  };
889
+ CollectionListComponent.prototype.toggleExpandAll = function () {
890
+ this.router.navigate(['./'], {
891
+ queryParams: {
892
+ expanded: this.expandAll ? 'all' : undefined,
893
+ },
894
+ queryParamsHandling: 'merge',
895
+ relativeTo: this.route,
896
+ });
897
+ };
822
898
  CollectionListComponent.prototype.onRearrange = function (event) {
823
899
  var _this = this;
824
900
  this.dataService.collection.moveCollection([event]).subscribe({
@@ -866,12 +942,13 @@
866
942
  this.dataService.client.setContentLanguage(code).subscribe();
867
943
  };
868
944
  CollectionListComponent.prototype.refresh = function () {
945
+ var filterTerm = this.route.snapshot.queryParamMap.get('q');
869
946
  this.queryResult.ref.refetch({
870
- options: Object.assign({ skip: 0, take: 1000 }, (this.filterTermControl.value
947
+ options: Object.assign({ skip: 0, take: 1000 }, (filterTerm
871
948
  ? {
872
949
  filter: {
873
950
  name: {
874
- contains: this.filterTermControl.value,
951
+ contains: filterTerm,
875
952
  },
876
953
  },
877
954
  }
@@ -883,7 +960,7 @@
883
960
  CollectionListComponent.decorators = [
884
961
  { type: i0.Component, args: [{
885
962
  selector: 'vdr-collection-list',
886
- template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <div class=\"flex center wrap\">\r\n <vdr-language-selector\r\n class=\"mt2\"\r\n [availableLanguageCodes]=\"availableLanguages$ | async\"\r\n [currentLanguageCode]=\"contentLanguage$ | async\"\r\n (languageCodeChange)=\"setLanguage($event)\"\r\n ></vdr-language-selector>\r\n <clr-checkbox-wrapper\r\n class=\"expand-all-toggle ml3\"\r\n [ngClass]=\"(availableLanguages$ | async)?.length === 1 ? 'mt3' : 'mt1'\"\r\n >\r\n <input type=\"checkbox\" clrCheckbox [(ngModel)]=\"expandAll\" />\r\n <label>{{ 'catalog.expand-all-collections' | translate }}</label>\r\n </clr-checkbox-wrapper>\r\n <input\r\n type='text'\r\n name='searchTerm'\r\n [formControl]='filterTermControl'\r\n [placeholder]=\"'catalog.filter-by-name' | translate\"\r\n class='clr-input search-input ml4'\r\n />\r\n </div>\r\n </vdr-ab-left>\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"collection-list\"></vdr-action-bar-items>\r\n <a\r\n class=\"btn btn-primary\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateCollection']\"\r\n [routerLink]=\"['./create']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.create-new-collection' | translate }}\r\n </a>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n<div class=\"collection-wrapper\">\r\n <vdr-collection-tree\r\n [collections]=\"items$ | async\"\r\n [activeCollectionId]=\"activeCollectionId$ | async\"\r\n [expandAll]=\"expandAll\"\r\n (rearrange)=\"onRearrange($event)\"\r\n (deleteCollection)=\"deleteCollection($event)\"\r\n ></vdr-collection-tree>\r\n\r\n <div class=\"collection-contents\" [class.expanded]=\"activeCollectionId$ | async\">\r\n <vdr-collection-contents [collectionId]=\"activeCollectionId$ | async\">\r\n <ng-template let-count>\r\n <div class=\"collection-title\">\r\n {{ activeCollectionTitle$ | async }} ({{\r\n 'common.results-count' | translate: { count: count }\r\n }})\r\n </div>\r\n <button type=\"button\" class=\"close-button\" (click)=\"closeContents()\">\r\n <clr-icon shape=\"close\"></clr-icon>\r\n </button>\r\n </ng-template>\r\n </vdr-collection-contents>\r\n </div>\r\n</div>\r\n",
963
+ template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <div class=\"flex center wrap\">\r\n <vdr-language-selector\r\n class=\"mt2\"\r\n [availableLanguageCodes]=\"availableLanguages$ | async\"\r\n [currentLanguageCode]=\"contentLanguage$ | async\"\r\n (languageCodeChange)=\"setLanguage($event)\"\r\n ></vdr-language-selector>\r\n <clr-checkbox-wrapper\r\n class=\"expand-all-toggle ml3\"\r\n [ngClass]=\"(availableLanguages$ | async)?.length === 1 ? 'mt3' : 'mt1'\"\r\n >\r\n <input type=\"checkbox\" clrCheckbox [(ngModel)]=\"expandAll\" (change)=\"toggleExpandAll()\"/>\r\n <label>{{ 'catalog.expand-all-collections' | translate }}</label>\r\n </clr-checkbox-wrapper>\r\n <input\r\n type='text'\r\n name='searchTerm'\r\n [formControl]='filterTermControl'\r\n [placeholder]=\"'catalog.filter-by-name' | translate\"\r\n class='clr-input search-input ml4'\r\n />\r\n </div>\r\n </vdr-ab-left>\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"collection-list\"></vdr-action-bar-items>\r\n <a\r\n class=\"btn btn-primary\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateCollection']\"\r\n [routerLink]=\"['./create']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.create-new-collection' | translate }}\r\n </a>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n<div class=\"collection-wrapper\">\r\n <vdr-collection-tree\r\n [collections]=\"items$ | async\"\r\n [activeCollectionId]=\"activeCollectionId$ | async\"\r\n [expandAll]=\"expandAll\"\r\n [expandedIds]=\"expandedIds\"\r\n (rearrange)=\"onRearrange($event)\"\r\n (deleteCollection)=\"deleteCollection($event)\"\r\n ></vdr-collection-tree>\r\n\r\n <div class=\"collection-contents\" [class.expanded]=\"activeCollectionId$ | async\">\r\n <vdr-collection-contents [collectionId]=\"activeCollectionId$ | async\">\r\n <ng-template let-count>\r\n <div class=\"collection-title\">\r\n {{ activeCollectionTitle$ | async }} ({{\r\n 'common.results-count' | translate: { count: count }\r\n }})\r\n </div>\r\n <button type=\"button\" class=\"close-button\" (click)=\"closeContents()\">\r\n <clr-icon shape=\"close\"></clr-icon>\r\n </button>\r\n </ng-template>\r\n </vdr-collection-contents>\r\n </div>\r\n</div>\r\n",
887
964
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
888
965
  styles: [":host{height:100%;display:flex;flex-direction:column}.expand-all-toggle{display:block}.collection-wrapper{display:flex;height:calc(100% - 50px)}.collection-wrapper vdr-collection-tree{flex:1;height:100%;overflow:auto}.collection-wrapper .collection-contents{height:100%;width:0;opacity:0;visibility:hidden;overflow:auto;transition:width .3s,opacity .2s .3s,visibility 0s .3s}.collection-wrapper .collection-contents.expanded{width:30vw;visibility:visible;opacity:1;padding-left:12px}.collection-wrapper .collection-contents .close-button{margin:0;background:none;border:none;cursor:pointer}.paging-controls{padding-top:6px;border-top:1px solid var(--color-component-border-100);display:flex;justify-content:space-between}\n"]
889
966
  },] }
@@ -2350,7 +2427,7 @@
2350
2427
  selector: 'vdr-product-detail',
2351
2428
  template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <div class=\"flex clr-flex-row\">\r\n <vdr-entity-info [entity]=\"entity$ | async\"></vdr-entity-info>\r\n <clr-toggle-wrapper *vdrIfPermissions=\"['UpdateCatalog', 'UpdateProduct']\">\r\n <input\r\n type=\"checkbox\"\r\n clrToggle\r\n name=\"enabled\"\r\n [formControl]=\"detailForm.get(['product', 'enabled'])\"\r\n />\r\n <label>{{ 'common.enabled' | translate }}</label>\r\n </clr-toggle-wrapper>\r\n </div>\r\n <vdr-language-selector\r\n [disabled]=\"isNew$ | async\"\r\n [availableLanguageCodes]=\"availableLanguages$ | async\"\r\n [currentLanguageCode]=\"languageCode$ | async\"\r\n (languageCodeChange)=\"setLanguage($event)\"\r\n ></vdr-language-selector>\r\n </vdr-ab-left>\r\n\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"product-detail\"></vdr-action-bar-items>\r\n <button\r\n class=\"btn btn-primary\"\r\n *ngIf=\"isNew$ | async; else updateButton\"\r\n (click)=\"create()\"\r\n [disabled]=\"detailForm.invalid || detailForm.pristine || !variantsToCreateAreValid()\"\r\n >\r\n {{ 'common.create' | translate }}\r\n </button>\r\n <ng-template #updateButton>\r\n <button\r\n *vdrIfPermissions=\"['UpdateCatalog', 'UpdateProduct']\"\r\n class=\"btn btn-primary\"\r\n (click)=\"save()\"\r\n [disabled]=\"\r\n (detailForm.invalid || detailForm.pristine) && !assetsChanged() && !variantAssetsChanged()\r\n \"\r\n >\r\n {{ 'common.update' | translate }}\r\n </button>\r\n </ng-template>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<form class=\"form\" [formGroup]=\"detailForm\" *ngIf=\"product$ | async as product\">\r\n <button type=\"submit\" hidden x-data=\"prevents enter key from triggering other buttons\"></button>\r\n <clr-tabs>\r\n <clr-tab>\r\n <button clrTabLink (click)=\"navigateToTab('details')\">\r\n {{ 'catalog.product-details' | translate }}\r\n </button>\r\n <clr-tab-content *clrIfActive=\"(activeTab$ | async) === 'details'\">\r\n <div class=\"clr-row\">\r\n <div class=\"clr-col\">\r\n <section class=\"form-block\" formGroupName=\"product\">\r\n <ng-container *ngIf=\"!(isNew$ | async)\">\r\n <ng-container *vdrIfMultichannel>\r\n <vdr-form-item\r\n [label]=\"'common.channels' | translate\"\r\n *vdrIfDefaultChannelActive\r\n >\r\n <div class=\"flex channel-assignment\">\r\n <ng-container *ngFor=\"let channel of productChannels$ | async\">\r\n <vdr-chip\r\n *ngIf=\"!isDefaultChannel(channel.code)\"\r\n icon=\"times-circle\"\r\n (iconClick)=\"removeFromChannel(channel.id)\"\r\n >\r\n <vdr-channel-badge\r\n [channelCode]=\"channel.code\"\r\n ></vdr-channel-badge>\r\n {{ channel.code | channelCodeToLabel }}\r\n </vdr-chip>\r\n </ng-container>\r\n <button class=\"btn btn-sm\" (click)=\"assignToChannel()\">\r\n <clr-icon shape=\"layers\"></clr-icon>\r\n {{ 'catalog.assign-to-channel' | translate }}\r\n </button>\r\n </div>\r\n </vdr-form-item>\r\n </ng-container>\r\n </ng-container>\r\n <vdr-form-field [label]=\"'catalog.product-name' | translate\" for=\"name\">\r\n <input\r\n id=\"name\"\r\n type=\"text\"\r\n formControlName=\"name\"\r\n [readonly]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n (input)=\"updateSlug($event.target.value)\"\r\n />\r\n </vdr-form-field>\r\n <div\r\n class=\"auto-rename-wrapper\"\r\n [class.visible]=\"\r\n (isNew$ | async) === false && detailForm.get(['product', 'name'])?.dirty\r\n \"\r\n >\r\n <clr-checkbox-wrapper>\r\n <input\r\n clrCheckbox\r\n type=\"checkbox\"\r\n id=\"auto-update\"\r\n formControlName=\"autoUpdateVariantNames\"\r\n />\r\n <label>{{\r\n 'catalog.auto-update-product-variant-name' | translate\r\n }}</label>\r\n </clr-checkbox-wrapper>\r\n </div>\r\n <vdr-form-field\r\n [label]=\"'catalog.slug' | translate\"\r\n for=\"slug\"\r\n [errors]=\"{ pattern: 'catalog.slug-pattern-error' | translate }\"\r\n >\r\n <input\r\n id=\"slug\"\r\n type=\"text\"\r\n formControlName=\"slug\"\r\n [readonly]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n />\r\n </vdr-form-field>\r\n <vdr-rich-text-editor\r\n formControlName=\"description\"\r\n [readonly]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n [label]=\"'common.description' | translate\"\r\n ></vdr-rich-text-editor>\r\n\r\n <section formGroupName=\"customFields\" *ngIf=\"customFields.length\">\r\n <label>{{ 'common.custom-fields' | translate }}</label>\r\n <vdr-tabbed-custom-fields\r\n entityName=\"Product\"\r\n [customFields]=\"customFields\"\r\n [customFieldsFormGroup]=\"detailForm.get(['product', 'customFields'])\"\r\n [readonly]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n ></vdr-tabbed-custom-fields>\r\n </section>\r\n <vdr-custom-detail-component-host\r\n locationId=\"product-detail\"\r\n [entity$]=\"entity$\"\r\n [detailForm]=\"detailForm\"\r\n ></vdr-custom-detail-component-host>\r\n </section>\r\n </div>\r\n <div class=\"clr-col-md-auto\">\r\n <vdr-assets\r\n [assets]=\"assetChanges.assets || product.assets\"\r\n [featuredAsset]=\"assetChanges.featuredAsset || product.featuredAsset\"\r\n [updatePermissions]=\"updatePermissions\"\r\n (change)=\"assetChanges = $event\"\r\n ></vdr-assets>\r\n <div class=\"facets\">\r\n <vdr-facet-value-chip\r\n *ngFor=\"let facetValue of facetValues$ | async\"\r\n [facetValue]=\"facetValue\"\r\n [removable]=\"['UpdateCatalog', 'UpdateProduct'] | hasPermission\"\r\n (remove)=\"removeProductFacetValue(facetValue.id)\"\r\n ></vdr-facet-value-chip>\r\n <button\r\n class=\"btn btn-sm btn-secondary\"\r\n *vdrIfPermissions=\"['UpdateCatalog', 'UpdateProduct']\"\r\n (click)=\"selectProductFacetValue()\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-facets' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"isNew$ | async\">\r\n <h4>{{ 'catalog.product-variants' | translate }}</h4>\r\n <vdr-generate-product-variants\r\n (variantsChange)=\"createVariantsConfig = $event\"\r\n ></vdr-generate-product-variants>\r\n </div>\r\n </clr-tab-content>\r\n </clr-tab>\r\n <clr-tab *ngIf=\"!(isNew$ | async)\">\r\n <button clrTabLink (click)=\"navigateToTab('variants')\">\r\n {{ 'catalog.product-variants' | translate }}\r\n </button>\r\n <clr-tab-content *clrIfActive=\"(activeTab$ | async) === 'variants'\">\r\n <section class=\"form-block\">\r\n <div class=\"view-mode\">\r\n <div class=\"btn-group\">\r\n <button\r\n class=\"btn btn-secondary-outline\"\r\n (click)=\"variantDisplayMode = 'card'\"\r\n [class.btn-primary]=\"variantDisplayMode === 'card'\"\r\n >\r\n <clr-icon shape=\"list\"></clr-icon>\r\n {{ 'catalog.display-variant-cards' | translate }}\r\n </button>\r\n <button\r\n class=\"btn\"\r\n (click)=\"variantDisplayMode = 'table'\"\r\n [class.btn-primary]=\"variantDisplayMode === 'table'\"\r\n >\r\n <clr-icon shape=\"table\"></clr-icon>\r\n {{ 'catalog.display-variant-table' | translate }}\r\n </button>\r\n </div>\r\n <div class=\"variant-filter\">\r\n <input\r\n [formControl]=\"filterInput\"\r\n [placeholder]=\"'catalog.filter-by-name-or-sku' | translate\"\r\n />\r\n <button class=\"icon-button\" (click)=\"filterInput.setValue('')\">\r\n <clr-icon shape=\"times\"></clr-icon>\r\n </button>\r\n </div>\r\n <div class=\"flex-spacer\"></div>\r\n <a\r\n *vdrIfPermissions=\"['UpdateCatalog', 'UpdateProduct']\"\r\n [routerLink]=\"['./', 'manage-variants']\"\r\n class=\"btn btn-secondary edit-variants-btn\"\r\n >\r\n <clr-icon shape=\"add-text\"></clr-icon>\r\n {{ 'catalog.manage-variants' | translate }}\r\n </a>\r\n </div>\r\n\r\n <div class=\"pagination-row mt4\" *ngIf=\"10 < (paginationConfig$ | async)?.totalItems\">\r\n <vdr-items-per-page-controls\r\n [itemsPerPage]=\"itemsPerPage$ | async\"\r\n (itemsPerPageChange)=\"setItemsPerPage($event)\"\r\n ></vdr-items-per-page-controls>\r\n\r\n <vdr-pagination-controls\r\n [id]=\"(paginationConfig$ | async)?.id\"\r\n [currentPage]=\"currentPage$ | async\"\r\n [itemsPerPage]=\"itemsPerPage$ | async\"\r\n (pageChange)=\"setPage($event)\"\r\n ></vdr-pagination-controls>\r\n </div>\r\n\r\n <vdr-product-variants-table\r\n *ngIf=\"variantDisplayMode === 'table'\"\r\n [variants]=\"variants$ | async\"\r\n [paginationConfig]=\"paginationConfig$ | async\"\r\n [optionGroups]=\"product.optionGroups\"\r\n [channelPriceIncludesTax]=\"channelPriceIncludesTax$ | async\"\r\n [productVariantsFormArray]=\"detailForm.get('variants')\"\r\n [pendingAssetChanges]=\"variantAssetChanges\"\r\n ></vdr-product-variants-table>\r\n <vdr-product-variants-list\r\n *ngIf=\"variantDisplayMode === 'card'\"\r\n [variants]=\"variants$ | async\"\r\n [paginationConfig]=\"paginationConfig$ | async\"\r\n [channelPriceIncludesTax]=\"channelPriceIncludesTax$ | async\"\r\n [facets]=\"facets$ | async\"\r\n [optionGroups]=\"product.optionGroups\"\r\n [productVariantsFormArray]=\"detailForm.get('variants')\"\r\n [taxCategories]=\"taxCategories$ | async\"\r\n [customFields]=\"customVariantFields\"\r\n [customOptionFields]=\"customOptionFields\"\r\n [activeLanguage]=\"languageCode$ | async\"\r\n [pendingAssetChanges]=\"variantAssetChanges\"\r\n (assignToChannel)=\"assignVariantToChannel($event)\"\r\n (removeFromChannel)=\"removeVariantFromChannel($event)\"\r\n (assetChange)=\"variantAssetChange($event)\"\r\n (updateProductOption)=\"updateProductOption($event)\"\r\n (selectionChange)=\"selectedVariantIds = $event\"\r\n (selectFacetValueClick)=\"selectVariantFacetValue($event)\"\r\n ></vdr-product-variants-list>\r\n </section>\r\n <div class=\"pagination-row mt4\" *ngIf=\"10 < (paginationConfig$ | async)?.totalItems\">\r\n <vdr-items-per-page-controls\r\n [itemsPerPage]=\"itemsPerPage$ | async\"\r\n (itemsPerPageChange)=\"setItemsPerPage($event)\"\r\n ></vdr-items-per-page-controls>\r\n\r\n <vdr-pagination-controls\r\n [id]=\"(paginationConfig$ | async)?.id\"\r\n [currentPage]=\"currentPage$ | async\"\r\n [itemsPerPage]=\"itemsPerPage$ | async\"\r\n (pageChange)=\"setPage($event)\"\r\n ></vdr-pagination-controls>\r\n </div>\r\n </clr-tab-content>\r\n </clr-tab>\r\n </clr-tabs>\r\n</form>\r\n",
2352
2429
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
2353
- styles: [":host ::ng-deep trix-toolbar{top:24px}.facets{margin-top:12px;display:flex;flex-wrap:wrap;align-items:center}@media screen and (min-width: 768px){.facets{max-width:340px}}vdr-action-bar clr-toggle-wrapper{margin-top:12px}.variant-filter{flex:1;display:flex}.variant-filter input{flex:1;max-width:initial;border-radius:3px 0 0 3px!important}.variant-filter .icon-button{border:1px solid var(--color-component-border-300);background-color:var(--color-component-bg-100);border-radius:0 3px 3px 0;border-left:none}.group-name{padding-right:6px}.view-mode{display:flex;justify-content:flex-end;align-items:center}.edit-variants-btn{margin-top:0}.channel-assignment{flex-wrap:wrap}.auto-rename-wrapper{overflow:hidden;max-height:0;padding-left:9.5rem;margin-bottom:0;transition:max-height .2s,margin-bottom .2s}.auto-rename-wrapper.visible{max-height:24px;margin-bottom:12px}.pagination-row{display:flex;align-items:baseline;justify-content:space-between}\n"]
2430
+ styles: [":host ::ng-deep trix-toolbar{top:24px}.facets{margin-top:12px;display:flex;flex-wrap:wrap;align-items:center}@media screen and (min-width: 768px){.facets{max-width:340px}}vdr-action-bar clr-toggle-wrapper{margin-top:12px}.variant-filter{flex:1;display:flex}.variant-filter input{flex:1;max-width:initial;border-radius:3px 0 0 3px!important}.variant-filter .icon-button{border:1px solid var(--color-component-border-300);background-color:var(--color-component-bg-100);border-radius:0 3px 3px 0;border-left:none}.group-name{padding-right:6px}.view-mode{display:flex;justify-content:flex-end;align-items:center}.edit-variants-btn{margin-top:0}.channel-assignment{flex-wrap:wrap;max-height:144px;overflow-y:auto}.auto-rename-wrapper{overflow:hidden;max-height:0;padding-left:9.5rem;margin-bottom:0;transition:max-height .2s,margin-bottom .2s}.auto-rename-wrapper.visible{max-height:24px;margin-bottom:12px}.pagination-row{display:flex;align-items:baseline;justify-content:space-between}\n"]
2354
2431
  },] }
2355
2432
  ];
2356
2433
  ProductDetailComponent.ctorParameters = function () { return [
@@ -2519,8 +2596,8 @@
2519
2596
  ProductListComponent.decorators = [
2520
2597
  { type: i0.Component, args: [{
2521
2598
  selector: 'vdr-products-list',
2522
- template: "<vdr-action-bar>\r\n <vdr-ab-left [grow]=\"true\">\r\n <div class=\"search-form\">\r\n <vdr-product-search-input\r\n #productSearchInputComponent\r\n [facetValueResults]=\"facetValues$ | async\"\r\n (searchTermChange)=\"setSearchTerm($event)\"\r\n (facetValueChange)=\"setFacetValueIds($event)\"\r\n ></vdr-product-search-input>\r\n <vdr-dropdown class=\"search-settings-menu mr3\">\r\n <button\r\n type=\"button\"\r\n class=\"icon-button search-index-button\"\r\n [title]=\"\r\n (pendingSearchIndexUpdates\r\n ? 'catalog.pending-search-index-updates'\r\n : 'catalog.search-index-controls'\r\n ) | translate\r\n \"\r\n vdrDropdownTrigger\r\n >\r\n <clr-icon shape=\"cog\"></clr-icon>\r\n <vdr-status-badge *ngIf=\"pendingSearchIndexUpdates\" type=\"warning\"> </vdr-status-badge>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <h4 class=\"dropdown-header\">{{ 'catalog.search-index-controls' | translate }}</h4>\r\n <ng-container *ngIf=\"pendingSearchIndexUpdates\">\r\n <button\r\n type=\"button\"\r\n class=\"run-updates-button\"\r\n vdrDropdownItem\r\n (click)=\"runPendingSearchIndexUpdates()\"\r\n [disabled]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n >\r\n <vdr-status-badge type=\"warning\"> </vdr-status-badge>\r\n {{\r\n 'catalog.run-pending-search-index-updates'\r\n | translate: { count: pendingSearchIndexUpdates }\r\n }}\r\n </button>\r\n <div class=\"dropdown-divider\"></div>\r\n </ng-container>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n (click)=\"rebuildSearchIndex()\"\r\n [disabled]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n >\r\n {{ 'catalog.rebuild-search-index' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </div>\r\n <div class=\"flex wrap\">\r\n <clr-checkbox-wrapper class=\"mt2\">\r\n <input type=\"checkbox\" clrCheckbox [(ngModel)]=\"groupByProduct\" (ngModelChange)=\"refresh()\" />\r\n <label>{{ 'catalog.group-by-product' | translate }}</label>\r\n </clr-checkbox-wrapper>\r\n <vdr-language-selector\r\n [availableLanguageCodes]=\"availableLanguages$ | async\"\r\n [currentLanguageCode]=\"contentLanguage$ | async\"\r\n (languageCodeChange)=\"setLanguage($event)\"\r\n ></vdr-language-selector>\r\n </div>\r\n </vdr-ab-left>\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"product-list\"></vdr-action-bar-items>\r\n <a\r\n class=\"btn btn-primary\"\r\n [routerLink]=\"['./create']\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateProduct']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n <span class=\"full-label\">{{ 'catalog.create-new-product' | translate }}</span>\r\n </a>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<vdr-data-table\r\n [items]=\"items$ | async\"\r\n [itemsPerPage]=\"itemsPerPage$ | async\"\r\n [totalItems]=\"totalItems$ | async\"\r\n [currentPage]=\"currentPage$ | async\"\r\n (pageChange)=\"setPageNumber($event)\"\r\n (itemsPerPageChange)=\"setItemsPerPage($event)\"\r\n>\r\n <ng-template let-result=\"item\">\r\n <td class=\"left align-middle\" [class.disabled]=\"!result.enabled\">\r\n <div class=\"image-placeholder\">\r\n <img\r\n *ngIf=\"\r\n groupByProduct\r\n ? result.productAsset\r\n : result.productVariantAsset || result.productAsset as asset;\r\n else imagePlaceholder\r\n \"\r\n [src]=\"asset | assetPreview: 'tiny'\"\r\n />\r\n <ng-template #imagePlaceholder>\r\n <div class=\"placeholder\">\r\n <clr-icon shape=\"image\" size=\"48\"></clr-icon>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </td>\r\n <td class=\"left align-middle\" [class.disabled]=\"!result.enabled\">\r\n {{ groupByProduct ? result.productName : result.productVariantName }}\r\n </td>\r\n <td class=\"align-middle\" [class.disabled]=\"!result.enabled\">\r\n <vdr-chip *ngIf=\"!result.enabled\">{{ 'common.disabled' | translate }}</vdr-chip>\r\n </td>\r\n <td class=\"right align-middle\" [class.disabled]=\"!result.enabled\">\r\n <vdr-table-row-action\r\n iconShape=\"edit\"\r\n [label]=\"'common.edit' | translate\"\r\n [linkTo]=\"['./', result.productId]\"\r\n ></vdr-table-row-action>\r\n </td>\r\n <td class=\"right align-middle\" [class.disabled]=\"!result.enabled\">\r\n <vdr-dropdown>\r\n <button type=\"button\" class=\"btn btn-link btn-sm\" vdrDropdownTrigger>\r\n {{ 'common.actions' | translate }}\r\n <clr-icon shape=\"caret down\"></clr-icon>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <button\r\n type=\"button\"\r\n class=\"delete-button\"\r\n (click)=\"deleteProduct(result.productId)\"\r\n [disabled]=\"!(['DeleteCatalog', 'DeleteProduct'] | hasPermission)\"\r\n vdrDropdownItem\r\n >\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon>\r\n {{ 'common.delete' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </td>\r\n </ng-template>\r\n</vdr-data-table>\r\n",
2523
- styles: [".image-placeholder{width:50px;height:50px;background-color:var(--color-component-bg-200)}.image-placeholder .placeholder{text-align:center;color:var(--color-grey-300)}.search-form{display:flex;align-items:center;width:100%;margin-bottom:6px}.search-input{min-width:300px}@media screen and (max-width: 768px){.search-input{min-width:100px}}.search-settings-menu{margin:0 12px}td.disabled{background-color:var(--color-component-bg-200)}.search-index-button{position:relative}.search-index-button vdr-status-badge{right:0;top:0}.run-updates-button{position:relative}.run-updates-button vdr-status-badge{left:10px;top:10px}\n"]
2599
+ template: "<vdr-action-bar>\r\n <vdr-ab-left [grow]=\"true\">\r\n <div class=\"search-form\">\r\n <vdr-product-search-input\r\n #productSearchInputComponent\r\n [facetValueResults]=\"facetValues$ | async\"\r\n (searchTermChange)=\"setSearchTerm($event)\"\r\n (facetValueChange)=\"setFacetValueIds($event)\"\r\n ></vdr-product-search-input>\r\n <vdr-dropdown class=\"search-settings-menu mr3\">\r\n <button\r\n type=\"button\"\r\n class=\"icon-button search-index-button\"\r\n [title]=\"\r\n (pendingSearchIndexUpdates\r\n ? 'catalog.pending-search-index-updates'\r\n : 'catalog.search-index-controls'\r\n ) | translate\r\n \"\r\n vdrDropdownTrigger\r\n >\r\n <clr-icon shape=\"cog\"></clr-icon>\r\n <vdr-status-badge *ngIf=\"pendingSearchIndexUpdates\" type=\"warning\"></vdr-status-badge>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <h4 class=\"dropdown-header\">{{ 'catalog.search-index-controls' | translate }}</h4>\r\n <ng-container *ngIf=\"pendingSearchIndexUpdates\">\r\n <button\r\n type=\"button\"\r\n class=\"run-updates-button\"\r\n vdrDropdownItem\r\n (click)=\"runPendingSearchIndexUpdates()\"\r\n [disabled]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n >\r\n <vdr-status-badge type=\"warning\"></vdr-status-badge>\r\n {{\r\n 'catalog.run-pending-search-index-updates'\r\n | translate: {count: pendingSearchIndexUpdates}\r\n }}\r\n </button>\r\n <div class=\"dropdown-divider\"></div>\r\n </ng-container>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n (click)=\"rebuildSearchIndex()\"\r\n [disabled]=\"!(['UpdateCatalog', 'UpdateProduct'] | hasPermission)\"\r\n >\r\n {{ 'catalog.rebuild-search-index' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </div>\r\n <div class=\"flex wrap\">\r\n <clr-checkbox-wrapper class=\"mt2\">\r\n <input type=\"checkbox\" clrCheckbox [(ngModel)]=\"groupByProduct\" (ngModelChange)=\"refresh()\"/>\r\n <label>{{ 'catalog.group-by-product' | translate }}</label>\r\n </clr-checkbox-wrapper>\r\n <vdr-language-selector\r\n [availableLanguageCodes]=\"availableLanguages$ | async\"\r\n [currentLanguageCode]=\"contentLanguage$ | async\"\r\n (languageCodeChange)=\"setLanguage($event)\"\r\n ></vdr-language-selector>\r\n </div>\r\n </vdr-ab-left>\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"product-list\"></vdr-action-bar-items>\r\n <a\r\n class=\"btn btn-primary\"\r\n [routerLink]=\"['./create']\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateProduct']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n <span class=\"full-label\">{{ 'catalog.create-new-product' | translate }}</span>\r\n </a>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<vdr-data-table\r\n [items]=\"items$ | async\"\r\n [itemsPerPage]=\"itemsPerPage$ | async\"\r\n [totalItems]=\"totalItems$ | async\"\r\n [currentPage]=\"currentPage$ | async\"\r\n (pageChange)=\"setPageNumber($event)\"\r\n (itemsPerPageChange)=\"setItemsPerPage($event)\"\r\n>\r\n <ng-template let-result=\"item\">\r\n <td class=\"left align-middle image-col\" [class.disabled]=\"!result.enabled\">\r\n <div class=\"image-placeholder\">\r\n <img\r\n *ngIf=\"\r\n groupByProduct\r\n ? result.productAsset\r\n : result.productVariantAsset || result.productAsset as asset;\r\n else imagePlaceholder\r\n \"\r\n [src]=\"asset | assetPreview: 'tiny'\"\r\n />\r\n <ng-template #imagePlaceholder>\r\n <div class=\"placeholder\">\r\n <clr-icon shape=\"image\" size=\"48\"></clr-icon>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </td>\r\n <td class=\"left align-middle\" [class.disabled]=\"!result.enabled\">\r\n {{ groupByProduct ? result.productName : result.productVariantName }}\r\n </td>\r\n <td class=\"align-middle\" [class.disabled]=\"!result.enabled\">\r\n <vdr-chip *ngIf=\"!result.enabled\">{{ 'common.disabled' | translate }}</vdr-chip>\r\n </td>\r\n <td class=\"right align-middle\" [class.disabled]=\"!result.enabled\">\r\n <vdr-table-row-action\r\n class=\"edit-button\"\r\n iconShape=\"edit\"\r\n [label]=\"'common.edit' | translate\"\r\n [linkTo]=\"['./', result.productId]\"\r\n ></vdr-table-row-action>\r\n <vdr-dropdown>\r\n <button type=\"button\" class=\"btn btn-link btn-sm\" vdrDropdownTrigger>\r\n {{ 'common.actions' | translate }}\r\n <clr-icon shape=\"caret down\"></clr-icon>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <button\r\n type=\"button\"\r\n class=\"delete-button\"\r\n (click)=\"deleteProduct(result.productId)\"\r\n [disabled]=\"!(['DeleteCatalog', 'DeleteProduct'] | hasPermission)\"\r\n vdrDropdownItem\r\n >\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon>\r\n {{ 'common.delete' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </td>\r\n </ng-template>\r\n</vdr-data-table>\r\n",
2600
+ styles: [".image-col{width:70px}.image-placeholder{width:50px;height:50px;background-color:var(--color-component-bg-200)}.image-placeholder img{border-radius:var(--border-radius-img)}.image-placeholder .placeholder{text-align:center;color:var(--color-grey-300)}.search-form{display:flex;align-items:center;width:100%;margin-bottom:6px}.search-input{min-width:300px}@media screen and (max-width: 768px){.search-input{min-width:100px}}.search-settings-menu{margin:0 12px}td.disabled{background-color:var(--color-component-bg-200)}.search-index-button{position:relative}.search-index-button vdr-status-badge{right:0;top:0}.run-updates-button{position:relative}.run-updates-button vdr-status-badge{left:10px;top:10px}.edit-button{margin-right:24px}\n"]
2524
2601
  },] }
2525
2602
  ];
2526
2603
  ProductListComponent.ctorParameters = function () { return [
@@ -3247,7 +3324,7 @@
3247
3324
  { type: i2.DataService }
3248
3325
  ]; };
3249
3326
 
3250
- var ɵ0$1 = {
3327
+ var ɵ0 = {
3251
3328
  breadcrumb: ngxTranslateExtractMarker.marker('breadcrumb.products'),
3252
3329
  }, ɵ1 = {
3253
3330
  breadcrumb: productBreadcrumb,
@@ -3272,7 +3349,7 @@
3272
3349
  {
3273
3350
  path: 'products',
3274
3351
  component: ProductListComponent,
3275
- data: ɵ0$1,
3352
+ data: ɵ0,
3276
3353
  },
3277
3354
  {
3278
3355
  path: 'products/:id',
@@ -3484,7 +3561,7 @@
3484
3561
  selector: 'vdr-assets',
3485
3562
  template: "<div class=\"card\" *ngIf=\"!compact; else compactView\">\r\n <div class=\"card-img\">\r\n <div class=\"featured-asset\">\r\n <img\r\n *ngIf=\"featuredAsset\"\r\n [src]=\"featuredAsset | assetPreview:'small'\"\r\n (click)=\"previewAsset(featuredAsset)\"\r\n />\r\n <div class=\"placeholder\" *ngIf=\"!featuredAsset\" (click)=\"selectAssets()\">\r\n <clr-icon shape=\"image\" size=\"128\"></clr-icon>\r\n <div>{{ 'catalog.no-featured-asset' | translate }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-block\"><ng-container *ngTemplateOutlet=\"assetList\"></ng-container></div>\r\n <div class=\"card-footer\" *vdrIfPermissions=\"updatePermissions\">\r\n <button class=\"btn\" (click)=\"selectAssets()\">\r\n <clr-icon shape=\"attachment\"></clr-icon>\r\n {{ 'asset.add-asset' | translate }}\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #compactView>\r\n <div class=\"featured-asset compact\">\r\n <img\r\n *ngIf=\"featuredAsset\"\r\n [src]=\"featuredAsset | assetPreview:'thumb'\"\r\n (click)=\"previewAsset(featuredAsset)\"\r\n />\r\n\r\n <div class=\"placeholder\" *ngIf=\"!featuredAsset\" (click)=\"selectAssets()\"><clr-icon shape=\"image\" size=\"150\"></clr-icon></div>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"assetList\"></ng-container>\r\n <button\r\n *vdrIfPermissions=\"updatePermissions\"\r\n class=\"compact-select btn btn-icon btn-sm btn-block\"\r\n [title]=\"'asset.add-asset' | translate\"\r\n (click)=\"selectAssets()\"\r\n >\r\n <clr-icon shape=\"attachment\"></clr-icon>\r\n {{ 'asset.add-asset' | translate }}\r\n </button>\r\n</ng-template>\r\n\r\n<ng-template #assetList>\r\n <div class=\"all-assets\" [class.compact]=\"compact\" cdkDropListGroup>\r\n <div\r\n *ngFor=\"let asset of assets; let index = index\"\r\n class=\"drop-list\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"index\"\r\n [cdkDropListDisabled]=\"!(updatePermissions | hasPermission)\"\r\n (cdkDropListDropped)=\"dropListDropped($event)\"\r\n >\r\n <vdr-dropdown cdkDrag>\r\n <div\r\n class=\"asset-thumb\"\r\n vdrDropdownTrigger\r\n [class.featured]=\"isFeatured(asset)\"\r\n [title]=\"\"\r\n tabindex=\"0\"\r\n >\r\n <img [src]=\"asset | assetPreview:'tiny'\" />\r\n </div>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <button type=\"button\" vdrDropdownItem (click)=\"previewAsset(asset)\">\r\n {{ 'asset.preview' | translate }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n [disabled]=\"isFeatured(asset) || !(updatePermissions | hasPermission)\"\r\n vdrDropdownItem\r\n (click)=\"setAsFeatured(asset)\"\r\n >\r\n {{ 'asset.set-as-featured-asset' | translate }}\r\n </button>\r\n <div class=\"dropdown-divider\"></div>\r\n <button\r\n type=\"button\"\r\n class=\"remove-asset\"\r\n vdrDropdownItem\r\n [disabled]=\"!(updatePermissions | hasPermission)\"\r\n (click)=\"removeAsset(asset)\"\r\n >\r\n {{ 'asset.remove-asset' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </div>\r\n </div>\r\n</ng-template>\r\n",
3486
3563
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
3487
- styles: [":host{width:340px;display:block}:host.compact{width:162px}.placeholder{text-align:center;color:var(--color-grey-300)}.featured-asset{text-align:center;background:var(--color-component-bg-200);padding:6px;cursor:pointer}.featured-asset.compact{width:100%;min-height:40px;position:relative;padding:6px}.featured-asset .compact-select{position:absolute;bottom:6px;right:6px;margin:0}.all-assets{display:flex;flex-wrap:wrap}.all-assets .drop-list{min-width:60px}.all-assets .asset-thumb{margin:3px;padding:0;border:2px solid var(--color-component-border-100);cursor:pointer}.all-assets .asset-thumb.featured{border-color:var(--color-primary-500)}.all-assets .remove-asset{color:var(--color-warning-500)}.all-assets.compact .drop-list{min-width:54px}.all-assets.compact .asset-thumb{margin:1px;border-width:1px}.all-assets.compact .cdk-drag-placeholder{width:50px}.all-assets.compact .cdk-drag-placeholder .asset-thumb{width:50px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.all-assets.cdk-drop-list-dragging vdr-dropdown:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-dragging>*:not(.cdk-drag-placeholder){display:none}\n"]
3564
+ styles: [":host{width:340px;display:block}:host.compact{width:162px}.placeholder{text-align:center;color:var(--color-grey-300)}.featured-asset{text-align:center;background:var(--color-component-bg-200);padding:6px;cursor:pointer;border-radius:var(--border-radius-img)}.featured-asset img{border-radius:var(--border-radius-img)}.featured-asset.compact{width:100%;min-height:40px;position:relative;padding:6px}.featured-asset .compact-select{position:absolute;bottom:6px;right:6px;margin:0}.all-assets{display:flex;flex-wrap:wrap}.all-assets .drop-list{min-width:60px}.all-assets .asset-thumb{margin:3px;padding:0;border:2px solid var(--color-component-border-100);border-radius:var(--border-radius-img);cursor:pointer}.all-assets .asset-thumb img{width:50px;height:50px;border-radius:var(--border-radius-img)}.all-assets .asset-thumb.featured{border-color:var(--color-primary-500);border-radius:calc(var(--border-radius-img) + 2px)}.all-assets .remove-asset{color:var(--color-warning-500)}.all-assets.compact .drop-list{min-width:54px}.all-assets.compact .asset-thumb{margin:1px;border-width:1px}.all-assets.compact .cdk-drag-placeholder{width:50px}.all-assets.compact .cdk-drag-placeholder .asset-thumb{width:50px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.all-assets.cdk-drop-list-dragging vdr-dropdown:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-dragging>*:not(.cdk-drag-placeholder){display:none}\n"]
3488
3565
  },] }
3489
3566
  ];
3490
3567
  AssetsComponent.ctorParameters = function () { return [
@@ -3504,36 +3581,66 @@
3504
3581
  this.route = route;
3505
3582
  this.router = router;
3506
3583
  this.dataService = dataService;
3584
+ this.previewUpdatedFilters = false;
3507
3585
  this.filterTermControl = new forms.FormControl('');
3586
+ this.isLoading = false;
3508
3587
  this.collectionIdChange$ = new rxjs.BehaviorSubject('');
3588
+ this.parentIdChange$ = new rxjs.BehaviorSubject('');
3589
+ this.filterChanges$ = new rxjs.BehaviorSubject([]);
3509
3590
  this.refresh$ = new rxjs.BehaviorSubject(true);
3510
3591
  this.destroy$ = new rxjs.Subject();
3511
3592
  }
3512
3593
  CollectionContentsComponent.prototype.ngOnInit = function () {
3513
3594
  var _this = this;
3514
- this.contentsCurrentPage$ = this.route.paramMap.pipe(operators.map(function (qpm) { return qpm.get('contentsPage'); }), operators.map(function (page) { return (!page ? 1 : +page); }), operators.startWith(1), operators.distinctUntilChanged());
3515
- this.contentsItemsPerPage$ = this.route.paramMap.pipe(operators.map(function (qpm) { return qpm.get('contentsPerPage'); }), operators.map(function (perPage) { return (!perPage ? 10 : +perPage); }), operators.startWith(10), operators.distinctUntilChanged());
3595
+ this.contentsCurrentPage$ = this.route.queryParamMap.pipe(operators.map(function (qpm) { return qpm.get('contentsPage'); }), operators.map(function (page) { return (!page ? 1 : +page); }), operators.startWith(1), operators.distinctUntilChanged());
3596
+ this.contentsItemsPerPage$ = this.route.queryParamMap.pipe(operators.map(function (qpm) { return qpm.get('contentsPerPage'); }), operators.map(function (perPage) { return (!perPage ? 10 : +perPage); }), operators.startWith(10), operators.distinctUntilChanged());
3516
3597
  var filterTerm$ = this.filterTermControl.valueChanges.pipe(operators.debounceTime(250), operators.tap(function () { return _this.setContentsPageNumber(1); }), operators.startWith(''));
3517
- var collection$ = rxjs.combineLatest(this.collectionIdChange$, this.contentsCurrentPage$, this.contentsItemsPerPage$, filterTerm$, this.refresh$).pipe(operators.takeUntil(this.destroy$), operators.switchMap(function (_a) {
3518
- var _b = __read(_a, 4), id = _b[0], currentPage = _b[1], itemsPerPage = _b[2], filterTerm = _b[3];
3598
+ var filterChanges$ = this.filterChanges$.asObservable().pipe(operators.filter(function () { return _this.previewUpdatedFilters; }), operators.tap(function () { return _this.setContentsPageNumber(1); }), operators.startWith([]));
3599
+ var fetchUpdate$ = rxjs.combineLatest(this.collectionIdChange$, this.parentIdChange$, this.contentsCurrentPage$, this.contentsItemsPerPage$, filterTerm$, filterChanges$, this.refresh$);
3600
+ var collection$ = fetchUpdate$.pipe(operators.takeUntil(this.destroy$), operators.tap(function () { return (_this.isLoading = true); }), operators.debounceTime(50), operators.switchMap(function (_b) {
3601
+ var _c = __read(_b, 6), id = _c[0], parentId = _c[1], currentPage = _c[2], itemsPerPage = _c[3], filterTerm = _c[4], filters = _c[5];
3519
3602
  var take = itemsPerPage;
3520
3603
  var skip = (currentPage - 1) * itemsPerPage;
3521
- if (id) {
3604
+ if (filters.length && _this.previewUpdatedFilters) {
3605
+ var filterClause = filterTerm
3606
+ ? { name: { contains: filterTerm } }
3607
+ : undefined;
3608
+ return _this.dataService.collection
3609
+ .previewCollectionVariants({
3610
+ parentId: parentId,
3611
+ filters: filters,
3612
+ }, {
3613
+ take: take,
3614
+ skip: skip,
3615
+ filter: filterClause,
3616
+ })
3617
+ .mapSingle(function (data) { return data.previewCollectionVariants; })
3618
+ .pipe(operators.catchError(function () { return rxjs.of({ items: [], totalItems: 0 }); }));
3619
+ }
3620
+ else if (id) {
3522
3621
  return _this.dataService.collection
3523
3622
  .getCollectionContents(id, take, skip, filterTerm)
3524
- .mapSingle(function (data) { return data.collection; });
3623
+ .mapSingle(function (data) { var _a; return (_a = data.collection) === null || _a === void 0 ? void 0 : _a.productVariants; });
3525
3624
  }
3526
3625
  else {
3527
3626
  return rxjs.of(null);
3528
3627
  }
3529
- }));
3530
- this.contents$ = collection$.pipe(operators.map(function (result) { return (result ? result.productVariants.items : []); }));
3531
- this.contentsTotalItems$ = collection$.pipe(operators.map(function (result) { return (result ? result.productVariants.totalItems : 0); }));
3628
+ }), operators.tap(function () { return (_this.isLoading = false); }), operators.finalize(function () { return (_this.isLoading = false); }));
3629
+ this.contents$ = collection$.pipe(operators.map(function (result) { return (result ? result.items : []); }));
3630
+ this.contentsTotalItems$ = collection$.pipe(operators.map(function (result) { return (result ? result.totalItems : 0); }));
3532
3631
  };
3533
3632
  CollectionContentsComponent.prototype.ngOnChanges = function (changes) {
3534
3633
  if ('collectionId' in changes) {
3535
3634
  this.collectionIdChange$.next(changes.collectionId.currentValue);
3536
3635
  }
3636
+ if ('parentId' in changes) {
3637
+ this.parentIdChange$.next(changes.parentId.currentValue);
3638
+ }
3639
+ if ('updatedFilters' in changes) {
3640
+ if (this.updatedFilters) {
3641
+ this.filterChanges$.next(this.updatedFilters);
3642
+ }
3643
+ }
3537
3644
  };
3538
3645
  CollectionContentsComponent.prototype.ngOnDestroy = function () {
3539
3646
  this.destroy$.next();
@@ -3549,10 +3656,14 @@
3549
3656
  this.refresh$.next(true);
3550
3657
  };
3551
3658
  CollectionContentsComponent.prototype.setParam = function (key, value) {
3552
- var _a;
3553
- this.router.navigate(['./', Object.assign(Object.assign({}, this.route.snapshot.params), (_a = {}, _a[key] = value, _a))], {
3659
+ var _b;
3660
+ this.router.navigate(['./'], {
3554
3661
  relativeTo: this.route,
3662
+ queryParams: (_b = {},
3663
+ _b[key] = value,
3664
+ _b),
3555
3665
  queryParamsHandling: 'merge',
3666
+ replaceUrl: true,
3556
3667
  });
3557
3668
  };
3558
3669
  return CollectionContentsComponent;
@@ -3560,9 +3671,9 @@
3560
3671
  CollectionContentsComponent.decorators = [
3561
3672
  { type: i0.Component, args: [{
3562
3673
  selector: 'vdr-collection-contents',
3563
- template: "<div class=\"contents-header\">\r\n <div class=\"header-title-row\">\r\n <ng-container\r\n *ngTemplateOutlet=\"headerTemplate; context: { $implicit: contentsTotalItems$ | async }\"\r\n ></ng-container>\r\n </div>\r\n <input\r\n type=\"text\"\r\n [placeholder]=\"'catalog.filter-by-name' | translate\"\r\n [formControl]=\"filterTermControl\"\r\n />\r\n</div>\r\n<vdr-data-table\r\n [items]=\"contents$ | async\"\r\n [itemsPerPage]=\"contentsItemsPerPage$ | async\"\r\n [totalItems]=\"contentsTotalItems$ | async\"\r\n [currentPage]=\"contentsCurrentPage$ | async\"\r\n (pageChange)=\"setContentsPageNumber($event)\"\r\n (itemsPerPageChange)=\"setContentsItemsPerPage($event)\"\r\n>\r\n <ng-template let-variant=\"item\">\r\n <td class=\"left align-middle\">{{ variant.name }}</td>\r\n <td class=\"right align-middle\">\r\n <vdr-table-row-action\r\n iconShape=\"edit\"\r\n [label]=\"'common.edit' | translate\"\r\n [linkTo]=\"['/catalog/products', variant.productId, { tab: 'variants' }]\"\r\n ></vdr-table-row-action>\r\n </td>\r\n </ng-template>\r\n</vdr-data-table>\r\n",
3674
+ template: "<div class=\"contents-header\">\r\n <div class=\"header-title-row\">\r\n <ng-container\r\n *ngTemplateOutlet=\"headerTemplate; context: { $implicit: contentsTotalItems$ | async }\"\r\n ></ng-container>\r\n </div>\r\n <input\r\n type=\"text\"\r\n [placeholder]=\"'catalog.filter-by-name' | translate\"\r\n [formControl]=\"filterTermControl\"\r\n />\r\n</div>\r\n<div class=\"table-wrapper\">\r\n <div class=\"progress loop\" [class.visible]=\"isLoading\"></div>\r\n <vdr-data-table\r\n [class.loading]=\"isLoading\"\r\n [items]=\"contents$ | async\"\r\n [itemsPerPage]=\"contentsItemsPerPage$ | async\"\r\n [totalItems]=\"contentsTotalItems$ | async\"\r\n [currentPage]=\"contentsCurrentPage$ | async\"\r\n (pageChange)=\"setContentsPageNumber($event)\"\r\n (itemsPerPageChange)=\"setContentsItemsPerPage($event)\"\r\n >\r\n <ng-template let-variant=\"item\">\r\n <td class=\"left align-middle\">{{ variant.name }}</td>\r\n <td class=\"left align-middle\"><small class=\"sku\">{{ variant.sku }}</small></td>\r\n <td class=\"right align-middle\">\r\n <vdr-table-row-action\r\n iconShape=\"edit\"\r\n [label]=\"'common.edit' | translate\"\r\n [linkTo]=\"['/catalog/products', variant.productId, { tab: 'variants' }]\"\r\n ></vdr-table-row-action>\r\n </td>\r\n </ng-template>\r\n </vdr-data-table>\r\n</div>\r\n",
3564
3675
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
3565
- styles: [".contents-header{background-color:var(--color-component-bg-100);position:sticky;top:0;padding:6px;z-index:1;border-bottom:1px solid var(--color-component-border-200)}.contents-header .header-title-row{display:flex;justify-content:space-between;align-items:center}.contents-header .clr-input{width:100%}:host ::ng-deep table{margin-top:-1px}\n"]
3676
+ styles: [".contents-header{background-color:var(--color-component-bg-100);position:sticky;top:0;padding:6px;z-index:1;border-bottom:1px solid var(--color-component-border-200)}.contents-header .header-title-row{display:flex;justify-content:space-between;align-items:center}.contents-header .clr-input{width:100%}:host{display:block}:host ::ng-deep table{margin-top:-1px}vdr-data-table{opacity:1;transition:opacity .3s}vdr-data-table.loading{opacity:.5}.table-wrapper{position:relative}.progress{position:absolute;top:0;left:0;overflow:hidden;height:6px;opacity:0;transition:opacity .1s}.progress.visible{opacity:1}.sku{color:var(--color-text-200)}\n"]
3566
3677
  },] }
3567
3678
  ];
3568
3679
  CollectionContentsComponent.ctorParameters = function () { return [
@@ -3572,6 +3683,9 @@
3572
3683
  ]; };
3573
3684
  CollectionContentsComponent.propDecorators = {
3574
3685
  collectionId: [{ type: i0.Input }],
3686
+ parentId: [{ type: i0.Input }],
3687
+ updatedFilters: [{ type: i0.Input }],
3688
+ previewUpdatedFilters: [{ type: i0.Input }],
3575
3689
  headerTemplate: [{ type: i0.ContentChild, args: [i0.TemplateRef, { static: true },] }]
3576
3690
  };
3577
3691
 
@@ -3579,8 +3693,9 @@
3579
3693
  * Builds a tree from an array of nodes which have a parent.
3580
3694
  * Based on https://stackoverflow.com/a/31247960/772859, modified to preserve ordering.
3581
3695
  */
3582
- function arrayToTree(nodes, currentState) {
3696
+ function arrayToTree(nodes, currentState, expandedIds) {
3583
3697
  var e_1, _c, e_2, _d;
3698
+ if (expandedIds === void 0) { expandedIds = []; }
3584
3699
  var _a, _b;
3585
3700
  var topLevelNodes = [];
3586
3701
  var mappedArr = {};
@@ -3604,7 +3719,7 @@
3604
3719
  var id = _f.value;
3605
3720
  if (mappedArr.hasOwnProperty(id)) {
3606
3721
  var mappedElem = mappedArr[id];
3607
- mappedElem.expanded = (_b = (_a = currentStateMap.get(id)) === null || _a === void 0 ? void 0 : _a.expanded) !== null && _b !== void 0 ? _b : false;
3722
+ mappedElem.expanded = (_b = (_a = currentStateMap.get(id)) === null || _a === void 0 ? void 0 : _a.expanded) !== null && _b !== void 0 ? _b : expandedIds.includes(id);
3608
3723
  var parent = mappedElem.parent;
3609
3724
  if (!parent) {
3610
3725
  continue;
@@ -3656,13 +3771,14 @@
3656
3771
  var CollectionTreeComponent = /** @class */ (function () {
3657
3772
  function CollectionTreeComponent() {
3658
3773
  this.expandAll = false;
3774
+ this.expandedIds = [];
3659
3775
  this.rearrange = new i0.EventEmitter();
3660
3776
  this.deleteCollection = new i0.EventEmitter();
3661
3777
  this.allMoveListItems = [];
3662
3778
  }
3663
3779
  CollectionTreeComponent.prototype.ngOnChanges = function (changes) {
3664
3780
  if ('collections' in changes && this.collections) {
3665
- this.collectionTree = arrayToTree(this.collections, this.collectionTree);
3781
+ this.collectionTree = arrayToTree(this.collections, this.collectionTree, this.expandedIds);
3666
3782
  this.allMoveListItems = [];
3667
3783
  }
3668
3784
  };
@@ -3722,15 +3838,18 @@
3722
3838
  collections: [{ type: i0.Input }],
3723
3839
  activeCollectionId: [{ type: i0.Input }],
3724
3840
  expandAll: [{ type: i0.Input }],
3841
+ expandedIds: [{ type: i0.Input }],
3725
3842
  rearrange: [{ type: i0.Output }],
3726
3843
  deleteCollection: [{ type: i0.Output }]
3727
3844
  };
3728
3845
 
3729
3846
  var CollectionTreeNodeComponent = /** @class */ (function () {
3730
- function CollectionTreeNodeComponent(parent, root, dataService) {
3847
+ function CollectionTreeNodeComponent(parent, root, dataService, router, route) {
3731
3848
  this.parent = parent;
3732
3849
  this.root = root;
3733
3850
  this.dataService = dataService;
3851
+ this.router = router;
3852
+ this.route = route;
3734
3853
  this.depth = 0;
3735
3854
  this.expandAll = false;
3736
3855
  this.moveListItems = [];
@@ -3758,6 +3877,24 @@
3758
3877
  CollectionTreeNodeComponent.prototype.trackByFn = function (index, item) {
3759
3878
  return item.id;
3760
3879
  };
3880
+ CollectionTreeNodeComponent.prototype.toggleExpanded = function (collection) {
3881
+ var _a, _b;
3882
+ collection.expanded = !collection.expanded;
3883
+ var expandedIds = (_b = (_a = this.route.snapshot.queryParamMap.get('expanded')) === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
3884
+ if (collection.expanded) {
3885
+ expandedIds.push(collection.id);
3886
+ }
3887
+ else {
3888
+ expandedIds = expandedIds.filter(function (id) { return id !== collection.id; });
3889
+ }
3890
+ this.router.navigate(['./'], {
3891
+ queryParams: {
3892
+ expanded: expandedIds.filter(function (id) { return !!id; }).join(','),
3893
+ },
3894
+ queryParamsHandling: 'merge',
3895
+ relativeTo: this.route,
3896
+ });
3897
+ };
3761
3898
  CollectionTreeNodeComponent.prototype.getMoveListItems = function (collection) {
3762
3899
  this.moveListItems = this.root.getMoveListItems(collection);
3763
3900
  };
@@ -3800,7 +3937,7 @@
3800
3937
  CollectionTreeNodeComponent.decorators = [
3801
3938
  { type: i0.Component, args: [{
3802
3939
  selector: 'vdr-collection-tree-node',
3803
- template: "<div\r\n cdkDropList\r\n class=\"tree-node\"\r\n #dropList\r\n [cdkDropListData]=\"collectionTree\"\r\n [cdkDropListDisabled]=\"!(hasUpdatePermission$ | async)\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n>\r\n <div\r\n class=\"collection\"\r\n [class.private]=\"collection.isPrivate\"\r\n *ngFor=\"let collection of collectionTree.children; index as i; trackBy: trackByFn\"\r\n cdkDrag\r\n [cdkDragData]=\"collection\"\r\n >\r\n <div\r\n class=\"collection-detail\"\r\n [ngClass]=\"'depth-' + depth\"\r\n [class.active]=\"collection.id === activeCollectionId\"\r\n >\r\n <div class=\"name\">\r\n <button\r\n class=\"icon-button folder-button\"\r\n [disabled]=\"expandAll\"\r\n *ngIf=\"collection.children?.length; else folderSpacer\"\r\n (click)=\"collection.expanded = !collection.expanded\"\r\n >\r\n <clr-icon shape=\"folder\" *ngIf=\"!collection.expanded && !expandAll\"></clr-icon>\r\n <clr-icon shape=\"folder-open\" *ngIf=\"collection.expanded || expandAll\"></clr-icon>\r\n </button>\r\n <ng-template #folderSpacer>\r\n <div class=\"folder-button-spacer\"></div>\r\n </ng-template>\r\n {{ collection.name }}\r\n </div>\r\n <div class=\"flex-spacer\"></div>\r\n <vdr-chip *ngIf=\"collection.isPrivate\">{{ 'catalog.private' | translate }}</vdr-chip>\r\n <a\r\n class=\"btn btn-link btn-sm\"\r\n [routerLink]=\"['./', { contents: collection.id }]\"\r\n queryParamsHandling=\"preserve\"\r\n >\r\n <clr-icon shape=\"view-list\"></clr-icon>\r\n {{ 'catalog.view-contents' | translate }}\r\n </a>\r\n <a class=\"btn btn-link btn-sm\" [routerLink]=\"['/catalog/collections/', collection.id]\">\r\n <clr-icon shape=\"edit\"></clr-icon>\r\n {{ 'common.edit' | translate }}\r\n </a>\r\n <div class=\"drag-handle\" cdkDragHandle *vdrIfPermissions=\"['UpdateCatalog', 'UpdateCollection']\">\r\n <clr-icon shape=\"drag-handle\" size=\"24\"></clr-icon>\r\n </div>\r\n <vdr-dropdown>\r\n <button class=\"icon-button\" vdrDropdownTrigger (click)=\"getMoveListItems(collection)\">\r\n <clr-icon shape=\"ellipsis-vertical\"></clr-icon>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <a\r\n class=\"dropdown-item\"\r\n [routerLink]=\"['./', 'create', { parentId: collection.id }]\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateCollection']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.create-new-collection' | translate }}\r\n </a>\r\n <div class=\"dropdown-divider\"></div>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n [disabled]=\"i === 0 || !(hasUpdatePermission$ | async)\"\r\n (click)=\"moveUp(collection, i)\"\r\n >\r\n <clr-icon shape=\"caret up\"></clr-icon>\r\n {{ 'catalog.move-up' | translate }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n [disabled]=\"\r\n i === collectionTree.children.length - 1 || !(hasUpdatePermission$ | async)\r\n \"\r\n (click)=\"moveDown(collection, i)\"\r\n >\r\n <clr-icon shape=\"caret down\"></clr-icon>\r\n {{ 'catalog.move-down' | translate }}\r\n </button>\r\n <h4 class=\"dropdown-header\">{{ 'catalog.move-to' | translate }}</h4>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n *ngFor=\"let item of moveListItems\"\r\n (click)=\"move(collection, item.id)\"\r\n [disabled]=\"!(hasUpdatePermission$ | async)\"\r\n >\r\n <div class=\"move-to-item\">\r\n <div class=\"move-icon\">\r\n <clr-icon shape=\"child-arrow\"></clr-icon>\r\n </div>\r\n <div class=\"path\">\r\n {{ item.path }}\r\n </div>\r\n </div>\r\n </button>\r\n <div class=\"dropdown-divider\"></div>\r\n <button\r\n class=\"button\"\r\n vdrDropdownItem\r\n (click)=\"delete(collection.id)\"\r\n [disabled]=\"!(hasDeletePermission$ | async)\"\r\n >\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon>\r\n {{ 'common.delete' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </div>\r\n <vdr-collection-tree-node\r\n *ngIf=\"collection.expanded || expandAll\"\r\n [expandAll]=\"expandAll\"\r\n [collectionTree]=\"collection\"\r\n [activeCollectionId]=\"activeCollectionId\"\r\n ></vdr-collection-tree-node>\r\n </div>\r\n</div>\r\n",
3940
+ template: "<div\r\n cdkDropList\r\n class=\"tree-node\"\r\n #dropList\r\n [cdkDropListData]=\"collectionTree\"\r\n [cdkDropListDisabled]=\"!(hasUpdatePermission$ | async)\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n>\r\n <div\r\n class=\"collection\"\r\n [class.private]=\"collection.isPrivate\"\r\n *ngFor=\"let collection of collectionTree.children; index as i; trackBy: trackByFn\"\r\n cdkDrag\r\n [cdkDragData]=\"collection\"\r\n >\r\n <div\r\n class=\"collection-detail\"\r\n [ngClass]=\"'depth-' + depth\"\r\n [class.active]=\"collection.id === activeCollectionId\"\r\n >\r\n <div class=\"name\">\r\n <button\r\n class=\"icon-button folder-button\"\r\n [disabled]=\"expandAll\"\r\n *ngIf=\"collection.children?.length; else folderSpacer\"\r\n (click)=\"toggleExpanded(collection)\"\r\n >\r\n <clr-icon shape=\"folder\" *ngIf=\"!collection.expanded && !expandAll\"></clr-icon>\r\n <clr-icon shape=\"folder-open\" *ngIf=\"collection.expanded || expandAll\"></clr-icon>\r\n </button>\r\n <ng-template #folderSpacer>\r\n <div class=\"folder-button-spacer\"></div>\r\n </ng-template>\r\n {{ collection.name }}\r\n </div>\r\n <div class=\"flex-spacer\"></div>\r\n <vdr-chip *ngIf=\"collection.isPrivate\">{{ 'catalog.private' | translate }}</vdr-chip>\r\n <a\r\n class=\"btn btn-link btn-sm\"\r\n [routerLink]=\"['./', { contents: collection.id }]\"\r\n queryParamsHandling=\"preserve\"\r\n >\r\n <clr-icon shape=\"view-list\"></clr-icon>\r\n {{ 'catalog.view-contents' | translate }}\r\n </a>\r\n <a class=\"btn btn-link btn-sm\" [routerLink]=\"['/catalog/collections/', collection.id]\">\r\n <clr-icon shape=\"edit\"></clr-icon>\r\n {{ 'common.edit' | translate }}\r\n </a>\r\n <div class=\"drag-handle\" cdkDragHandle *vdrIfPermissions=\"['UpdateCatalog', 'UpdateCollection']\">\r\n <clr-icon shape=\"drag-handle\" size=\"24\"></clr-icon>\r\n </div>\r\n <vdr-dropdown>\r\n <button class=\"icon-button\" vdrDropdownTrigger (click)=\"getMoveListItems(collection)\">\r\n <clr-icon shape=\"ellipsis-vertical\"></clr-icon>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <a\r\n class=\"dropdown-item\"\r\n [routerLink]=\"['./', 'create', { parentId: collection.id }]\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateCollection']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.create-new-collection' | translate }}\r\n </a>\r\n <div class=\"dropdown-divider\"></div>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n [disabled]=\"i === 0 || !(hasUpdatePermission$ | async)\"\r\n (click)=\"moveUp(collection, i)\"\r\n >\r\n <clr-icon shape=\"caret up\"></clr-icon>\r\n {{ 'catalog.move-up' | translate }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n [disabled]=\"\r\n i === collectionTree.children.length - 1 || !(hasUpdatePermission$ | async)\r\n \"\r\n (click)=\"moveDown(collection, i)\"\r\n >\r\n <clr-icon shape=\"caret down\"></clr-icon>\r\n {{ 'catalog.move-down' | translate }}\r\n </button>\r\n <h4 class=\"dropdown-header\">{{ 'catalog.move-to' | translate }}</h4>\r\n <button\r\n type=\"button\"\r\n vdrDropdownItem\r\n *ngFor=\"let item of moveListItems\"\r\n (click)=\"move(collection, item.id)\"\r\n [disabled]=\"!(hasUpdatePermission$ | async)\"\r\n >\r\n <div class=\"move-to-item\">\r\n <div class=\"move-icon\">\r\n <clr-icon shape=\"child-arrow\"></clr-icon>\r\n </div>\r\n <div class=\"path\">\r\n {{ item.path }}\r\n </div>\r\n </div>\r\n </button>\r\n <div class=\"dropdown-divider\"></div>\r\n <button\r\n class=\"button\"\r\n vdrDropdownItem\r\n (click)=\"delete(collection.id)\"\r\n [disabled]=\"!(hasDeletePermission$ | async)\"\r\n >\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon>\r\n {{ 'common.delete' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </div>\r\n <vdr-collection-tree-node\r\n *ngIf=\"collection.expanded || expandAll\"\r\n [expandAll]=\"expandAll\"\r\n [collectionTree]=\"collection\"\r\n [activeCollectionId]=\"activeCollectionId\"\r\n ></vdr-collection-tree-node>\r\n </div>\r\n</div>\r\n",
3804
3941
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
3805
3942
  styles: [":host{display:block}.collection{background-color:var(--color-component-bg-100);font-size:.65rem;transition:transform .25s cubic-bezier(0,0,.2,1);margin-bottom:2px;border-left:2px solid transparent;transition:border-left-color .2s}.collection.private{background-color:var(--color-component-bg-200)}.collection .collection-detail{padding:6px 12px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--color-component-border-100)}.collection .collection-detail.active{background-color:var(--clr-global-selection-color)}.collection .collection-detail.depth-1{padding-left:36px}.collection .collection-detail.depth-2{padding-left:60px}.collection .collection-detail.depth-3{padding-left:84px}.collection .collection-detail.depth-4{padding-left:108px}.collection .collection-detail .folder-button-spacer{display:inline-block;width:28px}.tree-node{display:block;background:var(--color-component-bg-100);overflow:hidden}.tree-node.cdk-drop-list-dragging>.collection{border-left-color:var(--color-primary-300)}.drag-placeholder{min-height:120px;background-color:var(--color-component-bg-300);transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-list.cdk-drop-list-dragging .tree-node:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.move-to-item{display:flex;white-space:normal;align-items:baseline}.move-to-item .move-icon{flex:none;margin-right:3px}.move-to-item .path{line-height:18px}\n"]
3806
3943
  },] }
@@ -3808,7 +3945,9 @@
3808
3945
  CollectionTreeNodeComponent.ctorParameters = function () { return [
3809
3946
  { type: CollectionTreeNodeComponent, decorators: [{ type: i0.SkipSelf }, { type: i0.Optional }] },
3810
3947
  { type: CollectionTreeComponent },
3811
- { type: i2.DataService }
3948
+ { type: i2.DataService },
3949
+ { type: i1.Router },
3950
+ { type: i1.ActivatedRoute }
3812
3951
  ]; };
3813
3952
  CollectionTreeNodeComponent.propDecorators = {
3814
3953
  collectionTree: [{ type: i0.Input }],
@@ -3991,110 +4130,6 @@
3991
4130
  textArea: [{ type: i0.ViewChild, args: ['textArea', { static: true },] }]
3992
4131
  };
3993
4132
 
3994
- var ɵ0 = i2.SingleSearchSelectionModelFactory;
3995
- var ProductSearchInputComponent = /** @class */ (function () {
3996
- function ProductSearchInputComponent() {
3997
- var _this = this;
3998
- this.searchTermChange = new i0.EventEmitter();
3999
- this.facetValueChange = new i0.EventEmitter();
4000
- this.lastTerm = '';
4001
- this.lastFacetValueIds = [];
4002
- this.filterFacetResults = function (term, item) {
4003
- if (!_this.isFacetValueItem(item)) {
4004
- return false;
4005
- }
4006
- var cix = term.indexOf(':');
4007
- var facetName = cix > -1 ? term.toLowerCase().slice(0, cix) : null;
4008
- var facetVal = cix > -1 ? term.toLowerCase().slice(cix + 1) : term.toLowerCase();
4009
- if (facetName) {
4010
- return (item.facetValue.facet.name.toLowerCase().includes(facetName) &&
4011
- item.facetValue.name.toLocaleLowerCase().includes(facetVal));
4012
- }
4013
- return (item.facetValue.name.toLowerCase().includes(term.toLowerCase()) ||
4014
- item.facetValue.facet.name.toLowerCase().includes(term.toLowerCase()));
4015
- };
4016
- this.isFacetValueItem = function (input) {
4017
- return typeof input === 'object' && !!input && input.hasOwnProperty('facetValue');
4018
- };
4019
- }
4020
- ProductSearchInputComponent.prototype.setSearchTerm = function (term) {
4021
- var _this = this;
4022
- if (term) {
4023
- this.selectComponent.select({ label: term, value: { label: term } });
4024
- }
4025
- else {
4026
- var currentTerm = this.selectComponent.selectedItems.find(function (i) { return !_this.isFacetValueItem(i.value); });
4027
- if (currentTerm) {
4028
- this.selectComponent.unselect(currentTerm);
4029
- }
4030
- }
4031
- };
4032
- ProductSearchInputComponent.prototype.setFacetValues = function (ids) {
4033
- var _this = this;
4034
- var items = this.selectComponent.items;
4035
- this.selectComponent.selectedItems.forEach(function (item) {
4036
- if (_this.isFacetValueItem(item.value) && !ids.includes(item.value.facetValue.id)) {
4037
- _this.selectComponent.unselect(item);
4038
- }
4039
- });
4040
- ids.map(function (id) {
4041
- return items === null || items === void 0 ? void 0 : items.find(function (item) { return _this.isFacetValueItem(item) && item.facetValue.id === id; });
4042
- })
4043
- .filter(sharedUtils.notNullOrUndefined)
4044
- .forEach(function (item) {
4045
- var isSelected = _this.selectComponent.selectedItems.find(function (i) {
4046
- var val = i.value;
4047
- if (_this.isFacetValueItem(val)) {
4048
- return val.facetValue.id === item.facetValue.id;
4049
- }
4050
- return false;
4051
- });
4052
- if (!isSelected) {
4053
- _this.selectComponent.select({ label: '', value: item });
4054
- }
4055
- });
4056
- };
4057
- ProductSearchInputComponent.prototype.onSelectChange = function (selectedItems) {
4058
- var _this = this;
4059
- if (!Array.isArray(selectedItems)) {
4060
- selectedItems = [selectedItems];
4061
- }
4062
- var searchTermItem = selectedItems.find(function (item) { return !_this.isFacetValueItem(item); });
4063
- var searchTerm = searchTermItem ? searchTermItem.label : '';
4064
- var facetValueIds = selectedItems.filter(this.isFacetValueItem).map(function (i) { return i.facetValue.id; });
4065
- if (searchTerm !== this.lastTerm) {
4066
- this.searchTermChange.emit(searchTerm);
4067
- this.lastTerm = searchTerm;
4068
- }
4069
- if (this.lastFacetValueIds.join(',') !== facetValueIds.join(',')) {
4070
- this.facetValueChange.emit(facetValueIds);
4071
- this.lastFacetValueIds = facetValueIds;
4072
- }
4073
- };
4074
- ProductSearchInputComponent.prototype.addTagFn = function (item) {
4075
- return { label: item };
4076
- };
4077
- ProductSearchInputComponent.prototype.isSearchHeaderSelected = function () {
4078
- return this.selectComponent.itemsList.markedIndex === -1;
4079
- };
4080
- return ProductSearchInputComponent;
4081
- }());
4082
- ProductSearchInputComponent.decorators = [
4083
- { type: i0.Component, args: [{
4084
- selector: 'vdr-product-search-input',
4085
- template: "<ng-select\r\n [addTag]=\"addTagFn\"\r\n [placeholder]=\"'catalog.search-product-name-or-code' | translate\"\r\n [items]=\"facetValueResults\"\r\n [searchFn]=\"filterFacetResults\"\r\n [hideSelected]=\"true\"\r\n [multiple]=\"true\"\r\n [markFirst]=\"false\"\r\n (change)=\"onSelectChange($event)\"\r\n #selectComponent\r\n>\r\n <ng-template ng-header-tmp>\r\n <div\r\n class=\"search-header\"\r\n *ngIf=\"selectComponent.searchTerm\"\r\n [class.selected]=\"isSearchHeaderSelected()\"\r\n (click)=\"selectComponent.selectTag()\"\r\n >\r\n {{ 'catalog.search-for-term' | translate }}: {{ selectComponent.searchTerm }}\r\n </div>\r\n </ng-template>\r\n <ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\">\r\n <ng-container *ngIf=\"item.facetValue\">\r\n <vdr-facet-value-chip\r\n [facetValue]=\"item.facetValue\"\r\n [removable]=\"true\"\r\n (remove)=\"clear(item)\"\r\n ></vdr-facet-value-chip>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.facetValue\">\r\n <vdr-chip [icon]=\"'times'\" (iconClick)=\"clear(item)\">\"{{ item.label }}\"</vdr-chip>\r\n </ng-container>\r\n </ng-template>\r\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\">\r\n <ng-container *ngIf=\"item.facetValue\">\r\n <vdr-facet-value-chip [facetValue]=\"item.facetValue\" [removable]=\"false\"></vdr-facet-value-chip>\r\n </ng-container>\r\n </ng-template>\r\n</ng-select>\r\n",
4086
- changeDetection: i0.ChangeDetectionStrategy.OnPush,
4087
- providers: [{ provide: ngSelect.SELECTION_MODEL_FACTORY, useValue: ɵ0 }],
4088
- styles: [":host{margin-top:6px;display:block;width:100%}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{background:none;margin:0}:host ::ng-deep .ng-dropdown-panel-items div.ng-option:last-child{display:none}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-header{border:none;padding:0}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container{padding:0}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{padding-left:8px}ng-select{width:100%;min-width:300px;margin-right:12px}.search-header{padding:8px 10px;border-bottom:1px solid var(--color-component-border-100);cursor:pointer}.search-header.selected,.search-header:hover{background-color:var(--color-component-bg-200)}\n"]
4089
- },] }
4090
- ];
4091
- ProductSearchInputComponent.propDecorators = {
4092
- facetValueResults: [{ type: i0.Input }],
4093
- searchTermChange: [{ type: i0.Output }],
4094
- facetValueChange: [{ type: i0.Output }],
4095
- selectComponent: [{ type: i0.ViewChild, args: ['selectComponent', { static: true },] }]
4096
- };
4097
-
4098
4133
  var UpdateProductOptionDialogComponent = /** @class */ (function () {
4099
4134
  function UpdateProductOptionDialogComponent() {
4100
4135
  this.updateVariantName = true;
@@ -4363,7 +4398,7 @@
4363
4398
  selector: 'vdr-product-variants-list',
4364
4399
  template: "<div class=\"variants-list\">\r\n <div\r\n class=\"variant-container card\"\r\n *ngFor=\"\r\n let variant of variants | paginate: paginationConfig || { itemsPerPage: 10, currentPage: 1 };\r\n trackBy: trackById;\r\n let i = index\r\n \"\r\n [class.disabled]=\"!formGroupMap.get(variant.id)?.get('enabled')?.value\"\r\n >\r\n <ng-container *ngIf=\"formGroupMap.get(variant.id) as formGroup\" [formGroup]=\"formGroup\">\r\n <div class=\"card-block header-row\">\r\n <div class=\"details\">\r\n <vdr-title-input class=\"sku\" [readonly]=\"!(updatePermission | hasPermission)\">\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"text\"\r\n formControlName=\"sku\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n [placeholder]=\"'catalog.sku' | translate\"\r\n />\r\n </clr-input-container>\r\n </vdr-title-input>\r\n <vdr-title-input class=\"name\" [readonly]=\"!(updatePermission | hasPermission)\">\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"text\"\r\n formControlName=\"name\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n [placeholder]=\"'common.name' | translate\"\r\n />\r\n </clr-input-container>\r\n </vdr-title-input>\r\n </div>\r\n <div class=\"right-controls\">\r\n <clr-toggle-wrapper *vdrIfPermissions=\"updatePermission\">\r\n <input type=\"checkbox\" clrToggle name=\"enabled\" formControlName=\"enabled\" />\r\n <label>{{ 'common.enabled' | translate }}</label>\r\n </clr-toggle-wrapper>\r\n </div>\r\n </div>\r\n <div class=\"card-block\">\r\n <div class=\"variant-body\">\r\n <div class=\"assets\">\r\n <vdr-assets\r\n [compact]=\"true\"\r\n [assets]=\"pendingAssetChanges[variant.id]?.assets || variant.assets\"\r\n [featuredAsset]=\"\r\n pendingAssetChanges[variant.id]?.featuredAsset || variant.featuredAsset\r\n \"\r\n [updatePermissions]=\"updatePermission\"\r\n (change)=\"onAssetChange(variant.id, $event)\"\r\n ></vdr-assets>\r\n </div>\r\n <div class=\"variant-form-inputs\">\r\n <div class=\"standard-fields\">\r\n <div class=\"variant-form-input-row\">\r\n <div class=\"tax-category\">\r\n <clr-select-container\r\n *vdrIfPermissions=\"updatePermission; else taxCategoryLabel\"\r\n >\r\n <label>{{ 'catalog.tax-category' | translate }}</label>\r\n <select clrSelect name=\"options\" formControlName=\"taxCategoryId\">\r\n <option\r\n *ngFor=\"let taxCategory of taxCategories\"\r\n [value]=\"taxCategory.id\"\r\n >\r\n {{ taxCategory.name }}\r\n </option>\r\n </select>\r\n </clr-select-container>\r\n <ng-template #taxCategoryLabel>\r\n <label class=\"clr-control-label\">{{\r\n 'catalog.tax-category' | translate\r\n }}</label>\r\n <div class=\"tax-category-label\">\r\n {{ getTaxCategoryName(formGroup) }}\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"price\">\r\n <clr-input-container>\r\n <label>{{ 'catalog.price' | translate }}</label>\r\n <vdr-currency-input\r\n *ngIf=\"!channelPriceIncludesTax\"\r\n clrInput\r\n [currencyCode]=\"variant.currencyCode\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n formControlName=\"price\"\r\n ></vdr-currency-input>\r\n <vdr-currency-input\r\n *ngIf=\"channelPriceIncludesTax\"\r\n clrInput\r\n [currencyCode]=\"variant.currencyCode\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n formControlName=\"priceWithTax\"\r\n ></vdr-currency-input>\r\n </clr-input-container>\r\n </div>\r\n <vdr-variant-price-detail\r\n [price]=\"formGroup.get('price')!.value\"\r\n [currencyCode]=\"variant.currencyCode\"\r\n [priceIncludesTax]=\"channelPriceIncludesTax\"\r\n [taxCategoryId]=\"formGroup.get('taxCategoryId')!.value\"\r\n ></vdr-variant-price-detail>\r\n </div>\r\n <div class=\"variant-form-input-row\">\r\n <clr-select-container *vdrIfPermissions=\"updatePermission\">\r\n <label\r\n >{{ 'catalog.track-inventory' | translate }}\r\n <vdr-help-tooltip\r\n [content]=\"'catalog.track-inventory-tooltip' | translate\"\r\n ></vdr-help-tooltip>\r\n </label>\r\n <select clrSelect name=\"options\" formControlName=\"trackInventory\">\r\n <option [value]=\"GlobalFlag.TRUE\">\r\n {{ 'catalog.track-inventory-true' | translate }}\r\n </option>\r\n <option [value]=\"GlobalFlag.FALSE\">\r\n {{ 'catalog.track-inventory-false' | translate }}\r\n </option>\r\n <option [value]=\"GlobalFlag.INHERIT\">\r\n {{ 'catalog.track-inventory-inherit' | translate }}\r\n </option>\r\n </select>\r\n </clr-select-container>\r\n <clr-input-container>\r\n <label\r\n >{{ 'catalog.stock-on-hand' | translate }}\r\n <vdr-help-tooltip\r\n [content]=\"'catalog.stock-on-hand-tooltip' | translate\"\r\n ></vdr-help-tooltip\r\n ></label>\r\n <input\r\n [class.inventory-untracked]=\"inventoryIsNotTracked(formGroup)\"\r\n clrInput\r\n type=\"number\"\r\n [min]=\"getStockOnHandMinValue(formGroup)\"\r\n step=\"1\"\r\n formControlName=\"stockOnHand\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n [vdrDisabled]=\"inventoryIsNotTracked(formGroup)\"\r\n />\r\n </clr-input-container>\r\n <div [class.inventory-untracked]=\"inventoryIsNotTracked(formGroup)\">\r\n <label class=\"clr-control-label\"\r\n >{{ 'catalog.stock-allocated' | translate }}\r\n <vdr-help-tooltip\r\n [content]=\"'catalog.stock-allocated-tooltip' | translate\"\r\n ></vdr-help-tooltip\r\n ></label>\r\n <div class=\"value\">\r\n {{ variant.stockAllocated }}\r\n </div>\r\n </div>\r\n <div [class.inventory-untracked]=\"inventoryIsNotTracked(formGroup)\">\r\n <label class=\"clr-control-label\"\r\n >{{ 'catalog.stock-saleable' | translate }}\r\n <vdr-help-tooltip\r\n [content]=\"'catalog.stock-saleable-tooltip' | translate\"\r\n ></vdr-help-tooltip\r\n ></label>\r\n <div class=\"value\">\r\n {{ getSaleableStockLevel(variant) }}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"variant-form-input-row\">\r\n <div\r\n class=\"out-of-stock-threshold-wrapper\"\r\n [class.inventory-untracked]=\"inventoryIsNotTracked(formGroup)\"\r\n >\r\n <label class=\"clr-control-label\"\r\n >{{ 'catalog.out-of-stock-threshold' | translate\r\n }}<vdr-help-tooltip\r\n [content]=\"'catalog.out-of-stock-threshold-tooltip' | translate\"\r\n ></vdr-help-tooltip\r\n ></label>\r\n <div class=\"flex\">\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"number\"\r\n [formControl]=\"formGroup.get('outOfStockThreshold')\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n [vdrDisabled]=\"\r\n formGroup.get('useGlobalOutOfStockThreshold')?.value !==\r\n false || inventoryIsNotTracked(formGroup)\r\n \"\r\n />\r\n </clr-input-container>\r\n <clr-toggle-wrapper>\r\n <input\r\n type=\"checkbox\"\r\n clrToggle\r\n name=\"useGlobalOutOfStockThreshold\"\r\n formControlName=\"useGlobalOutOfStockThreshold\"\r\n [vdrDisabled]=\"\r\n !(updatePermission | hasPermission) ||\r\n inventoryIsNotTracked(formGroup)\r\n \"\r\n />\r\n <label\r\n >{{ 'catalog.use-global-value' | translate }} ({{\r\n globalOutOfStockThreshold\r\n }})</label\r\n >\r\n </clr-toggle-wrapper>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"custom-fields\">\r\n <div class=\"variant-form-input-row\">\r\n <section formGroupName=\"customFields\" *ngIf=\"customFields.length\">\r\n <vdr-tabbed-custom-fields\r\n entityName=\"ProductVariant\"\r\n [customFields]=\"customFields\"\r\n [compact]=\"true\"\r\n [customFieldsFormGroup]=\"formGroup.get('customFields')\"\r\n [readonly]=\"!(updatePermission | hasPermission)\"\r\n ></vdr-tabbed-custom-fields>\r\n </section>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-block\">\r\n <div class=\"options-facets\">\r\n <vdr-entity-info [entity]=\"variant\"></vdr-entity-info>\r\n <div *ngIf=\"variant.options.length\">\r\n <div class=\"options\">\r\n <vdr-chip\r\n *ngFor=\"let option of variant.options | sort: 'groupId'\"\r\n [colorFrom]=\"optionGroupName(option.groupId)\"\r\n [invert]=\"true\"\r\n (iconClick)=\"editOption(option)\"\r\n [icon]=\"(updatePermission | hasPermission) && 'pencil'\"\r\n >\r\n <span class=\"option-group-name\">{{ optionGroupName(option.groupId) }}</span>\r\n {{ optionName(option) }}\r\n </vdr-chip>\r\n <a [routerLink]=\"['./', 'options']\" class=\"btn btn-link btn-sm\"\r\n >{{ 'catalog.edit-options' | translate }}...</a\r\n >\r\n </div>\r\n </div>\r\n <div class=\"flex-spacer\"></div>\r\n <div class=\"facets\">\r\n <vdr-facet-value-chip\r\n *ngFor=\"let facetValue of existingFacetValues(variant)\"\r\n [facetValue]=\"facetValue\"\r\n [removable]=\"updatePermission | hasPermission\"\r\n (remove)=\"removeFacetValue(variant, facetValue.id)\"\r\n ></vdr-facet-value-chip>\r\n <vdr-facet-value-chip\r\n *ngFor=\"let facetValue of pendingFacetValues(variant)\"\r\n [facetValue]=\"facetValue\"\r\n [removable]=\"updatePermission | hasPermission\"\r\n (remove)=\"removeFacetValue(variant, facetValue.id)\"\r\n ></vdr-facet-value-chip>\r\n <button\r\n *vdrIfPermissions=\"updatePermission\"\r\n class=\"btn btn-sm btn-secondary\"\r\n (click)=\"selectFacetValueClick.emit([variant.id])\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-facets' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <ng-container *vdrIfMultichannel>\r\n <div class=\"card-block\" *vdrIfDefaultChannelActive>\r\n <div class=\"flex channel-assignment\">\r\n <ng-container *ngFor=\"let channel of variant.channels\">\r\n <vdr-chip\r\n *ngIf=\"!isDefaultChannel(channel.code)\"\r\n icon=\"times-circle\"\r\n [title]=\"'catalog.remove-from-channel' | translate\"\r\n (iconClick)=\"\r\n removeFromChannel.emit({ channelId: channel.id, variant: variant })\r\n \"\r\n >\r\n <vdr-channel-badge [channelCode]=\"channel.code\"></vdr-channel-badge>\r\n {{ channel.code | channelCodeToLabel }}\r\n </vdr-chip>\r\n </ng-container>\r\n <button class=\"btn btn-sm\" (click)=\"assignToChannel.emit(variant)\">\r\n <clr-icon shape=\"layers\"></clr-icon>\r\n {{ 'catalog.assign-to-channel' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n</div>\r\n",
4365
4400
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
4366
- styles: [".with-selected{display:flex;min-height:52px;align-items:center;border:1px solid var(--color-component-border-100);border-radius:3px;padding:6px 18px}.with-selected vdr-select-toggle{margin-right:12px}.with-selected>label{margin-right:12px}.variant-container{transition:background-color .2s;min-height:330px}.variant-container.disabled{background-color:var(--color-component-bg-200)}.variant-container .header-row{display:flex;align-items:center;flex-wrap:wrap}.variant-container .variant-body{display:flex;flex-direction:column}@media screen and (min-width: 768px){.variant-container .variant-body{flex-direction:row}}.variant-container .details{display:flex;flex-direction:column;flex:1;margin-right:12px}@media screen and (min-width: 768px){.variant-container .details{flex-direction:row;height:36px}}.variant-container .details .name{flex:1}.variant-container .details .name ::ng-deep .clr-control-container{width:100%}.variant-container .details .name ::ng-deep .clr-control-container input.clr-input{min-width:100%}.variant-container .details .sku{width:160px;margin-right:20px;flex:0}.variant-container .details ::ng-deep .name input{min-width:300px}.variant-container .right-controls{display:flex}.variant-container .tax-category-label{margin-top:3px}.variant-container .variant-form-inputs{flex:1;display:flex;flex-direction:column}@media screen and (min-width: 768px){.variant-container .variant-form-inputs{flex-direction:row}}.variant-container .variant-form-input-row{display:flex;flex-wrap:wrap}@media screen and (min-width: 768px){.variant-container .variant-form-input-row{margin:0 6px 8px 24px}}.variant-container .variant-form-input-row>*{margin-right:24px;margin-bottom:24px}.variant-container .track-inventory-toggle{margin-top:22px}.variant-container .clr-form-control{margin-top:0}.variant-container .facets{display:flex;flex-wrap:wrap;align-items:center}.variant-container .pricing{display:flex}.variant-container .pricing>div{margin-right:12px}.variant-container .option-group-name{color:var(--color-text-200);text-transform:uppercase;font-size:10px;margin-right:3px;height:11px}.variant-container .options-facets{display:flex;color:var(--color-grey-400)}.variant-container ::ng-deep .clr-control-container{width:100%}.channel-assignment{justify-content:flex-end}.channel-assignment .btn{margin:6px 12px 6px 0}.out-of-stock-threshold-wrapper{display:flex;flex-direction:column}.out-of-stock-threshold-wrapper clr-toggle-wrapper{margin-left:24px}.inventory-untracked{opacity:.5}\n"]
4401
+ styles: [".with-selected{display:flex;min-height:52px;align-items:center;border:1px solid var(--color-component-border-100);border-radius:3px;padding:6px 18px}.with-selected vdr-select-toggle{margin-right:12px}.with-selected>label{margin-right:12px}.variant-container{transition:background-color .2s;min-height:330px}.variant-container.disabled{background-color:var(--color-component-bg-200)}.variant-container .header-row{display:flex;align-items:center;flex-wrap:wrap}.variant-container .variant-body{display:flex;flex-direction:column}@media screen and (min-width: 768px){.variant-container .variant-body{flex-direction:row}}.variant-container .details{display:flex;flex-direction:column;flex:1;margin-right:12px}@media screen and (min-width: 768px){.variant-container .details{flex-direction:row;height:36px}}.variant-container .details .name{flex:1}.variant-container .details .name ::ng-deep .clr-control-container{width:100%}.variant-container .details .name ::ng-deep .clr-control-container input.clr-input{min-width:100%}.variant-container .details .sku{width:160px;margin-right:20px;flex:0}.variant-container .details ::ng-deep .name input{min-width:300px}.variant-container .right-controls{display:flex}.variant-container .tax-category-label{margin-top:3px}.variant-container .variant-form-inputs{flex:1;display:flex;flex-direction:column}@media screen and (min-width: 768px){.variant-container .variant-form-inputs{flex-direction:row}}.variant-container .variant-form-input-row{display:flex;flex-wrap:wrap}@media screen and (min-width: 768px){.variant-container .variant-form-input-row{margin:0 6px 8px 24px}}.variant-container .variant-form-input-row>*{margin-right:24px;margin-bottom:24px}.variant-container .track-inventory-toggle{margin-top:22px}.variant-container .clr-form-control{margin-top:0}.variant-container .facets{display:flex;flex-wrap:wrap;align-items:center}.variant-container .pricing{display:flex}.variant-container .pricing>div{margin-right:12px}.variant-container .option-group-name{color:var(--color-text-200);text-transform:uppercase;font-size:10px;margin-right:3px;height:11px}.variant-container .options-facets{display:flex;color:var(--color-grey-400)}.variant-container ::ng-deep .clr-control-container{width:100%}.channel-assignment{justify-content:flex-end;flex-wrap:wrap;max-height:110px;overflow-y:auto}.channel-assignment .btn{margin:6px 12px 6px 0}.out-of-stock-threshold-wrapper{display:flex;flex-direction:column}.out-of-stock-threshold-wrapper clr-toggle-wrapper{margin-left:24px}.inventory-untracked{opacity:.5}\n"]
4367
4402
  },] }
4368
4403
  ];
4369
4404
  ProductVariantsListComponent.ctorParameters = function () { return [
@@ -4543,7 +4578,6 @@
4543
4578
  CollectionTreeNodeComponent,
4544
4579
  CollectionContentsComponent,
4545
4580
  ProductVariantsTableComponent,
4546
- ProductSearchInputComponent,
4547
4581
  OptionValueInputComponent,
4548
4582
  UpdateProductOptionDialogComponent,
4549
4583
  ProductVariantsEditorComponent,
@@ -4597,7 +4631,6 @@
4597
4631
  exports.ProductListComponent = ProductListComponent;
4598
4632
  exports.ProductOptionsEditorComponent = ProductOptionsEditorComponent;
4599
4633
  exports.ProductResolver = ProductResolver;
4600
- exports.ProductSearchInputComponent = ProductSearchInputComponent;
4601
4634
  exports.ProductVariantsEditorComponent = ProductVariantsEditorComponent;
4602
4635
  exports.ProductVariantsListComponent = ProductVariantsListComponent;
4603
4636
  exports.ProductVariantsResolver = ProductVariantsResolver;
@@ -4613,6 +4646,7 @@
4613
4646
  exports.productOptionsEditorBreadcrumb = productOptionsEditorBreadcrumb;
4614
4647
  exports.productVariantEditorBreadcrumb = productVariantEditorBreadcrumb;
4615
4648
  exports.replaceLast = replaceLast;
4649
+ exports.ɵ0 = ɵ0;
4616
4650
  exports.ɵ1 = ɵ1;
4617
4651
  exports.ɵ2 = ɵ2;
4618
4652
  exports.ɵ3 = ɵ3;