@vendure/admin-ui 1.7.4 → 1.8.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 (228) hide show
  1. package/bundles/vendure-admin-ui-catalog.umd.js +902 -74
  2. package/bundles/vendure-admin-ui-catalog.umd.js.map +1 -1
  3. package/bundles/vendure-admin-ui-core.umd.js +2392 -820
  4. package/bundles/vendure-admin-ui-core.umd.js.map +1 -1
  5. package/bundles/vendure-admin-ui-customer.umd.js +4 -3
  6. package/bundles/vendure-admin-ui-customer.umd.js.map +1 -1
  7. package/bundles/vendure-admin-ui-dashboard.umd.js +3 -1
  8. package/bundles/vendure-admin-ui-dashboard.umd.js.map +1 -1
  9. package/bundles/vendure-admin-ui-order.umd.js +781 -175
  10. package/bundles/vendure-admin-ui-order.umd.js.map +1 -1
  11. package/bundles/vendure-admin-ui-settings.umd.js +5 -4
  12. package/bundles/vendure-admin-ui-settings.umd.js.map +1 -1
  13. package/bundles/vendure-admin-ui-system.umd.js +1 -1
  14. package/catalog/catalog.module.d.ts +3 -0
  15. package/catalog/components/assign-to-channel-dialog/assign-to-channel-dialog.component.d.ts +17 -0
  16. package/catalog/components/bulk-add-facet-values-dialog/bulk-add-facet-values-dialog.component.d.ts +38 -0
  17. package/catalog/components/bulk-add-facet-values-dialog/bulk-add-facet-values-dialog.graphql.d.ts +4 -0
  18. package/catalog/components/collection-list/collection-list-bulk-actions.d.ts +6 -0
  19. package/catalog/components/collection-list/collection-list.component.d.ts +7 -5
  20. package/catalog/components/collection-tree/collection-tree-node.component.d.ts +8 -4
  21. package/catalog/components/collection-tree/collection-tree.component.d.ts +2 -1
  22. package/catalog/components/facet-list/facet-list-bulk-actions.d.ts +5 -0
  23. package/catalog/components/facet-list/facet-list.component.d.ts +2 -1
  24. package/catalog/components/product-list/product-list-bulk-actions.d.ts +6 -0
  25. package/catalog/components/product-list/product-list.component.d.ts +2 -1
  26. package/catalog/public_api.d.ts +6 -0
  27. package/catalog/vendure-admin-ui-catalog.metadata.json +1 -1
  28. package/core/common/component-registry-types.d.ts +1 -1
  29. package/core/common/generated-types.d.ts +609 -3
  30. package/core/common/utilities/bulk-action-utils.d.ts +19 -0
  31. package/core/common/utilities/selection-manager.d.ts +7 -0
  32. package/core/common/version.d.ts +1 -1
  33. package/core/data/definitions/collection-definitions.d.ts +3 -0
  34. package/core/data/definitions/facet-definitions.d.ts +3 -0
  35. package/core/data/definitions/order-definitions.d.ts +12 -0
  36. package/core/data/definitions/product-definitions.d.ts +1 -0
  37. package/core/data/providers/collection-data.service.d.ts +4 -1
  38. package/core/data/providers/facet-data.service.d.ts +4 -1
  39. package/core/data/providers/order-data.service.d.ts +18 -1
  40. package/core/data/providers/product-data.service.d.ts +1 -0
  41. package/core/providers/bulk-action-registry/bulk-action-registry.service.d.ts +6 -0
  42. package/core/providers/bulk-action-registry/bulk-action-types.d.ts +149 -0
  43. package/core/providers/bulk-action-registry/register-bulk-action.d.ts +53 -0
  44. package/core/providers/modal/modal.service.d.ts +2 -0
  45. package/core/providers/nav-builder/nav-builder-types.d.ts +1 -0
  46. package/core/public_api.d.ts +18 -1
  47. package/core/shared/components/asset-gallery/asset-gallery.component.d.ts +3 -3
  48. package/core/shared/components/bulk-action-menu/bulk-action-menu.component.d.ts +29 -0
  49. package/core/shared/components/data-table/data-table.component.d.ts +26 -7
  50. package/core/shared/components/dropdown/dropdown-menu.component.d.ts +1 -0
  51. package/core/shared/components/radio-card/radio-card-fieldset.component.d.ts +21 -0
  52. package/core/shared/components/radio-card/radio-card.component.d.ts +19 -0
  53. package/core/shared/components/rich-text-editor/prosemirror/context-menu/context-menu.component.d.ts +28 -0
  54. package/core/shared/components/rich-text-editor/prosemirror/context-menu/context-menu.service.d.ts +31 -0
  55. package/core/shared/components/rich-text-editor/prosemirror/custom-nodes.d.ts +4 -0
  56. package/core/shared/components/rich-text-editor/prosemirror/inputrules.d.ts +5 -5
  57. package/core/shared/components/rich-text-editor/prosemirror/menu/links.d.ts +1 -1
  58. package/core/shared/components/rich-text-editor/prosemirror/menu/menu-common.d.ts +12 -0
  59. package/core/shared/components/rich-text-editor/prosemirror/menu/menu-plugin.d.ts +9 -0
  60. package/core/shared/components/rich-text-editor/prosemirror/menu/sub-menu-with-icon.d.ts +14 -0
  61. package/core/shared/components/rich-text-editor/prosemirror/plugins/image-plugin.d.ts +7 -0
  62. package/core/shared/components/rich-text-editor/prosemirror/plugins/link-select-plugin.d.ts +1 -1
  63. package/core/shared/components/rich-text-editor/prosemirror/plugins/raw-editor-plugin.d.ts +7 -0
  64. package/core/shared/components/rich-text-editor/prosemirror/plugins/tables-plugin.d.ts +13 -0
  65. package/core/shared/components/rich-text-editor/prosemirror/prosemirror.service.d.ts +7 -3
  66. package/core/shared/components/rich-text-editor/prosemirror/types.d.ts +0 -2
  67. package/core/shared/components/rich-text-editor/raw-html-dialog/raw-html-dialog.component.d.ts +18 -0
  68. package/core/shared/components/rich-text-editor/rich-text-editor.component.d.ts +6 -2
  69. package/core/shared/dynamic-form-inputs/code-editor-form-input/base-code-editor-form-input.component.d.ts +27 -0
  70. package/core/shared/dynamic-form-inputs/code-editor-form-input/html-editor-form-input.component.d.ts +19 -0
  71. package/core/shared/dynamic-form-inputs/code-editor-form-input/json-editor-form-input.component.d.ts +5 -17
  72. package/core/shared/dynamic-form-inputs/register-dynamic-input-components.d.ts +2 -1
  73. package/core/vendure-admin-ui-core.metadata.json +1 -1
  74. package/customer/components/customer-group-member-list/customer-group-member-list.component.d.ts +11 -4
  75. package/customer/vendure-admin-ui-customer.metadata.json +1 -1
  76. package/esm2015/catalog/catalog.module.js +25 -2
  77. package/esm2015/catalog/components/assign-products-to-channel-dialog/assign-products-to-channel-dialog.component.js +4 -1
  78. package/esm2015/catalog/components/assign-to-channel-dialog/assign-to-channel-dialog.component.js +51 -0
  79. package/esm2015/catalog/components/bulk-add-facet-values-dialog/bulk-add-facet-values-dialog.component.js +89 -0
  80. package/esm2015/catalog/components/bulk-add-facet-values-dialog/bulk-add-facet-values-dialog.graphql.js +69 -0
  81. package/esm2015/catalog/components/collection-detail/collection-detail.component.js +3 -3
  82. package/esm2015/catalog/components/collection-list/collection-list-bulk-actions.js +147 -0
  83. package/esm2015/catalog/components/collection-list/collection-list.component.js +17 -8
  84. package/esm2015/catalog/components/collection-tree/collection-tree-node.component.js +16 -7
  85. package/esm2015/catalog/components/collection-tree/collection-tree.component.js +3 -2
  86. package/esm2015/catalog/components/facet-list/facet-list-bulk-actions.js +208 -0
  87. package/esm2015/catalog/components/facet-list/facet-list.component.js +13 -4
  88. package/esm2015/catalog/components/product-detail/product-detail.component.js +35 -23
  89. package/esm2015/catalog/components/product-list/product-list-bulk-actions.js +173 -0
  90. package/esm2015/catalog/components/product-list/product-list.component.js +10 -5
  91. package/esm2015/catalog/components/product-variants-list/product-variants-list.component.js +2 -2
  92. package/esm2015/catalog/providers/routing/collection-resolver.js +2 -1
  93. package/esm2015/catalog/public_api.js +7 -1
  94. package/esm2015/core/common/component-registry-types.js +1 -1
  95. package/esm2015/core/common/generated-types.js +5 -1
  96. package/esm2015/core/common/introspection-result.js +296 -191
  97. package/esm2015/core/common/utilities/bulk-action-utils.js +44 -0
  98. package/esm2015/core/common/utilities/selection-manager.js +33 -1
  99. package/esm2015/core/common/version.js +2 -2
  100. package/esm2015/core/components/breadcrumb/breadcrumb.component.js +1 -1
  101. package/esm2015/core/data/definitions/collection-definitions.js +30 -1
  102. package/esm2015/core/data/definitions/facet-definitions.js +31 -1
  103. package/esm2015/core/data/definitions/order-definitions.js +114 -1
  104. package/esm2015/core/data/definitions/product-definitions.js +15 -1
  105. package/esm2015/core/data/providers/collection-data.service.js +17 -2
  106. package/esm2015/core/data/providers/customer-data.service.js +8 -4
  107. package/esm2015/core/data/providers/facet-data.service.js +18 -2
  108. package/esm2015/core/data/providers/order-data.service.js +38 -2
  109. package/esm2015/core/data/providers/product-data.service.js +7 -2
  110. package/esm2015/core/data/utils/remove-readonly-custom-fields.js +5 -1
  111. package/esm2015/core/providers/bulk-action-registry/bulk-action-registry.service.js +27 -0
  112. package/esm2015/core/providers/bulk-action-registry/bulk-action-types.js +2 -0
  113. package/esm2015/core/providers/bulk-action-registry/register-bulk-action.js +63 -0
  114. package/esm2015/core/providers/dashboard-widget/dashboard-widget.service.js +1 -4
  115. package/esm2015/core/providers/modal/modal.service.js +2 -1
  116. package/esm2015/core/providers/nav-builder/nav-builder-types.js +1 -1
  117. package/esm2015/core/public_api.js +19 -2
  118. package/esm2015/core/shared/components/action-bar/action-bar.component.js +4 -8
  119. package/esm2015/core/shared/components/asset-gallery/asset-gallery.component.js +2 -2
  120. package/esm2015/core/shared/components/bulk-action-menu/bulk-action-menu.component.js +99 -0
  121. package/esm2015/core/shared/components/data-table/data-table.component.js +64 -15
  122. package/esm2015/core/shared/components/dropdown/dropdown-menu.component.js +4 -3
  123. package/esm2015/core/shared/components/facet-value-selector/facet-value-selector.component.js +2 -2
  124. package/esm2015/core/shared/components/language-selector/language-selector.component.js +2 -2
  125. package/esm2015/core/shared/components/order-state-label/order-state-label.component.js +2 -1
  126. package/esm2015/core/shared/components/product-search-input/product-search-input.component.js +1 -1
  127. package/esm2015/core/shared/components/product-selector/product-selector.component.js +1 -1
  128. package/esm2015/core/shared/components/radio-card/radio-card-fieldset.component.js +57 -0
  129. package/esm2015/core/shared/components/radio-card/radio-card.component.js +54 -0
  130. package/esm2015/core/shared/components/rich-text-editor/external-image-dialog/external-image-dialog.component.js +2 -2
  131. package/esm2015/core/shared/components/rich-text-editor/prosemirror/context-menu/context-menu.component.js +140 -0
  132. package/esm2015/core/shared/components/rich-text-editor/prosemirror/context-menu/context-menu.service.js +45 -0
  133. package/esm2015/core/shared/components/rich-text-editor/prosemirror/custom-nodes.js +60 -0
  134. package/esm2015/core/shared/components/rich-text-editor/prosemirror/menu/links.js +4 -4
  135. package/esm2015/core/shared/components/rich-text-editor/prosemirror/menu/menu-common.js +23 -1
  136. package/esm2015/core/shared/components/rich-text-editor/prosemirror/menu/menu-plugin.js +12 -0
  137. package/esm2015/core/shared/components/rich-text-editor/prosemirror/menu/menu.js +73 -18
  138. package/esm2015/core/shared/components/rich-text-editor/prosemirror/menu/sub-menu-with-icon.js +16 -0
  139. package/esm2015/core/shared/components/rich-text-editor/prosemirror/plugins/image-plugin.js +100 -0
  140. package/esm2015/core/shared/components/rich-text-editor/prosemirror/plugins/raw-editor-plugin.js +97 -0
  141. package/esm2015/core/shared/components/rich-text-editor/prosemirror/plugins/tables-plugin.js +166 -0
  142. package/esm2015/core/shared/components/rich-text-editor/prosemirror/prosemirror.service.js +47 -17
  143. package/esm2015/core/shared/components/rich-text-editor/prosemirror/types.js +1 -1
  144. package/esm2015/core/shared/components/rich-text-editor/raw-html-dialog/raw-html-dialog.component.js +57 -0
  145. package/esm2015/core/shared/components/rich-text-editor/rich-text-editor.component.js +20 -9
  146. package/esm2015/core/shared/components/simple-dialog/simple-dialog.component.js +2 -2
  147. package/esm2015/core/shared/dynamic-form-inputs/code-editor-form-input/base-code-editor-form-input.component.js +59 -0
  148. package/esm2015/core/shared/dynamic-form-inputs/code-editor-form-input/html-editor-form-input.component.js +66 -0
  149. package/esm2015/core/shared/dynamic-form-inputs/code-editor-form-input/json-editor-form-input.component.js +47 -84
  150. package/esm2015/core/shared/dynamic-form-inputs/dynamic-form-input/dynamic-form-input.component.js +3 -3
  151. package/esm2015/core/shared/dynamic-form-inputs/register-dynamic-input-components.js +3 -1
  152. package/esm2015/core/shared/pipes/state-i18n-token.pipe.js +2 -1
  153. package/esm2015/core/shared/shared.module.js +13 -1
  154. package/esm2015/customer/components/customer-group-list/customer-group-list.component.js +2 -2
  155. package/esm2015/customer/components/customer-group-member-list/customer-group-member-list.component.js +6 -6
  156. package/esm2015/customer/components/customer-list/customer-list.component.js +2 -2
  157. package/esm2015/dashboard/dashboard.module.js +6 -2
  158. package/esm2015/order/components/coupon-code-selector/coupon-code-selector.component.js +42 -0
  159. package/esm2015/order/components/draft-order-detail/draft-order-detail.component.js +195 -0
  160. package/esm2015/order/components/draft-order-variant-selector/draft-order-variant-selector.component.js +59 -0
  161. package/esm2015/order/components/order-detail/order-detail.component.js +2 -2
  162. package/esm2015/order/components/order-editor/order-editor.component.js +5 -11
  163. package/esm2015/order/components/order-list/order-list.component.js +20 -4
  164. package/esm2015/order/components/order-table/order-table.component.js +16 -5
  165. package/esm2015/order/components/select-address-dialog/select-address-dialog.component.js +91 -0
  166. package/esm2015/order/components/select-address-dialog/select-address-dialog.graphql.js +14 -0
  167. package/esm2015/order/components/select-customer-dialog/select-customer-dialog.component.js +59 -0
  168. package/esm2015/order/components/select-shipping-method-dialog/select-shipping-method-dialog.component.js +30 -0
  169. package/esm2015/order/order.module.js +13 -1
  170. package/esm2015/order/order.routes.js +26 -7
  171. package/esm2015/order/providers/routing/order-resolver.js +29 -12
  172. package/esm2015/order/providers/routing/order.guard.js +41 -0
  173. package/esm2015/order/public_api.js +9 -1
  174. package/esm2015/settings/components/country-list/country-list.component.js +2 -2
  175. package/esm2015/settings/components/profile/profile.component.js +2 -2
  176. package/esm2015/settings/components/zone-list/zone-list.component.js +2 -2
  177. package/esm2015/settings/components/zone-member-list/zone-member-list.component.js +2 -2
  178. package/esm2015/system/components/health-check/health-check.component.js +1 -1
  179. package/fesm2015/vendure-admin-ui-catalog.js +835 -61
  180. package/fesm2015/vendure-admin-ui-catalog.js.map +1 -1
  181. package/fesm2015/vendure-admin-ui-core.js +3122 -1514
  182. package/fesm2015/vendure-admin-ui-core.js.map +1 -1
  183. package/fesm2015/vendure-admin-ui-customer.js +7 -7
  184. package/fesm2015/vendure-admin-ui-customer.js.map +1 -1
  185. package/fesm2015/vendure-admin-ui-dashboard.js +5 -1
  186. package/fesm2015/vendure-admin-ui-dashboard.js.map +1 -1
  187. package/fesm2015/vendure-admin-ui-order.js +780 -232
  188. package/fesm2015/vendure-admin-ui-order.js.map +1 -1
  189. package/fesm2015/vendure-admin-ui-settings.js +4 -4
  190. package/fesm2015/vendure-admin-ui-settings.js.map +1 -1
  191. package/fesm2015/vendure-admin-ui-system.js +1 -1
  192. package/order/components/coupon-code-selector/coupon-code-selector.component.d.ts +18 -0
  193. package/order/components/draft-order-detail/draft-order-detail.component.d.ts +49 -0
  194. package/order/components/draft-order-variant-selector/draft-order-variant-selector.component.d.ts +21 -0
  195. package/order/components/order-editor/order-editor.component.d.ts +1 -6
  196. package/order/components/order-list/order-list.component.d.ts +1 -0
  197. package/order/components/order-table/order-table.component.d.ts +11 -2
  198. package/order/components/select-address-dialog/select-address-dialog.component.d.ts +24 -0
  199. package/order/components/select-address-dialog/select-address-dialog.graphql.d.ts +1 -0
  200. package/order/components/select-customer-dialog/select-customer-dialog.component.d.ts +22 -0
  201. package/order/components/select-shipping-method-dialog/select-shipping-method-dialog.component.d.ts +16 -0
  202. package/order/providers/routing/order-resolver.d.ts +8 -5
  203. package/order/providers/routing/order.guard.d.ts +9 -0
  204. package/order/public_api.d.ts +8 -0
  205. package/order/vendure-admin-ui-order.metadata.json +1 -1
  206. package/package.json +13 -12
  207. package/settings/components/zone-member-list/zone-member-list.component.d.ts +3 -1
  208. package/settings/vendure-admin-ui-settings.metadata.json +1 -1
  209. package/static/i18n-messages/cs.json +33 -0
  210. package/static/i18n-messages/de.json +33 -0
  211. package/static/i18n-messages/en.json +36 -4
  212. package/static/i18n-messages/es.json +33 -0
  213. package/static/i18n-messages/fr.json +33 -0
  214. package/static/i18n-messages/it.json +33 -0
  215. package/static/i18n-messages/pl.json +33 -0
  216. package/static/i18n-messages/pt_BR.json +33 -0
  217. package/static/i18n-messages/pt_PT.json +33 -0
  218. package/static/i18n-messages/ru.json +33 -0
  219. package/static/i18n-messages/uk.json +33 -0
  220. package/static/i18n-messages/zh_Hans.json +33 -0
  221. package/static/i18n-messages/zh_Hant.json +33 -0
  222. package/static/styles/global/_forms.scss +4 -2
  223. package/static/styles/global/_overrides.scss +1 -1
  224. package/static/styles/global/_utilities.scss +4 -0
  225. package/static/theme.min.css +1 -1
  226. package/system/vendure-admin-ui-system.metadata.json +1 -1
  227. package/core/shared/components/rich-text-editor/prosemirror/menu/images.d.ts +0 -4
  228. package/esm2015/core/shared/components/rich-text-editor/prosemirror/menu/images.js +0 -36
@@ -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')) :
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';
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('apollo-angular')) :
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', 'apollo-angular'], 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.apolloAngular));
5
+ }(this, (function (exports, i0, i1, i2, ngxTranslateExtractMarker, operators, forms, rxjs, normalizeString, sharedUtils, generatedShopTypes, common, sharedConstants, unique, pick, dragDrop, apolloAngular) { 'use strict';
6
6
 
7
7
  function _interopNamespace(e) {
8
8
  if (e && e.__esModule) return e;
@@ -808,9 +808,9 @@
808
808
  CollectionDetailComponent.decorators = [
809
809
  { type: i0.Component, args: [{
810
810
  selector: 'vdr-collection-detail',
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",
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<form class=\"form\" [formGroup]=\"detailForm\" *ngIf=\"entity$ | async as collection\">\r\n\r\n <nav role=\"navigation\">\r\n <ul class=\"collection-breadcrumbs\">\r\n <li *ngFor=\"let breadcrumb of collection.breadcrumbs; let isFirst = first; let isLast = last\">\r\n <a [routerLink]=\"['/catalog/collections']\" *ngIf=\"isFirst\">{{ 'catalog.root-collection' | translate }}</a>\r\n <a [routerLink]=\"['/catalog/collections', breadcrumb.id]\" *ngIf=\"!isFirst && !isLast\">{{ breadcrumb.name | translate }}</a>\r\n <ng-container *ngIf=\"isLast\">{{ breadcrumb.name | translate }}</ng-container>\r\n </li>\r\n </ul>\r\n </nav>\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]=\"collection.assets\"\r\n [featuredAsset]=\"collection.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",
812
812
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
813
- styles: [".visible-toggle{margin-top:-3px!important}clr-checkbox-wrapper{transition:opacity .3s}clr-checkbox-wrapper.disabled{opacity:.5}\n"]
813
+ styles: ["@charset \"UTF-8\";.visible-toggle{margin-top:-3px!important}clr-checkbox-wrapper{transition:opacity .3s}clr-checkbox-wrapper.disabled{opacity:.5}.collection-breadcrumbs{list-style-type:none;background-color:var(--color-component-bg-200);padding:2px 6px;margin-bottom:6px;border-radius:var(--clr-global-borderradius)}.collection-breadcrumbs li{font-size:.65rem;display:inline-block;margin-right:10px}.collection-breadcrumbs li:not(:last-child):after{content:\"\\203a\";top:0;color:var(--color-grey-400);margin-left:10px}\n"]
814
814
  },] }
815
815
  ];
816
816
  CollectionDetailComponent.ctorParameters = function () { return [
@@ -829,23 +829,31 @@
829
829
  };
830
830
 
831
831
  var CollectionListComponent = /** @class */ (function () {
832
- function CollectionListComponent(dataService, notificationService, modalService, router, route, serverConfigService) {
832
+ function CollectionListComponent(dataService, notificationService, modalService, router, route, serverConfigService, changeDetectorRef) {
833
833
  this.dataService = dataService;
834
834
  this.notificationService = notificationService;
835
835
  this.modalService = modalService;
836
836
  this.router = router;
837
837
  this.route = route;
838
838
  this.serverConfigService = serverConfigService;
839
+ this.changeDetectorRef = changeDetectorRef;
839
840
  this.filterTermControl = new forms.FormControl('');
840
841
  this.expandAll = false;
841
842
  this.expandedIds = [];
842
843
  this.destroy$ = new rxjs.Subject();
844
+ this.selectionManager = new i2.SelectionManager({
845
+ additiveMode: true,
846
+ multiSelect: true,
847
+ itemsAreEqual: function (a, b) { return a.id === b.id; },
848
+ });
843
849
  }
844
850
  CollectionListComponent.prototype.ngOnInit = function () {
845
851
  var _this = this;
846
852
  var _a, _b;
847
853
  this.queryResult = this.dataService.collection.getCollections(1000, 0).refetchOnChannelChange();
848
- this.items$ = this.queryResult.mapStream(function (data) { return data.collections.items; }).pipe(operators.shareReplay(1));
854
+ this.items$ = this.queryResult
855
+ .mapStream(function (data) { return data.collections.items; })
856
+ .pipe(operators.tap(function (items) { return _this.selectionManager.setCurrentItems(items); }), operators.shareReplay(1));
849
857
  this.activeCollectionId$ = this.route.paramMap.pipe(operators.map(function (pm) { return pm.get('contents'); }), operators.distinctUntilChanged());
850
858
  this.expandedIds = (_b = (_a = this.route.snapshot.queryParamMap.get('expanded')) === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
851
859
  this.expandAll = this.route.snapshot.queryParamMap.get('expanded') === 'all';
@@ -960,9 +968,9 @@
960
968
  CollectionListComponent.decorators = [
961
969
  { type: i0.Component, args: [{
962
970
  selector: 'vdr-collection-list',
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",
971
+ template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <div class=\"\">\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\"\r\n />\r\n <div class=\"flex center\">\r\n <clr-toggle-wrapper\r\n class=\"expand-all-toggle mt2\"\r\n >\r\n <input type=\"checkbox\" clrToggle [(ngModel)]=\"expandAll\" (change)=\"toggleExpandAll()\" />\r\n <label>\r\n {{ 'catalog.expand-all-collections' | translate }}\r\n </label>\r\n </clr-toggle-wrapper>\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 </div>\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=\"bulk-select-controls\">\r\n <input\r\n type=\"checkbox\"\r\n clrCheckbox\r\n [checked]=\"selectionManager.areAllCurrentItemsSelected()\"\r\n (click)=\"selectionManager.toggleSelectAll()\"\r\n />\r\n <vdr-bulk-action-menu\r\n class=\"ml2\"\r\n locationId=\"collection-list\"\r\n [hostComponent]=\"this\"\r\n [selectionManager]=\"selectionManager\"\r\n ></vdr-bulk-action-menu>\r\n</div>\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 [selectionManager]=\"selectionManager\"\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",
964
972
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
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"]
973
+ styles: [":host{height:100%;display:flex;flex-direction:column}.bulk-select-controls{min-height:36px;padding-left:14px;display:flex;align-items:center;border-bottom:1px solid var(--color-component-border-200)}.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"]
966
974
  },] }
967
975
  ];
968
976
  CollectionListComponent.ctorParameters = function () { return [
@@ -971,7 +979,8 @@
971
979
  { type: i2.ModalService },
972
980
  { type: i1.Router },
973
981
  { type: i1.ActivatedRoute },
974
- { type: i2.ServerConfigService }
982
+ { type: i2.ServerConfigService },
983
+ { type: i0.ChangeDetectorRef }
975
984
  ]; };
976
985
 
977
986
  var FacetDetailComponent = /** @class */ (function (_super) {
@@ -1360,6 +1369,11 @@
1360
1369
  },
1361
1370
  },
1362
1371
  }); });
1372
+ _this.selectionManager = new i2.SelectionManager({
1373
+ multiSelect: true,
1374
+ itemsAreEqual: function (a, b) { return a.id === b.id; },
1375
+ additiveMode: true,
1376
+ });
1363
1377
  return _this;
1364
1378
  }
1365
1379
  FacetListComponent.prototype.ngOnInit = function () {
@@ -1420,7 +1434,11 @@
1420
1434
  body: message,
1421
1435
  buttons: [
1422
1436
  { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
1423
- { type: 'danger', label: ngxTranslateExtractMarker.marker('common.delete'), returnValue: true },
1437
+ {
1438
+ type: 'danger',
1439
+ label: message ? ngxTranslateExtractMarker.marker('common.force-delete') : ngxTranslateExtractMarker.marker('common.delete'),
1440
+ returnValue: true,
1441
+ },
1424
1442
  ],
1425
1443
  })
1426
1444
  .pipe(operators.switchMap(function (res) { return (res ? _this.dataService.facet.deleteFacet(facetId, !!message) : rxjs.EMPTY); }), operators.map(function (res) { return res.deleteFacet; }));
@@ -1430,7 +1448,7 @@
1430
1448
  FacetListComponent.decorators = [
1431
1449
  { type: i0.Component, args: [{
1432
1450
  selector: 'vdr-facet-list',
1433
- template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <div class=\"flex center wrap\">\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 <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=\"facet-list\"></vdr-action-bar-items>\r\n <a\r\n class=\"btn btn-primary\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateFacet']\"\r\n [routerLink]=\"['./create']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.create-new-facet' | translate }}\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 <vdr-dt-column>{{ 'common.code' | translate }}</vdr-dt-column>\r\n <vdr-dt-column>{{ 'common.name' | translate }}</vdr-dt-column>\r\n <vdr-dt-column [expand]=\"true\">{{ 'catalog.values' | translate }}</vdr-dt-column>\r\n <vdr-dt-column>{{ 'catalog.visibility' | translate }}</vdr-dt-column>\r\n <vdr-dt-column></vdr-dt-column>\r\n <vdr-dt-column></vdr-dt-column>\r\n <ng-template let-facet=\"item\">\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">{{ facet.code }}</td>\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">{{ facet.name }}</td>\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">\r\n <vdr-facet-value-chip\r\n *ngFor=\"let value of facet.values | slice: 0:displayLimit[facet.id] || 3\"\r\n [facetValue]=\"value\"\r\n [removable]=\"false\"\r\n [displayFacetName]=\"false\"\r\n ></vdr-facet-value-chip>\r\n <button\r\n class=\"btn btn-sm btn-secondary btn-icon\"\r\n *ngIf=\"facet.values.length > initialLimit\"\r\n (click)=\"toggleDisplayLimit(facet)\"\r\n >\r\n <ng-container *ngIf=\"(displayLimit[facet.id] || 0) < facet.values.length; else collapse\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ facet.values.length - initialLimit }}\r\n </ng-container>\r\n <ng-template #collapse>\r\n <clr-icon shape=\"minus\"></clr-icon>\r\n </ng-template>\r\n </button>\r\n </td>\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">\r\n <vdr-chip>\r\n <ng-container *ngIf=\"!facet.isPrivate; else private\">{{\r\n 'catalog.public' | translate\r\n }}</ng-container>\r\n <ng-template #private>{{ 'catalog.private' | translate }}</ng-template>\r\n </vdr-chip>\r\n </td>\r\n <td class=\"right align-middle\" [class.private]=\"facet.isPrivate\">\r\n <vdr-table-row-action\r\n iconShape=\"edit\"\r\n [label]=\"'common.edit' | translate\"\r\n [linkTo]=\"['./', facet.id]\"\r\n ></vdr-table-row-action>\r\n </td>\r\n <td class=\"right align-middle\" [class.private]=\"facet.isPrivate\">\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)=\"deleteFacet(facet.id)\"\r\n [disabled]=\"!(['DeleteCatalog', 'DeleteFacet'] | 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",
1451
+ template: "<vdr-action-bar>\r\n <vdr-ab-left>\r\n <div class=\"\">\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\"\r\n />\r\n <div>\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 </div>\r\n </vdr-ab-left>\r\n <vdr-ab-right>\r\n <vdr-action-bar-items locationId=\"facet-list\"></vdr-action-bar-items>\r\n <a\r\n class=\"btn btn-primary\"\r\n *vdrIfPermissions=\"['CreateCatalog', 'CreateFacet']\"\r\n [routerLink]=\"['./create']\"\r\n >\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.create-new-facet' | translate }}\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 [selectionManager]=\"selectionManager\"\r\n>\r\n <vdr-bulk-action-menu\r\n locationId=\"facet-list\"\r\n [hostComponent]=\"this\"\r\n [selectionManager]=\"selectionManager\"\r\n ></vdr-bulk-action-menu>\r\n <vdr-dt-column>{{ 'common.code' | translate }}</vdr-dt-column>\r\n <vdr-dt-column>{{ 'common.name' | translate }}</vdr-dt-column>\r\n <vdr-dt-column [expand]=\"true\">{{ 'catalog.values' | translate }}</vdr-dt-column>\r\n <vdr-dt-column>{{ 'catalog.visibility' | translate }}</vdr-dt-column>\r\n <vdr-dt-column></vdr-dt-column>\r\n <vdr-dt-column></vdr-dt-column>\r\n <ng-template let-facet=\"item\">\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">{{ facet.code }}</td>\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">{{ facet.name }}</td>\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">\r\n <vdr-facet-value-chip\r\n *ngFor=\"let value of facet.values | slice: 0:displayLimit[facet.id] || 3\"\r\n [facetValue]=\"value\"\r\n [removable]=\"false\"\r\n [displayFacetName]=\"false\"\r\n ></vdr-facet-value-chip>\r\n <button\r\n class=\"btn btn-sm btn-secondary btn-icon\"\r\n *ngIf=\"facet.values.length > initialLimit\"\r\n (click)=\"toggleDisplayLimit(facet)\"\r\n >\r\n <ng-container *ngIf=\"(displayLimit[facet.id] || 0) < facet.values.length; else collapse\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ facet.values.length - initialLimit }}\r\n </ng-container>\r\n <ng-template #collapse>\r\n <clr-icon shape=\"minus\"></clr-icon>\r\n </ng-template>\r\n </button>\r\n </td>\r\n <td class=\"left align-middle\" [class.private]=\"facet.isPrivate\">\r\n <vdr-chip>\r\n <ng-container *ngIf=\"!facet.isPrivate; else private\">{{\r\n 'catalog.public' | translate\r\n }}</ng-container>\r\n <ng-template #private>{{ 'catalog.private' | translate }}</ng-template>\r\n </vdr-chip>\r\n </td>\r\n <td class=\"right align-middle\" [class.private]=\"facet.isPrivate\">\r\n <vdr-table-row-action\r\n iconShape=\"edit\"\r\n [label]=\"'common.edit' | translate\"\r\n [linkTo]=\"['./', facet.id]\"\r\n ></vdr-table-row-action>\r\n </td>\r\n <td class=\"right align-middle\" [class.private]=\"facet.isPrivate\">\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)=\"deleteFacet(facet.id)\"\r\n [disabled]=\"!(['DeleteCatalog', 'DeleteFacet'] | 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",
1434
1452
  styles: ["td.private{background-color:var(--color-component-bg-200)}\n"]
1435
1453
  },] }
1436
1454
  ];
@@ -1808,6 +1826,7 @@
1808
1826
  .subscribe(function () {
1809
1827
  _this.notificationService.success(ngxTranslateExtractMarker.marker('catalog.assign-product-to-channel-success'), {
1810
1828
  channel: selectedChannel.code,
1829
+ count: _this.productIds.length,
1811
1830
  });
1812
1831
  _this.resolveWith(true);
1813
1832
  });
@@ -1822,6 +1841,8 @@
1822
1841
  .subscribe(function () {
1823
1842
  _this.notificationService.success(ngxTranslateExtractMarker.marker('catalog.assign-variant-to-channel-success'), {
1824
1843
  channel: selectedChannel.code,
1844
+ // tslint:disable-next-line:no-non-null-assertion
1845
+ count: _this.productVariantIds.length,
1825
1846
  });
1826
1847
  _this.resolveWith(true);
1827
1848
  });
@@ -2033,15 +2054,22 @@
2033
2054
  };
2034
2055
  ProductDetailComponent.prototype.removeFromChannel = function (channelId) {
2035
2056
  var _this = this;
2036
- this.modalService
2037
- .dialog({
2038
- title: ngxTranslateExtractMarker.marker('catalog.remove-product-from-channel'),
2039
- buttons: [
2040
- { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
2041
- { type: 'danger', label: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'), returnValue: true },
2042
- ],
2043
- })
2044
- .pipe(operators.switchMap(function (response) { return response
2057
+ rxjs.from(i2.getChannelCodeFromUserStatus(this.dataService, channelId))
2058
+ .pipe(operators.switchMap(function (_c) {
2059
+ var channelCode = _c.channelCode;
2060
+ return _this.modalService.dialog({
2061
+ title: ngxTranslateExtractMarker.marker('catalog.remove-product-from-channel'),
2062
+ buttons: [
2063
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
2064
+ {
2065
+ type: 'danger',
2066
+ label: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
2067
+ translationVars: { channelCode: channelCode },
2068
+ returnValue: true,
2069
+ },
2070
+ ],
2071
+ });
2072
+ }), operators.switchMap(function (response) { return response
2045
2073
  ? _this.dataService.product.removeProductsFromChannel({
2046
2074
  channelId: channelId,
2047
2075
  productIds: [_this.id],
@@ -2068,15 +2096,22 @@
2068
2096
  ProductDetailComponent.prototype.removeVariantFromChannel = function (_c) {
2069
2097
  var _this = this;
2070
2098
  var channelId = _c.channelId, variant = _c.variant;
2071
- this.modalService
2072
- .dialog({
2073
- title: ngxTranslateExtractMarker.marker('catalog.remove-product-variant-from-channel'),
2074
- buttons: [
2075
- { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
2076
- { type: 'danger', label: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'), returnValue: true },
2077
- ],
2078
- })
2079
- .pipe(operators.switchMap(function (response) { return response
2099
+ rxjs.from(i2.getChannelCodeFromUserStatus(this.dataService, channelId))
2100
+ .pipe(operators.switchMap(function (_c) {
2101
+ var channelCode = _c.channelCode;
2102
+ return _this.modalService.dialog({
2103
+ title: ngxTranslateExtractMarker.marker('catalog.remove-product-variant-from-channel'),
2104
+ buttons: [
2105
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
2106
+ {
2107
+ type: 'danger',
2108
+ label: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
2109
+ translationVars: { channelCode: channelCode },
2110
+ returnValue: true,
2111
+ },
2112
+ ],
2113
+ });
2114
+ }), operators.switchMap(function (response) { return response
2080
2115
  ? _this.dataService.product.removeVariantsFromChannel({
2081
2116
  channelId: channelId,
2082
2117
  productVariantIds: [variant.id],
@@ -2425,9 +2460,9 @@
2425
2460
  ProductDetailComponent.decorators = [
2426
2461
  { type: i0.Component, args: [{
2427
2462
  selector: 'vdr-product-detail',
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",
2463
+ 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 <span class=\"full-label\">{{ 'catalog.display-variant-cards' | translate }}</span>\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 <span class=\"full-label\">{{ 'catalog.display-variant-table' | translate }}</span>\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 mb0 mr0\"\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",
2429
2464
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
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"]
2465
+ 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;flex-direction:column;justify-content:space-between}@media screen and (min-width: 768px){.view-mode{flex-direction:row}}.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"]
2431
2466
  },] }
2432
2467
  ];
2433
2468
  ProductDetailComponent.ctorParameters = function () { return [
@@ -2490,6 +2525,11 @@
2490
2525
  groupByProduct: _this.groupByProduct,
2491
2526
  },
2492
2527
  }); });
2528
+ _this.selectionManager = new i2.SelectionManager({
2529
+ multiSelect: true,
2530
+ itemsAreEqual: function (a, b) { return _this.groupByProduct ? a.productId === b.productId : a.productVariantId === b.productVariantId; },
2531
+ additiveMode: true,
2532
+ });
2493
2533
  return _this;
2494
2534
  }
2495
2535
  ProductListComponent.prototype.ngOnInit = function () {
@@ -2596,8 +2636,8 @@
2596
2636
  ProductListComponent.decorators = [
2597
2637
  { type: i0.Component, args: [{
2598
2638
  selector: 'vdr-products-list',
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"]
2639
+ 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-toggle-wrapper class=\"mt2\">\r\n <input type=\"checkbox\" clrToggle [(ngModel)]=\"groupByProduct\" (ngModelChange)=\"refresh()\" />\r\n <label>\r\n {{ 'catalog.group-by-product' | translate }}\r\n </label>\r\n </clr-toggle-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 {{ 'catalog.create-new-product' | translate }}\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 [selectionManager]=\"selectionManager\"\r\n>\r\n <vdr-bulk-action-menu\r\n locationId=\"product-list\"\r\n [hostComponent]=\"this\"\r\n [selectionManager]=\"selectionManager\"\r\n ></vdr-bulk-action-menu>\r\n <vdr-dt-column> </vdr-dt-column>\r\n <vdr-dt-column></vdr-dt-column>\r\n <vdr-dt-column></vdr-dt-column>\r\n <vdr-dt-column></vdr-dt-column>\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 <div>{{ groupByProduct ? result.productName : result.productVariantName }}</div>\r\n <div *ngIf=\"!groupByProduct\" class=\"sku\">{{ result.sku }}</div>\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",
2640
+ 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%}vdr-product-search-input{min-width:300px}@media screen and (max-width: 768px){vdr-product-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}.sku{color:var(--color-text-300)}\n"]
2601
2641
  },] }
2602
2642
  ];
2603
2643
  ProductListComponent.ctorParameters = function () { return [
@@ -3327,6 +3367,7 @@
3327
3367
  name: '',
3328
3368
  slug: '',
3329
3369
  isPrivate: false,
3370
+ breadcrumbs: [],
3330
3371
  description: '',
3331
3372
  featuredAsset: null,
3332
3373
  assets: [],
@@ -3442,88 +3483,88 @@
3442
3483
  { type: i2.DataService }
3443
3484
  ]; };
3444
3485
 
3445
- var ɵ0 = {
3486
+ var ɵ0$3 = {
3446
3487
  breadcrumb: ngxTranslateExtractMarker.marker('breadcrumb.products'),
3447
- }, ɵ1 = {
3488
+ }, ɵ1$3 = {
3448
3489
  breadcrumb: productBreadcrumb,
3449
- }, ɵ2 = {
3490
+ }, ɵ2$3 = {
3450
3491
  breadcrumb: productVariantEditorBreadcrumb,
3451
- }, ɵ3 = {
3492
+ }, ɵ3$3 = {
3452
3493
  breadcrumb: productOptionsEditorBreadcrumb,
3453
- }, ɵ4 = {
3494
+ }, ɵ4$3 = {
3454
3495
  breadcrumb: ngxTranslateExtractMarker.marker('breadcrumb.facets'),
3455
- }, ɵ5 = {
3496
+ }, ɵ5$3 = {
3456
3497
  breadcrumb: facetBreadcrumb,
3457
- }, ɵ6 = {
3498
+ }, ɵ6$3 = {
3458
3499
  breadcrumb: ngxTranslateExtractMarker.marker('breadcrumb.collections'),
3459
- }, ɵ7 = {
3500
+ }, ɵ7$3 = {
3460
3501
  breadcrumb: collectionBreadcrumb,
3461
- }, ɵ8 = {
3502
+ }, ɵ8$3 = {
3462
3503
  breadcrumb: ngxTranslateExtractMarker.marker('breadcrumb.assets'),
3463
- }, ɵ9 = {
3504
+ }, ɵ9$1 = {
3464
3505
  breadcrumb: assetBreadcrumb,
3465
3506
  };
3466
3507
  var catalogRoutes = [
3467
3508
  {
3468
3509
  path: 'products',
3469
3510
  component: ProductListComponent,
3470
- data: ɵ0,
3511
+ data: ɵ0$3,
3471
3512
  },
3472
3513
  {
3473
3514
  path: 'products/:id',
3474
3515
  component: ProductDetailComponent,
3475
3516
  resolve: i2.createResolveData(ProductResolver),
3476
3517
  canDeactivate: [i2.CanDeactivateDetailGuard],
3477
- data: ɵ1,
3518
+ data: ɵ1$3,
3478
3519
  },
3479
3520
  {
3480
3521
  path: 'products/:id/manage-variants',
3481
3522
  component: ProductVariantsEditorComponent,
3482
3523
  resolve: i2.createResolveData(ProductVariantsResolver),
3483
3524
  canDeactivate: [i2.CanDeactivateDetailGuard],
3484
- data: ɵ2,
3525
+ data: ɵ2$3,
3485
3526
  },
3486
3527
  {
3487
3528
  path: 'products/:id/options',
3488
3529
  component: ProductOptionsEditorComponent,
3489
3530
  resolve: i2.createResolveData(ProductVariantsResolver),
3490
3531
  canDeactivate: [i2.CanDeactivateDetailGuard],
3491
- data: ɵ3,
3532
+ data: ɵ3$3,
3492
3533
  },
3493
3534
  {
3494
3535
  path: 'facets',
3495
3536
  component: FacetListComponent,
3496
- data: ɵ4,
3537
+ data: ɵ4$3,
3497
3538
  },
3498
3539
  {
3499
3540
  path: 'facets/:id',
3500
3541
  component: FacetDetailComponent,
3501
3542
  resolve: i2.createResolveData(FacetResolver),
3502
3543
  canDeactivate: [i2.CanDeactivateDetailGuard],
3503
- data: ɵ5,
3544
+ data: ɵ5$3,
3504
3545
  },
3505
3546
  {
3506
3547
  path: 'collections',
3507
3548
  component: CollectionListComponent,
3508
- data: ɵ6,
3549
+ data: ɵ6$3,
3509
3550
  },
3510
3551
  {
3511
3552
  path: 'collections/:id',
3512
3553
  component: CollectionDetailComponent,
3513
3554
  resolve: i2.createResolveData(CollectionResolver),
3514
3555
  canDeactivate: [i2.CanDeactivateDetailGuard],
3515
- data: ɵ7,
3556
+ data: ɵ7$3,
3516
3557
  },
3517
3558
  {
3518
3559
  path: 'assets',
3519
3560
  component: AssetListComponent,
3520
- data: ɵ8,
3561
+ data: ɵ8$3,
3521
3562
  },
3522
3563
  {
3523
3564
  path: 'assets/:id',
3524
3565
  component: AssetDetailComponent,
3525
3566
  resolve: i2.createResolveData(AssetResolver),
3526
- data: ɵ9,
3567
+ data: ɵ9$1,
3527
3568
  },
3528
3569
  ];
3529
3570
  function productBreadcrumb(data, params) {
@@ -3694,6 +3735,153 @@
3694
3735
  updatePermissions: [{ type: i0.Input }]
3695
3736
  };
3696
3737
 
3738
+ var AssignToChannelDialogComponent = /** @class */ (function () {
3739
+ // assigned by ModalService.fromComponent() call
3740
+ function AssignToChannelDialogComponent(dataService, notificationService) {
3741
+ this.dataService = dataService;
3742
+ this.notificationService = notificationService;
3743
+ this.selectedChannelIdControl = new forms.FormControl();
3744
+ }
3745
+ AssignToChannelDialogComponent.prototype.ngOnInit = function () {
3746
+ var _this = this;
3747
+ var activeChannelId$ = this.dataService.client
3748
+ .userStatus()
3749
+ .mapSingle(function (_a) {
3750
+ var userStatus = _a.userStatus;
3751
+ return userStatus.activeChannelId;
3752
+ });
3753
+ var allChannels$ = this.dataService.settings.getChannels().mapSingle(function (data) { return data.channels; });
3754
+ rxjs.combineLatest(activeChannelId$, allChannels$).subscribe(function (_a) {
3755
+ var _b = __read(_a, 2), activeChannelId = _b[0], channels = _b[1];
3756
+ // tslint:disable-next-line:no-non-null-assertion
3757
+ _this.currentChannel = channels.find(function (c) { return c.id === activeChannelId; });
3758
+ _this.availableChannels = channels;
3759
+ });
3760
+ this.selectedChannelIdControl.valueChanges.subscribe(function (ids) {
3761
+ _this.selectChannel(ids);
3762
+ });
3763
+ };
3764
+ AssignToChannelDialogComponent.prototype.selectChannel = function (channelIds) {
3765
+ this.selectedChannel = this.availableChannels.find(function (c) { return c.id === channelIds[0]; });
3766
+ };
3767
+ AssignToChannelDialogComponent.prototype.assign = function () {
3768
+ var selectedChannel = this.selectedChannel;
3769
+ if (selectedChannel) {
3770
+ this.resolveWith(selectedChannel);
3771
+ }
3772
+ };
3773
+ AssignToChannelDialogComponent.prototype.cancel = function () {
3774
+ this.resolveWith();
3775
+ };
3776
+ return AssignToChannelDialogComponent;
3777
+ }());
3778
+ AssignToChannelDialogComponent.decorators = [
3779
+ { type: i0.Component, args: [{
3780
+ selector: 'vdr-assign-to-channel-dialog',
3781
+ template: "<ng-template vdrDialogTitle>\r\n {{ 'catalog.assign-to-channel' | translate }}\r\n</ng-template>\r\n<clr-input-container class=\"mb4\">\r\n <label>{{ 'common.channel' | translate }}</label>\r\n <vdr-channel-assignment-control\r\n clrInput\r\n [multiple]=\"false\"\r\n [includeDefaultChannel]=\"false\"\r\n [formControl]=\"selectedChannelIdControl\"\r\n ></vdr-channel-assignment-control>\r\n</clr-input-container>\r\n\r\n<ng-template vdrDialogButtons>\r\n <button type=\"button\" class=\"btn\" (click)=\"cancel()\">{{ 'common.cancel' | translate }}</button>\r\n <button type=\"submit\" (click)=\"assign()\" [disabled]=\"!selectedChannel\" class=\"btn btn-primary\">\r\n <ng-template [ngIf]=\"selectedChannel\" [ngIfElse]=\"noSelection\">\r\n {{ 'catalog.assign-to-named-channel' | translate: { channelCode: selectedChannel?.code } }}\r\n </ng-template>\r\n <ng-template #noSelection>\r\n {{ 'catalog.no-channel-selected' | translate }}\r\n </ng-template>\r\n </button>\r\n</ng-template>\r\n",
3782
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
3783
+ styles: ["vdr-channel-assignment-control{min-width:200px}\n"]
3784
+ },] }
3785
+ ];
3786
+ AssignToChannelDialogComponent.ctorParameters = function () { return [
3787
+ { type: i2.DataService },
3788
+ { type: i2.NotificationService }
3789
+ ]; };
3790
+
3791
+ var GET_PRODUCTS_WITH_FACET_VALUES_BY_IDS = apolloAngular.gql(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n query GetProductsWithFacetValuesByIds($ids: [String!]!) {\n products(options: { filter: { id: { in: $ids } } }) {\n items {\n id\n name\n facetValues {\n id\n name\n code\n facet {\n id\n name\n code\n }\n }\n }\n }\n }\n"], ["\n query GetProductsWithFacetValuesByIds($ids: [String!]!) {\n products(options: { filter: { id: { in: $ids } } }) {\n items {\n id\n name\n facetValues {\n id\n name\n code\n facet {\n id\n name\n code\n }\n }\n }\n }\n }\n"])));
3792
+ var GET_VARIANTS_WITH_FACET_VALUES_BY_IDS = apolloAngular.gql(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n query GetVariantsWithFacetValuesByIds($ids: [String!]!) {\n productVariants(options: { filter: { id: { in: $ids } } }) {\n items {\n id\n name\n sku\n facetValues {\n id\n name\n code\n facet {\n id\n name\n code\n }\n }\n }\n }\n }\n"], ["\n query GetVariantsWithFacetValuesByIds($ids: [String!]!) {\n productVariants(options: { filter: { id: { in: $ids } } }) {\n items {\n id\n name\n sku\n facetValues {\n id\n name\n code\n facet {\n id\n name\n code\n }\n }\n }\n }\n }\n"])));
3793
+ var UPDATE_PRODUCTS_BULK = apolloAngular.gql(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n mutation UpdateProductsBulk($input: [UpdateProductInput!]!) {\n updateProducts(input: $input) {\n id\n name\n facetValues {\n id\n name\n code\n }\n }\n }\n"], ["\n mutation UpdateProductsBulk($input: [UpdateProductInput!]!) {\n updateProducts(input: $input) {\n id\n name\n facetValues {\n id\n name\n code\n }\n }\n }\n"])));
3794
+ var UPDATE_VARIANTS_BULK = apolloAngular.gql(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n mutation UpdateVariantsBulk($input: [UpdateProductVariantInput!]!) {\n updateProductVariants(input: $input) {\n id\n name\n facetValues {\n id\n name\n code\n }\n }\n }\n"], ["\n mutation UpdateVariantsBulk($input: [UpdateProductVariantInput!]!) {\n updateProductVariants(input: $input) {\n id\n name\n facetValues {\n id\n name\n code\n }\n }\n }\n"])));
3795
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
3796
+
3797
+ var BulkAddFacetValuesDialogComponent = /** @class */ (function () {
3798
+ function BulkAddFacetValuesDialogComponent(dataService, changeDetectorRef) {
3799
+ this.dataService = dataService;
3800
+ this.changeDetectorRef = changeDetectorRef;
3801
+ /* provided by call to ModalService */
3802
+ this.mode = 'product';
3803
+ this.facets = [];
3804
+ this.state = 'loading';
3805
+ this.selectedValues = [];
3806
+ this.items = [];
3807
+ this.facetValuesRemoved = false;
3808
+ }
3809
+ BulkAddFacetValuesDialogComponent.prototype.ngOnInit = function () {
3810
+ var _this = this;
3811
+ var _a, _b;
3812
+ var fetchData$ = this.mode === 'product'
3813
+ ? this.dataService
3814
+ .query(GET_PRODUCTS_WITH_FACET_VALUES_BY_IDS, {
3815
+ ids: (_a = this.ids) !== null && _a !== void 0 ? _a : [],
3816
+ })
3817
+ .mapSingle(function (_c) {
3818
+ var products = _c.products;
3819
+ return products.items.map(function (p) { return (Object.assign(Object.assign({}, p), { facetValues: __spreadArray([], __read(p.facetValues)) })); });
3820
+ })
3821
+ : this.dataService
3822
+ .query(GET_VARIANTS_WITH_FACET_VALUES_BY_IDS, {
3823
+ ids: (_b = this.ids) !== null && _b !== void 0 ? _b : [],
3824
+ })
3825
+ .mapSingle(function (_c) {
3826
+ var productVariants = _c.productVariants;
3827
+ return productVariants.items.map(function (p) { return (Object.assign(Object.assign({}, p), { facetValues: __spreadArray([], __read(p.facetValues)) })); });
3828
+ });
3829
+ this.subscription = fetchData$.subscribe({
3830
+ next: function (items) {
3831
+ _this.items = items;
3832
+ _this.state = 'ready';
3833
+ _this.changeDetectorRef.markForCheck();
3834
+ },
3835
+ });
3836
+ };
3837
+ BulkAddFacetValuesDialogComponent.prototype.ngOnDestroy = function () {
3838
+ var _a;
3839
+ (_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
3840
+ };
3841
+ BulkAddFacetValuesDialogComponent.prototype.cancel = function () {
3842
+ this.resolveWith();
3843
+ };
3844
+ BulkAddFacetValuesDialogComponent.prototype.removeFacetValue = function (item, facetValueId) {
3845
+ item.facetValues = item.facetValues.filter(function (fv) { return fv.id !== facetValueId; });
3846
+ this.facetValuesRemoved = true;
3847
+ };
3848
+ BulkAddFacetValuesDialogComponent.prototype.addFacetValues = function () {
3849
+ var _this = this;
3850
+ var _a, _b;
3851
+ var selectedFacetValueIds = this.selectedValues.map(function (sv) { return sv.id; });
3852
+ this.state = 'saving';
3853
+ var save$ = this.mode === 'product'
3854
+ ? this.dataService.mutate(UPDATE_PRODUCTS_BULK, {
3855
+ input: (_a = this.items) === null || _a === void 0 ? void 0 : _a.map(function (product) { return ({
3856
+ id: product.id,
3857
+ facetValueIds: unique.unique(__spreadArray(__spreadArray([], __read(product.facetValues.map(function (fv) { return fv.id; }))), __read(selectedFacetValueIds))),
3858
+ }); }),
3859
+ })
3860
+ : this.dataService.mutate(UPDATE_VARIANTS_BULK, {
3861
+ input: (_b = this.items) === null || _b === void 0 ? void 0 : _b.map(function (product) { return ({
3862
+ id: product.id,
3863
+ facetValueIds: unique.unique(__spreadArray(__spreadArray([], __read(product.facetValues.map(function (fv) { return fv.id; }))), __read(selectedFacetValueIds))),
3864
+ }); }),
3865
+ });
3866
+ return save$.subscribe(function (result) {
3867
+ _this.resolveWith(_this.selectedValues);
3868
+ });
3869
+ };
3870
+ return BulkAddFacetValuesDialogComponent;
3871
+ }());
3872
+ BulkAddFacetValuesDialogComponent.decorators = [
3873
+ { type: i0.Component, args: [{
3874
+ selector: 'vdr-bulk-add-facet-values-dialog',
3875
+ template: "<ng-template vdrDialogTitle>\r\n {{ 'catalog.edit-facet-values' | translate }}\r\n</ng-template>\r\n\r\n<div class=\"flex\">\r\n <div class=\"flex center\">\r\n <div class=\"mr2\">\r\n {{ 'catalog.add-facet-value' | translate }}\r\n </div>\r\n <vdr-facet-value-selector\r\n [facets]=\"facets\"\r\n (selectedValuesChange)=\"selectedValues = $event\"\r\n ></vdr-facet-value-selector>\r\n </div>\r\n</div>\r\n\r\n<table class=\"table\" *ngIf=\"state !== 'loading'; else placeholder\">\r\n <tbody>\r\n <tr *ngFor=\"let item of items\">\r\n <td class=\"left align-middle\">\r\n <div>{{ item.name }}</div>\r\n <div *ngIf=\"item.sku\" class=\"sku\">{{ item.sku }}</div>\r\n </td>\r\n <td class=\"left\">\r\n <vdr-facet-value-chip\r\n *ngFor=\"let facetValue of item.facetValues\"\r\n [facetValue]=\"facetValue\"\r\n (remove)=\"removeFacetValue(item, facetValue.id)\"\r\n ></vdr-facet-value-chip>\r\n </td>\r\n </tr>\r\n </tbody>\r\n</table>\r\n\r\n<ng-template #placeholder>\r\n <div class=\"loading\">\r\n <clr-spinner></clr-spinner>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template vdrDialogButtons>\r\n <button type=\"button\" class=\"btn\" (click)=\"cancel()\">{{ 'common.cancel' | translate }}</button>\r\n <button\r\n type=\"submit\"\r\n (click)=\"addFacetValues()\"\r\n [disabled]=\"selectedValues.length === 0 && facetValuesRemoved === false\"\r\n class=\"btn btn-primary\"\r\n >\r\n {{ 'common.update' | translate }}\r\n </button>\r\n</ng-template>\r\n",
3876
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
3877
+ styles: [".loading{min-height:25vh;display:flex;justify-content:center;align-items:center}.sku{color:var(--color-text-300)}\n"]
3878
+ },] }
3879
+ ];
3880
+ BulkAddFacetValuesDialogComponent.ctorParameters = function () { return [
3881
+ { type: i2.DataService },
3882
+ { type: i0.ChangeDetectorRef }
3883
+ ]; };
3884
+
3697
3885
  var CollectionContentsComponent = /** @class */ (function () {
3698
3886
  function CollectionContentsComponent(route, router, dataService) {
3699
3887
  this.route = route;
@@ -3807,6 +3995,175 @@
3807
3995
  headerTemplate: [{ type: i0.ContentChild, args: [i0.TemplateRef, { static: true },] }]
3808
3996
  };
3809
3997
 
3998
+ var ɵ0$2 = function (userPermissions) { return userPermissions.includes(i2.Permission.DeleteCollection) ||
3999
+ userPermissions.includes(i2.Permission.DeleteCatalog); }, ɵ1$2 = function (_a) {
4000
+ var injector = _a.injector, selection = _a.selection, hostComponent = _a.hostComponent, clearSelection = _a.clearSelection;
4001
+ var modalService = injector.get(i2.ModalService);
4002
+ var dataService = injector.get(i2.DataService);
4003
+ var notificationService = injector.get(i2.NotificationService);
4004
+ modalService
4005
+ .dialog({
4006
+ title: ngxTranslateExtractMarker.marker('catalog.confirm-bulk-delete-collections'),
4007
+ translationVars: {
4008
+ count: selection.length,
4009
+ },
4010
+ buttons: [
4011
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
4012
+ { type: 'danger', label: ngxTranslateExtractMarker.marker('common.delete'), returnValue: true },
4013
+ ],
4014
+ })
4015
+ .pipe(operators.switchMap(function (response) { return response
4016
+ ? dataService.collection.deleteCollections(unique.unique(selection.map(function (c) { return c.id; })))
4017
+ : rxjs.EMPTY; }))
4018
+ .subscribe(function (result) {
4019
+ var e_1, _a;
4020
+ var deleted = 0;
4021
+ var errors = [];
4022
+ try {
4023
+ for (var _b = __values(result.deleteCollections), _c = _b.next(); !_c.done; _c = _b.next()) {
4024
+ var item = _c.value;
4025
+ if (item.result === i2.DeletionResult.DELETED) {
4026
+ deleted++;
4027
+ }
4028
+ else if (item.message) {
4029
+ errors.push(item.message);
4030
+ }
4031
+ }
4032
+ }
4033
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4034
+ finally {
4035
+ try {
4036
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
4037
+ }
4038
+ finally { if (e_1) throw e_1.error; }
4039
+ }
4040
+ if (0 < deleted) {
4041
+ notificationService.success(ngxTranslateExtractMarker.marker('catalog.notify-bulk-delete-collections-success'), {
4042
+ count: deleted,
4043
+ });
4044
+ }
4045
+ if (0 < errors.length) {
4046
+ notificationService.error(errors.join('\n'));
4047
+ }
4048
+ hostComponent.refresh();
4049
+ clearSelection();
4050
+ });
4051
+ };
4052
+ var deleteCollectionsBulkAction = {
4053
+ location: 'collection-list',
4054
+ label: ngxTranslateExtractMarker.marker('common.delete'),
4055
+ icon: 'trash',
4056
+ iconClass: 'is-danger',
4057
+ requiresPermission: ɵ0$2,
4058
+ onClick: ɵ1$2,
4059
+ };
4060
+ var ɵ2$2 = function (userPermissions) { return userPermissions.includes(i2.Permission.UpdateCatalog) ||
4061
+ userPermissions.includes(i2.Permission.UpdateProduct); }, ɵ3$2 = function (_a) {
4062
+ var injector = _a.injector;
4063
+ return i2.isMultiChannel(injector.get(i2.DataService));
4064
+ }, ɵ4$2 = function (_a) {
4065
+ var injector = _a.injector, selection = _a.selection, hostComponent = _a.hostComponent, clearSelection = _a.clearSelection;
4066
+ var modalService = injector.get(i2.ModalService);
4067
+ var dataService = injector.get(i2.DataService);
4068
+ var notificationService = injector.get(i2.NotificationService);
4069
+ modalService
4070
+ .fromComponent(AssignToChannelDialogComponent, {
4071
+ size: 'md',
4072
+ locals: {},
4073
+ })
4074
+ .pipe(operators.switchMap(function (result) {
4075
+ if (result) {
4076
+ return dataService.collection
4077
+ .assignCollectionsToChannel({
4078
+ collectionIds: selection.map(function (c) { return c.id; }),
4079
+ channelId: result.id,
4080
+ })
4081
+ .pipe(operators.mapTo(result));
4082
+ }
4083
+ else {
4084
+ return rxjs.EMPTY;
4085
+ }
4086
+ }))
4087
+ .subscribe(function (result) {
4088
+ notificationService.success(ngxTranslateExtractMarker.marker('catalog.assign-collections-to-channel-success'), {
4089
+ count: selection.length,
4090
+ channelCode: result.code,
4091
+ });
4092
+ clearSelection();
4093
+ });
4094
+ };
4095
+ var assignCollectionsToChannelBulkAction = {
4096
+ location: 'collection-list',
4097
+ label: ngxTranslateExtractMarker.marker('catalog.assign-to-channel'),
4098
+ icon: 'layers',
4099
+ requiresPermission: ɵ2$2,
4100
+ isVisible: ɵ3$2,
4101
+ onClick: ɵ4$2,
4102
+ };
4103
+ var ɵ5$2 = function (userPermissions) { return userPermissions.includes(i2.Permission.UpdateChannel) ||
4104
+ userPermissions.includes(i2.Permission.UpdateProduct); }, ɵ6$2 = function (_a) {
4105
+ var injector = _a.injector;
4106
+ return i2.getChannelCodeFromUserStatus(injector.get(i2.DataService));
4107
+ }, ɵ7$2 = function (_a) {
4108
+ var injector = _a.injector;
4109
+ return i2.currentChannelIsNotDefault(injector.get(i2.DataService));
4110
+ }, ɵ8$2 = function (_a) {
4111
+ var injector = _a.injector, selection = _a.selection, hostComponent = _a.hostComponent, clearSelection = _a.clearSelection;
4112
+ var modalService = injector.get(i2.ModalService);
4113
+ var dataService = injector.get(i2.DataService);
4114
+ var notificationService = injector.get(i2.NotificationService);
4115
+ var activeChannelId$ = dataService.client
4116
+ .userStatus()
4117
+ .mapSingle(function (_a) {
4118
+ var userStatus = _a.userStatus;
4119
+ return userStatus.activeChannelId;
4120
+ });
4121
+ rxjs.from(i2.getChannelCodeFromUserStatus(injector.get(i2.DataService)))
4122
+ .pipe(operators.switchMap(function (_a) {
4123
+ var channelCode = _a.channelCode;
4124
+ return modalService.dialog({
4125
+ title: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
4126
+ translationVars: {
4127
+ channelCode: channelCode,
4128
+ },
4129
+ buttons: [
4130
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
4131
+ {
4132
+ type: 'danger',
4133
+ label: ngxTranslateExtractMarker.marker('common.remove'),
4134
+ returnValue: true,
4135
+ },
4136
+ ],
4137
+ });
4138
+ }), operators.switchMap(function (res) { return res
4139
+ ? activeChannelId$.pipe(operators.switchMap(function (activeChannelId) { return activeChannelId
4140
+ ? dataService.collection.removeCollectionsFromChannel({
4141
+ channelId: activeChannelId,
4142
+ collectionIds: selection.map(function (c) { return c.id; }),
4143
+ })
4144
+ : rxjs.EMPTY; }), operators.mapTo(true))
4145
+ : rxjs.of(false); }))
4146
+ .subscribe(function (removed) {
4147
+ if (removed) {
4148
+ clearSelection();
4149
+ notificationService.success(ngxTranslateExtractMarker.marker('catalog.notify-remove-collections-from-channel-success'), {
4150
+ count: selection.length,
4151
+ });
4152
+ hostComponent.refresh();
4153
+ }
4154
+ });
4155
+ };
4156
+ var removeCollectionsFromChannelBulkAction = {
4157
+ location: 'collection-list',
4158
+ label: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
4159
+ requiresPermission: ɵ5$2,
4160
+ getTranslationVars: ɵ6$2,
4161
+ icon: 'layers',
4162
+ iconClass: 'is-warning',
4163
+ isVisible: ɵ7$2,
4164
+ onClick: ɵ8$2,
4165
+ };
4166
+
3810
4167
  /**
3811
4168
  * Builds a tree from an array of nodes which have a parent.
3812
4169
  * Based on https://stackoverflow.com/a/31247960/772859, modified to preserve ordering.
@@ -3947,7 +4304,7 @@
3947
4304
  CollectionTreeComponent.decorators = [
3948
4305
  { type: i0.Component, args: [{
3949
4306
  selector: 'vdr-collection-tree',
3950
- template: "<vdr-collection-tree-node\r\n *ngIf=\"collectionTree\"\r\n cdkDropListGroup\r\n [expandAll]=\"expandAll\"\r\n [collectionTree]=\"collectionTree\"\r\n [activeCollectionId]=\"activeCollectionId\"\r\n></vdr-collection-tree-node>\r\n",
4307
+ template: "<vdr-collection-tree-node\r\n *ngIf=\"collectionTree\"\r\n cdkDropListGroup\r\n [expandAll]=\"expandAll\"\r\n [collectionTree]=\"collectionTree\"\r\n [selectionManager]=\"selectionManager\"\r\n [activeCollectionId]=\"activeCollectionId\"\r\n></vdr-collection-tree-node>\r\n",
3951
4308
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
3952
4309
  styles: [""]
3953
4310
  },] }
@@ -3957,17 +4314,19 @@
3957
4314
  activeCollectionId: [{ type: i0.Input }],
3958
4315
  expandAll: [{ type: i0.Input }],
3959
4316
  expandedIds: [{ type: i0.Input }],
4317
+ selectionManager: [{ type: i0.Input }],
3960
4318
  rearrange: [{ type: i0.Output }],
3961
4319
  deleteCollection: [{ type: i0.Output }]
3962
4320
  };
3963
4321
 
3964
4322
  var CollectionTreeNodeComponent = /** @class */ (function () {
3965
- function CollectionTreeNodeComponent(parent, root, dataService, router, route) {
4323
+ function CollectionTreeNodeComponent(parent, root, dataService, router, route, changeDetectorRef) {
3966
4324
  this.parent = parent;
3967
4325
  this.root = root;
3968
4326
  this.dataService = dataService;
3969
4327
  this.router = router;
3970
4328
  this.route = route;
4329
+ this.changeDetectorRef = changeDetectorRef;
3971
4330
  this.depth = 0;
3972
4331
  this.expandAll = false;
3973
4332
  this.moveListItems = [];
@@ -3976,6 +4335,8 @@
3976
4335
  }
3977
4336
  }
3978
4337
  CollectionTreeNodeComponent.prototype.ngOnInit = function () {
4338
+ var _this = this;
4339
+ var _a;
3979
4340
  this.parentName = this.collectionTree.name || '<root>';
3980
4341
  var permissions$ = this.dataService.client
3981
4342
  .userStatus()
@@ -3983,6 +4344,7 @@
3983
4344
  .pipe(operators.shareReplay(1));
3984
4345
  this.hasUpdatePermission$ = permissions$.pipe(operators.map(function (perms) { return perms.includes(i2.Permission.UpdateCatalog) || perms.includes(i2.Permission.UpdateCollection); }));
3985
4346
  this.hasDeletePermission$ = permissions$.pipe(operators.map(function (perms) { return perms.includes(i2.Permission.DeleteCatalog) || perms.includes(i2.Permission.DeleteCollection); }));
4347
+ this.subscription = (_a = this.selectionManager) === null || _a === void 0 ? void 0 : _a.selectionChanges$.subscribe(function () { return _this.changeDetectorRef.markForCheck(); });
3986
4348
  };
3987
4349
  CollectionTreeNodeComponent.prototype.ngOnChanges = function (changes) {
3988
4350
  var expandAllChange = changes['expandAll'];
@@ -3992,6 +4354,10 @@
3992
4354
  }
3993
4355
  }
3994
4356
  };
4357
+ CollectionTreeNodeComponent.prototype.ngOnDestroy = function () {
4358
+ var _a;
4359
+ (_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
4360
+ };
3995
4361
  CollectionTreeNodeComponent.prototype.trackByFn = function (index, item) {
3996
4362
  return item.id;
3997
4363
  };
@@ -4055,9 +4421,9 @@
4055
4421
  CollectionTreeNodeComponent.decorators = [
4056
4422
  { type: i0.Component, args: [{
4057
4423
  selector: 'vdr-collection-tree-node',
4058
- 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",
4424
+ 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>\r\n <input\r\n type=\"checkbox\"\r\n clrCheckbox\r\n [checked]=\"selectionManager.isSelected(collection)\"\r\n (click)=\"selectionManager.toggleSelection(collection, $event)\"\r\n />\r\n </div>\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 [selectionManager]=\"selectionManager\"\r\n ></vdr-collection-tree-node>\r\n </div>\r\n</div>\r\n",
4059
4425
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
4060
- 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"]
4426
+ styles: [":host{display:block}.collection{background-color:var(--clr-table-bgcolor);border-radius:var(--clr-global-borderradius);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-color:var(--clr-table-bgcolor);border-radius:var(--clr-global-borderradius);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"]
4061
4427
  },] }
4062
4428
  ];
4063
4429
  CollectionTreeNodeComponent.ctorParameters = function () { return [
@@ -4065,12 +4431,256 @@
4065
4431
  { type: CollectionTreeComponent },
4066
4432
  { type: i2.DataService },
4067
4433
  { type: i1.Router },
4068
- { type: i1.ActivatedRoute }
4434
+ { type: i1.ActivatedRoute },
4435
+ { type: i0.ChangeDetectorRef }
4069
4436
  ]; };
4070
4437
  CollectionTreeNodeComponent.propDecorators = {
4071
4438
  collectionTree: [{ type: i0.Input }],
4072
4439
  activeCollectionId: [{ type: i0.Input }],
4073
- expandAll: [{ type: i0.Input }]
4440
+ expandAll: [{ type: i0.Input }],
4441
+ selectionManager: [{ type: i0.Input }]
4442
+ };
4443
+
4444
+ var ɵ0$1 = function (userPermissions) { return userPermissions.includes(i2.Permission.DeleteFacet) ||
4445
+ userPermissions.includes(i2.Permission.DeleteCatalog); }, ɵ1$1 = function (_b) {
4446
+ var injector = _b.injector, selection = _b.selection, hostComponent = _b.hostComponent, clearSelection = _b.clearSelection;
4447
+ var modalService = injector.get(i2.ModalService);
4448
+ var dataService = injector.get(i2.DataService);
4449
+ var notificationService = injector.get(i2.NotificationService);
4450
+ function showModalAndDelete(facetIds, message) {
4451
+ return modalService
4452
+ .dialog({
4453
+ title: ngxTranslateExtractMarker.marker('catalog.confirm-bulk-delete-facets'),
4454
+ translationVars: {
4455
+ count: selection.length,
4456
+ },
4457
+ size: message ? 'lg' : 'md',
4458
+ body: message,
4459
+ buttons: [
4460
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
4461
+ {
4462
+ type: 'danger',
4463
+ label: message ? ngxTranslateExtractMarker.marker('common.force-delete') : ngxTranslateExtractMarker.marker('common.delete'),
4464
+ returnValue: true,
4465
+ },
4466
+ ],
4467
+ })
4468
+ .pipe(operators.switchMap(function (res) { return res
4469
+ ? dataService.facet
4470
+ .deleteFacets(facetIds, !!message)
4471
+ .pipe(operators.map(function (res2) { return res2.deleteFacets; }))
4472
+ : rxjs.of([]); }));
4473
+ }
4474
+ showModalAndDelete(unique.unique(selection.map(function (f) { return f.id; })))
4475
+ .pipe(operators.switchMap(function (result) {
4476
+ var e_1, _b;
4477
+ var _a;
4478
+ var deletedCount = 0;
4479
+ var errors = [];
4480
+ var errorIds = [];
4481
+ var i = 0;
4482
+ try {
4483
+ for (var result_1 = __values(result), result_1_1 = result_1.next(); !result_1_1.done; result_1_1 = result_1.next()) {
4484
+ var item = result_1_1.value;
4485
+ if (item.result === i2.DeletionResult.DELETED) {
4486
+ deletedCount++;
4487
+ }
4488
+ else if (item.message) {
4489
+ errors.push(item.message);
4490
+ errorIds.push((_a = selection[i]) === null || _a === void 0 ? void 0 : _a.id);
4491
+ }
4492
+ i++;
4493
+ }
4494
+ }
4495
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4496
+ finally {
4497
+ try {
4498
+ if (result_1_1 && !result_1_1.done && (_b = result_1.return)) _b.call(result_1);
4499
+ }
4500
+ finally { if (e_1) throw e_1.error; }
4501
+ }
4502
+ if (0 < errorIds.length) {
4503
+ return showModalAndDelete(errorIds, errors.join('\n')).pipe(operators.map(function (result2) {
4504
+ var deletedCount2 = result2.filter(function (r) { return r.result === i2.DeletionResult.DELETED; }).length;
4505
+ return deletedCount + deletedCount2;
4506
+ }));
4507
+ }
4508
+ else {
4509
+ return rxjs.of(deletedCount);
4510
+ }
4511
+ }))
4512
+ .subscribe(function (deletedCount) {
4513
+ if (deletedCount) {
4514
+ hostComponent.refresh();
4515
+ clearSelection();
4516
+ notificationService.success(ngxTranslateExtractMarker.marker('catalog.notify-bulk-delete-facets-success'), {
4517
+ count: deletedCount,
4518
+ });
4519
+ }
4520
+ });
4521
+ };
4522
+ var deleteFacetsBulkAction = {
4523
+ location: 'facet-list',
4524
+ label: ngxTranslateExtractMarker.marker('common.delete'),
4525
+ icon: 'trash',
4526
+ iconClass: 'is-danger',
4527
+ requiresPermission: ɵ0$1,
4528
+ onClick: ɵ1$1,
4529
+ };
4530
+ var ɵ2$1 = function (userPermissions) { return userPermissions.includes(i2.Permission.UpdateFacet) ||
4531
+ userPermissions.includes(i2.Permission.UpdateCatalog); }, ɵ3$1 = function (_b) {
4532
+ var injector = _b.injector;
4533
+ return i2.isMultiChannel(injector.get(i2.DataService));
4534
+ }, ɵ4$1 = function (_b) {
4535
+ var injector = _b.injector, selection = _b.selection, hostComponent = _b.hostComponent, clearSelection = _b.clearSelection;
4536
+ var modalService = injector.get(i2.ModalService);
4537
+ var dataService = injector.get(i2.DataService);
4538
+ var notificationService = injector.get(i2.NotificationService);
4539
+ modalService
4540
+ .fromComponent(AssignToChannelDialogComponent, {
4541
+ size: 'md',
4542
+ locals: {},
4543
+ })
4544
+ .pipe(operators.switchMap(function (result) {
4545
+ if (result) {
4546
+ return dataService.facet
4547
+ .assignFacetsToChannel({
4548
+ facetIds: selection.map(function (f) { return f.id; }),
4549
+ channelId: result.id,
4550
+ })
4551
+ .pipe(operators.mapTo(result));
4552
+ }
4553
+ else {
4554
+ return rxjs.EMPTY;
4555
+ }
4556
+ }))
4557
+ .subscribe(function (result) {
4558
+ notificationService.success(ngxTranslateExtractMarker.marker('catalog.assign-facets-to-channel-success'), {
4559
+ count: selection.length,
4560
+ channelCode: result.code,
4561
+ });
4562
+ clearSelection();
4563
+ });
4564
+ };
4565
+ var assignFacetsToChannelBulkAction = {
4566
+ location: 'facet-list',
4567
+ label: ngxTranslateExtractMarker.marker('catalog.assign-to-channel'),
4568
+ icon: 'layers',
4569
+ requiresPermission: ɵ2$1,
4570
+ isVisible: ɵ3$1,
4571
+ onClick: ɵ4$1,
4572
+ };
4573
+ var ɵ5$1 = function (_b) {
4574
+ var injector = _b.injector;
4575
+ return i2.getChannelCodeFromUserStatus(injector.get(i2.DataService));
4576
+ }, ɵ6$1 = function (userPermissions) { return userPermissions.includes(i2.Permission.UpdateFacet) ||
4577
+ userPermissions.includes(i2.Permission.UpdateCatalog); }, ɵ7$1 = function (_b) {
4578
+ var injector = _b.injector;
4579
+ return i2.currentChannelIsNotDefault(injector.get(i2.DataService));
4580
+ }, ɵ8$1 = function (_b) {
4581
+ var injector = _b.injector, selection = _b.selection, hostComponent = _b.hostComponent, clearSelection = _b.clearSelection;
4582
+ var modalService = injector.get(i2.ModalService);
4583
+ var dataService = injector.get(i2.DataService);
4584
+ var notificationService = injector.get(i2.NotificationService);
4585
+ var activeChannelId$ = dataService.client
4586
+ .userStatus()
4587
+ .mapSingle(function (_b) {
4588
+ var userStatus = _b.userStatus;
4589
+ return userStatus.activeChannelId;
4590
+ });
4591
+ function showModalAndDelete(facetIds, message) {
4592
+ return modalService
4593
+ .dialog({
4594
+ title: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
4595
+ translationVars: {
4596
+ count: selection.length,
4597
+ },
4598
+ size: message ? 'lg' : 'md',
4599
+ body: message,
4600
+ buttons: [
4601
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
4602
+ {
4603
+ type: 'danger',
4604
+ label: message ? ngxTranslateExtractMarker.marker('common.force-remove') : ngxTranslateExtractMarker.marker('common.remove'),
4605
+ returnValue: true,
4606
+ },
4607
+ ],
4608
+ })
4609
+ .pipe(operators.switchMap(function (res) { return res
4610
+ ? activeChannelId$.pipe(operators.switchMap(function (activeChannelId) { return activeChannelId
4611
+ ? dataService.facet.removeFacetsFromChannel({
4612
+ channelId: activeChannelId,
4613
+ facetIds: facetIds,
4614
+ force: !!message,
4615
+ })
4616
+ : rxjs.EMPTY; }), operators.map(function (res2) { return res2.removeFacetsFromChannel; }))
4617
+ : rxjs.EMPTY; }));
4618
+ }
4619
+ showModalAndDelete(unique.unique(selection.map(function (f) { return f.id; })))
4620
+ .pipe(operators.switchMap(function (result) {
4621
+ var e_2, _b;
4622
+ var _a;
4623
+ var removedCount = selection.length;
4624
+ var errors = [];
4625
+ var errorIds = [];
4626
+ var i = 0;
4627
+ try {
4628
+ for (var result_2 = __values(result), result_2_1 = result_2.next(); !result_2_1.done; result_2_1 = result_2.next()) {
4629
+ var item = result_2_1.value;
4630
+ if (item.__typename === 'FacetInUseError') {
4631
+ errors.push(item.message);
4632
+ errorIds.push((_a = selection[i]) === null || _a === void 0 ? void 0 : _a.id);
4633
+ removedCount--;
4634
+ }
4635
+ i++;
4636
+ }
4637
+ }
4638
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
4639
+ finally {
4640
+ try {
4641
+ if (result_2_1 && !result_2_1.done && (_b = result_2.return)) _b.call(result_2);
4642
+ }
4643
+ finally { if (e_2) throw e_2.error; }
4644
+ }
4645
+ if (0 < errorIds.length) {
4646
+ return showModalAndDelete(errorIds, errors.join('\n')).pipe(operators.map(function (result2) {
4647
+ var notRemovedCount = result2.filter(function (r) { return r.__typename === 'FacetInUseError'; }).length;
4648
+ return selection.length - notRemovedCount;
4649
+ }));
4650
+ }
4651
+ else {
4652
+ return rxjs.of(removedCount);
4653
+ }
4654
+ }), operators.switchMap(function (removedCount) { return removedCount
4655
+ ? i2.getChannelCodeFromUserStatus(dataService).then(function (_b) {
4656
+ var channelCode = _b.channelCode;
4657
+ return ({
4658
+ channelCode: channelCode,
4659
+ removedCount: removedCount,
4660
+ });
4661
+ })
4662
+ : rxjs.EMPTY; }))
4663
+ .subscribe(function (_b) {
4664
+ var removedCount = _b.removedCount, channelCode = _b.channelCode;
4665
+ if (removedCount) {
4666
+ hostComponent.refresh();
4667
+ clearSelection();
4668
+ notificationService.success(ngxTranslateExtractMarker.marker('catalog.notify-remove-facets-from-channel-success'), {
4669
+ count: removedCount,
4670
+ channelCode: channelCode,
4671
+ });
4672
+ }
4673
+ });
4674
+ };
4675
+ var removeFacetsFromChannelBulkAction = {
4676
+ location: 'facet-list',
4677
+ label: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
4678
+ getTranslationVars: ɵ5$1,
4679
+ icon: 'layers',
4680
+ iconClass: 'is-warning',
4681
+ requiresPermission: ɵ6$1,
4682
+ isVisible: ɵ7$1,
4683
+ onClick: ɵ8$1,
4074
4684
  };
4075
4685
 
4076
4686
  var DEFAULT_VARIANT_CODE = '__DEFAULT_VARIANT__';
@@ -4328,6 +4938,201 @@
4328
4938
  disabled: [{ type: i0.Input }]
4329
4939
  };
4330
4940
 
4941
+ var ɵ0 = function (userPermissions) { return userPermissions.includes(i2.Permission.DeleteProduct) ||
4942
+ userPermissions.includes(i2.Permission.DeleteCatalog); }, ɵ1 = function (_a) {
4943
+ var injector = _a.injector, selection = _a.selection, hostComponent = _a.hostComponent, clearSelection = _a.clearSelection;
4944
+ var modalService = injector.get(i2.ModalService);
4945
+ var dataService = injector.get(i2.DataService);
4946
+ var notificationService = injector.get(i2.NotificationService);
4947
+ modalService
4948
+ .dialog({
4949
+ title: ngxTranslateExtractMarker.marker('catalog.confirm-bulk-delete-products'),
4950
+ translationVars: {
4951
+ count: selection.length,
4952
+ },
4953
+ buttons: [
4954
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
4955
+ { type: 'danger', label: ngxTranslateExtractMarker.marker('common.delete'), returnValue: true },
4956
+ ],
4957
+ })
4958
+ .pipe(operators.switchMap(function (response) { return response
4959
+ ? dataService.product.deleteProducts(unique.unique(selection.map(function (p) { return p.productId; })))
4960
+ : rxjs.EMPTY; }))
4961
+ .subscribe(function (result) {
4962
+ var e_1, _a;
4963
+ var deleted = 0;
4964
+ var errors = [];
4965
+ try {
4966
+ for (var _b = __values(result.deleteProducts), _c = _b.next(); !_c.done; _c = _b.next()) {
4967
+ var item = _c.value;
4968
+ if (item.result === i2.DeletionResult.DELETED) {
4969
+ deleted++;
4970
+ }
4971
+ else if (item.message) {
4972
+ errors.push(item.message);
4973
+ }
4974
+ }
4975
+ }
4976
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4977
+ finally {
4978
+ try {
4979
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
4980
+ }
4981
+ finally { if (e_1) throw e_1.error; }
4982
+ }
4983
+ if (0 < deleted) {
4984
+ notificationService.success(ngxTranslateExtractMarker.marker('catalog.notify-bulk-delete-products-success'), {
4985
+ count: deleted,
4986
+ });
4987
+ }
4988
+ if (0 < errors.length) {
4989
+ notificationService.error(errors.join('\n'));
4990
+ }
4991
+ hostComponent.refresh();
4992
+ clearSelection();
4993
+ });
4994
+ };
4995
+ var deleteProductsBulkAction = {
4996
+ location: 'product-list',
4997
+ label: ngxTranslateExtractMarker.marker('common.delete'),
4998
+ icon: 'trash',
4999
+ iconClass: 'is-danger',
5000
+ requiresPermission: ɵ0,
5001
+ onClick: ɵ1,
5002
+ };
5003
+ var ɵ2 = function (userPermissions) { return userPermissions.includes(i2.Permission.UpdateCatalog) ||
5004
+ userPermissions.includes(i2.Permission.UpdateProduct); }, ɵ3 = function (_a) {
5005
+ var injector = _a.injector;
5006
+ return i2.isMultiChannel(injector.get(i2.DataService));
5007
+ }, ɵ4 = function (_a) {
5008
+ var injector = _a.injector, selection = _a.selection, hostComponent = _a.hostComponent, clearSelection = _a.clearSelection;
5009
+ var modalService = injector.get(i2.ModalService);
5010
+ var dataService = injector.get(i2.DataService);
5011
+ var notificationService = injector.get(i2.NotificationService);
5012
+ modalService
5013
+ .fromComponent(AssignProductsToChannelDialogComponent, {
5014
+ size: 'lg',
5015
+ locals: {
5016
+ productIds: unique.unique(selection.map(function (p) { return p.productId; })),
5017
+ currentChannelIds: [],
5018
+ },
5019
+ })
5020
+ .subscribe(function (result) {
5021
+ if (result) {
5022
+ clearSelection();
5023
+ }
5024
+ });
5025
+ };
5026
+ var assignProductsToChannelBulkAction = {
5027
+ location: 'product-list',
5028
+ label: ngxTranslateExtractMarker.marker('catalog.assign-to-channel'),
5029
+ icon: 'layers',
5030
+ requiresPermission: ɵ2,
5031
+ isVisible: ɵ3,
5032
+ onClick: ɵ4,
5033
+ };
5034
+ var ɵ5 = function (userPermissions) { return userPermissions.includes(i2.Permission.UpdateChannel) ||
5035
+ userPermissions.includes(i2.Permission.UpdateProduct); }, ɵ6 = function (_a) {
5036
+ var injector = _a.injector;
5037
+ return i2.getChannelCodeFromUserStatus(injector.get(i2.DataService));
5038
+ }, ɵ7 = function (_a) {
5039
+ var injector = _a.injector;
5040
+ return i2.currentChannelIsNotDefault(injector.get(i2.DataService));
5041
+ }, ɵ8 = function (_a) {
5042
+ var injector = _a.injector, selection = _a.selection, hostComponent = _a.hostComponent, clearSelection = _a.clearSelection;
5043
+ var modalService = injector.get(i2.ModalService);
5044
+ var dataService = injector.get(i2.DataService);
5045
+ var notificationService = injector.get(i2.NotificationService);
5046
+ var activeChannelId$ = dataService.client
5047
+ .userStatus()
5048
+ .mapSingle(function (_a) {
5049
+ var userStatus = _a.userStatus;
5050
+ return userStatus.activeChannelId;
5051
+ });
5052
+ rxjs.from(i2.getChannelCodeFromUserStatus(injector.get(i2.DataService)))
5053
+ .pipe(operators.switchMap(function (_a) {
5054
+ var channelCode = _a.channelCode;
5055
+ return modalService.dialog({
5056
+ title: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
5057
+ translationVars: {
5058
+ channelCode: channelCode,
5059
+ },
5060
+ buttons: [
5061
+ { type: 'secondary', label: ngxTranslateExtractMarker.marker('common.cancel') },
5062
+ {
5063
+ type: 'danger',
5064
+ label: ngxTranslateExtractMarker.marker('common.remove'),
5065
+ returnValue: true,
5066
+ },
5067
+ ],
5068
+ });
5069
+ }), operators.switchMap(function (res) { return res
5070
+ ? activeChannelId$.pipe(operators.switchMap(function (activeChannelId) { return activeChannelId
5071
+ ? dataService.product.removeProductsFromChannel({
5072
+ channelId: activeChannelId,
5073
+ productIds: selection.map(function (p) { return p.productId; }),
5074
+ })
5075
+ : rxjs.EMPTY; }), operators.mapTo(true))
5076
+ : rxjs.of(false); }))
5077
+ .subscribe(function (removed) {
5078
+ if (removed) {
5079
+ clearSelection();
5080
+ notificationService.success(ngxTranslateExtractMarker.marker('common.notify-remove-products-from-channel-success'), {
5081
+ count: selection.length,
5082
+ });
5083
+ setTimeout(function () { return hostComponent.refresh(); }, 1000);
5084
+ }
5085
+ });
5086
+ };
5087
+ var removeProductsFromChannelBulkAction = {
5088
+ location: 'product-list',
5089
+ label: ngxTranslateExtractMarker.marker('catalog.remove-from-channel'),
5090
+ requiresPermission: ɵ5,
5091
+ getTranslationVars: ɵ6,
5092
+ icon: 'layers',
5093
+ iconClass: 'is-warning',
5094
+ isVisible: ɵ7,
5095
+ onClick: ɵ8,
5096
+ };
5097
+ var ɵ9 = function (userPermissions) { return userPermissions.includes(i2.Permission.UpdateCatalog) ||
5098
+ userPermissions.includes(i2.Permission.UpdateProduct); }, ɵ10 = function (_a) {
5099
+ var injector = _a.injector, selection = _a.selection, hostComponent = _a.hostComponent, clearSelection = _a.clearSelection;
5100
+ var modalService = injector.get(i2.ModalService);
5101
+ var dataService = injector.get(i2.DataService);
5102
+ var notificationService = injector.get(i2.NotificationService);
5103
+ var mode = hostComponent.groupByProduct ? 'product' : 'variant';
5104
+ var ids = mode === 'product'
5105
+ ? unique.unique(selection.map(function (p) { return p.productId; }))
5106
+ : unique.unique(selection.map(function (p) { return p.productVariantId; }));
5107
+ return dataService.facet
5108
+ .getAllFacets()
5109
+ .mapSingle(function (data) { return data.facets.items; })
5110
+ .pipe(operators.switchMap(function (facets) { return modalService.fromComponent(BulkAddFacetValuesDialogComponent, {
5111
+ size: 'xl',
5112
+ locals: {
5113
+ facets: facets,
5114
+ mode: mode,
5115
+ ids: ids,
5116
+ },
5117
+ }); }))
5118
+ .subscribe(function (result) {
5119
+ if (result) {
5120
+ notificationService.success(ngxTranslateExtractMarker.marker('common.notify-bulk-update-success'), {
5121
+ count: selection.length,
5122
+ entity: mode === 'product' ? 'Products' : 'ProductVariants',
5123
+ });
5124
+ clearSelection();
5125
+ }
5126
+ });
5127
+ };
5128
+ var assignFacetValuesToProductsBulkAction = {
5129
+ location: 'product-list',
5130
+ label: ngxTranslateExtractMarker.marker('catalog.edit-facet-values'),
5131
+ icon: 'tag',
5132
+ requiresPermission: ɵ9,
5133
+ onClick: ɵ10,
5134
+ };
5135
+
4331
5136
  var UpdateProductOptionDialogComponent = /** @class */ (function () {
4332
5137
  function UpdateProductOptionDialogComponent() {
4333
5138
  this.updateVariantName = true;
@@ -4594,7 +5399,7 @@
4594
5399
  ProductVariantsListComponent.decorators = [
4595
5400
  { type: i0.Component, args: [{
4596
5401
  selector: 'vdr-product-variants-list',
4597
- 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",
5402
+ 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: { channelCode: channel.code }\"\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",
4598
5403
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
4599
5404
  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"]
4600
5405
  },] }
@@ -4783,9 +5588,22 @@
4783
5588
  AssetDetailComponent,
4784
5589
  ConfirmVariantDeletionDialogComponent,
4785
5590
  ProductOptionsEditorComponent,
5591
+ BulkAddFacetValuesDialogComponent,
5592
+ AssignToChannelDialogComponent,
4786
5593
  ];
4787
5594
  var CatalogModule = /** @class */ (function () {
4788
- function CatalogModule() {
5595
+ function CatalogModule(bulkActionRegistryService) {
5596
+ this.bulkActionRegistryService = bulkActionRegistryService;
5597
+ bulkActionRegistryService.registerBulkAction(assignFacetValuesToProductsBulkAction);
5598
+ bulkActionRegistryService.registerBulkAction(assignProductsToChannelBulkAction);
5599
+ bulkActionRegistryService.registerBulkAction(removeProductsFromChannelBulkAction);
5600
+ bulkActionRegistryService.registerBulkAction(deleteProductsBulkAction);
5601
+ bulkActionRegistryService.registerBulkAction(assignFacetsToChannelBulkAction);
5602
+ bulkActionRegistryService.registerBulkAction(removeFacetsFromChannelBulkAction);
5603
+ bulkActionRegistryService.registerBulkAction(deleteFacetsBulkAction);
5604
+ bulkActionRegistryService.registerBulkAction(assignCollectionsToChannelBulkAction);
5605
+ bulkActionRegistryService.registerBulkAction(removeCollectionsFromChannelBulkAction);
5606
+ bulkActionRegistryService.registerBulkAction(deleteCollectionsBulkAction);
4789
5607
  }
4790
5608
  return CatalogModule;
4791
5609
  }());
@@ -4795,7 +5613,10 @@
4795
5613
  exports: __spreadArray([], __read(CATALOG_COMPONENTS)),
4796
5614
  declarations: __spreadArray([], __read(CATALOG_COMPONENTS)),
4797
5615
  },] }
4798
- ];
5616
+ ];
5617
+ CatalogModule.ctorParameters = function () { return [
5618
+ { type: i2.BulkActionRegistryService }
5619
+ ]; };
4799
5620
 
4800
5621
  // This file was generated by the build-public-api.ts script
4801
5622
 
@@ -4809,6 +5630,8 @@
4809
5630
  exports.AssetResolver = AssetResolver;
4810
5631
  exports.AssetsComponent = AssetsComponent;
4811
5632
  exports.AssignProductsToChannelDialogComponent = AssignProductsToChannelDialogComponent;
5633
+ exports.AssignToChannelDialogComponent = AssignToChannelDialogComponent;
5634
+ exports.BulkAddFacetValuesDialogComponent = BulkAddFacetValuesDialogComponent;
4812
5635
  exports.CatalogModule = CatalogModule;
4813
5636
  exports.CollectionContentsComponent = CollectionContentsComponent;
4814
5637
  exports.CollectionDetailComponent = CollectionDetailComponent;
@@ -4820,6 +5643,8 @@
4820
5643
  exports.FacetDetailComponent = FacetDetailComponent;
4821
5644
  exports.FacetListComponent = FacetListComponent;
4822
5645
  exports.FacetResolver = FacetResolver;
5646
+ exports.GET_PRODUCTS_WITH_FACET_VALUES_BY_IDS = GET_PRODUCTS_WITH_FACET_VALUES_BY_IDS;
5647
+ exports.GET_VARIANTS_WITH_FACET_VALUES_BY_IDS = GET_VARIANTS_WITH_FACET_VALUES_BY_IDS;
4823
5648
  exports.GenerateProductVariantsComponent = GenerateProductVariantsComponent;
4824
5649
  exports.GeneratedVariant = GeneratedVariant;
4825
5650
  exports.OPTION_VALUE_INPUT_VALUE_ACCESSOR = OPTION_VALUE_INPUT_VALUE_ACCESSOR;
@@ -4833,27 +5658,30 @@
4833
5658
  exports.ProductVariantsListComponent = ProductVariantsListComponent;
4834
5659
  exports.ProductVariantsResolver = ProductVariantsResolver;
4835
5660
  exports.ProductVariantsTableComponent = ProductVariantsTableComponent;
5661
+ exports.UPDATE_PRODUCTS_BULK = UPDATE_PRODUCTS_BULK;
5662
+ exports.UPDATE_VARIANTS_BULK = UPDATE_VARIANTS_BULK;
4836
5663
  exports.UpdateProductOptionDialogComponent = UpdateProductOptionDialogComponent;
4837
5664
  exports.VariantPriceDetailComponent = VariantPriceDetailComponent;
4838
5665
  exports.arrayToTree = arrayToTree;
4839
5666
  exports.assetBreadcrumb = assetBreadcrumb;
5667
+ exports.assignCollectionsToChannelBulkAction = assignCollectionsToChannelBulkAction;
5668
+ exports.assignFacetValuesToProductsBulkAction = assignFacetValuesToProductsBulkAction;
5669
+ exports.assignFacetsToChannelBulkAction = assignFacetsToChannelBulkAction;
5670
+ exports.assignProductsToChannelBulkAction = assignProductsToChannelBulkAction;
4840
5671
  exports.catalogRoutes = catalogRoutes;
4841
5672
  exports.collectionBreadcrumb = collectionBreadcrumb;
5673
+ exports.deleteCollectionsBulkAction = deleteCollectionsBulkAction;
5674
+ exports.deleteFacetsBulkAction = deleteFacetsBulkAction;
5675
+ exports.deleteProductsBulkAction = deleteProductsBulkAction;
4842
5676
  exports.facetBreadcrumb = facetBreadcrumb;
4843
5677
  exports.productBreadcrumb = productBreadcrumb;
4844
5678
  exports.productOptionsEditorBreadcrumb = productOptionsEditorBreadcrumb;
4845
5679
  exports.productVariantEditorBreadcrumb = productVariantEditorBreadcrumb;
5680
+ exports.removeCollectionsFromChannelBulkAction = removeCollectionsFromChannelBulkAction;
5681
+ exports.removeFacetsFromChannelBulkAction = removeFacetsFromChannelBulkAction;
5682
+ exports.removeProductsFromChannelBulkAction = removeProductsFromChannelBulkAction;
4846
5683
  exports.replaceLast = replaceLast;
4847
- exports.ɵ0 = ɵ0;
4848
- exports.ɵ1 = ɵ1;
4849
- exports.ɵ2 = ɵ2;
4850
- exports.ɵ3 = ɵ3;
4851
- exports.ɵ4 = ɵ4;
4852
- exports.ɵ5 = ɵ5;
4853
- exports.ɵ6 = ɵ6;
4854
- exports.ɵ7 = ɵ7;
4855
- exports.ɵ8 = ɵ8;
4856
- exports.ɵ9 = ɵ9;
5684
+ exports.ɵ10 = ɵ10;
4857
5685
 
4858
5686
  Object.defineProperty(exports, '__esModule', { value: true });
4859
5687