@vendure/admin-ui 1.5.2 → 1.6.2

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 (126) hide show
  1. package/bundles/vendure-admin-ui-catalog.umd.js +212 -173
  2. package/bundles/vendure-admin-ui-catalog.umd.js.map +1 -1
  3. package/bundles/vendure-admin-ui-core.umd.js +2337 -1864
  4. package/bundles/vendure-admin-ui-core.umd.js.map +1 -1
  5. package/bundles/vendure-admin-ui-dashboard.umd.js +3 -3
  6. package/bundles/vendure-admin-ui-dashboard.umd.js.map +1 -1
  7. package/bundles/vendure-admin-ui-login.umd.js +2 -2
  8. package/bundles/vendure-admin-ui-login.umd.js.map +1 -1
  9. package/bundles/vendure-admin-ui-marketing.umd.js +1 -1
  10. package/bundles/vendure-admin-ui-marketing.umd.js.map +1 -1
  11. package/bundles/vendure-admin-ui-order.umd.js +1 -1
  12. package/bundles/vendure-admin-ui-order.umd.js.map +1 -1
  13. package/catalog/components/collection-contents/collection-contents.component.d.ts +7 -2
  14. package/catalog/components/collection-detail/collection-detail.component.d.ts +12 -4
  15. package/catalog/components/collection-list/collection-list.component.d.ts +2 -0
  16. package/catalog/components/collection-tree/array-to-tree.d.ts +1 -1
  17. package/catalog/components/collection-tree/collection-tree-node.component.d.ts +5 -1
  18. package/catalog/components/collection-tree/collection-tree.component.d.ts +1 -0
  19. package/catalog/components/product-variants-editor/product-variants-editor.component.d.ts +13 -10
  20. package/catalog/providers/product-detail/product-detail.service.d.ts +2 -2
  21. package/catalog/public_api.d.ts +0 -1
  22. package/catalog/vendure-admin-ui-catalog.metadata.json +1 -1
  23. package/core/common/generated-types.d.ts +32 -3
  24. package/core/common/utilities/selection-manager.d.ts +23 -0
  25. package/core/common/version.d.ts +1 -1
  26. package/core/components/app-shell/app-shell.component.d.ts +1 -0
  27. package/core/data/definitions/collection-definitions.d.ts +1 -0
  28. package/core/data/providers/collection-data.service.d.ts +6 -2
  29. package/core/providers/local-storage/local-storage.service.d.ts +1 -0
  30. package/core/public_api.d.ts +5 -0
  31. package/core/shared/components/asset-gallery/asset-gallery.component.d.ts +21 -6
  32. package/core/shared/components/configurable-input/configurable-input.component.d.ts +7 -2
  33. package/core/shared/components/product-multi-selector-dialog/product-multi-selector-dialog.component.d.ts +35 -0
  34. package/{catalog → core/shared}/components/product-search-input/product-search-input.component.d.ts +1 -1
  35. package/core/shared/components/select-toggle/select-toggle.component.d.ts +1 -0
  36. package/core/shared/dynamic-form-inputs/combination-mode-form-input/combination-mode-form-input.component.d.ts +25 -0
  37. package/core/shared/dynamic-form-inputs/product-multi-selector-form-input/product-multi-selector-form-input.component.d.ts +20 -0
  38. package/core/shared/dynamic-form-inputs/register-dynamic-input-components.d.ts +3 -1
  39. package/core/shared/dynamic-form-inputs/relation-form-input/asset/relation-asset-input.component.d.ts +5 -2
  40. package/core/vendure-admin-ui-core.metadata.json +1 -1
  41. package/dashboard/vendure-admin-ui-dashboard.metadata.json +1 -1
  42. package/esm2015/catalog/catalog.module.js +1 -3
  43. package/esm2015/catalog/components/assets/assets.component.js +1 -1
  44. package/esm2015/catalog/components/collection-contents/collection-contents.component.js +51 -14
  45. package/esm2015/catalog/components/collection-detail/collection-detail.component.js +67 -29
  46. package/esm2015/catalog/components/collection-list/collection-list.component.js +30 -4
  47. package/esm2015/catalog/components/collection-tree/array-to-tree.js +3 -3
  48. package/esm2015/catalog/components/collection-tree/collection-tree-node.component.js +27 -4
  49. package/esm2015/catalog/components/collection-tree/collection-tree.component.js +4 -2
  50. package/esm2015/catalog/components/product-detail/product-detail.component.js +1 -1
  51. package/esm2015/catalog/components/product-list/product-list.component.js +3 -3
  52. package/esm2015/catalog/components/product-variants-editor/product-variants-editor.component.js +7 -2
  53. package/esm2015/catalog/components/product-variants-list/product-variants-list.component.js +1 -1
  54. package/esm2015/catalog/public_api.js +1 -2
  55. package/esm2015/core/app.component.module.js +1 -1
  56. package/esm2015/core/common/base-detail.component.js +1 -1
  57. package/esm2015/core/common/deactivate-aware.js +1 -1
  58. package/esm2015/core/common/generated-types.js +1 -1
  59. package/esm2015/core/common/introspection-result.js +255 -189
  60. package/esm2015/core/common/utilities/configurable-operation-utils.js +2 -2
  61. package/esm2015/core/common/utilities/selection-manager.js +64 -0
  62. package/esm2015/core/common/version.js +2 -2
  63. package/esm2015/core/components/app-shell/app-shell.component.js +4 -3
  64. package/esm2015/core/components/main-nav/main-nav.component.js +2 -2
  65. package/esm2015/core/core.module.js +1 -1
  66. package/esm2015/core/data/definitions/collection-definitions.js +18 -1
  67. package/esm2015/core/data/definitions/order-definitions.js +431 -430
  68. package/esm2015/core/data/definitions/shared-definitions.js +29 -28
  69. package/esm2015/core/data/providers/collection-data.service.js +5 -2
  70. package/esm2015/core/providers/local-storage/local-storage.service.js +1 -1
  71. package/esm2015/core/public_api.js +6 -1
  72. package/esm2015/core/shared/components/address-form/address-form.component.js +2 -2
  73. package/esm2015/core/shared/components/asset-gallery/asset-gallery.component.js +24 -42
  74. package/esm2015/core/shared/components/configurable-input/configurable-input.component.js +13 -3
  75. package/esm2015/core/shared/components/formatted-address/formatted-address.component.js +2 -2
  76. package/esm2015/core/shared/components/help-tooltip/help-tooltip.component.js +1 -1
  77. package/esm2015/core/shared/components/product-multi-selector-dialog/product-multi-selector-dialog.component.js +129 -0
  78. package/esm2015/core/shared/components/product-search-input/product-search-input.component.js +104 -0
  79. package/esm2015/core/shared/components/rich-text-editor/rich-text-editor.component.js +1 -1
  80. package/esm2015/core/shared/components/select-toggle/select-toggle.component.js +5 -3
  81. package/esm2015/core/shared/dynamic-form-inputs/combination-mode-form-input/combination-mode-form-input.component.js +45 -0
  82. package/esm2015/core/shared/dynamic-form-inputs/product-multi-selector-form-input/product-multi-selector-form-input.component.js +53 -0
  83. package/esm2015/core/shared/dynamic-form-inputs/register-dynamic-input-components.js +5 -1
  84. package/esm2015/core/shared/dynamic-form-inputs/relation-form-input/asset/relation-asset-input.component.js +8 -7
  85. package/esm2015/core/shared/shared.module.js +9 -1
  86. package/esm2015/dashboard/components/dashboard/dashboard.component.js +1 -1
  87. package/esm2015/dashboard/components/dashboard-widget/dashboard-widget.component.js +2 -2
  88. package/esm2015/dashboard/widgets/order-summary-widget/order-summary-widget.component.js +1 -1
  89. package/esm2015/login/components/login/login.component.js +3 -3
  90. package/esm2015/marketing/components/promotion-detail/promotion-detail.component.js +2 -2
  91. package/esm2015/order/components/order-list/order-list.component.js +2 -2
  92. package/fesm2015/vendure-admin-ui-catalog.js +187 -158
  93. package/fesm2015/vendure-admin-ui-catalog.js.map +1 -1
  94. package/fesm2015/vendure-admin-ui-core.js +1824 -1359
  95. package/fesm2015/vendure-admin-ui-core.js.map +1 -1
  96. package/fesm2015/vendure-admin-ui-dashboard.js +3 -3
  97. package/fesm2015/vendure-admin-ui-dashboard.js.map +1 -1
  98. package/fesm2015/vendure-admin-ui-login.js +2 -2
  99. package/fesm2015/vendure-admin-ui-login.js.map +1 -1
  100. package/fesm2015/vendure-admin-ui-marketing.js +1 -1
  101. package/fesm2015/vendure-admin-ui-marketing.js.map +1 -1
  102. package/fesm2015/vendure-admin-ui-order.js +1 -1
  103. package/fesm2015/vendure-admin-ui-order.js.map +1 -1
  104. package/login/vendure-admin-ui-login.metadata.json +1 -1
  105. package/marketing/vendure-admin-ui-marketing.metadata.json +1 -1
  106. package/order/vendure-admin-ui-order.metadata.json +1 -1
  107. package/package.json +2 -2
  108. package/static/i18n-messages/cs.json +683 -673
  109. package/static/i18n-messages/de.json +683 -673
  110. package/static/i18n-messages/en.json +684 -674
  111. package/static/i18n-messages/es.json +683 -673
  112. package/static/i18n-messages/fr.json +683 -673
  113. package/static/i18n-messages/it.json +683 -673
  114. package/static/i18n-messages/pl.json +683 -673
  115. package/static/i18n-messages/pt_BR.json +683 -673
  116. package/static/i18n-messages/pt_PT.json +683 -673
  117. package/static/i18n-messages/ru.json +683 -673
  118. package/static/i18n-messages/uk.json +683 -673
  119. package/static/i18n-messages/zh_Hans.json +683 -673
  120. package/static/i18n-messages/zh_Hant.json +683 -673
  121. package/static/styles/global/_forms.scss +4 -5
  122. package/static/styles/global/_overrides.scss +5 -1
  123. package/static/styles/global/_utilities.scss +9 -0
  124. package/static/styles/theme/default.scss +13 -1
  125. package/static/theme.min.css +1 -1
  126. package/esm2015/catalog/components/product-search-input/product-search-input.component.js +0 -104
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Injector, isDevMode, Component, Inject, HostListener, ChangeDetectionStrategy, ComponentFactoryResolver, APP_INITIALIZER, ViewChild, ViewContainerRef, EventEmitter, Input, Output, NgModule, ChangeDetectorRef, HostBinding, ContentChild, forwardRef, TemplateRef, ContentChildren, Directive, ElementRef, Optional, SkipSelf, ViewChildren, Pipe, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2
+ import { Injectable, Injector, isDevMode, Component, Inject, HostListener, ChangeDetectionStrategy, ComponentFactoryResolver, APP_INITIALIZER, ViewChild, ViewContainerRef, EventEmitter, Input, Output, NgModule, ChangeDetectorRef, forwardRef, Optional, HostBinding, ContentChild, TemplateRef, ContentChildren, Directive, ElementRef, SkipSelf, ViewChildren, Pipe, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { Location, DOCUMENT, CommonModule, PlatformLocation } from '@angular/common';
5
5
  import { map, filter, distinctUntilChanged, skip, takeUntil, tap, take, finalize, concatMap, bufferCount, switchMap, mergeMap, mapTo, catchError, startWith, throttleTime, shareReplay, scan, debounceTime, delay } from 'rxjs/operators';
@@ -22,7 +22,7 @@ import * as i1$4 from '@angular/router';
22
22
  import { Router, NavigationEnd, PRIMARY_OUTLET, ActivatedRoute, RouterModule, ActivationStart } from '@angular/router';
23
23
  import { DEFAULT_CHANNEL_CODE, DEFAULT_AUTH_TOKEN_HEADER_KEY } from '@vendure/common/lib/shared-constants';
24
24
  import { flatten } from 'lodash';
25
- import { FormControl, NG_VALUE_ACCESSOR, FormBuilder, FormGroup, Validators, NG_VALIDATORS, NgControl, FormControlName, FormControlDirective, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
25
+ import { FormControl, FormGroup, Validators, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormBuilder, NgControl, FormControlName, FormControlDirective, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
26
26
  import { marker } from '@biesbjerg/ngx-translate-extract-marker';
27
27
  import { setContext } from '@apollo/client/link/context';
28
28
  import { ApolloLink as ApolloLink$1 } from '@apollo/client/link/core';
@@ -252,35 +252,36 @@ class AdministratorDataService {
252
252
  }
253
253
  }
254
254
 
255
- const CONFIGURABLE_OPERATION_FRAGMENT = gql `
256
- fragment ConfigurableOperation on ConfigurableOperation {
257
- args {
258
- name
259
- value
260
- }
261
- code
262
- }
255
+ const CONFIGURABLE_OPERATION_FRAGMENT = gql `
256
+ fragment ConfigurableOperation on ConfigurableOperation {
257
+ args {
258
+ name
259
+ value
260
+ }
261
+ code
262
+ }
263
263
  `;
264
- const CONFIGURABLE_OPERATION_DEF_FRAGMENT = gql `
265
- fragment ConfigurableOperationDef on ConfigurableOperationDefinition {
266
- args {
267
- name
268
- type
269
- required
270
- defaultValue
271
- list
272
- ui
273
- label
274
- }
275
- code
276
- description
277
- }
264
+ const CONFIGURABLE_OPERATION_DEF_FRAGMENT = gql `
265
+ fragment ConfigurableOperationDef on ConfigurableOperationDefinition {
266
+ args {
267
+ name
268
+ type
269
+ required
270
+ defaultValue
271
+ list
272
+ ui
273
+ label
274
+ description
275
+ }
276
+ code
277
+ description
278
+ }
278
279
  `;
279
- const ERROR_RESULT_FRAGMENT = gql `
280
- fragment ErrorResult on ErrorResult {
281
- errorCode
282
- message
283
- }
280
+ const ERROR_RESULT_FRAGMENT = gql `
281
+ fragment ErrorResult on ErrorResult {
282
+ errorCode
283
+ message
284
+ }
284
285
  `;
285
286
 
286
287
  const CURRENT_USER_FRAGMENT = gql `
@@ -2650,11 +2651,28 @@ const GET_COLLECTION_CONTENTS = gql `
2650
2651
  id
2651
2652
  productId
2652
2653
  name
2654
+ sku
2653
2655
  }
2654
2656
  totalItems
2655
2657
  }
2656
2658
  }
2657
2659
  }
2660
+ `;
2661
+ const PREVIEW_COLLECTION_CONTENTS = gql `
2662
+ query PreviewCollectionContents(
2663
+ $input: PreviewCollectionVariantsInput!
2664
+ $options: ProductVariantListOptions
2665
+ ) {
2666
+ previewCollectionVariants(input: $input, options: $options) {
2667
+ items {
2668
+ id
2669
+ productId
2670
+ name
2671
+ sku
2672
+ }
2673
+ totalItems
2674
+ }
2675
+ }
2658
2676
  `;
2659
2677
 
2660
2678
  class CollectionDataService {
@@ -2710,6 +2728,9 @@ class CollectionDataService {
2710
2728
  id,
2711
2729
  });
2712
2730
  }
2731
+ previewCollectionVariants(input, options) {
2732
+ return this.baseDataService.query(PREVIEW_COLLECTION_CONTENTS, { input, options });
2733
+ }
2713
2734
  getCollectionContents(id, take = 10, skip = 0, filterTerm) {
2714
2735
  const filter = filterTerm
2715
2736
  ? { name: { contains: filterTerm } }
@@ -3271,469 +3292,470 @@ class FacetDataService {
3271
3292
  }
3272
3293
  }
3273
3294
 
3274
- const DISCOUNT_FRAGMENT = gql `
3275
- fragment Discount on Discount {
3276
- adjustmentSource
3277
- amount
3278
- amountWithTax
3279
- description
3280
- type
3281
- }
3295
+ const DISCOUNT_FRAGMENT = gql `
3296
+ fragment Discount on Discount {
3297
+ adjustmentSource
3298
+ amount
3299
+ amountWithTax
3300
+ description
3301
+ type
3302
+ }
3282
3303
  `;
3283
- const REFUND_FRAGMENT = gql `
3284
- fragment Refund on Refund {
3285
- id
3286
- state
3287
- items
3288
- shipping
3289
- adjustment
3290
- transactionId
3291
- paymentId
3292
- }
3304
+ const REFUND_FRAGMENT = gql `
3305
+ fragment Refund on Refund {
3306
+ id
3307
+ state
3308
+ items
3309
+ shipping
3310
+ adjustment
3311
+ transactionId
3312
+ paymentId
3313
+ }
3293
3314
  `;
3294
- const ORDER_ADDRESS_FRAGMENT = gql `
3295
- fragment OrderAddress on OrderAddress {
3296
- fullName
3297
- company
3298
- streetLine1
3299
- streetLine2
3300
- city
3301
- province
3302
- postalCode
3303
- country
3304
- countryCode
3305
- phoneNumber
3306
- }
3315
+ const ORDER_ADDRESS_FRAGMENT = gql `
3316
+ fragment OrderAddress on OrderAddress {
3317
+ fullName
3318
+ company
3319
+ streetLine1
3320
+ streetLine2
3321
+ city
3322
+ province
3323
+ postalCode
3324
+ country
3325
+ countryCode
3326
+ phoneNumber
3327
+ }
3307
3328
  `;
3308
- const ORDER_FRAGMENT = gql `
3309
- fragment Order on Order {
3310
- id
3311
- createdAt
3312
- updatedAt
3313
- orderPlacedAt
3314
- code
3315
- state
3316
- nextStates
3317
- total
3318
- currencyCode
3319
- customer {
3320
- id
3321
- firstName
3322
- lastName
3323
- }
3324
- shippingLines {
3325
- shippingMethod {
3326
- name
3327
- }
3328
- }
3329
- }
3329
+ const ORDER_FRAGMENT = gql `
3330
+ fragment Order on Order {
3331
+ id
3332
+ createdAt
3333
+ updatedAt
3334
+ orderPlacedAt
3335
+ code
3336
+ state
3337
+ nextStates
3338
+ total
3339
+ totalWithTax
3340
+ currencyCode
3341
+ customer {
3342
+ id
3343
+ firstName
3344
+ lastName
3345
+ }
3346
+ shippingLines {
3347
+ shippingMethod {
3348
+ name
3349
+ }
3350
+ }
3351
+ }
3330
3352
  `;
3331
- const FULFILLMENT_FRAGMENT = gql `
3332
- fragment Fulfillment on Fulfillment {
3333
- id
3334
- state
3335
- nextStates
3336
- createdAt
3337
- updatedAt
3338
- method
3339
- orderItems {
3340
- id
3341
- }
3342
- trackingCode
3343
- }
3353
+ const FULFILLMENT_FRAGMENT = gql `
3354
+ fragment Fulfillment on Fulfillment {
3355
+ id
3356
+ state
3357
+ nextStates
3358
+ createdAt
3359
+ updatedAt
3360
+ method
3361
+ orderItems {
3362
+ id
3363
+ }
3364
+ trackingCode
3365
+ }
3344
3366
  `;
3345
- const ORDER_LINE_FRAGMENT = gql `
3346
- fragment OrderLine on OrderLine {
3347
- id
3348
- featuredAsset {
3349
- preview
3350
- }
3351
- productVariant {
3352
- id
3353
- name
3354
- sku
3355
- trackInventory
3356
- stockOnHand
3357
- }
3358
- discounts {
3359
- ...Discount
3360
- }
3361
- unitPrice
3362
- unitPriceWithTax
3363
- proratedUnitPrice
3364
- proratedUnitPriceWithTax
3365
- quantity
3366
- items {
3367
- id
3368
- unitPrice
3369
- unitPriceWithTax
3370
- taxRate
3371
- refundId
3372
- cancelled
3373
- fulfillment {
3374
- ...Fulfillment
3375
- }
3376
- }
3377
- linePrice
3378
- lineTax
3379
- linePriceWithTax
3380
- discountedLinePrice
3381
- discountedLinePriceWithTax
3382
- }
3367
+ const ORDER_LINE_FRAGMENT = gql `
3368
+ fragment OrderLine on OrderLine {
3369
+ id
3370
+ featuredAsset {
3371
+ preview
3372
+ }
3373
+ productVariant {
3374
+ id
3375
+ name
3376
+ sku
3377
+ trackInventory
3378
+ stockOnHand
3379
+ }
3380
+ discounts {
3381
+ ...Discount
3382
+ }
3383
+ unitPrice
3384
+ unitPriceWithTax
3385
+ proratedUnitPrice
3386
+ proratedUnitPriceWithTax
3387
+ quantity
3388
+ items {
3389
+ id
3390
+ unitPrice
3391
+ unitPriceWithTax
3392
+ taxRate
3393
+ refundId
3394
+ cancelled
3395
+ fulfillment {
3396
+ ...Fulfillment
3397
+ }
3398
+ }
3399
+ linePrice
3400
+ lineTax
3401
+ linePriceWithTax
3402
+ discountedLinePrice
3403
+ discountedLinePriceWithTax
3404
+ }
3383
3405
  `;
3384
- const ORDER_DETAIL_FRAGMENT = gql `
3385
- fragment OrderDetail on Order {
3386
- id
3387
- createdAt
3388
- updatedAt
3389
- code
3390
- state
3391
- nextStates
3392
- active
3393
- couponCodes
3394
- customer {
3395
- id
3396
- firstName
3397
- lastName
3398
- }
3399
- lines {
3400
- ...OrderLine
3401
- }
3402
- surcharges {
3403
- id
3404
- sku
3405
- description
3406
- price
3407
- priceWithTax
3408
- taxRate
3409
- }
3410
- discounts {
3411
- ...Discount
3412
- }
3413
- promotions {
3414
- id
3415
- couponCode
3416
- }
3417
- subTotal
3418
- subTotalWithTax
3419
- total
3420
- totalWithTax
3421
- currencyCode
3422
- shipping
3423
- shippingWithTax
3424
- shippingLines {
3425
- shippingMethod {
3426
- id
3427
- code
3428
- name
3429
- fulfillmentHandlerCode
3430
- description
3431
- }
3432
- }
3433
- taxSummary {
3434
- description
3435
- taxBase
3436
- taxRate
3437
- taxTotal
3438
- }
3439
- shippingAddress {
3440
- ...OrderAddress
3441
- }
3442
- billingAddress {
3443
- ...OrderAddress
3444
- }
3445
- payments {
3446
- id
3447
- createdAt
3448
- transactionId
3449
- amount
3450
- method
3451
- state
3452
- nextStates
3453
- errorMessage
3454
- metadata
3455
- refunds {
3456
- id
3457
- createdAt
3458
- state
3459
- items
3460
- adjustment
3461
- total
3462
- paymentId
3463
- reason
3464
- transactionId
3465
- method
3466
- metadata
3467
- orderItems {
3468
- id
3469
- }
3470
- }
3471
- }
3472
- fulfillments {
3473
- ...Fulfillment
3474
- }
3475
- modifications {
3476
- id
3477
- createdAt
3478
- isSettled
3479
- priceChange
3480
- note
3481
- payment {
3482
- id
3483
- amount
3484
- }
3485
- orderItems {
3486
- id
3487
- }
3488
- refund {
3489
- id
3490
- paymentId
3491
- total
3492
- }
3493
- surcharges {
3494
- id
3495
- }
3496
- }
3497
- }
3498
- ${DISCOUNT_FRAGMENT}
3499
- ${ORDER_ADDRESS_FRAGMENT}
3500
- ${FULFILLMENT_FRAGMENT}
3501
- ${ORDER_LINE_FRAGMENT}
3406
+ const ORDER_DETAIL_FRAGMENT = gql `
3407
+ fragment OrderDetail on Order {
3408
+ id
3409
+ createdAt
3410
+ updatedAt
3411
+ code
3412
+ state
3413
+ nextStates
3414
+ active
3415
+ couponCodes
3416
+ customer {
3417
+ id
3418
+ firstName
3419
+ lastName
3420
+ }
3421
+ lines {
3422
+ ...OrderLine
3423
+ }
3424
+ surcharges {
3425
+ id
3426
+ sku
3427
+ description
3428
+ price
3429
+ priceWithTax
3430
+ taxRate
3431
+ }
3432
+ discounts {
3433
+ ...Discount
3434
+ }
3435
+ promotions {
3436
+ id
3437
+ couponCode
3438
+ }
3439
+ subTotal
3440
+ subTotalWithTax
3441
+ total
3442
+ totalWithTax
3443
+ currencyCode
3444
+ shipping
3445
+ shippingWithTax
3446
+ shippingLines {
3447
+ shippingMethod {
3448
+ id
3449
+ code
3450
+ name
3451
+ fulfillmentHandlerCode
3452
+ description
3453
+ }
3454
+ }
3455
+ taxSummary {
3456
+ description
3457
+ taxBase
3458
+ taxRate
3459
+ taxTotal
3460
+ }
3461
+ shippingAddress {
3462
+ ...OrderAddress
3463
+ }
3464
+ billingAddress {
3465
+ ...OrderAddress
3466
+ }
3467
+ payments {
3468
+ id
3469
+ createdAt
3470
+ transactionId
3471
+ amount
3472
+ method
3473
+ state
3474
+ nextStates
3475
+ errorMessage
3476
+ metadata
3477
+ refunds {
3478
+ id
3479
+ createdAt
3480
+ state
3481
+ items
3482
+ adjustment
3483
+ total
3484
+ paymentId
3485
+ reason
3486
+ transactionId
3487
+ method
3488
+ metadata
3489
+ orderItems {
3490
+ id
3491
+ }
3492
+ }
3493
+ }
3494
+ fulfillments {
3495
+ ...Fulfillment
3496
+ }
3497
+ modifications {
3498
+ id
3499
+ createdAt
3500
+ isSettled
3501
+ priceChange
3502
+ note
3503
+ payment {
3504
+ id
3505
+ amount
3506
+ }
3507
+ orderItems {
3508
+ id
3509
+ }
3510
+ refund {
3511
+ id
3512
+ paymentId
3513
+ total
3514
+ }
3515
+ surcharges {
3516
+ id
3517
+ }
3518
+ }
3519
+ }
3520
+ ${DISCOUNT_FRAGMENT}
3521
+ ${ORDER_ADDRESS_FRAGMENT}
3522
+ ${FULFILLMENT_FRAGMENT}
3523
+ ${ORDER_LINE_FRAGMENT}
3524
+ `;
3525
+ const GET_ORDERS_LIST = gql `
3526
+ query GetOrderList($options: OrderListOptions) {
3527
+ orders(options: $options) {
3528
+ items {
3529
+ ...Order
3530
+ }
3531
+ totalItems
3532
+ }
3533
+ }
3534
+ ${ORDER_FRAGMENT}
3502
3535
  `;
3503
- const GET_ORDERS_LIST = gql `
3504
- query GetOrderList($options: OrderListOptions) {
3505
- orders(options: $options) {
3506
- items {
3507
- ...Order
3508
- }
3509
- totalItems
3510
- }
3511
- }
3512
- ${ORDER_FRAGMENT}
3536
+ const GET_ORDER = gql `
3537
+ query GetOrder($id: ID!) {
3538
+ order(id: $id) {
3539
+ ...OrderDetail
3540
+ }
3541
+ }
3542
+ ${ORDER_DETAIL_FRAGMENT}
3543
+ `;
3544
+ const SETTLE_PAYMENT = gql `
3545
+ mutation SettlePayment($id: ID!) {
3546
+ settlePayment(id: $id) {
3547
+ ... on Payment {
3548
+ id
3549
+ transactionId
3550
+ amount
3551
+ method
3552
+ state
3553
+ metadata
3554
+ }
3555
+ ...ErrorResult
3556
+ ... on SettlePaymentError {
3557
+ paymentErrorMessage
3558
+ }
3559
+ ... on PaymentStateTransitionError {
3560
+ transitionError
3561
+ }
3562
+ ... on OrderStateTransitionError {
3563
+ transitionError
3564
+ }
3565
+ }
3566
+ }
3567
+ ${ERROR_RESULT_FRAGMENT}
3568
+ `;
3569
+ const TRANSITION_PAYMENT_TO_STATE = gql `
3570
+ mutation TransitionPaymentToState($id: ID!, $state: String!) {
3571
+ transitionPaymentToState(id: $id, state: $state) {
3572
+ ... on Payment {
3573
+ id
3574
+ transactionId
3575
+ amount
3576
+ method
3577
+ state
3578
+ metadata
3579
+ }
3580
+ ...ErrorResult
3581
+ ... on PaymentStateTransitionError {
3582
+ transitionError
3583
+ }
3584
+ }
3585
+ }
3586
+ ${ERROR_RESULT_FRAGMENT}
3587
+ `;
3588
+ const CREATE_FULFILLMENT = gql `
3589
+ mutation CreateFulfillment($input: FulfillOrderInput!) {
3590
+ addFulfillmentToOrder(input: $input) {
3591
+ ...Fulfillment
3592
+ ... on CreateFulfillmentError {
3593
+ errorCode
3594
+ message
3595
+ fulfillmentHandlerError
3596
+ }
3597
+ ... on FulfillmentStateTransitionError {
3598
+ errorCode
3599
+ message
3600
+ transitionError
3601
+ }
3602
+ ...ErrorResult
3603
+ }
3604
+ }
3605
+ ${FULFILLMENT_FRAGMENT}
3606
+ ${ERROR_RESULT_FRAGMENT}
3607
+ `;
3608
+ const CANCEL_ORDER = gql `
3609
+ mutation CancelOrder($input: CancelOrderInput!) {
3610
+ cancelOrder(input: $input) {
3611
+ ...OrderDetail
3612
+ ...ErrorResult
3613
+ }
3614
+ }
3615
+ ${ORDER_DETAIL_FRAGMENT}
3616
+ ${ERROR_RESULT_FRAGMENT}
3617
+ `;
3618
+ const REFUND_ORDER = gql `
3619
+ mutation RefundOrder($input: RefundOrderInput!) {
3620
+ refundOrder(input: $input) {
3621
+ ...Refund
3622
+ ...ErrorResult
3623
+ }
3624
+ }
3625
+ ${REFUND_FRAGMENT}
3626
+ ${ERROR_RESULT_FRAGMENT}
3627
+ `;
3628
+ const SETTLE_REFUND = gql `
3629
+ mutation SettleRefund($input: SettleRefundInput!) {
3630
+ settleRefund(input: $input) {
3631
+ ...Refund
3632
+ ...ErrorResult
3633
+ }
3634
+ }
3635
+ ${REFUND_FRAGMENT}
3636
+ ${ERROR_RESULT_FRAGMENT}
3637
+ `;
3638
+ const GET_ORDER_HISTORY = gql `
3639
+ query GetOrderHistory($id: ID!, $options: HistoryEntryListOptions) {
3640
+ order(id: $id) {
3641
+ id
3642
+ history(options: $options) {
3643
+ totalItems
3644
+ items {
3645
+ id
3646
+ type
3647
+ createdAt
3648
+ isPublic
3649
+ administrator {
3650
+ id
3651
+ firstName
3652
+ lastName
3653
+ }
3654
+ data
3655
+ }
3656
+ }
3657
+ }
3658
+ }
3513
3659
  `;
3514
- const GET_ORDER = gql `
3515
- query GetOrder($id: ID!) {
3516
- order(id: $id) {
3517
- ...OrderDetail
3518
- }
3519
- }
3520
- ${ORDER_DETAIL_FRAGMENT}
3660
+ const ADD_NOTE_TO_ORDER = gql `
3661
+ mutation AddNoteToOrder($input: AddNoteToOrderInput!) {
3662
+ addNoteToOrder(input: $input) {
3663
+ id
3664
+ }
3665
+ }
3521
3666
  `;
3522
- const SETTLE_PAYMENT = gql `
3523
- mutation SettlePayment($id: ID!) {
3524
- settlePayment(id: $id) {
3525
- ... on Payment {
3526
- id
3527
- transactionId
3528
- amount
3529
- method
3530
- state
3531
- metadata
3532
- }
3533
- ...ErrorResult
3534
- ... on SettlePaymentError {
3535
- paymentErrorMessage
3536
- }
3537
- ... on PaymentStateTransitionError {
3538
- transitionError
3539
- }
3540
- ... on OrderStateTransitionError {
3541
- transitionError
3542
- }
3543
- }
3544
- }
3545
- ${ERROR_RESULT_FRAGMENT}
3667
+ const UPDATE_ORDER_NOTE = gql `
3668
+ mutation UpdateOrderNote($input: UpdateOrderNoteInput!) {
3669
+ updateOrderNote(input: $input) {
3670
+ id
3671
+ data
3672
+ isPublic
3673
+ }
3674
+ }
3546
3675
  `;
3547
- const TRANSITION_PAYMENT_TO_STATE = gql `
3548
- mutation TransitionPaymentToState($id: ID!, $state: String!) {
3549
- transitionPaymentToState(id: $id, state: $state) {
3550
- ... on Payment {
3551
- id
3552
- transactionId
3553
- amount
3554
- method
3555
- state
3556
- metadata
3557
- }
3558
- ...ErrorResult
3559
- ... on PaymentStateTransitionError {
3560
- transitionError
3561
- }
3562
- }
3563
- }
3564
- ${ERROR_RESULT_FRAGMENT}
3676
+ const DELETE_ORDER_NOTE = gql `
3677
+ mutation DeleteOrderNote($id: ID!) {
3678
+ deleteOrderNote(id: $id) {
3679
+ result
3680
+ message
3681
+ }
3682
+ }
3565
3683
  `;
3566
- const CREATE_FULFILLMENT = gql `
3567
- mutation CreateFulfillment($input: FulfillOrderInput!) {
3568
- addFulfillmentToOrder(input: $input) {
3569
- ...Fulfillment
3570
- ... on CreateFulfillmentError {
3571
- errorCode
3572
- message
3573
- fulfillmentHandlerError
3574
- }
3575
- ... on FulfillmentStateTransitionError {
3576
- errorCode
3577
- message
3578
- transitionError
3579
- }
3580
- ...ErrorResult
3581
- }
3582
- }
3583
- ${FULFILLMENT_FRAGMENT}
3584
- ${ERROR_RESULT_FRAGMENT}
3684
+ const TRANSITION_ORDER_TO_STATE = gql `
3685
+ mutation TransitionOrderToState($id: ID!, $state: String!) {
3686
+ transitionOrderToState(id: $id, state: $state) {
3687
+ ...Order
3688
+ ...ErrorResult
3689
+ ... on OrderStateTransitionError {
3690
+ transitionError
3691
+ }
3692
+ }
3693
+ }
3694
+ ${ORDER_FRAGMENT}
3695
+ ${ERROR_RESULT_FRAGMENT}
3585
3696
  `;
3586
- const CANCEL_ORDER = gql `
3587
- mutation CancelOrder($input: CancelOrderInput!) {
3588
- cancelOrder(input: $input) {
3589
- ...OrderDetail
3590
- ...ErrorResult
3591
- }
3592
- }
3593
- ${ORDER_DETAIL_FRAGMENT}
3594
- ${ERROR_RESULT_FRAGMENT}
3697
+ const UPDATE_ORDER_CUSTOM_FIELDS = gql `
3698
+ mutation UpdateOrderCustomFields($input: UpdateOrderInput!) {
3699
+ setOrderCustomFields(input: $input) {
3700
+ ...Order
3701
+ }
3702
+ }
3703
+ ${ORDER_FRAGMENT}
3704
+ `;
3705
+ const TRANSITION_FULFILLMENT_TO_STATE = gql `
3706
+ mutation TransitionFulfillmentToState($id: ID!, $state: String!) {
3707
+ transitionFulfillmentToState(id: $id, state: $state) {
3708
+ ...Fulfillment
3709
+ ...ErrorResult
3710
+ ... on FulfillmentStateTransitionError {
3711
+ transitionError
3712
+ }
3713
+ }
3714
+ }
3715
+ ${FULFILLMENT_FRAGMENT}
3716
+ ${ERROR_RESULT_FRAGMENT}
3717
+ `;
3718
+ const GET_ORDER_SUMMARY = gql `
3719
+ query GetOrderSummary($start: DateTime!, $end: DateTime!) {
3720
+ orders(options: { filter: { orderPlacedAt: { between: { start: $start, end: $end } } } }) {
3721
+ totalItems
3722
+ items {
3723
+ id
3724
+ total
3725
+ currencyCode
3726
+ }
3727
+ }
3728
+ }
3595
3729
  `;
3596
- const REFUND_ORDER = gql `
3597
- mutation RefundOrder($input: RefundOrderInput!) {
3598
- refundOrder(input: $input) {
3599
- ...Refund
3600
- ...ErrorResult
3601
- }
3730
+ const MODIFY_ORDER = gql `
3731
+ mutation ModifyOrder($input: ModifyOrderInput!) {
3732
+ modifyOrder(input: $input) {
3733
+ ...OrderDetail
3734
+ ...ErrorResult
3735
+ }
3736
+ }
3737
+ ${ORDER_DETAIL_FRAGMENT}
3738
+ ${ERROR_RESULT_FRAGMENT}
3739
+ `;
3740
+ const ADD_MANUAL_PAYMENT_TO_ORDER = gql `
3741
+ mutation AddManualPayment($input: ManualPaymentInput!) {
3742
+ addManualPaymentToOrder(input: $input) {
3743
+ ...OrderDetail
3744
+ ...ErrorResult
3745
+ }
3746
+ }
3747
+ ${ORDER_DETAIL_FRAGMENT}
3748
+ ${ERROR_RESULT_FRAGMENT}
3749
+ `;
3750
+
3751
+ class OrderDataService {
3752
+ constructor(baseDataService) {
3753
+ this.baseDataService = baseDataService;
3602
3754
  }
3603
- ${REFUND_FRAGMENT}
3604
- ${ERROR_RESULT_FRAGMENT}
3605
- `;
3606
- const SETTLE_REFUND = gql `
3607
- mutation SettleRefund($input: SettleRefundInput!) {
3608
- settleRefund(input: $input) {
3609
- ...Refund
3610
- ...ErrorResult
3611
- }
3612
- }
3613
- ${REFUND_FRAGMENT}
3614
- ${ERROR_RESULT_FRAGMENT}
3615
- `;
3616
- const GET_ORDER_HISTORY = gql `
3617
- query GetOrderHistory($id: ID!, $options: HistoryEntryListOptions) {
3618
- order(id: $id) {
3619
- id
3620
- history(options: $options) {
3621
- totalItems
3622
- items {
3623
- id
3624
- type
3625
- createdAt
3626
- isPublic
3627
- administrator {
3628
- id
3629
- firstName
3630
- lastName
3631
- }
3632
- data
3633
- }
3634
- }
3635
- }
3636
- }
3637
- `;
3638
- const ADD_NOTE_TO_ORDER = gql `
3639
- mutation AddNoteToOrder($input: AddNoteToOrderInput!) {
3640
- addNoteToOrder(input: $input) {
3641
- id
3642
- }
3643
- }
3644
- `;
3645
- const UPDATE_ORDER_NOTE = gql `
3646
- mutation UpdateOrderNote($input: UpdateOrderNoteInput!) {
3647
- updateOrderNote(input: $input) {
3648
- id
3649
- data
3650
- isPublic
3651
- }
3652
- }
3653
- `;
3654
- const DELETE_ORDER_NOTE = gql `
3655
- mutation DeleteOrderNote($id: ID!) {
3656
- deleteOrderNote(id: $id) {
3657
- result
3658
- message
3659
- }
3660
- }
3661
- `;
3662
- const TRANSITION_ORDER_TO_STATE = gql `
3663
- mutation TransitionOrderToState($id: ID!, $state: String!) {
3664
- transitionOrderToState(id: $id, state: $state) {
3665
- ...Order
3666
- ...ErrorResult
3667
- ... on OrderStateTransitionError {
3668
- transitionError
3669
- }
3670
- }
3671
- }
3672
- ${ORDER_FRAGMENT}
3673
- ${ERROR_RESULT_FRAGMENT}
3674
- `;
3675
- const UPDATE_ORDER_CUSTOM_FIELDS = gql `
3676
- mutation UpdateOrderCustomFields($input: UpdateOrderInput!) {
3677
- setOrderCustomFields(input: $input) {
3678
- ...Order
3679
- }
3680
- }
3681
- ${ORDER_FRAGMENT}
3682
- `;
3683
- const TRANSITION_FULFILLMENT_TO_STATE = gql `
3684
- mutation TransitionFulfillmentToState($id: ID!, $state: String!) {
3685
- transitionFulfillmentToState(id: $id, state: $state) {
3686
- ...Fulfillment
3687
- ...ErrorResult
3688
- ... on FulfillmentStateTransitionError {
3689
- transitionError
3690
- }
3691
- }
3692
- }
3693
- ${FULFILLMENT_FRAGMENT}
3694
- ${ERROR_RESULT_FRAGMENT}
3695
- `;
3696
- const GET_ORDER_SUMMARY = gql `
3697
- query GetOrderSummary($start: DateTime!, $end: DateTime!) {
3698
- orders(options: { filter: { orderPlacedAt: { between: { start: $start, end: $end } } } }) {
3699
- totalItems
3700
- items {
3701
- id
3702
- total
3703
- currencyCode
3704
- }
3705
- }
3706
- }
3707
- `;
3708
- const MODIFY_ORDER = gql `
3709
- mutation ModifyOrder($input: ModifyOrderInput!) {
3710
- modifyOrder(input: $input) {
3711
- ...OrderDetail
3712
- ...ErrorResult
3713
- }
3714
- }
3715
- ${ORDER_DETAIL_FRAGMENT}
3716
- ${ERROR_RESULT_FRAGMENT}
3717
- `;
3718
- const ADD_MANUAL_PAYMENT_TO_ORDER = gql `
3719
- mutation AddManualPayment($input: ManualPaymentInput!) {
3720
- addManualPaymentToOrder(input: $input) {
3721
- ...OrderDetail
3722
- ...ErrorResult
3723
- }
3724
- }
3725
- ${ORDER_DETAIL_FRAGMENT}
3726
- ${ERROR_RESULT_FRAGMENT}
3727
- `;
3728
-
3729
- class OrderDataService {
3730
- constructor(baseDataService) {
3731
- this.baseDataService = baseDataService;
3732
- }
3733
- getOrders(options = { take: 10 }) {
3734
- return this.baseDataService.query(GET_ORDERS_LIST, {
3735
- options,
3736
- });
3755
+ getOrders(options = { take: 10 }) {
3756
+ return this.baseDataService.query(GET_ORDERS_LIST, {
3757
+ options,
3758
+ });
3737
3759
  }
3738
3760
  getOrder(id) {
3739
3761
  return this.baseDataService.query(GET_ORDER, { id });
@@ -6384,6 +6406,7 @@ class AppShellComponent {
6384
6406
  this.modalService = modalService;
6385
6407
  this.localStorageService = localStorageService;
6386
6408
  this.availableLanguages = [];
6409
+ this.hideVendureBranding = getAppConfig().hideVendureBranding;
6387
6410
  }
6388
6411
  ngOnInit() {
6389
6412
  this.userName$ = this.dataService.client
@@ -6429,8 +6452,8 @@ class AppShellComponent {
6429
6452
  AppShellComponent.decorators = [
6430
6453
  { type: Component, args: [{
6431
6454
  selector: 'vdr-app-shell',
6432
- template: "<clr-main-container>\r\n <clr-header>\r\n <div class=\"branding\">\r\n <a [routerLink]=\"['/']\"><img src=\"assets/logo-75px.png\" class=\"logo\" /></a>\r\n </div>\r\n <div class=\"header-nav\"></div>\r\n <div class=\"header-actions\">\r\n <vdr-channel-switcher *vdrIfMultichannel></vdr-channel-switcher>\r\n <vdr-user-menu [userName]=\"userName$ | async\"\r\n [uiLanguageAndLocale]=\"uiLanguageAndLocale$ | async\"\r\n [availableLanguages]=\"availableLanguages\"\r\n (selectUiLanguage)=\"selectUiLanguage()\"\r\n (logOut)=\"logOut()\"></vdr-user-menu>\r\n </div>\r\n </clr-header>\r\n <nav class=\"subnav\"><vdr-breadcrumb></vdr-breadcrumb></nav>\r\n\r\n <div class=\"content-container\">\r\n <div class=\"content-area\"><router-outlet></router-outlet></div>\r\n <vdr-main-nav></vdr-main-nav>\r\n </div>\r\n</clr-main-container>\r\n",
6433
- styles: [".branding{min-width:0}.logo{width:60px}@media screen and (min-width: 768px){vdr-breadcrumb{margin-left:10.8rem}}.header-actions{align-items:center}.content-area{position:relative}\n"]
6455
+ template: "<clr-main-container>\r\n <clr-header>\r\n <div class=\"branding\">\r\n <a [routerLink]=\"['/']\"><img src=\"assets/logo-75px.png\" class=\"logo\" /><span class=\"wordmark\" *ngIf=\"!hideVendureBranding\">vendure</span></a>\r\n </div>\r\n <div class=\"header-nav\"></div>\r\n <div class=\"header-actions\">\r\n <vdr-channel-switcher *vdrIfMultichannel></vdr-channel-switcher>\r\n <vdr-user-menu [userName]=\"userName$ | async\"\r\n [uiLanguageAndLocale]=\"uiLanguageAndLocale$ | async\"\r\n [availableLanguages]=\"availableLanguages\"\r\n (selectUiLanguage)=\"selectUiLanguage()\"\r\n (logOut)=\"logOut()\"></vdr-user-menu>\r\n </div>\r\n </clr-header>\r\n <nav class=\"subnav\"><vdr-breadcrumb></vdr-breadcrumb></nav>\r\n\r\n <div class=\"content-container\">\r\n <div class=\"content-area\"><router-outlet></router-outlet></div>\r\n <vdr-main-nav></vdr-main-nav>\r\n </div>\r\n</clr-main-container>\r\n",
6456
+ styles: [".branding{min-width:0}.logo{width:40px}.wordmark{font-weight:bold;margin-left:12px;font-size:24px;color:var(--color-primary-500)}@media screen and (min-width: 768px){vdr-breadcrumb{margin-left:10.8rem}}.header-actions{align-items:center}.content-area{position:relative}::ng-deep .header{background-image:linear-gradient(to right,var(--color-header-gradient-from),var(--color-header-gradient-to))}\n"]
6434
6457
  },] }
6435
6458
  ];
6436
6459
  AppShellComponent.ctorParameters = () => [
@@ -7248,7 +7271,7 @@ class MainNavComponent {
7248
7271
  MainNavComponent.decorators = [
7249
7272
  { type: Component, args: [{
7250
7273
  selector: 'vdr-main-nav',
7251
- template: "<nav class=\"sidenav\" [clr-nav-level]=\"2\">\r\n <section class=\"sidenav-content\">\r\n <ng-container *ngFor=\"let section of navBuilderService.navMenuConfig$ | async\">\r\n <section\r\n class=\"nav-group\"\r\n [attr.data-section-id]=\"section.id\"\r\n [class.collapsible]=\"section.collapsible\"\r\n *ngIf=\"shouldDisplayLink(section)\"\r\n >\r\n <vdr-ui-extension-point [locationId]=\"section.id\" api=\"navMenu\" [topPx]=\"-6\" [leftPx]=\"8\">\r\n <ng-container *ngIf=\"navBuilderService.sectionBadges[section.id] | async as sectionBadge\">\r\n <vdr-status-badge\r\n *ngIf=\"sectionBadge !== 'none'\"\r\n [type]=\"sectionBadge\"\r\n ></vdr-status-badge>\r\n </ng-container>\r\n <input [id]=\"section.id\" type=\"checkbox\" [checked]=\"section.collapsedByDefault\" />\r\n <label class=\"nav-group-header\" [for]=\"section.id\">{{ section.label | translate }}</label>\r\n <ul class=\"nav-list\">\r\n <ng-container *ngFor=\"let item of section.items\">\r\n <li *ngIf=\"shouldDisplayLink(item)\">\r\n <a\r\n class=\"nav-link\"\r\n [attr.data-item-id]=\"section.id\"\r\n [routerLink]=\"getRouterLink(item)\"\r\n routerLinkActive=\"active\"\r\n >\r\n <ng-container *ngIf=\"item.statusBadge | async as itemBadge\">\r\n <vdr-status-badge\r\n *ngIf=\"itemBadge.type !== 'none'\"\r\n [type]=\"itemBadge.type\"\r\n ></vdr-status-badge>\r\n </ng-container>\r\n <clr-icon [attr.shape]=\"item.icon || 'block'\" size=\"20\"></clr-icon>\r\n {{ item.label | translate }}\r\n </a>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </vdr-ui-extension-point>\r\n </section>\r\n </ng-container>\r\n </section>\r\n</nav>\r\n",
7274
+ template: "<nav class=\"sidenav\" [clr-nav-level]=\"2\">\r\n <section class=\"sidenav-content\">\r\n <ng-container *ngFor=\"let section of navBuilderService.navMenuConfig$ | async\">\r\n <section\r\n class=\"nav-group\"\r\n [attr.data-section-id]=\"section.id\"\r\n [class.collapsible]=\"section.collapsible\"\r\n *ngIf=\"shouldDisplayLink(section)\"\r\n >\r\n <vdr-ui-extension-point [locationId]=\"section.id\" api=\"navMenu\" [topPx]=\"-6\" [leftPx]=\"8\">\r\n <ng-container *ngIf=\"navBuilderService.sectionBadges[section.id] | async as sectionBadge\">\r\n <vdr-status-badge\r\n *ngIf=\"sectionBadge !== 'none'\"\r\n [type]=\"sectionBadge\"\r\n ></vdr-status-badge>\r\n </ng-container>\r\n <input [id]=\"section.id\" type=\"checkbox\" [checked]=\"section.collapsedByDefault\" />\r\n <label class=\"nav-group-header\" [for]=\"section.id\">{{ section.label | translate }}</label>\r\n <ul class=\"nav-list\">\r\n <ng-container *ngFor=\"let item of section.items\">\r\n <li *ngIf=\"shouldDisplayLink(item)\">\r\n <a\r\n class=\"nav-link\"\r\n [attr.data-item-id]=\"section.id\"\r\n [routerLink]=\"getRouterLink(item)\"\r\n routerLinkActive=\"active\"\r\n (click)=\"item.onClick && item.onClick($event)\"\r\n >\r\n <ng-container *ngIf=\"item.statusBadge | async as itemBadge\">\r\n <vdr-status-badge\r\n *ngIf=\"itemBadge.type !== 'none'\"\r\n [type]=\"itemBadge.type\"\r\n ></vdr-status-badge>\r\n </ng-container>\r\n <clr-icon [attr.shape]=\"item.icon || 'block'\" size=\"20\"></clr-icon>\r\n {{ item.label | translate }}\r\n </a>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </vdr-ui-extension-point>\r\n </section>\r\n </ng-container>\r\n </section>\r\n</nav>\r\n",
7252
7275
  styles: [":host{order:-1;background-color:var(--clr-nav-background-color)}nav.sidenav{height:100%;width:10.8rem;border-right-color:var(--clr-sidenav-border-color)}.sidenav .nav-group .nav-list{margin:0}.sidenav .nav-group .nav-group-header{margin:0;line-height:1.2}.sidenav .nav-group .nav-link{display:inline-flex;line-height:1rem;padding-right:.6rem}.nav-list clr-icon{flex-shrink:0;margin-right:12px}.nav-group{-webkit-hyphens:auto;hyphens:auto}.nav-group,.nav-link{position:relative}.nav-group vdr-status-badge{left:10px;top:6px}.nav-link vdr-status-badge{left:25px;top:3px}\n"]
7253
7276
  },] }
7254
7277
  ];
@@ -7404,194 +7427,260 @@ UserMenuComponent.propDecorators = {
7404
7427
 
7405
7428
  // tslint:disable
7406
7429
  const result = {
7407
- possibleTypes: {
7408
- AddFulfillmentToOrderResult: [
7409
- 'Fulfillment',
7410
- 'EmptyOrderLineSelectionError',
7411
- 'ItemsAlreadyFulfilledError',
7412
- 'InsufficientStockOnHandError',
7413
- 'InvalidFulfillmentHandlerError',
7414
- 'FulfillmentStateTransitionError',
7415
- 'CreateFulfillmentError',
7430
+ "possibleTypes": {
7431
+ "AddFulfillmentToOrderResult": [
7432
+ "Fulfillment",
7433
+ "EmptyOrderLineSelectionError",
7434
+ "ItemsAlreadyFulfilledError",
7435
+ "InsufficientStockOnHandError",
7436
+ "InvalidFulfillmentHandlerError",
7437
+ "FulfillmentStateTransitionError",
7438
+ "CreateFulfillmentError"
7416
7439
  ],
7417
- AddManualPaymentToOrderResult: ['Order', 'ManualPaymentStateError'],
7418
- AuthenticationResult: ['CurrentUser', 'InvalidCredentialsError'],
7419
- CancelOrderResult: [
7420
- 'Order',
7421
- 'EmptyOrderLineSelectionError',
7422
- 'QuantityTooGreatError',
7423
- 'MultipleOrderError',
7424
- 'CancelActiveOrderError',
7425
- 'OrderStateTransitionError',
7440
+ "AddManualPaymentToOrderResult": [
7441
+ "Order",
7442
+ "ManualPaymentStateError"
7426
7443
  ],
7427
- CreateAssetResult: ['Asset', 'MimeTypeError'],
7428
- CreateChannelResult: ['Channel', 'LanguageNotAvailableError'],
7429
- CreateCustomerResult: ['Customer', 'EmailAddressConflictError'],
7430
- CreatePromotionResult: ['Promotion', 'MissingConditionsError'],
7431
- CustomField: [
7432
- 'BooleanCustomFieldConfig',
7433
- 'DateTimeCustomFieldConfig',
7434
- 'FloatCustomFieldConfig',
7435
- 'IntCustomFieldConfig',
7436
- 'LocaleStringCustomFieldConfig',
7437
- 'RelationCustomFieldConfig',
7438
- 'StringCustomFieldConfig',
7439
- 'TextCustomFieldConfig',
7444
+ "AuthenticationResult": [
7445
+ "CurrentUser",
7446
+ "InvalidCredentialsError"
7440
7447
  ],
7441
- CustomFieldConfig: [
7442
- 'StringCustomFieldConfig',
7443
- 'LocaleStringCustomFieldConfig',
7444
- 'IntCustomFieldConfig',
7445
- 'FloatCustomFieldConfig',
7446
- 'BooleanCustomFieldConfig',
7447
- 'DateTimeCustomFieldConfig',
7448
- 'RelationCustomFieldConfig',
7449
- 'TextCustomFieldConfig',
7448
+ "CancelOrderResult": [
7449
+ "Order",
7450
+ "EmptyOrderLineSelectionError",
7451
+ "QuantityTooGreatError",
7452
+ "MultipleOrderError",
7453
+ "CancelActiveOrderError",
7454
+ "OrderStateTransitionError"
7450
7455
  ],
7451
- ErrorResult: [
7452
- 'AlreadyRefundedError',
7453
- 'CancelActiveOrderError',
7454
- 'ChannelDefaultLanguageError',
7455
- 'CouponCodeExpiredError',
7456
- 'CouponCodeInvalidError',
7457
- 'CouponCodeLimitError',
7458
- 'CreateFulfillmentError',
7459
- 'EmailAddressConflictError',
7460
- 'EmptyOrderLineSelectionError',
7461
- 'FulfillmentStateTransitionError',
7462
- 'InsufficientStockError',
7463
- 'InsufficientStockOnHandError',
7464
- 'InvalidCredentialsError',
7465
- 'InvalidFulfillmentHandlerError',
7466
- 'ItemsAlreadyFulfilledError',
7467
- 'LanguageNotAvailableError',
7468
- 'ManualPaymentStateError',
7469
- 'MimeTypeError',
7470
- 'MissingConditionsError',
7471
- 'MultipleOrderError',
7472
- 'NativeAuthStrategyError',
7473
- 'NegativeQuantityError',
7474
- 'NoChangesSpecifiedError',
7475
- 'NothingToRefundError',
7476
- 'OrderLimitError',
7477
- 'OrderModificationStateError',
7478
- 'OrderStateTransitionError',
7479
- 'PaymentMethodMissingError',
7480
- 'PaymentOrderMismatchError',
7481
- 'PaymentStateTransitionError',
7482
- 'ProductOptionInUseError',
7483
- 'QuantityTooGreatError',
7484
- 'RefundOrderStateError',
7485
- 'RefundPaymentIdMissingError',
7486
- 'RefundStateTransitionError',
7487
- 'SettlePaymentError',
7456
+ "CreateAssetResult": [
7457
+ "Asset",
7458
+ "MimeTypeError"
7488
7459
  ],
7489
- ModifyOrderResult: [
7490
- 'Order',
7491
- 'NoChangesSpecifiedError',
7492
- 'OrderModificationStateError',
7493
- 'PaymentMethodMissingError',
7494
- 'RefundPaymentIdMissingError',
7495
- 'OrderLimitError',
7496
- 'NegativeQuantityError',
7497
- 'InsufficientStockError',
7498
- 'CouponCodeExpiredError',
7499
- 'CouponCodeInvalidError',
7500
- 'CouponCodeLimitError',
7460
+ "CreateChannelResult": [
7461
+ "Channel",
7462
+ "LanguageNotAvailableError"
7501
7463
  ],
7502
- NativeAuthenticationResult: ['CurrentUser', 'InvalidCredentialsError', 'NativeAuthStrategyError'],
7503
- Node: [
7504
- 'Address',
7505
- 'Administrator',
7506
- 'Allocation',
7507
- 'Asset',
7508
- 'AuthenticationMethod',
7509
- 'Cancellation',
7510
- 'Channel',
7511
- 'Collection',
7512
- 'Country',
7513
- 'Customer',
7514
- 'CustomerGroup',
7515
- 'Facet',
7516
- 'FacetValue',
7517
- 'Fulfillment',
7518
- 'HistoryEntry',
7519
- 'Job',
7520
- 'Order',
7521
- 'OrderItem',
7522
- 'OrderLine',
7523
- 'OrderModification',
7524
- 'Payment',
7525
- 'PaymentMethod',
7526
- 'Product',
7527
- 'ProductOption',
7528
- 'ProductOptionGroup',
7529
- 'ProductVariant',
7530
- 'Promotion',
7531
- 'Refund',
7532
- 'Release',
7533
- 'Return',
7534
- 'Role',
7535
- 'Sale',
7536
- 'ShippingMethod',
7537
- 'StockAdjustment',
7538
- 'Surcharge',
7539
- 'Tag',
7540
- 'TaxCategory',
7541
- 'TaxRate',
7542
- 'User',
7543
- 'Zone',
7464
+ "CreateCustomerResult": [
7465
+ "Customer",
7466
+ "EmailAddressConflictError"
7544
7467
  ],
7545
- PaginatedList: [
7546
- 'AdministratorList',
7547
- 'AssetList',
7548
- 'CollectionList',
7549
- 'CountryList',
7550
- 'CustomerGroupList',
7551
- 'CustomerList',
7552
- 'FacetList',
7553
- 'HistoryEntryList',
7554
- 'JobList',
7555
- 'OrderList',
7556
- 'PaymentMethodList',
7557
- 'ProductList',
7558
- 'ProductVariantList',
7559
- 'PromotionList',
7560
- 'RoleList',
7561
- 'ShippingMethodList',
7562
- 'TagList',
7563
- 'TaxRateList',
7468
+ "CreatePromotionResult": [
7469
+ "Promotion",
7470
+ "MissingConditionsError"
7564
7471
  ],
7565
- RefundOrderResult: [
7566
- 'Refund',
7567
- 'QuantityTooGreatError',
7568
- 'NothingToRefundError',
7569
- 'OrderStateTransitionError',
7570
- 'MultipleOrderError',
7571
- 'PaymentOrderMismatchError',
7572
- 'RefundOrderStateError',
7573
- 'AlreadyRefundedError',
7574
- 'RefundStateTransitionError',
7472
+ "CustomField": [
7473
+ "BooleanCustomFieldConfig",
7474
+ "DateTimeCustomFieldConfig",
7475
+ "FloatCustomFieldConfig",
7476
+ "IntCustomFieldConfig",
7477
+ "LocaleStringCustomFieldConfig",
7478
+ "RelationCustomFieldConfig",
7479
+ "StringCustomFieldConfig",
7480
+ "TextCustomFieldConfig"
7575
7481
  ],
7576
- RemoveOptionGroupFromProductResult: ['Product', 'ProductOptionInUseError'],
7577
- SearchResultPrice: ['PriceRange', 'SinglePrice'],
7578
- SettlePaymentResult: [
7579
- 'Payment',
7580
- 'SettlePaymentError',
7581
- 'PaymentStateTransitionError',
7582
- 'OrderStateTransitionError',
7482
+ "CustomFieldConfig": [
7483
+ "StringCustomFieldConfig",
7484
+ "LocaleStringCustomFieldConfig",
7485
+ "IntCustomFieldConfig",
7486
+ "FloatCustomFieldConfig",
7487
+ "BooleanCustomFieldConfig",
7488
+ "DateTimeCustomFieldConfig",
7489
+ "RelationCustomFieldConfig",
7490
+ "TextCustomFieldConfig"
7583
7491
  ],
7584
- SettleRefundResult: ['Refund', 'RefundStateTransitionError'],
7585
- StockMovement: ['Allocation', 'Cancellation', 'Release', 'Return', 'Sale', 'StockAdjustment'],
7586
- StockMovementItem: ['StockAdjustment', 'Allocation', 'Sale', 'Cancellation', 'Return', 'Release'],
7587
- TransitionFulfillmentToStateResult: ['Fulfillment', 'FulfillmentStateTransitionError'],
7588
- TransitionOrderToStateResult: ['Order', 'OrderStateTransitionError'],
7589
- TransitionPaymentToStateResult: ['Payment', 'PaymentStateTransitionError'],
7590
- UpdateChannelResult: ['Channel', 'LanguageNotAvailableError'],
7591
- UpdateCustomerResult: ['Customer', 'EmailAddressConflictError'],
7592
- UpdateGlobalSettingsResult: ['GlobalSettings', 'ChannelDefaultLanguageError'],
7593
- UpdatePromotionResult: ['Promotion', 'MissingConditionsError'],
7594
- },
7492
+ "ErrorResult": [
7493
+ "AlreadyRefundedError",
7494
+ "CancelActiveOrderError",
7495
+ "ChannelDefaultLanguageError",
7496
+ "CouponCodeExpiredError",
7497
+ "CouponCodeInvalidError",
7498
+ "CouponCodeLimitError",
7499
+ "CreateFulfillmentError",
7500
+ "EmailAddressConflictError",
7501
+ "EmptyOrderLineSelectionError",
7502
+ "FulfillmentStateTransitionError",
7503
+ "InsufficientStockError",
7504
+ "InsufficientStockOnHandError",
7505
+ "InvalidCredentialsError",
7506
+ "InvalidFulfillmentHandlerError",
7507
+ "ItemsAlreadyFulfilledError",
7508
+ "LanguageNotAvailableError",
7509
+ "ManualPaymentStateError",
7510
+ "MimeTypeError",
7511
+ "MissingConditionsError",
7512
+ "MultipleOrderError",
7513
+ "NativeAuthStrategyError",
7514
+ "NegativeQuantityError",
7515
+ "NoChangesSpecifiedError",
7516
+ "NothingToRefundError",
7517
+ "OrderLimitError",
7518
+ "OrderModificationStateError",
7519
+ "OrderStateTransitionError",
7520
+ "PaymentMethodMissingError",
7521
+ "PaymentOrderMismatchError",
7522
+ "PaymentStateTransitionError",
7523
+ "ProductOptionInUseError",
7524
+ "QuantityTooGreatError",
7525
+ "RefundOrderStateError",
7526
+ "RefundPaymentIdMissingError",
7527
+ "RefundStateTransitionError",
7528
+ "SettlePaymentError"
7529
+ ],
7530
+ "ModifyOrderResult": [
7531
+ "Order",
7532
+ "NoChangesSpecifiedError",
7533
+ "OrderModificationStateError",
7534
+ "PaymentMethodMissingError",
7535
+ "RefundPaymentIdMissingError",
7536
+ "OrderLimitError",
7537
+ "NegativeQuantityError",
7538
+ "InsufficientStockError",
7539
+ "CouponCodeExpiredError",
7540
+ "CouponCodeInvalidError",
7541
+ "CouponCodeLimitError"
7542
+ ],
7543
+ "NativeAuthenticationResult": [
7544
+ "CurrentUser",
7545
+ "InvalidCredentialsError",
7546
+ "NativeAuthStrategyError"
7547
+ ],
7548
+ "Node": [
7549
+ "Address",
7550
+ "Administrator",
7551
+ "Allocation",
7552
+ "Asset",
7553
+ "AuthenticationMethod",
7554
+ "Cancellation",
7555
+ "Channel",
7556
+ "Collection",
7557
+ "Country",
7558
+ "Customer",
7559
+ "CustomerGroup",
7560
+ "Facet",
7561
+ "FacetValue",
7562
+ "Fulfillment",
7563
+ "HistoryEntry",
7564
+ "Job",
7565
+ "Order",
7566
+ "OrderItem",
7567
+ "OrderLine",
7568
+ "OrderModification",
7569
+ "Payment",
7570
+ "PaymentMethod",
7571
+ "Product",
7572
+ "ProductOption",
7573
+ "ProductOptionGroup",
7574
+ "ProductVariant",
7575
+ "Promotion",
7576
+ "Refund",
7577
+ "Release",
7578
+ "Return",
7579
+ "Role",
7580
+ "Sale",
7581
+ "ShippingMethod",
7582
+ "StockAdjustment",
7583
+ "Surcharge",
7584
+ "Tag",
7585
+ "TaxCategory",
7586
+ "TaxRate",
7587
+ "User",
7588
+ "Zone"
7589
+ ],
7590
+ "PaginatedList": [
7591
+ "AdministratorList",
7592
+ "AssetList",
7593
+ "CollectionList",
7594
+ "CountryList",
7595
+ "CustomerGroupList",
7596
+ "CustomerList",
7597
+ "FacetList",
7598
+ "HistoryEntryList",
7599
+ "JobList",
7600
+ "OrderList",
7601
+ "PaymentMethodList",
7602
+ "ProductList",
7603
+ "ProductVariantList",
7604
+ "PromotionList",
7605
+ "RoleList",
7606
+ "ShippingMethodList",
7607
+ "TagList",
7608
+ "TaxRateList"
7609
+ ],
7610
+ "RefundOrderResult": [
7611
+ "Refund",
7612
+ "QuantityTooGreatError",
7613
+ "NothingToRefundError",
7614
+ "OrderStateTransitionError",
7615
+ "MultipleOrderError",
7616
+ "PaymentOrderMismatchError",
7617
+ "RefundOrderStateError",
7618
+ "AlreadyRefundedError",
7619
+ "RefundStateTransitionError"
7620
+ ],
7621
+ "RemoveOptionGroupFromProductResult": [
7622
+ "Product",
7623
+ "ProductOptionInUseError"
7624
+ ],
7625
+ "SearchResultPrice": [
7626
+ "PriceRange",
7627
+ "SinglePrice"
7628
+ ],
7629
+ "SettlePaymentResult": [
7630
+ "Payment",
7631
+ "SettlePaymentError",
7632
+ "PaymentStateTransitionError",
7633
+ "OrderStateTransitionError"
7634
+ ],
7635
+ "SettleRefundResult": [
7636
+ "Refund",
7637
+ "RefundStateTransitionError"
7638
+ ],
7639
+ "StockMovement": [
7640
+ "Allocation",
7641
+ "Cancellation",
7642
+ "Release",
7643
+ "Return",
7644
+ "Sale",
7645
+ "StockAdjustment"
7646
+ ],
7647
+ "StockMovementItem": [
7648
+ "StockAdjustment",
7649
+ "Allocation",
7650
+ "Sale",
7651
+ "Cancellation",
7652
+ "Return",
7653
+ "Release"
7654
+ ],
7655
+ "TransitionFulfillmentToStateResult": [
7656
+ "Fulfillment",
7657
+ "FulfillmentStateTransitionError"
7658
+ ],
7659
+ "TransitionOrderToStateResult": [
7660
+ "Order",
7661
+ "OrderStateTransitionError"
7662
+ ],
7663
+ "TransitionPaymentToStateResult": [
7664
+ "Payment",
7665
+ "PaymentStateTransitionError"
7666
+ ],
7667
+ "UpdateChannelResult": [
7668
+ "Channel",
7669
+ "LanguageNotAvailableError"
7670
+ ],
7671
+ "UpdateCustomerResult": [
7672
+ "Customer",
7673
+ "EmailAddressConflictError"
7674
+ ],
7675
+ "UpdateGlobalSettingsResult": [
7676
+ "GlobalSettings",
7677
+ "ChannelDefaultLanguageError"
7678
+ ],
7679
+ "UpdatePromotionResult": [
7680
+ "Promotion",
7681
+ "MissingConditionsError"
7682
+ ]
7683
+ }
7595
7684
  };
7596
7685
 
7597
7686
  // Allows the introspectionResult to be imported as a named symbol
@@ -7656,7 +7745,7 @@ function getClientDefaults(localStorageService) {
7656
7745
  };
7657
7746
  }
7658
7747
 
7659
- const ɵ0$2 = (_, args, { cache }) => {
7748
+ const ɵ0$3 = (_, args, { cache }) => {
7660
7749
  return updateRequestsInFlight(cache, 1);
7661
7750
  }, ɵ1 = (_, args, { cache }) => {
7662
7751
  return updateRequestsInFlight(cache, -1);
@@ -7746,7 +7835,7 @@ const ɵ0$2 = (_, args, { cache }) => {
7746
7835
  };
7747
7836
  const clientResolvers = {
7748
7837
  Mutation: {
7749
- requestStarted: ɵ0$2,
7838
+ requestStarted: ɵ0$3,
7750
7839
  requestCompleted: ɵ1,
7751
7840
  setAsLoggedIn: ɵ2,
7752
7841
  setAsLoggedOut: ɵ3,
@@ -8170,7 +8259,7 @@ function createApollo(localStorageService, fetchAdapter, injector) {
8170
8259
  resolvers: clientResolvers,
8171
8260
  };
8172
8261
  }
8173
- const ɵ0$1 = initializeServerConfigService;
8262
+ const ɵ0$2 = initializeServerConfigService;
8174
8263
  /**
8175
8264
  * The DataModule is responsible for all API calls *and* serves as the source of truth for global app
8176
8265
  * state via the apollo-link-state package.
@@ -8196,7 +8285,7 @@ DataModule.decorators = [
8196
8285
  {
8197
8286
  provide: APP_INITIALIZER,
8198
8287
  multi: true,
8199
- useFactory: ɵ0$1,
8288
+ useFactory: ɵ0$2,
8200
8289
  deps: [ServerConfigService],
8201
8290
  },
8202
8291
  ],
@@ -8474,414 +8563,949 @@ JsonEditorFormInputComponent.propDecorators = {
8474
8563
  };
8475
8564
 
8476
8565
  /**
8477
- * @description
8478
- * An input for monetary values. Should be used with `int` type fields.
8479
- *
8480
- * @docsCategory custom-input-components
8481
- * @docsPage default-inputs
8566
+ * ConfigArg values are always stored as strings. If they are not primitives, then
8567
+ * they are JSON-encoded. This function unwraps them back into their original
8568
+ * data type.
8482
8569
  */
8483
- class CurrencyFormInputComponent {
8484
- constructor(dataService) {
8485
- this.dataService = dataService;
8486
- this.currencyCode$ = this.dataService.settings
8487
- .getActiveChannel()
8488
- .mapStream(data => data.activeChannel.currencyCode);
8570
+ function getConfigArgValue(value) {
8571
+ try {
8572
+ return value ? JSON.parse(value) : undefined;
8573
+ }
8574
+ catch (e) {
8575
+ return value;
8489
8576
  }
8490
8577
  }
8491
- CurrencyFormInputComponent.id = 'currency-form-input';
8492
- CurrencyFormInputComponent.decorators = [
8493
- { type: Component, args: [{
8494
- selector: 'vdr-currency-form-input',
8495
- template: "<vdr-currency-input\r\n [formControl]=\"formControl\"\r\n [readonly]=\"readonly\"\r\n [currencyCode]=\"currencyCode$ | async\"\r\n></vdr-currency-input>\r\n",
8496
- changeDetection: ChangeDetectionStrategy.OnPush,
8497
- styles: [""]
8498
- },] }
8499
- ];
8500
- CurrencyFormInputComponent.ctorParameters = () => [
8501
- { type: DataService }
8502
- ];
8503
- CurrencyFormInputComponent.propDecorators = {
8504
- readonly: [{ type: Input }]
8505
- };
8506
-
8578
+ function encodeConfigArgValue(value) {
8579
+ return Array.isArray(value) ? JSON.stringify(value) : (value !== null && value !== void 0 ? value : '').toString();
8580
+ }
8507
8581
  /**
8508
- * @description
8509
- * Allows the selection of a Customer via an autocomplete select input.
8510
- * Should be used with `ID` type fields which represent Customer IDs.
8511
- *
8512
- * @docsCategory custom-input-components
8513
- * @docsPage default-inputs
8582
+ * Creates an empty ConfigurableOperation object based on the definition.
8514
8583
  */
8515
- class CustomerGroupFormInputComponent {
8516
- constructor(dataService) {
8517
- this.dataService = dataService;
8584
+ function configurableDefinitionToInstance(def) {
8585
+ return Object.assign(Object.assign({}, def), { args: def.args.map(arg => {
8586
+ return Object.assign(Object.assign({}, arg), { value: getDefaultConfigArgValue(arg) });
8587
+ }) });
8588
+ }
8589
+ /**
8590
+ * Converts an object of the type:
8591
+ * ```
8592
+ * {
8593
+ * code: 'my-operation',
8594
+ * args: {
8595
+ * someProperty: 'foo'
8596
+ * }
8597
+ * }
8598
+ * ```
8599
+ * to the format defined by the ConfigurableOperationInput GraphQL input type:
8600
+ * ```
8601
+ * {
8602
+ * code: 'my-operation',
8603
+ * args: [
8604
+ * { name: 'someProperty', value: 'foo' }
8605
+ * ]
8606
+ * }
8607
+ * ```
8608
+ */
8609
+ function toConfigurableOperationInput(operation, formValueOperations) {
8610
+ return {
8611
+ code: operation.code,
8612
+ arguments: Object.values(formValueOperations.args || {}).map((value, j) => ({
8613
+ name: operation.args[j].name,
8614
+ value: (value === null || value === void 0 ? void 0 : value.hasOwnProperty('value'))
8615
+ ? encodeConfigArgValue(value.value)
8616
+ : encodeConfigArgValue(value),
8617
+ })),
8618
+ };
8619
+ }
8620
+ function configurableOperationValueIsValid(def, value) {
8621
+ if (!def || !value) {
8622
+ return false;
8518
8623
  }
8519
- ngOnInit() {
8520
- this.customerGroups$ = this.dataService.customer
8521
- .getCustomerGroupList({
8522
- take: 1000,
8523
- })
8524
- .mapSingle(res => res.customerGroups.items)
8525
- .pipe(startWith([]));
8624
+ if (def.code !== value.code) {
8625
+ return false;
8526
8626
  }
8527
- selectGroup(group) {
8528
- this.formControl.setValue(group.id);
8627
+ for (const argDef of def.args) {
8628
+ const argVal = value.args[argDef.name];
8629
+ if (argDef.required && (argVal == null || argVal === '' || argVal === '0')) {
8630
+ return false;
8631
+ }
8529
8632
  }
8633
+ return true;
8530
8634
  }
8531
- CustomerGroupFormInputComponent.id = 'customer-group-form-input';
8532
- CustomerGroupFormInputComponent.decorators = [
8533
- { type: Component, args: [{
8534
- selector: 'vdr-customer-group-form-input',
8535
- template: "<ng-select\r\n [items]=\"customerGroups$ | async\"\r\n appendTo=\"body\"\r\n [addTag]=\"false\"\r\n [multiple]=\"false\"\r\n bindValue=\"id\"\r\n [clearable]=\"true\"\r\n [searchable]=\"false\"\r\n [ngModel]=\"formControl.value\"\r\n (change)=\"selectGroup($event)\"\r\n>\r\n <ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\">\r\n <vdr-chip [colorFrom]=\"item.id\">{{ item.name }}</vdr-chip>\r\n </ng-template>\r\n <ng-template ng-option-tmp let-item=\"item\">\r\n <vdr-chip [colorFrom]=\"item.id\">{{ item.name }}</vdr-chip>\r\n </ng-template>\r\n</ng-select>\r\n",
8536
- changeDetection: ChangeDetectionStrategy.OnPush,
8537
- styles: [""]
8538
- },] }
8539
- ];
8540
- CustomerGroupFormInputComponent.ctorParameters = () => [
8541
- { type: DataService }
8542
- ];
8543
- CustomerGroupFormInputComponent.propDecorators = {
8544
- readonly: [{ type: Input }]
8545
- };
8546
-
8547
8635
  /**
8548
- * @description
8549
- * Allows selection of a datetime. Default input for `datetime` type fields.
8550
- *
8551
- * @docsCategory custom-input-components
8552
- * @docsPage default-inputs
8636
+ * Returns a default value based on the type of the config arg.
8553
8637
  */
8554
- class DateFormInputComponent {
8555
- get min() {
8556
- var _a;
8557
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.min) || this.config.min;
8638
+ function getDefaultConfigArgValue(arg) {
8639
+ if (arg.list) {
8640
+ return [];
8558
8641
  }
8559
- get max() {
8560
- var _a;
8561
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.max) || this.config.max;
8642
+ if (arg.defaultValue) {
8643
+ return arg.defaultValue;
8562
8644
  }
8563
- get yearRange() {
8564
- var _a;
8565
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.yearRange) || this.config.yearRange;
8645
+ const type = arg.type;
8646
+ switch (type) {
8647
+ case 'string':
8648
+ case 'datetime':
8649
+ case 'float':
8650
+ case 'ID':
8651
+ case 'int':
8652
+ return null;
8653
+ case 'boolean':
8654
+ return false;
8655
+ default:
8656
+ assertNever(type);
8566
8657
  }
8567
- }
8568
- DateFormInputComponent.id = 'date-form-input';
8569
- DateFormInputComponent.decorators = [
8570
- { type: Component, args: [{
8571
- selector: 'vdr-date-form-input',
8572
- template: "<vdr-datetime-picker\r\n [formControl]=\"formControl\"\r\n [min]=\"min\"\r\n [max]=\"max\"\r\n [yearRange]=\"yearRange\"\r\n [readonly]=\"readonly\"\r\n>\r\n</vdr-datetime-picker>\r\n",
8573
- changeDetection: ChangeDetectionStrategy.OnPush,
8574
- styles: [""]
8575
- },] }
8576
- ];
8577
- DateFormInputComponent.propDecorators = {
8578
- readonly: [{ type: Input }]
8579
- };
8658
+ }
8580
8659
 
8581
8660
  /**
8582
- * @description
8583
- * Allows the selection of multiple FacetValues via an autocomplete select input.
8584
- * Should be used with `ID` type **list** fields which represent FacetValue IDs.
8585
- *
8586
- * @docsCategory custom-input-components
8587
- * @docsPage default-inputs
8661
+ * Interpolates the description of an ConfigurableOperation with the given values.
8588
8662
  */
8589
- class FacetValueFormInputComponent {
8590
- constructor(dataService) {
8591
- this.dataService = dataService;
8592
- this.isListInput = true;
8663
+ function interpolateDescription(operation, values) {
8664
+ if (!operation) {
8665
+ return '';
8666
+ }
8667
+ const templateString = operation.description;
8668
+ const interpolated = templateString.replace(/{\s*([a-zA-Z0-9]+)\s*}/gi, (substring, argName) => {
8669
+ const normalizedArgName = argName.toLowerCase();
8670
+ const value = values[normalizedArgName];
8671
+ if (value == null) {
8672
+ return '_';
8673
+ }
8674
+ let formatted = value;
8675
+ const argDef = operation.args.find(arg => arg.name === normalizedArgName);
8676
+ if (argDef && argDef.type === 'int' && argDef.ui && argDef.ui.component === 'currency-form-input') {
8677
+ formatted = value / 100;
8678
+ }
8679
+ if (argDef && argDef.type === 'datetime' && value instanceof Date) {
8680
+ formatted = value.toLocaleDateString();
8681
+ }
8682
+ return formatted;
8683
+ });
8684
+ return interpolated;
8685
+ }
8686
+
8687
+ /**
8688
+ * A form input which renders a card with the internal form fields of the given ConfigurableOperation.
8689
+ */
8690
+ class ConfigurableInputComponent {
8691
+ constructor() {
8692
+ this.readonly = false;
8693
+ this.removable = true;
8694
+ this.position = 0;
8695
+ this.remove = new EventEmitter();
8696
+ this.argValues = {};
8697
+ this.form = new FormGroup({});
8698
+ this.positionChangeSubject = new BehaviorSubject(0);
8699
+ }
8700
+ interpolateDescription() {
8701
+ if (this.operationDefinition) {
8702
+ return interpolateDescription(this.operationDefinition, this.form.value);
8703
+ }
8704
+ else {
8705
+ return '';
8706
+ }
8593
8707
  }
8594
8708
  ngOnInit() {
8595
- this.facets$ = this.dataService.facet
8596
- .getAllFacets()
8597
- .mapSingle(data => data.facets.items)
8598
- .pipe(shareReplay(1));
8709
+ this.positionChange$ = this.positionChangeSubject.asObservable();
8710
+ }
8711
+ ngOnChanges(changes) {
8712
+ if ('operation' in changes || 'operationDefinition' in changes) {
8713
+ this.createForm();
8714
+ }
8715
+ if ('position' in changes) {
8716
+ this.positionChangeSubject.next(this.position);
8717
+ }
8718
+ }
8719
+ ngOnDestroy() {
8720
+ if (this.subscription) {
8721
+ this.subscription.unsubscribe();
8722
+ }
8723
+ }
8724
+ registerOnChange(fn) {
8725
+ this.onChange = fn;
8726
+ }
8727
+ registerOnTouched(fn) {
8728
+ this.onTouch = fn;
8729
+ }
8730
+ setDisabledState(isDisabled) {
8731
+ if (isDisabled) {
8732
+ this.form.disable();
8733
+ }
8734
+ else {
8735
+ this.form.enable();
8736
+ }
8737
+ }
8738
+ writeValue(value) {
8739
+ if (value) {
8740
+ this.form.patchValue(value);
8741
+ }
8742
+ }
8743
+ trackByName(index, arg) {
8744
+ return arg.name;
8745
+ }
8746
+ getArgDef(arg) {
8747
+ var _a;
8748
+ return (_a = this.operationDefinition) === null || _a === void 0 ? void 0 : _a.args.find(a => a.name === arg.name);
8749
+ }
8750
+ createForm() {
8751
+ var _a, _b;
8752
+ if (!this.operation) {
8753
+ return;
8754
+ }
8755
+ if (this.subscription) {
8756
+ this.subscription.unsubscribe();
8757
+ }
8758
+ this.form = new FormGroup({});
8759
+ this.form.__id = Math.random().toString(36).substr(10);
8760
+ if (this.operation.args) {
8761
+ for (const arg of ((_a = this.operationDefinition) === null || _a === void 0 ? void 0 : _a.args) || []) {
8762
+ let value = (_b = this.operation.args.find(a => a.name === arg.name)) === null || _b === void 0 ? void 0 : _b.value;
8763
+ if (value === undefined) {
8764
+ value = getDefaultConfigArgValue(arg);
8765
+ }
8766
+ const validators = arg.list ? undefined : arg.required ? Validators.required : undefined;
8767
+ this.form.addControl(arg.name, new FormControl(value, validators));
8768
+ }
8769
+ }
8770
+ this.subscription = this.form.valueChanges.subscribe(value => {
8771
+ if (this.onChange) {
8772
+ this.onChange({
8773
+ code: this.operation && this.operation.code,
8774
+ args: value,
8775
+ });
8776
+ }
8777
+ if (this.onTouch) {
8778
+ this.onTouch();
8779
+ }
8780
+ });
8781
+ }
8782
+ validate(c) {
8783
+ if (this.form.invalid) {
8784
+ return {
8785
+ required: true,
8786
+ };
8787
+ }
8788
+ return null;
8599
8789
  }
8600
8790
  }
8601
- FacetValueFormInputComponent.id = 'facet-value-form-input';
8602
- FacetValueFormInputComponent.decorators = [
8791
+ ConfigurableInputComponent.decorators = [
8603
8792
  { type: Component, args: [{
8604
- selector: 'vdr-facet-value-form-input',
8605
- template: "<vdr-facet-value-selector\r\n *ngIf=\"facets$ | async as facets\"\r\n [readonly]=\"readonly\"\r\n [facets]=\"facets\"\r\n [formControl]=\"formControl\"\r\n></vdr-facet-value-selector>\r\n",
8793
+ selector: 'vdr-configurable-input',
8794
+ template: "<div class=\"card\" *ngIf=\"operation\">\r\n <div class=\"card-block\">{{ interpolateDescription() }}</div>\r\n <div class=\"card-block\" *ngIf=\"operation.args?.length\">\r\n <form [formGroup]=\"form\" *ngIf=\"operation\" class=\"operation-inputs\">\r\n <div *ngFor=\"let arg of operation.args; trackBy: trackByName\" class=\"arg-row\">\r\n <ng-container *ngIf=\"form.get(arg.name) && getArgDef(arg) as argDef\">\r\n <label class=\"clr-control-label\">{{ argDef.label || (arg.name | sentenceCase) }}</label>\r\n <vdr-help-tooltip\r\n class=\"mr3\"\r\n *ngIf=\"argDef.description\"\r\n [content]=\"argDef.description\"\r\n ></vdr-help-tooltip>\r\n <vdr-dynamic-form-input\r\n [def]=\"getArgDef(arg)\"\r\n [readonly]=\"readonly\"\r\n [control]=\"form.get(arg.name)\"\r\n [formControlName]=\"arg.name\"\r\n ></vdr-dynamic-form-input>\r\n </ng-container>\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer\" *ngIf=\"!readonly && removable\">\r\n <button class=\"btn btn-sm btn-link btn-warning\" (click)=\"remove.emit(operation)\">\r\n <clr-icon shape=\"times\"></clr-icon>\r\n {{ 'common.remove' | translate }}\r\n </button>\r\n </div>\r\n</div>\r\n",
8606
8795
  changeDetection: ChangeDetectionStrategy.OnPush,
8607
- styles: [""]
8796
+ providers: [
8797
+ {
8798
+ provide: NG_VALUE_ACCESSOR,
8799
+ useExisting: ConfigurableInputComponent,
8800
+ multi: true,
8801
+ },
8802
+ {
8803
+ provide: NG_VALIDATORS,
8804
+ useExisting: forwardRef(() => ConfigurableInputComponent),
8805
+ multi: true,
8806
+ },
8807
+ ],
8808
+ styles: [":host{display:block;margin-bottom:12px}:host>.card{margin-top:6px}.operation-inputs{padding-top:0}.operation-inputs .arg-row:not(:last-child){margin-bottom:12px}.operation-inputs .arg-row{display:flex;flex-wrap:wrap;align-items:center}.operation-inputs .arg-row label{margin-right:6px}.operation-inputs .hidden{display:none}.operation-inputs label{min-width:130px;display:inline-block}\n"]
8608
8809
  },] }
8609
8810
  ];
8610
- FacetValueFormInputComponent.ctorParameters = () => [
8611
- { type: DataService }
8612
- ];
8811
+ ConfigurableInputComponent.propDecorators = {
8812
+ operation: [{ type: Input }],
8813
+ operationDefinition: [{ type: Input }],
8814
+ readonly: [{ type: Input }],
8815
+ removable: [{ type: Input }],
8816
+ position: [{ type: Input }],
8817
+ remove: [{ type: Output }]
8818
+ };
8613
8819
 
8614
8820
  /**
8615
8821
  * @description
8616
- * Displays a number input. Default input for `int` and `float` type fields.
8822
+ * A special input used to display the "Combination mode" AND/OR toggle.
8617
8823
  *
8618
8824
  * @docsCategory custom-input-components
8619
8825
  * @docsPage default-inputs
8620
8826
  */
8621
- class NumberFormInputComponent {
8622
- get prefix() {
8623
- var _a;
8624
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.prefix) || this.config.prefix;
8625
- }
8626
- get suffix() {
8627
- var _a;
8628
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.suffix) || this.config.suffix;
8827
+ class CombinationModeFormInputComponent {
8828
+ constructor(configurableInputComponent) {
8829
+ this.configurableInputComponent = configurableInputComponent;
8629
8830
  }
8630
- get min() {
8631
- var _a;
8632
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.min) || this.config.min;
8831
+ ngOnInit() {
8832
+ const selectable$ = this.configurableInputComponent
8833
+ ? this.configurableInputComponent.positionChange$.pipe(map(position => 0 < position))
8834
+ : of(true);
8835
+ this.selectable$ = selectable$.pipe(tap(selectable => {
8836
+ if (!selectable) {
8837
+ this.formControl.setValue(true, { emitEvent: false });
8838
+ }
8839
+ }));
8633
8840
  }
8634
- get max() {
8635
- var _a;
8636
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.max) || this.config.max;
8841
+ setCombinationModeAnd() {
8842
+ this.formControl.setValue(true);
8637
8843
  }
8638
- get step() {
8639
- var _a;
8640
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.step) || this.config.step;
8844
+ setCombinationModeOr() {
8845
+ this.formControl.setValue(false);
8641
8846
  }
8642
8847
  }
8643
- NumberFormInputComponent.id = 'number-form-input';
8644
- NumberFormInputComponent.decorators = [
8848
+ CombinationModeFormInputComponent.id = 'combination-mode-form-input';
8849
+ CombinationModeFormInputComponent.decorators = [
8645
8850
  { type: Component, args: [{
8646
- selector: 'vdr-number-form-input',
8647
- template: "<vdr-affixed-input\r\n [suffix]=\"suffix\"\r\n [prefix]=\"prefix\"\r\n>\r\n <input\r\n type=\"number\"\r\n [readonly]=\"readonly\"\r\n [min]=\"min\"\r\n [max]=\"max\"\r\n [step]=\"step\"\r\n [formControl]=\"formControl\"\r\n />\r\n</vdr-affixed-input>\r\n",
8851
+ selector: 'vdr-combination-mode-form-input',
8852
+ template: "<ng-container *ngIf=\"selectable$ | async; else default\">\r\n <div class=\"btn-group btn-outline-primary btn-sm mode-select\">\r\n <button\r\n class=\"btn\"\r\n (click)=\"setCombinationModeAnd()\"\r\n [class.btn-primary]=\"formControl.value === true\"\r\n >\r\n {{ 'common.boolean-and' | translate }}\r\n </button>\r\n <button\r\n class=\"btn\"\r\n (click)=\"setCombinationModeOr()\"\r\n [class.btn-primary]=\"formControl.value === false\"\r\n >\r\n {{ 'common.boolean-or' | translate }}\r\n </button>\r\n </div>\r\n</ng-container>\r\n<ng-template #default>\r\n <small>{{ 'common.not-applicable' | translate }}</small>\r\n</ng-template>\r\n",
8648
8853
  changeDetection: ChangeDetectionStrategy.OnPush,
8649
- styles: [""]
8854
+ styles: [".mode-select{text-transform:uppercase}\n"]
8650
8855
  },] }
8651
8856
  ];
8652
- NumberFormInputComponent.propDecorators = {
8653
- readonly: [{ type: Input }]
8654
- };
8857
+ CombinationModeFormInputComponent.ctorParameters = () => [
8858
+ { type: ConfigurableInputComponent, decorators: [{ type: Optional }] }
8859
+ ];
8655
8860
 
8656
8861
  /**
8657
8862
  * @description
8658
- * Displays a password text input. Should be used with `string` type fields.
8863
+ * An input for monetary values. Should be used with `int` type fields.
8659
8864
  *
8660
8865
  * @docsCategory custom-input-components
8661
8866
  * @docsPage default-inputs
8662
8867
  */
8663
- class PasswordFormInputComponent {
8868
+ class CurrencyFormInputComponent {
8869
+ constructor(dataService) {
8870
+ this.dataService = dataService;
8871
+ this.currencyCode$ = this.dataService.settings
8872
+ .getActiveChannel()
8873
+ .mapStream(data => data.activeChannel.currencyCode);
8874
+ }
8664
8875
  }
8665
- PasswordFormInputComponent.id = 'password-form-input';
8666
- PasswordFormInputComponent.decorators = [
8876
+ CurrencyFormInputComponent.id = 'currency-form-input';
8877
+ CurrencyFormInputComponent.decorators = [
8667
8878
  { type: Component, args: [{
8668
- selector: 'vdr-password-form-input',
8669
- template: "<input\r\n type=\"password\"\r\n [readonly]=\"readonly\"\r\n [formControl]=\"formControl\"\r\n/>\r\n",
8879
+ selector: 'vdr-currency-form-input',
8880
+ template: "<vdr-currency-input\r\n [formControl]=\"formControl\"\r\n [readonly]=\"readonly\"\r\n [currencyCode]=\"currencyCode$ | async\"\r\n></vdr-currency-input>\r\n",
8670
8881
  changeDetection: ChangeDetectionStrategy.OnPush,
8671
8882
  styles: [""]
8672
8883
  },] }
8673
- ];
8884
+ ];
8885
+ CurrencyFormInputComponent.ctorParameters = () => [
8886
+ { type: DataService }
8887
+ ];
8888
+ CurrencyFormInputComponent.propDecorators = {
8889
+ readonly: [{ type: Input }]
8890
+ };
8674
8891
 
8675
8892
  /**
8676
8893
  * @description
8677
- * Allows the selection of multiple ProductVariants via an autocomplete select input.
8678
- * Should be used with `ID` type **list** fields which represent ProductVariant IDs.
8894
+ * Allows the selection of a Customer via an autocomplete select input.
8895
+ * Should be used with `ID` type fields which represent Customer IDs.
8679
8896
  *
8680
8897
  * @docsCategory custom-input-components
8681
8898
  * @docsPage default-inputs
8682
8899
  */
8683
- class ProductSelectorFormInputComponent {
8900
+ class CustomerGroupFormInputComponent {
8684
8901
  constructor(dataService) {
8685
8902
  this.dataService = dataService;
8686
- this.isListInput = true;
8687
8903
  }
8688
8904
  ngOnInit() {
8689
- this.formControl.setValidators([
8690
- control => {
8691
- if (!control.value || !control.value.length) {
8692
- return {
8693
- atLeastOne: { length: control.value.length },
8694
- };
8695
- }
8696
- return null;
8697
- },
8698
- ]);
8699
- this.selection$ = this.formControl.valueChanges.pipe(startWith(this.formControl.value), switchMap(value => {
8700
- if (Array.isArray(value) && 0 < value.length) {
8701
- return forkJoin(value.map(id => this.dataService.product
8702
- .getProductVariant(id)
8703
- .mapSingle(data => data.productVariant)));
8704
- }
8705
- return of([]);
8706
- }), map(variants => variants.filter(notNullOrUndefined)));
8905
+ this.customerGroups$ = this.dataService.customer
8906
+ .getCustomerGroupList({
8907
+ take: 1000,
8908
+ })
8909
+ .mapSingle(res => res.customerGroups.items)
8910
+ .pipe(startWith([]));
8707
8911
  }
8708
- addProductVariant(product) {
8709
- const value = this.formControl.value;
8710
- this.formControl.setValue([...new Set([...value, product.productVariantId])]);
8711
- }
8712
- removeProductVariant(id) {
8713
- const value = this.formControl.value;
8714
- this.formControl.setValue(value.filter(_id => _id !== id));
8912
+ selectGroup(group) {
8913
+ this.formControl.setValue(group.id);
8715
8914
  }
8716
8915
  }
8717
- ProductSelectorFormInputComponent.id = 'product-selector-form-input';
8718
- ProductSelectorFormInputComponent.decorators = [
8916
+ CustomerGroupFormInputComponent.id = 'customer-group-form-input';
8917
+ CustomerGroupFormInputComponent.decorators = [
8719
8918
  { type: Component, args: [{
8720
- selector: 'vdr-product-selector-form-input',
8721
- template: "<ul class=\"list-unstyled\">\r\n <li *ngFor=\"let variant of selection$ | async\" class=\"variant\">\r\n <div class=\"thumb\">\r\n <img [src]=\"variant.product.featuredAsset | assetPreview: 32\" />\r\n </div>\r\n <div class=\"detail\">\r\n <div>{{ variant.name }}</div>\r\n <div class=\"sku\">{{ variant.sku }}</div>\r\n </div>\r\n <div class=\"flex-spacer\"></div>\r\n <button\r\n class=\"btn btn-link btn-sm btn-warning\"\r\n (click)=\"removeProductVariant(variant.id)\"\r\n [title]=\"'common.remove-item-from-list' | translate\"\r\n >\r\n <clr-icon shape=\"times\"></clr-icon>\r\n </button>\r\n </li>\r\n</ul>\r\n<vdr-product-selector (productSelected)=\"addProductVariant($event)\"></vdr-product-selector>\r\n",
8919
+ selector: 'vdr-customer-group-form-input',
8920
+ template: "<ng-select\r\n [items]=\"customerGroups$ | async\"\r\n appendTo=\"body\"\r\n [addTag]=\"false\"\r\n [multiple]=\"false\"\r\n bindValue=\"id\"\r\n [clearable]=\"true\"\r\n [searchable]=\"false\"\r\n [ngModel]=\"formControl.value\"\r\n (change)=\"selectGroup($event)\"\r\n>\r\n <ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\">\r\n <vdr-chip [colorFrom]=\"item.id\">{{ item.name }}</vdr-chip>\r\n </ng-template>\r\n <ng-template ng-option-tmp let-item=\"item\">\r\n <vdr-chip [colorFrom]=\"item.id\">{{ item.name }}</vdr-chip>\r\n </ng-template>\r\n</ng-select>\r\n",
8722
8921
  changeDetection: ChangeDetectionStrategy.OnPush,
8723
- styles: [".variant{margin-bottom:6px;display:flex;align-items:center;transition:background-color .2s}.variant:hover{background-color:var(--color-component-bg-200)}.thumb{margin-right:6px}.sku{color:var(--color-grey-400);font-size:smaller;line-height:1em}\n"]
8922
+ styles: [""]
8724
8923
  },] }
8725
8924
  ];
8726
- ProductSelectorFormInputComponent.ctorParameters = () => [
8925
+ CustomerGroupFormInputComponent.ctorParameters = () => [
8727
8926
  { type: DataService }
8728
- ];
8927
+ ];
8928
+ CustomerGroupFormInputComponent.propDecorators = {
8929
+ readonly: [{ type: Input }]
8930
+ };
8729
8931
 
8730
8932
  /**
8731
8933
  * @description
8732
- * The default input component for `relation` type custom fields. Allows the selection
8733
- * of a ProductVariant, Product, Customer or Asset. For other entity types, a custom
8734
- * implementation will need to be defined. See {@link registerFormInputComponent}.
8934
+ * Allows selection of a datetime. Default input for `datetime` type fields.
8735
8935
  *
8736
8936
  * @docsCategory custom-input-components
8737
8937
  * @docsPage default-inputs
8738
8938
  */
8739
- class RelationFormInputComponent {
8939
+ class DateFormInputComponent {
8940
+ get min() {
8941
+ var _a;
8942
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.min) || this.config.min;
8943
+ }
8944
+ get max() {
8945
+ var _a;
8946
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.max) || this.config.max;
8947
+ }
8948
+ get yearRange() {
8949
+ var _a;
8950
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.yearRange) || this.config.yearRange;
8951
+ }
8740
8952
  }
8741
- RelationFormInputComponent.id = 'relation-form-input';
8742
- RelationFormInputComponent.decorators = [
8953
+ DateFormInputComponent.id = 'date-form-input';
8954
+ DateFormInputComponent.decorators = [
8743
8955
  { type: Component, args: [{
8744
- selector: 'vdr-relation-form-input',
8745
- template: "<div [ngSwitch]=\"config.entity\">\r\n <vdr-relation-asset-input\r\n *ngSwitchCase=\"'Asset'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-asset-input>\r\n <vdr-relation-product-input\r\n *ngSwitchCase=\"'Product'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-product-input>\r\n <vdr-relation-customer-input\r\n *ngSwitchCase=\"'Customer'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-customer-input>\r\n <vdr-relation-product-variant-input\r\n *ngSwitchCase=\"'ProductVariant'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-product-variant-input>\r\n <ng-template ngSwitchDefault>\r\n <vdr-relation-generic-input\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-generic-input>\r\n </ng-template>\r\n</div>\r\n",
8956
+ selector: 'vdr-date-form-input',
8957
+ template: "<vdr-datetime-picker\r\n [formControl]=\"formControl\"\r\n [min]=\"min\"\r\n [max]=\"max\"\r\n [yearRange]=\"yearRange\"\r\n [readonly]=\"readonly\"\r\n>\r\n</vdr-datetime-picker>\r\n",
8746
8958
  changeDetection: ChangeDetectionStrategy.OnPush,
8747
- styles: [":host{display:block;background-color:var(--color-component-bg-200);padding:3px}\n"]
8959
+ styles: [""]
8748
8960
  },] }
8749
8961
  ];
8750
- RelationFormInputComponent.propDecorators = {
8962
+ DateFormInputComponent.propDecorators = {
8751
8963
  readonly: [{ type: Input }]
8752
8964
  };
8753
8965
 
8754
8966
  /**
8755
8967
  * @description
8756
- * Uses the {@link RichTextEditorComponent} as in input for `text` type fields.
8968
+ * Allows the selection of multiple FacetValues via an autocomplete select input.
8969
+ * Should be used with `ID` type **list** fields which represent FacetValue IDs.
8757
8970
  *
8758
8971
  * @docsCategory custom-input-components
8759
8972
  * @docsPage default-inputs
8760
8973
  */
8761
- class RichTextFormInputComponent {
8974
+ class FacetValueFormInputComponent {
8975
+ constructor(dataService) {
8976
+ this.dataService = dataService;
8977
+ this.isListInput = true;
8978
+ }
8979
+ ngOnInit() {
8980
+ this.facets$ = this.dataService.facet
8981
+ .getAllFacets()
8982
+ .mapSingle(data => data.facets.items)
8983
+ .pipe(shareReplay(1));
8984
+ }
8762
8985
  }
8763
- RichTextFormInputComponent.id = 'rich-text-form-input';
8764
- RichTextFormInputComponent.decorators = [
8986
+ FacetValueFormInputComponent.id = 'facet-value-form-input';
8987
+ FacetValueFormInputComponent.decorators = [
8765
8988
  { type: Component, args: [{
8766
- selector: 'vdr-rich-text-form-input',
8767
- template: "<vdr-rich-text-editor\r\n [readonly]=\"readonly\"\r\n [formControl]=\"formControl\"\r\n></vdr-rich-text-editor>\r\n",
8989
+ selector: 'vdr-facet-value-form-input',
8990
+ template: "<vdr-facet-value-selector\r\n *ngIf=\"facets$ | async as facets\"\r\n [readonly]=\"readonly\"\r\n [facets]=\"facets\"\r\n [formControl]=\"formControl\"\r\n></vdr-facet-value-selector>\r\n",
8768
8991
  changeDetection: ChangeDetectionStrategy.OnPush,
8769
- styles: [":host textarea{resize:both;height:6rem;width:100%}\n"]
8992
+ styles: [""]
8770
8993
  },] }
8994
+ ];
8995
+ FacetValueFormInputComponent.ctorParameters = () => [
8996
+ { type: DataService }
8771
8997
  ];
8772
8998
 
8773
8999
  /**
8774
9000
  * @description
8775
- * Uses a select input to allow the selection of a string value. Should be used with
8776
- * `string` type fields with options.
9001
+ * Displays a number input. Default input for `int` and `float` type fields.
8777
9002
  *
8778
9003
  * @docsCategory custom-input-components
8779
9004
  * @docsPage default-inputs
8780
9005
  */
8781
- class SelectFormInputComponent {
8782
- get options() {
9006
+ class NumberFormInputComponent {
9007
+ get prefix() {
8783
9008
  var _a;
8784
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.options) || this.config.options;
9009
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.prefix) || this.config.prefix;
9010
+ }
9011
+ get suffix() {
9012
+ var _a;
9013
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.suffix) || this.config.suffix;
9014
+ }
9015
+ get min() {
9016
+ var _a;
9017
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.min) || this.config.min;
9018
+ }
9019
+ get max() {
9020
+ var _a;
9021
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.max) || this.config.max;
9022
+ }
9023
+ get step() {
9024
+ var _a;
9025
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.step) || this.config.step;
8785
9026
  }
8786
9027
  }
8787
- SelectFormInputComponent.id = 'select-form-input';
8788
- SelectFormInputComponent.decorators = [
9028
+ NumberFormInputComponent.id = 'number-form-input';
9029
+ NumberFormInputComponent.decorators = [
8789
9030
  { type: Component, args: [{
8790
- selector: 'vdr-select-form-input',
8791
- template: "<select clrSelect [formControl]=\"formControl\" [vdrDisabled]=\"readonly\">\r\n <option *ngIf=\"config.nullable\" [ngValue]=\"null\"></option>\r\n <option *ngFor=\"let option of options\" [ngValue]=\"option.value\">\r\n {{ (option | customFieldLabel) || option.label || option.value }}\r\n </option>\r\n</select>\r\n",
9031
+ selector: 'vdr-number-form-input',
9032
+ template: "<vdr-affixed-input\r\n [suffix]=\"suffix\"\r\n [prefix]=\"prefix\"\r\n>\r\n <input\r\n type=\"number\"\r\n [readonly]=\"readonly\"\r\n [min]=\"min\"\r\n [max]=\"max\"\r\n [step]=\"step\"\r\n [formControl]=\"formControl\"\r\n />\r\n</vdr-affixed-input>\r\n",
8792
9033
  changeDetection: ChangeDetectionStrategy.OnPush,
8793
- styles: ["select{width:100%}\n"]
9034
+ styles: [""]
8794
9035
  },] }
8795
9036
  ];
8796
- SelectFormInputComponent.propDecorators = {
9037
+ NumberFormInputComponent.propDecorators = {
8797
9038
  readonly: [{ type: Input }]
8798
9039
  };
8799
9040
 
8800
9041
  /**
8801
9042
  * @description
8802
- * Uses a regular text form input. This is the default input for `string` and `localeString` type fields.
9043
+ * Displays a password text input. Should be used with `string` type fields.
8803
9044
  *
8804
9045
  * @docsCategory custom-input-components
8805
9046
  * @docsPage default-inputs
8806
9047
  */
8807
- class TextFormInputComponent {
8808
- get prefix() {
8809
- var _a;
8810
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.prefix) || this.config.prefix;
8811
- }
8812
- get suffix() {
8813
- var _a;
8814
- return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.suffix) || this.config.suffix;
8815
- }
9048
+ class PasswordFormInputComponent {
8816
9049
  }
8817
- TextFormInputComponent.id = 'text-form-input';
8818
- TextFormInputComponent.decorators = [
9050
+ PasswordFormInputComponent.id = 'password-form-input';
9051
+ PasswordFormInputComponent.decorators = [
8819
9052
  { type: Component, args: [{
8820
- selector: 'vdr-text-form-input',
8821
- template: "<vdr-affixed-input\r\n [suffix]=\"suffix\"\r\n [prefix]=\"prefix\"\r\n>\r\n <input type=\"text\" [readonly]=\"readonly\" [formControl]=\"formControl\" />\r\n</vdr-affixed-input>\r\n",
9053
+ selector: 'vdr-password-form-input',
9054
+ template: "<input\r\n type=\"password\"\r\n [readonly]=\"readonly\"\r\n [formControl]=\"formControl\"\r\n/>\r\n",
8822
9055
  changeDetection: ChangeDetectionStrategy.OnPush,
8823
- styles: ["input{width:100%}\n"]
9056
+ styles: [""]
8824
9057
  },] }
8825
9058
  ];
8826
9059
 
8827
9060
  /**
8828
9061
  * @description
8829
- * Uses textarea form input. This is the default input for `text` type fields.
8830
- *
8831
- * @docsCategory custom-input-components
8832
- * @docsPage default-inputs
9062
+ * A helper class used to manage selection of list items. Supports multiple selection via
9063
+ * cmd/ctrl/shift key.
8833
9064
  */
8834
- class TextareaFormInputComponent {
8835
- get spellcheck() {
8836
- return this.config.spellcheck === true;
9065
+ class SelectionManager {
9066
+ constructor(options) {
9067
+ this.options = options;
9068
+ this._selection = [];
9069
+ this.items = [];
9070
+ }
9071
+ get selection() {
9072
+ return this._selection;
9073
+ }
9074
+ setMultiSelect(isMultiSelect) {
9075
+ this.options.multiSelect = isMultiSelect;
9076
+ }
9077
+ setCurrentItems(items) {
9078
+ this.items = items;
9079
+ }
9080
+ toggleSelection(item, event) {
9081
+ const { multiSelect, itemsAreEqual, additiveMode } = this.options;
9082
+ const index = this._selection.findIndex(a => itemsAreEqual(a, item));
9083
+ if (multiSelect && (event === null || event === void 0 ? void 0 : event.shiftKey) && 1 <= this._selection.length) {
9084
+ const lastSelection = this._selection[this._selection.length - 1];
9085
+ const lastSelectionIndex = this.items.findIndex(a => itemsAreEqual(a, lastSelection));
9086
+ const currentIndex = this.items.findIndex(a => itemsAreEqual(a, item));
9087
+ const start = currentIndex < lastSelectionIndex ? currentIndex : lastSelectionIndex;
9088
+ const end = currentIndex > lastSelectionIndex ? currentIndex + 1 : lastSelectionIndex;
9089
+ this._selection.push(...this.items.slice(start, end).filter(a => !this._selection.find(s => itemsAreEqual(a, s))));
9090
+ }
9091
+ else if (index === -1) {
9092
+ if (multiSelect && ((event === null || event === void 0 ? void 0 : event.ctrlKey) || (event === null || event === void 0 ? void 0 : event.shiftKey) || additiveMode)) {
9093
+ this._selection.push(item);
9094
+ }
9095
+ else {
9096
+ this._selection = [item];
9097
+ }
9098
+ }
9099
+ else {
9100
+ if (multiSelect && (event === null || event === void 0 ? void 0 : event.ctrlKey)) {
9101
+ this._selection.splice(index, 1);
9102
+ }
9103
+ else if (1 < this._selection.length && !additiveMode) {
9104
+ this._selection = [item];
9105
+ }
9106
+ else {
9107
+ this._selection.splice(index, 1);
9108
+ }
9109
+ }
9110
+ // Make the selection mutable
9111
+ this._selection = this._selection.map(x => (Object.assign({}, x)));
9112
+ }
9113
+ selectMultiple(items) {
9114
+ this._selection = items;
9115
+ }
9116
+ isSelected(item) {
9117
+ return !!this._selection.find(a => this.options.itemsAreEqual(a, item));
9118
+ }
9119
+ lastSelected() {
9120
+ return this._selection[this._selection.length - 1];
9121
+ }
9122
+ }
9123
+
9124
+ class ProductMultiSelectorDialogComponent {
9125
+ constructor(dataService, changeDetector) {
9126
+ this.dataService = dataService;
9127
+ this.changeDetector = changeDetector;
9128
+ this.mode = 'product';
9129
+ this.initialSelectionIds = [];
9130
+ this.searchTerm$ = new BehaviorSubject('');
9131
+ this.searchFacetValueIds$ = new BehaviorSubject([]);
9132
+ this.paginationConfig = {
9133
+ currentPage: 1,
9134
+ itemsPerPage: 25,
9135
+ totalItems: 1,
9136
+ };
9137
+ this.paginationConfig$ = new BehaviorSubject(this.paginationConfig);
9138
+ }
9139
+ ngOnInit() {
9140
+ const idFn = this.mode === 'product'
9141
+ ? (a, b) => a.productId === b.productId
9142
+ : (a, b) => a.productVariantId === b.productVariantId;
9143
+ this.selectionManager = new SelectionManager({
9144
+ multiSelect: true,
9145
+ itemsAreEqual: idFn,
9146
+ additiveMode: true,
9147
+ });
9148
+ const searchQueryResult = this.dataService.product.searchProducts('', this.paginationConfig.itemsPerPage, 0);
9149
+ const result$ = combineLatest(this.searchTerm$, this.searchFacetValueIds$, this.paginationConfig$).subscribe(([term, facetValueIds, pagination]) => {
9150
+ const take = +pagination.itemsPerPage;
9151
+ const skip = (pagination.currentPage - 1) * take;
9152
+ return searchQueryResult.ref.refetch({
9153
+ input: { skip, take, term, facetValueIds, groupByProduct: this.mode === 'product' },
9154
+ });
9155
+ });
9156
+ this.items$ = searchQueryResult.stream$.pipe(tap(data => {
9157
+ this.paginationConfig.totalItems = data.search.totalItems;
9158
+ this.selectionManager.setCurrentItems(data.search.items);
9159
+ }), map(data => data.search.items));
9160
+ this.facetValues$ = searchQueryResult.stream$.pipe(map(data => data.search.facetValues));
9161
+ if (this.initialSelectionIds.length) {
9162
+ if (this.mode === 'product') {
9163
+ this.dataService.product
9164
+ .getProducts({
9165
+ filter: {
9166
+ id: {
9167
+ in: this.initialSelectionIds,
9168
+ },
9169
+ },
9170
+ })
9171
+ .single$.subscribe(({ products }) => {
9172
+ this.selectionManager.selectMultiple(products.items.map(product => ({
9173
+ productId: product.id,
9174
+ productName: product.name,
9175
+ })));
9176
+ this.changeDetector.markForCheck();
9177
+ });
9178
+ }
9179
+ else {
9180
+ this.dataService.product
9181
+ .getProductVariants({
9182
+ filter: {
9183
+ id: {
9184
+ in: this.initialSelectionIds,
9185
+ },
9186
+ },
9187
+ })
9188
+ .single$.subscribe(({ productVariants }) => {
9189
+ this.selectionManager.selectMultiple(productVariants.items.map(variant => ({
9190
+ productVariantId: variant.id,
9191
+ productVariantName: variant.name,
9192
+ })));
9193
+ this.changeDetector.markForCheck();
9194
+ });
9195
+ }
9196
+ }
9197
+ }
9198
+ trackByFn(index, item) {
9199
+ return item.productId;
9200
+ }
9201
+ setSearchTerm(term) {
9202
+ this.searchTerm$.next(term);
9203
+ }
9204
+ setFacetValueIds(ids) {
9205
+ this.searchFacetValueIds$.next(ids);
9206
+ }
9207
+ toggleSelection(item, event) {
9208
+ this.selectionManager.toggleSelection(item, event);
9209
+ }
9210
+ clearSelection() {
9211
+ this.selectionManager.selectMultiple([]);
9212
+ }
9213
+ isSelected(item) {
9214
+ return this.selectionManager.isSelected(item);
9215
+ }
9216
+ entityInfoClick(event) {
9217
+ event.preventDefault();
9218
+ event.stopPropagation();
9219
+ }
9220
+ pageChange(page) {
9221
+ this.paginationConfig.currentPage = page;
9222
+ this.paginationConfig$.next(this.paginationConfig);
9223
+ }
9224
+ itemsPerPageChange(itemsPerPage) {
9225
+ this.paginationConfig.itemsPerPage = itemsPerPage;
9226
+ this.paginationConfig$.next(this.paginationConfig);
9227
+ }
9228
+ select() {
9229
+ this.resolveWith(this.selectionManager.selection);
9230
+ }
9231
+ cancel() {
9232
+ this.resolveWith();
8837
9233
  }
8838
9234
  }
8839
- TextareaFormInputComponent.id = 'textarea-form-input';
8840
- TextareaFormInputComponent.decorators = [
9235
+ ProductMultiSelectorDialogComponent.decorators = [
8841
9236
  { type: Component, args: [{
8842
- selector: 'vdr-textarea-form-input',
8843
- template: "<textarea [spellcheck]=\"spellcheck\" autocomplete=\"off\" autocorrect=\"off\"\r\n [readonly]=\"readonly\"\r\n [formControl]=\"formControl\"\r\n></textarea>\r\n",
9237
+ selector: 'vdr-product-multi-selector-dialog',
9238
+ template: "<ng-template vdrDialogTitle>\r\n <div class=\"title-row\">\r\n <span *ngIf=\"mode === 'product'\">{{ 'common.select-products' | translate }}</span>\r\n <span *ngIf=\"mode === 'variant'\">{{ 'common.select-variants' | translate }}</span>\r\n </div>\r\n</ng-template>\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<div class=\"flex-wrapper\">\r\n <div class=\"gallery\">\r\n <div\r\n class=\"card\"\r\n *ngFor=\"let item of (items$ | async) || [] | paginate: paginationConfig; trackBy: trackByFn\"\r\n (click)=\"toggleSelection(item, $event)\"\r\n [class.selected]=\"isSelected(item)\"\r\n >\r\n <div class=\"card-img\">\r\n <vdr-select-toggle\r\n [selected]=\"isSelected(item)\"\r\n [disabled]=\"true\"\r\n [hiddenWhenOff]=\"true\"\r\n ></vdr-select-toggle>\r\n <img\r\n [src]=\"\r\n (mode === 'product'\r\n ? item.productAsset\r\n : item.productVariantAsset || item.productAsset\r\n ) | assetPreview: 'thumb'\r\n \"\r\n />\r\n </div>\r\n <div class=\"detail\">\r\n <span [title]=\"mode === 'product' ? item.productName : item.productVariantName\">{{\r\n mode === 'product' ? item.productName : item.productVariantName\r\n }}</span>\r\n <div *ngIf=\"mode === 'variant'\"><small>{{ item.sku }}</small></div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"selection\">\r\n <div class=\"m2 flex center\">\r\n <div>\r\n {{ 'common.items-selected-count' | translate: { count: selectionManager.selection.length } }}\r\n </div>\r\n <div class=\"flex-spacer\"></div>\r\n <button class=\"btn btn-sm btn-link\" (click)=\"clearSelection()\">\r\n <cds-icon shape=\"times\"></cds-icon> {{ 'common.clear-selection' | translate }}\r\n </button>\r\n </div>\r\n <div class=\"selected-items\">\r\n <div *ngFor=\"let item of selectionManager.selection\" class=\"flex item-row\">\r\n <div class=\"\">{{ mode === 'product' ? item.productName : item.productVariantName }}</div>\r\n <div class=\"flex-spacer\"></div>\r\n <div>\r\n <button class=\"icon-button\" (click)=\"toggleSelection(item, $event)\">\r\n <cds-icon shape=\"times\"></cds-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"paging-controls\">\r\n <vdr-items-per-page-controls\r\n [itemsPerPage]=\"paginationConfig.itemsPerPage\"\r\n (itemsPerPageChange)=\"itemsPerPageChange($event)\"\r\n ></vdr-items-per-page-controls>\r\n\r\n <vdr-pagination-controls\r\n [currentPage]=\"paginationConfig.currentPage\"\r\n [itemsPerPage]=\"paginationConfig.itemsPerPage\"\r\n [totalItems]=\"paginationConfig.totalItems\"\r\n (pageChange)=\"pageChange($event)\"\r\n ></vdr-pagination-controls>\r\n</div>\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)=\"select()\"\r\n class=\"btn btn-primary\"\r\n [disabled]=\"selectionManager.selection.length === 0\"\r\n >\r\n {{ 'common.select-items-with-count' | translate: { count: selectionManager.selection.length } }}\r\n </button>\r\n</ng-template>\r\n",
8844
9239
  changeDetection: ChangeDetectionStrategy.OnPush,
8845
- styles: [":host textarea{resize:both;height:6rem;width:100%}\n"]
9240
+ styles: [":host{display:flex;flex-direction:column;flex-direction:1;height:70vh}.flex-wrapper{display:flex;overflow-y:hidden}.gallery{flex:1;display:grid;grid-template-columns:repeat(auto-fill,125px);grid-template-rows:repeat(auto-fill,200px);grid-gap:10px 20px;padding-left:12px;padding-top:12px;padding-bottom:64px;overflow-y:auto}.gallery .card:hover{box-shadow:0 .125rem 0 0 var(--color-primary-500);border:1px solid var(--color-primary-500)}.detail{margin:0 3px;font-size:12px;line-height:.8rem}vdr-select-toggle{position:absolute;top:-12px;left:-12px}vdr-select-toggle ::ng-deep .toggle{box-shadow:0 5px 5px -4px #000000bf}.card.selected{box-shadow:0 .125rem 0 0 var(--color-primary-500);border:1px solid var(--color-primary-500)}.card.selected .selected-checkbox{opacity:1}.selection{width:23vw;max-width:400px;padding:6px;display:flex;flex-direction:column}.selection .selected-items{flex:1;overflow-y:auto}.selection .selected-items .item-row{padding-left:3px}.selection .selected-items .item-row:hover{background-color:var(--color-component-bg-200)}.paging-controls{display:flex;align-items:center;justify-content:space-between}\n"]
8846
9241
  },] }
9242
+ ];
9243
+ ProductMultiSelectorDialogComponent.ctorParameters = () => [
9244
+ { type: DataService },
9245
+ { type: ChangeDetectorRef }
8847
9246
  ];
8848
9247
 
8849
- const defaultFormInputs = [
8850
- BooleanFormInputComponent,
8851
- CurrencyFormInputComponent,
8852
- DateFormInputComponent,
8853
- FacetValueFormInputComponent,
8854
- NumberFormInputComponent,
8855
- SelectFormInputComponent,
8856
- TextFormInputComponent,
8857
- ProductSelectorFormInputComponent,
8858
- CustomerGroupFormInputComponent,
8859
- PasswordFormInputComponent,
8860
- RelationFormInputComponent,
8861
- TextareaFormInputComponent,
8862
- RichTextFormInputComponent,
8863
- JsonEditorFormInputComponent,
8864
- ];
8865
- /**
8866
- * @description
8867
- * Registers a custom FormInputComponent which can be used to control the argument inputs
8868
- * of a {@link ConfigurableOperationDef} (e.g. CollectionFilter, ShippingMethod etc) or for
8869
- * a custom field.
8870
- *
8871
- * @example
8872
- * ```TypeScript
8873
- * \@NgModule({
8874
- * imports: [SharedModule],
8875
- * declarations: [MyCustomFieldControl],
8876
- * providers: [
8877
- * registerFormInputComponent('my-custom-input', MyCustomFieldControl),
8878
- * ],
8879
- * })
8880
- * export class MyUiExtensionModule {}
8881
- * ```
8882
- *
8883
- * This input component can then be used in a custom field:
8884
- *
9248
+ class ProductMultiSelectorFormInputComponent {
9249
+ constructor(modalService, dataService, changeDetector) {
9250
+ this.modalService = modalService;
9251
+ this.dataService = dataService;
9252
+ this.changeDetector = changeDetector;
9253
+ this.mode = 'product';
9254
+ this.isListInput = true;
9255
+ }
9256
+ ngOnInit() {
9257
+ var _a, _b;
9258
+ this.mode = (_b = (_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.selectionMode) !== null && _b !== void 0 ? _b : 'product';
9259
+ }
9260
+ select() {
9261
+ this.modalService
9262
+ .fromComponent(ProductMultiSelectorDialogComponent, {
9263
+ size: 'xl',
9264
+ locals: {
9265
+ mode: this.mode,
9266
+ initialSelectionIds: this.formControl.value,
9267
+ },
9268
+ })
9269
+ .subscribe(selection => {
9270
+ if (selection) {
9271
+ this.formControl.setValue(selection.map(item => this.mode === 'product' ? item.productId : item.productVariantId));
9272
+ this.changeDetector.markForCheck();
9273
+ }
9274
+ });
9275
+ }
9276
+ }
9277
+ ProductMultiSelectorFormInputComponent.id = 'product-multi-form-input';
9278
+ ProductMultiSelectorFormInputComponent.decorators = [
9279
+ { type: Component, args: [{
9280
+ selector: 'vdr-product-multi-selector-form-input',
9281
+ template: "<div class=\"flex\">\r\n <button (click)=\"select()\" class=\"btn btn-sm btn-secondary\">\r\n {{ 'common.items-selected-count' | translate: { count: formControl.value?.length ?? 0 } }}...\r\n </button>\r\n</div>\r\n",
9282
+ changeDetection: ChangeDetectionStrategy.OnPush,
9283
+ styles: [""]
9284
+ },] }
9285
+ ];
9286
+ ProductMultiSelectorFormInputComponent.ctorParameters = () => [
9287
+ { type: ModalService },
9288
+ { type: DataService },
9289
+ { type: ChangeDetectorRef }
9290
+ ];
9291
+ ProductMultiSelectorFormInputComponent.propDecorators = {
9292
+ config: [{ type: Input }],
9293
+ formControl: [{ type: Input }],
9294
+ readonly: [{ type: Input }]
9295
+ };
9296
+
9297
+ /**
9298
+ * @description
9299
+ * Allows the selection of multiple ProductVariants via an autocomplete select input.
9300
+ * Should be used with `ID` type **list** fields which represent ProductVariant IDs.
9301
+ *
9302
+ * @docsCategory custom-input-components
9303
+ * @docsPage default-inputs
9304
+ */
9305
+ class ProductSelectorFormInputComponent {
9306
+ constructor(dataService) {
9307
+ this.dataService = dataService;
9308
+ this.isListInput = true;
9309
+ }
9310
+ ngOnInit() {
9311
+ this.formControl.setValidators([
9312
+ control => {
9313
+ if (!control.value || !control.value.length) {
9314
+ return {
9315
+ atLeastOne: { length: control.value.length },
9316
+ };
9317
+ }
9318
+ return null;
9319
+ },
9320
+ ]);
9321
+ this.selection$ = this.formControl.valueChanges.pipe(startWith(this.formControl.value), switchMap(value => {
9322
+ if (Array.isArray(value) && 0 < value.length) {
9323
+ return forkJoin(value.map(id => this.dataService.product
9324
+ .getProductVariant(id)
9325
+ .mapSingle(data => data.productVariant)));
9326
+ }
9327
+ return of([]);
9328
+ }), map(variants => variants.filter(notNullOrUndefined)));
9329
+ }
9330
+ addProductVariant(product) {
9331
+ const value = this.formControl.value;
9332
+ this.formControl.setValue([...new Set([...value, product.productVariantId])]);
9333
+ }
9334
+ removeProductVariant(id) {
9335
+ const value = this.formControl.value;
9336
+ this.formControl.setValue(value.filter(_id => _id !== id));
9337
+ }
9338
+ }
9339
+ ProductSelectorFormInputComponent.id = 'product-selector-form-input';
9340
+ ProductSelectorFormInputComponent.decorators = [
9341
+ { type: Component, args: [{
9342
+ selector: 'vdr-product-selector-form-input',
9343
+ template: "<ul class=\"list-unstyled\">\r\n <li *ngFor=\"let variant of selection$ | async\" class=\"variant\">\r\n <div class=\"thumb\">\r\n <img [src]=\"variant.product.featuredAsset | assetPreview: 32\" />\r\n </div>\r\n <div class=\"detail\">\r\n <div>{{ variant.name }}</div>\r\n <div class=\"sku\">{{ variant.sku }}</div>\r\n </div>\r\n <div class=\"flex-spacer\"></div>\r\n <button\r\n class=\"btn btn-link btn-sm btn-warning\"\r\n (click)=\"removeProductVariant(variant.id)\"\r\n [title]=\"'common.remove-item-from-list' | translate\"\r\n >\r\n <clr-icon shape=\"times\"></clr-icon>\r\n </button>\r\n </li>\r\n</ul>\r\n<vdr-product-selector (productSelected)=\"addProductVariant($event)\"></vdr-product-selector>\r\n",
9344
+ changeDetection: ChangeDetectionStrategy.OnPush,
9345
+ styles: [".variant{margin-bottom:6px;display:flex;align-items:center;transition:background-color .2s}.variant:hover{background-color:var(--color-component-bg-200)}.thumb{margin-right:6px}.sku{color:var(--color-grey-400);font-size:smaller;line-height:1em}\n"]
9346
+ },] }
9347
+ ];
9348
+ ProductSelectorFormInputComponent.ctorParameters = () => [
9349
+ { type: DataService }
9350
+ ];
9351
+
9352
+ /**
9353
+ * @description
9354
+ * The default input component for `relation` type custom fields. Allows the selection
9355
+ * of a ProductVariant, Product, Customer or Asset. For other entity types, a custom
9356
+ * implementation will need to be defined. See {@link registerFormInputComponent}.
9357
+ *
9358
+ * @docsCategory custom-input-components
9359
+ * @docsPage default-inputs
9360
+ */
9361
+ class RelationFormInputComponent {
9362
+ }
9363
+ RelationFormInputComponent.id = 'relation-form-input';
9364
+ RelationFormInputComponent.decorators = [
9365
+ { type: Component, args: [{
9366
+ selector: 'vdr-relation-form-input',
9367
+ template: "<div [ngSwitch]=\"config.entity\">\r\n <vdr-relation-asset-input\r\n *ngSwitchCase=\"'Asset'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-asset-input>\r\n <vdr-relation-product-input\r\n *ngSwitchCase=\"'Product'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-product-input>\r\n <vdr-relation-customer-input\r\n *ngSwitchCase=\"'Customer'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-customer-input>\r\n <vdr-relation-product-variant-input\r\n *ngSwitchCase=\"'ProductVariant'\"\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-product-variant-input>\r\n <ng-template ngSwitchDefault>\r\n <vdr-relation-generic-input\r\n [parentFormControl]=\"formControl\"\r\n [config]=\"config\"\r\n [readonly]=\"readonly\"\r\n ></vdr-relation-generic-input>\r\n </ng-template>\r\n</div>\r\n",
9368
+ changeDetection: ChangeDetectionStrategy.OnPush,
9369
+ styles: [":host{display:block;background-color:var(--color-component-bg-200);padding:3px}\n"]
9370
+ },] }
9371
+ ];
9372
+ RelationFormInputComponent.propDecorators = {
9373
+ readonly: [{ type: Input }]
9374
+ };
9375
+
9376
+ /**
9377
+ * @description
9378
+ * Uses the {@link RichTextEditorComponent} as in input for `text` type fields.
9379
+ *
9380
+ * @docsCategory custom-input-components
9381
+ * @docsPage default-inputs
9382
+ */
9383
+ class RichTextFormInputComponent {
9384
+ }
9385
+ RichTextFormInputComponent.id = 'rich-text-form-input';
9386
+ RichTextFormInputComponent.decorators = [
9387
+ { type: Component, args: [{
9388
+ selector: 'vdr-rich-text-form-input',
9389
+ template: "<vdr-rich-text-editor\r\n [readonly]=\"readonly\"\r\n [formControl]=\"formControl\"\r\n></vdr-rich-text-editor>\r\n",
9390
+ changeDetection: ChangeDetectionStrategy.OnPush,
9391
+ styles: [":host textarea{resize:both;height:6rem;width:100%}\n"]
9392
+ },] }
9393
+ ];
9394
+
9395
+ /**
9396
+ * @description
9397
+ * Uses a select input to allow the selection of a string value. Should be used with
9398
+ * `string` type fields with options.
9399
+ *
9400
+ * @docsCategory custom-input-components
9401
+ * @docsPage default-inputs
9402
+ */
9403
+ class SelectFormInputComponent {
9404
+ get options() {
9405
+ var _a;
9406
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.options) || this.config.options;
9407
+ }
9408
+ }
9409
+ SelectFormInputComponent.id = 'select-form-input';
9410
+ SelectFormInputComponent.decorators = [
9411
+ { type: Component, args: [{
9412
+ selector: 'vdr-select-form-input',
9413
+ template: "<select clrSelect [formControl]=\"formControl\" [vdrDisabled]=\"readonly\">\r\n <option *ngIf=\"config.nullable\" [ngValue]=\"null\"></option>\r\n <option *ngFor=\"let option of options\" [ngValue]=\"option.value\">\r\n {{ (option | customFieldLabel) || option.label || option.value }}\r\n </option>\r\n</select>\r\n",
9414
+ changeDetection: ChangeDetectionStrategy.OnPush,
9415
+ styles: ["select{width:100%}\n"]
9416
+ },] }
9417
+ ];
9418
+ SelectFormInputComponent.propDecorators = {
9419
+ readonly: [{ type: Input }]
9420
+ };
9421
+
9422
+ /**
9423
+ * @description
9424
+ * Uses a regular text form input. This is the default input for `string` and `localeString` type fields.
9425
+ *
9426
+ * @docsCategory custom-input-components
9427
+ * @docsPage default-inputs
9428
+ */
9429
+ class TextFormInputComponent {
9430
+ get prefix() {
9431
+ var _a;
9432
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.prefix) || this.config.prefix;
9433
+ }
9434
+ get suffix() {
9435
+ var _a;
9436
+ return ((_a = this.config.ui) === null || _a === void 0 ? void 0 : _a.suffix) || this.config.suffix;
9437
+ }
9438
+ }
9439
+ TextFormInputComponent.id = 'text-form-input';
9440
+ TextFormInputComponent.decorators = [
9441
+ { type: Component, args: [{
9442
+ selector: 'vdr-text-form-input',
9443
+ template: "<vdr-affixed-input\r\n [suffix]=\"suffix\"\r\n [prefix]=\"prefix\"\r\n>\r\n <input type=\"text\" [readonly]=\"readonly\" [formControl]=\"formControl\" />\r\n</vdr-affixed-input>\r\n",
9444
+ changeDetection: ChangeDetectionStrategy.OnPush,
9445
+ styles: ["input{width:100%}\n"]
9446
+ },] }
9447
+ ];
9448
+
9449
+ /**
9450
+ * @description
9451
+ * Uses textarea form input. This is the default input for `text` type fields.
9452
+ *
9453
+ * @docsCategory custom-input-components
9454
+ * @docsPage default-inputs
9455
+ */
9456
+ class TextareaFormInputComponent {
9457
+ get spellcheck() {
9458
+ return this.config.spellcheck === true;
9459
+ }
9460
+ }
9461
+ TextareaFormInputComponent.id = 'textarea-form-input';
9462
+ TextareaFormInputComponent.decorators = [
9463
+ { type: Component, args: [{
9464
+ selector: 'vdr-textarea-form-input',
9465
+ template: "<textarea [spellcheck]=\"spellcheck\" autocomplete=\"off\" autocorrect=\"off\"\r\n [readonly]=\"readonly\"\r\n [formControl]=\"formControl\"\r\n></textarea>\r\n",
9466
+ changeDetection: ChangeDetectionStrategy.OnPush,
9467
+ styles: [":host textarea{resize:both;height:6rem;width:100%}\n"]
9468
+ },] }
9469
+ ];
9470
+
9471
+ const defaultFormInputs = [
9472
+ BooleanFormInputComponent,
9473
+ CurrencyFormInputComponent,
9474
+ DateFormInputComponent,
9475
+ FacetValueFormInputComponent,
9476
+ NumberFormInputComponent,
9477
+ SelectFormInputComponent,
9478
+ TextFormInputComponent,
9479
+ ProductSelectorFormInputComponent,
9480
+ CustomerGroupFormInputComponent,
9481
+ PasswordFormInputComponent,
9482
+ RelationFormInputComponent,
9483
+ TextareaFormInputComponent,
9484
+ RichTextFormInputComponent,
9485
+ JsonEditorFormInputComponent,
9486
+ ProductMultiSelectorFormInputComponent,
9487
+ CombinationModeFormInputComponent,
9488
+ ];
9489
+ /**
9490
+ * @description
9491
+ * Registers a custom FormInputComponent which can be used to control the argument inputs
9492
+ * of a {@link ConfigurableOperationDef} (e.g. CollectionFilter, ShippingMethod etc) or for
9493
+ * a custom field.
9494
+ *
9495
+ * @example
9496
+ * ```TypeScript
9497
+ * \@NgModule({
9498
+ * imports: [SharedModule],
9499
+ * declarations: [MyCustomFieldControl],
9500
+ * providers: [
9501
+ * registerFormInputComponent('my-custom-input', MyCustomFieldControl),
9502
+ * ],
9503
+ * })
9504
+ * export class MyUiExtensionModule {}
9505
+ * ```
9506
+ *
9507
+ * This input component can then be used in a custom field:
9508
+ *
8885
9509
  * @example
8886
9510
  * ```TypeScript
8887
9511
  * const config = {
@@ -9080,7 +9704,7 @@ class AddressFormComponent {
9080
9704
  AddressFormComponent.decorators = [
9081
9705
  { type: Component, args: [{
9082
9706
  selector: 'vdr-address-form',
9083
- template: "<form [formGroup]=\"formGroup\">\r\n <clr-input-container>\r\n <label>{{ 'customer.full-name' | translate }}</label>\r\n <input formControlName=\"fullName\" type=\"text\" clrInput/>\r\n </clr-input-container>\r\n\r\n <div class=\"clr-row\">\r\n <div class=\"clr-col-md-4\">\r\n <clr-input-container>\r\n <label>{{ 'customer.street-line-1' | translate }}</label>\r\n <input formControlName=\"streetLine1\" type=\"text\" clrInput/>\r\n </clr-input-container>\r\n </div>\r\n <div class=\"clr-col-md-4\">\r\n <clr-input-container>\r\n <label>{{ 'customer.street-line-2' | translate }}</label>\r\n <input formControlName=\"streetLine2\" type=\"text\" clrInput/>\r\n </clr-input-container>\r\n </div>\r\n </div>\r\n <div class=\"clr-row\">\r\n <div class=\"clr-col-md-4\">\r\n <clr-input-container>\r\n <label>{{ 'customer.city' | translate }}</label>\r\n <input formControlName=\"city\" type=\"text\" clrInput/>\r\n </clr-input-container>\r\n </div>\r\n <div class=\"clr-col-md-4\">\r\n <clr-input-container>\r\n <label>{{ 'customer.province' | translate }}</label>\r\n <input formControlName=\"province\" type=\"text\" clrInput/>\r\n </clr-input-container>\r\n </div>\r\n </div>\r\n <div class=\"clr-row\">\r\n <div class=\"clr-col-md-4\">\r\n <clr-input-container>\r\n <label>{{ 'customer.postal-code' | translate }}</label>\r\n <input formControlName=\"postalCode\" type=\"text\" clrInput/>\r\n </clr-input-container>\r\n </div>\r\n <div class=\"clr-col-md-4\">\r\n <clr-input-container>\r\n <label>{{ 'customer.country' | translate }}</label>\r\n <select name=\"countryCode\" formControlName=\"countryCode\" clrInput clrSelect>\r\n <option *ngFor=\"let country of availableCountries\" [value]=\"country.code\">\r\n {{ country.name }}\r\n </option>\r\n </select>\r\n </clr-input-container>\r\n </div>\r\n </div>\r\n <clr-input-container>\r\n <label>{{ 'customer.phone-number' | translate }}</label>\r\n <input formControlName=\"phoneNumber\" type=\"text\" clrInput/>\r\n </clr-input-container>\r\n <section formGroupName=\"customFields\" *ngIf=\"formGroup.get('customFields') as customFieldsGroup\">\r\n <label>{{ 'common.custom-fields' | translate }}</label>\r\n <vdr-tabbed-custom-fields\r\n entityName=\"Address\"\r\n [customFields]=\"customFields\"\r\n [customFieldsFormGroup]=\"customFieldsGroup\"\r\n ></vdr-tabbed-custom-fields>\r\n </section>\r\n</form>\r\n",
9707
+ template: "<form [formGroup]=\"formGroup\">\n <div class=\"clr-row\">\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.full-name' | translate }}</label>\n <input formControlName=\"fullName\" type=\"text\" clrInput />\n </clr-input-container>\n </div>\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.company' | translate }}</label>\n <input formControlName=\"company\" type=\"text\" clrInput />\n </clr-input-container>\n </div>\n </div>\n\n <div class=\"clr-row\">\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.street-line-1' | translate }}</label>\n <input formControlName=\"streetLine1\" type=\"text\" clrInput />\n </clr-input-container>\n </div>\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.street-line-2' | translate }}</label>\n <input formControlName=\"streetLine2\" type=\"text\" clrInput />\n </clr-input-container>\n </div>\n </div>\n <div class=\"clr-row\">\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.city' | translate }}</label>\n <input formControlName=\"city\" type=\"text\" clrInput />\n </clr-input-container>\n </div>\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.province' | translate }}</label>\n <input formControlName=\"province\" type=\"text\" clrInput />\n </clr-input-container>\n </div>\n </div>\n <div class=\"clr-row\">\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.postal-code' | translate }}</label>\n <input formControlName=\"postalCode\" type=\"text\" clrInput />\n </clr-input-container>\n </div>\n <div class=\"clr-col-md-4\">\n <clr-input-container>\n <label>{{ 'customer.country' | translate }}</label>\n <select name=\"countryCode\" formControlName=\"countryCode\" clrInput clrSelect>\n <option *ngFor=\"let country of availableCountries\" [value]=\"country.code\">\n {{ country.name }}\n </option>\n </select>\n </clr-input-container>\n </div>\n </div>\n <clr-input-container>\n <label>{{ 'customer.phone-number' | translate }}</label>\n <input formControlName=\"phoneNumber\" type=\"text\" clrInput />\n </clr-input-container>\n <section formGroupName=\"customFields\" *ngIf=\"formGroup.get('customFields') as customFieldsGroup\">\n <label>{{ 'common.custom-fields' | translate }}</label>\n <vdr-tabbed-custom-fields\n entityName=\"Address\"\n [customFields]=\"customFields\"\n [customFieldsFormGroup]=\"customFieldsGroup\"\n ></vdr-tabbed-custom-fields>\n </section>\n</form>\n",
9084
9708
  changeDetection: ChangeDetectionStrategy.OnPush,
9085
9709
  styles: [""]
9086
9710
  },] }
@@ -9307,11 +9931,15 @@ class AssetGalleryComponent {
9307
9931
  this.canDelete = false;
9308
9932
  this.selectionChange = new EventEmitter();
9309
9933
  this.deleteAssets = new EventEmitter();
9310
- this.selection = [];
9934
+ this.selectionManager = new SelectionManager({
9935
+ multiSelect: this.multiSelect,
9936
+ itemsAreEqual: (a, b) => a.id === b.id,
9937
+ additiveMode: false,
9938
+ });
9311
9939
  }
9312
- ngOnChanges() {
9940
+ ngOnChanges(changes) {
9313
9941
  if (this.assets) {
9314
- for (const asset of this.selection) {
9942
+ for (const asset of this.selectionManager.selection) {
9315
9943
  // Update and selected assets with any changes
9316
9944
  const match = this.assets.find(a => a.id === asset.id);
9317
9945
  if (match) {
@@ -9319,49 +9947,26 @@ class AssetGalleryComponent {
9319
9947
  }
9320
9948
  }
9321
9949
  }
9322
- }
9323
- toggleSelection(asset, event) {
9324
- const index = this.selection.findIndex(a => a.id === asset.id);
9325
- if (this.multiSelect && (event === null || event === void 0 ? void 0 : event.shiftKey) && 1 <= this.selection.length) {
9326
- const lastSelection = this.selection[this.selection.length - 1];
9327
- const lastSelectionIndex = this.assets.findIndex(a => a.id === lastSelection.id);
9328
- const currentIndex = this.assets.findIndex(a => a.id === asset.id);
9329
- const start = currentIndex < lastSelectionIndex ? currentIndex : lastSelectionIndex;
9330
- const end = currentIndex > lastSelectionIndex ? currentIndex + 1 : lastSelectionIndex;
9331
- this.selection.push(...this.assets.slice(start, end).filter(a => !this.selection.find(s => s.id === a.id)));
9950
+ if (changes['assets']) {
9951
+ this.selectionManager.setCurrentItems(this.assets);
9332
9952
  }
9333
- else if (index === -1) {
9334
- if (this.multiSelect && ((event === null || event === void 0 ? void 0 : event.ctrlKey) || (event === null || event === void 0 ? void 0 : event.shiftKey))) {
9335
- this.selection.push(asset);
9336
- }
9337
- else {
9338
- this.selection = [asset];
9339
- }
9953
+ if (changes['multiSelect']) {
9954
+ this.selectionManager.setMultiSelect(this.multiSelect);
9340
9955
  }
9341
- else {
9342
- if (this.multiSelect && (event === null || event === void 0 ? void 0 : event.ctrlKey)) {
9343
- this.selection.splice(index, 1);
9344
- }
9345
- else if (1 < this.selection.length) {
9346
- this.selection = [asset];
9347
- }
9348
- else {
9349
- this.selection.splice(index, 1);
9350
- }
9351
- }
9352
- // Make the selection mutable
9353
- this.selection = this.selection.map(x => (Object.assign({}, x)));
9354
- this.selectionChange.emit(this.selection);
9956
+ }
9957
+ toggleSelection(asset, event) {
9958
+ this.selectionManager.toggleSelection(asset, event);
9959
+ this.selectionChange.emit(this.selectionManager.selection);
9355
9960
  }
9356
9961
  selectMultiple(assets) {
9357
- this.selection = assets;
9358
- this.selectionChange.emit(this.selection);
9962
+ this.selectionManager.selectMultiple(assets);
9963
+ this.selectionChange.emit(this.selectionManager.selection);
9359
9964
  }
9360
9965
  isSelected(asset) {
9361
- return !!this.selection.find(a => a.id === asset.id);
9966
+ return this.selectionManager.isSelected(asset);
9362
9967
  }
9363
9968
  lastSelected() {
9364
- return this.selection[this.selection.length - 1];
9969
+ return this.selectionManager.lastSelected();
9365
9970
  }
9366
9971
  previewAsset(asset) {
9367
9972
  this.modalService
@@ -9380,9 +9985,9 @@ class AssetGalleryComponent {
9380
9985
  AssetGalleryComponent.decorators = [
9381
9986
  { type: Component, args: [{
9382
9987
  selector: 'vdr-asset-gallery',
9383
- template: "<div class=\"gallery\">\r\n <div\r\n class=\"card\"\r\n *ngFor=\"let asset of assets\"\r\n (click)=\"toggleSelection(asset, $event)\"\r\n [class.selected]=\"isSelected(asset)\"\r\n >\r\n <div class=\"card-img\">\r\n <div class=\"selected-checkbox\"><clr-icon shape=\"check-circle\" size=\"32\"></clr-icon></div>\r\n <img [src]=\"asset | assetPreview: 'thumb'\" />\r\n </div>\r\n <div class=\"detail\">\r\n <vdr-entity-info\r\n [entity]=\"asset\"\r\n [small]=\"true\"\r\n (click)=\"entityInfoClick($event)\"\r\n ></vdr-entity-info>\r\n <span [title]=\"asset.name\">{{ asset.name }}</span>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"info-bar\">\r\n <div class=\"card\">\r\n <div class=\"card-img\">\r\n <div class=\"placeholder\" *ngIf=\"selection.length === 0\">\r\n <clr-icon shape=\"image\" size=\"128\"></clr-icon>\r\n <div>{{ 'catalog.no-selection' | translate }}</div>\r\n </div>\r\n <img\r\n class=\"preview\"\r\n *ngIf=\"selection.length >= 1\"\r\n [src]=\"lastSelected().preview + '?preset=medium'\"\r\n />\r\n </div>\r\n <div class=\"card-block details\" *ngIf=\"selection.length >= 1\">\r\n <div class=\"name\">{{ lastSelected().name }}</div>\r\n <div>{{ 'asset.original-asset-size' | translate }}: {{ lastSelected().fileSize | filesize }}</div>\r\n\r\n <ng-container *ngIf=\"selection.length === 1\">\r\n <vdr-chip *ngFor=\"let tag of lastSelected().tags\" [colorFrom]=\"tag.value\"\r\n ><clr-icon shape=\"tag\" class=\"mr2\"></clr-icon> {{ tag.value }}</vdr-chip\r\n >\r\n <div>\r\n <button (click)=\"previewAsset(lastSelected())\" class=\"btn btn-link\">\r\n <clr-icon shape=\"eye\"></clr-icon> {{ 'asset.preview' | translate }}\r\n </button>\r\n </div>\r\n <div>\r\n <vdr-asset-preview-links class=\"\" [asset]=\"lastSelected()\"></vdr-asset-preview-links>\r\n </div>\r\n <div>\r\n <a [routerLink]=\"['./', lastSelected().id]\" class=\"btn btn-link\">\r\n <clr-icon shape=\"pencil\"></clr-icon> {{ 'common.edit' | translate }}\r\n </a>\r\n </div>\r\n </ng-container>\r\n <div *ngIf=\"canDelete\">\r\n <button (click)=\"deleteAssets.emit(selection)\" class=\"btn btn-link\">\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon> {{ 'common.delete' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card stack\" [class.visible]=\"selection.length > 1\"></div>\r\n <div class=\"selection-count\" [class.visible]=\"selection.length > 1\">\r\n {{ 'asset.assets-selected-count' | translate: { count: selection.length } }}\r\n <ul>\r\n <li *ngFor=\"let asset of selection\">{{ asset.name }}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n",
9988
+ template: "<div class=\"gallery\">\r\n <div\r\n class=\"card\"\r\n *ngFor=\"let asset of assets\"\r\n (click)=\"toggleSelection(asset, $event)\"\r\n [class.selected]=\"isSelected(asset)\"\r\n >\r\n <div class=\"card-img\">\r\n <vdr-select-toggle\r\n [selected]=\"isSelected(asset)\"\r\n [disabled]=\"true\"\r\n [hiddenWhenOff]=\"true\"\r\n ></vdr-select-toggle>\r\n <img class=\"asset-thumb\" [src]=\"asset | assetPreview: 'thumb'\" />\r\n </div>\r\n <div class=\"detail\">\r\n <vdr-entity-info\r\n [entity]=\"asset\"\r\n [small]=\"true\"\r\n (click)=\"entityInfoClick($event)\"\r\n ></vdr-entity-info>\r\n <span [title]=\"asset.name\">{{ asset.name }}</span>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"info-bar\">\r\n <div class=\"card\">\r\n <div class=\"card-img\">\r\n <div class=\"placeholder\" *ngIf=\"selectionManager.selection.length === 0\">\r\n <clr-icon shape=\"image\" size=\"128\"></clr-icon>\r\n <div>{{ 'catalog.no-selection' | translate }}</div>\r\n </div>\r\n <img\r\n class=\"preview\"\r\n *ngIf=\"selectionManager.selection.length >= 1\"\r\n [src]=\"lastSelected().preview + '?preset=medium'\"\r\n />\r\n </div>\r\n <div class=\"card-block details\" *ngIf=\"selectionManager.selection.length >= 1\">\r\n <div class=\"name\">{{ lastSelected().name }}</div>\r\n <div>{{ 'asset.original-asset-size' | translate }}: {{ lastSelected().fileSize | filesize }}</div>\r\n\r\n <ng-container *ngIf=\"selectionManager.selection.length === 1\">\r\n <vdr-chip *ngFor=\"let tag of lastSelected().tags\" [colorFrom]=\"tag.value\"\r\n ><clr-icon shape=\"tag\" class=\"mr2\"></clr-icon> {{ tag.value }}</vdr-chip\r\n >\r\n <div>\r\n <button (click)=\"previewAsset(lastSelected())\" class=\"btn btn-link\">\r\n <clr-icon shape=\"eye\"></clr-icon> {{ 'asset.preview' | translate }}\r\n </button>\r\n </div>\r\n <div>\r\n <vdr-asset-preview-links class=\"\" [asset]=\"lastSelected()\"></vdr-asset-preview-links>\r\n </div>\r\n <div>\r\n <a [routerLink]=\"['./', lastSelected().id]\" class=\"btn btn-link\">\r\n <clr-icon shape=\"pencil\"></clr-icon> {{ 'common.edit' | translate }}\r\n </a>\r\n </div>\r\n </ng-container>\r\n <div *ngIf=\"canDelete\">\r\n <button (click)=\"deleteAssets.emit(selectionManager.selection)\" class=\"btn btn-link\">\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon> {{ 'common.delete' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card stack\" [class.visible]=\"selectionManager.selection.length > 1\"></div>\r\n <div class=\"selection-count\" [class.visible]=\"selectionManager.selection.length > 1\">\r\n {{ 'asset.assets-selected-count' | translate: { count: selectionManager.selection.length } }}\r\n <ul>\r\n <li *ngFor=\"let asset of selectionManager.selection\">{{ asset.name }}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n",
9384
9989
  changeDetection: ChangeDetectionStrategy.OnPush,
9385
- styles: [":host{display:flex;overflow:hidden}.gallery{flex:1;display:grid;grid-template-columns:repeat(auto-fill,150px);grid-template-rows:repeat(auto-fill,180px);grid-gap:10px 20px;overflow-y:auto;padding-left:12px;padding-top:12px;padding-bottom:12px}.gallery .card:hover{box-shadow:0 .125rem 0 0 var(--color-primary-500);border:1px solid var(--color-primary-500)}.card{margin-top:0;position:relative}.selected-checkbox{opacity:0;position:absolute;color:var(--color-success-500);background-color:#fff;border-radius:50%;top:-12px;left:-12px;box-shadow:0 5px 5px -4px #000000bf;transition:opacity .1s}.card.selected{box-shadow:0 .125rem 0 0 var(--color-primary-500);border:1px solid var(--color-primary-500)}.card.selected .selected-checkbox{opacity:1}.detail{font-size:12px;margin:3px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.detail vdr-entity-info{height:16px}.info-bar{width:25%;padding:0 6px;overflow-y:auto}.info-bar .card{z-index:1}.info-bar .stack{z-index:0;opacity:0;transform:perspective(500px) translateZ(0) translateY(-16px);height:16px;transition:transform .3s,opacity 0s .3s;background-color:#fff}.info-bar .stack.visible{opacity:1;transform:perspective(500px) translateZ(-44px) translateY(0);background-color:var(--color-component-bg-100);transition:transform .3s,color .3s}.info-bar .selection-count{opacity:0;position:relative;text-align:center;visibility:hidden;transition:opacity .3s,visibility 0s .3s}.info-bar .selection-count.visible{opacity:1;visibility:visible;transition:opacity .3s,visibility 0s}.info-bar .selection-count ul{text-align:left;list-style-type:none;margin-left:12px}.info-bar .selection-count ul li{font-size:12px}.info-bar .placeholder{text-align:center;color:var(--color-grey-300)}.info-bar .preview img{max-width:100%}.info-bar .details{font-size:12px;word-break:break-all}.info-bar .name{line-height:14px;font-weight:bold}\n"]
9990
+ styles: [":host{display:flex;overflow:hidden}.gallery{flex:1;display:grid;grid-template-columns:repeat(auto-fill,150px);grid-template-rows:repeat(auto-fill,180px);grid-gap:10px 20px;overflow-y:auto;padding-left:12px;padding-top:12px;padding-bottom:12px}.gallery .card:hover{box-shadow:0 .125rem 0 0 var(--color-primary-500);border:1px solid var(--color-primary-500)}.card{margin-top:0;position:relative}img.asset-thumb{aspect-ratio:1}vdr-select-toggle{position:absolute;top:-12px;left:-12px}vdr-select-toggle ::ng-deep .toggle{box-shadow:0 5px 5px -4px #000000bf}.card.selected{box-shadow:0 .125rem 0 0 var(--color-primary-500);border:1px solid var(--color-primary-500)}.card.selected .selected-checkbox{opacity:1}.detail{font-size:12px;margin:3px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.detail vdr-entity-info{height:16px}.info-bar{width:25%;padding:0 6px;overflow-y:auto}.info-bar .card{z-index:1}.info-bar .stack{z-index:0;opacity:0;transform:perspective(500px) translateZ(0) translateY(-16px);height:16px;transition:transform .3s,opacity 0s .3s;background-color:#fff}.info-bar .stack.visible{opacity:1;transform:perspective(500px) translateZ(-44px) translateY(0);background-color:var(--color-component-bg-100);transition:transform .3s,color .3s}.info-bar .selection-count{opacity:0;position:relative;text-align:center;visibility:hidden;transition:opacity .3s,visibility 0s .3s}.info-bar .selection-count.visible{opacity:1;visibility:visible;transition:opacity .3s,visibility 0s}.info-bar .selection-count ul{text-align:left;list-style-type:none;margin-left:12px}.info-bar .selection-count ul li{font-size:12px}.info-bar .placeholder{text-align:center;color:var(--color-grey-300)}.info-bar .preview img{max-width:100%}.info-bar .details{font-size:12px;word-break:break-all}.info-bar .name{line-height:14px;font-weight:bold}\n"]
9386
9991
  },] }
9387
9992
  ];
9388
9993
  AssetGalleryComponent.ctorParameters = () => [
@@ -9817,7 +10422,7 @@ function SingleSearchSelectionModelFactory() {
9817
10422
  return new SingleSearchSelectionModel();
9818
10423
  }
9819
10424
 
9820
- const ɵ0 = SingleSearchSelectionModelFactory;
10425
+ const ɵ0$1 = SingleSearchSelectionModelFactory;
9821
10426
  class AssetSearchInputComponent {
9822
10427
  constructor() {
9823
10428
  this.searchTermChange = new EventEmitter();
@@ -9903,7 +10508,7 @@ AssetSearchInputComponent.decorators = [
9903
10508
  selector: 'vdr-asset-search-input',
9904
10509
  template: "<ng-select\r\n [addTag]=\"addTagFn\"\r\n [placeholder]=\"'catalog.search-asset-name-or-tag' | translate\"\r\n [items]=\"tags\"\r\n [searchFn]=\"filterTagResults\"\r\n [hideSelected]=\"true\"\r\n [multiple]=\"true\"\r\n [markFirst]=\"false\"\r\n (change)=\"onSelectChange($event)\"\r\n #selectComponent\r\n>\r\n <ng-template ng-header-tmp>\r\n <div\r\n class=\"search-header\"\r\n *ngIf=\"selectComponent.searchTerm\"\r\n [class.selected]=\"isSearchHeaderSelected()\"\r\n (click)=\"selectComponent.selectTag()\"\r\n >\r\n {{ 'catalog.search-for-term' | translate }}: {{ selectComponent.searchTerm }}\r\n </div>\r\n </ng-template>\r\n <ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\">\r\n <ng-container *ngIf=\"item.value\">\r\n <vdr-chip [colorFrom]=\"item.value\" icon=\"close\" (iconClick)=\"clear(item)\"><clr-icon shape=\"tag\" class=\"mr2\"></clr-icon> {{ item.value }}</vdr-chip>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.value\">\r\n <vdr-chip [icon]=\"'times'\" (iconClick)=\"clear(item)\">\"{{ item.label || item }}\"</vdr-chip>\r\n </ng-container>\r\n </ng-template>\r\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\">\r\n <ng-container *ngIf=\"item.value\">\r\n <vdr-chip [colorFrom]=\"item.value\"><clr-icon shape=\"tag\" class=\"mr2\"></clr-icon> {{ item.value }}</vdr-chip>\r\n </ng-container>\r\n </ng-template>\r\n</ng-select>\r\n",
9905
10510
  changeDetection: ChangeDetectionStrategy.OnPush,
9906
- providers: [{ provide: SELECTION_MODEL_FACTORY, useValue: ɵ0 }],
10511
+ providers: [{ provide: SELECTION_MODEL_FACTORY, useValue: ɵ0$1 }],
9907
10512
  styles: [":host{display:block;width:100%}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{background:none;margin:0}:host ::ng-deep .ng-dropdown-panel-items div.ng-option:last-child{display:none}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-header{border:none;padding:0}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container{padding:0}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{padding-left:8px}ng-select{width:100%;min-width:300px;margin-right:12px}.search-header{padding:8px 10px;border-bottom:1px solid var(--color-component-border-100);cursor:pointer}.search-header.selected,.search-header:hover{background-color:var(--color-component-bg-200)}\n"]
9908
10513
  },] }
9909
10514
  ];
@@ -9921,404 +10526,158 @@ class ChannelAssignmentControlComponent {
9921
10526
  this.includeDefaultChannel = true;
9922
10527
  this.disableChannelIds = [];
9923
10528
  this.value = [];
9924
- this.disabled = false;
9925
- }
9926
- ngOnInit() {
9927
- this.channels$ = this.dataService.client.userStatus().single$.pipe(map(({ userStatus }) => userStatus.channels.filter(c => this.includeDefaultChannel ? true : c.code !== DEFAULT_CHANNEL_CODE)), tap(channels => {
9928
- if (!this.channels) {
9929
- this.channels = channels;
9930
- this.mapIncomingValueToChannels(this.lastIncomingValue);
9931
- }
9932
- else {
9933
- this.channels = channels;
9934
- }
9935
- }));
9936
- }
9937
- registerOnChange(fn) {
9938
- this.onChange = fn;
9939
- }
9940
- registerOnTouched(fn) {
9941
- this.onTouched = fn;
9942
- }
9943
- setDisabledState(isDisabled) {
9944
- this.disabled = isDisabled;
9945
- }
9946
- writeValue(obj) {
9947
- this.lastIncomingValue = obj;
9948
- this.mapIncomingValueToChannels(obj);
9949
- }
9950
- focussed() {
9951
- if (this.onTouched) {
9952
- this.onTouched();
9953
- }
9954
- }
9955
- channelIsDisabled(id) {
9956
- return this.disableChannelIds.includes(id);
9957
- }
9958
- valueChanged(value) {
9959
- if (Array.isArray(value)) {
9960
- this.onChange(value.map(c => c.id));
9961
- }
9962
- else {
9963
- this.onChange([value ? value.id : undefined]);
9964
- }
9965
- }
9966
- compareFn(c1, c2) {
9967
- const c1id = typeof c1 === 'string' ? c1 : c1.id;
9968
- const c2id = typeof c2 === 'string' ? c2 : c2.id;
9969
- return c1id === c2id;
9970
- }
9971
- mapIncomingValueToChannels(value) {
9972
- var _a;
9973
- if (Array.isArray(value)) {
9974
- if (typeof value[0] === 'string') {
9975
- this.value = value
9976
- .map(id => { var _a; return (_a = this.channels) === null || _a === void 0 ? void 0 : _a.find(c => c.id === id); })
9977
- .filter(notNullOrUndefined);
9978
- }
9979
- else {
9980
- this.value = value;
9981
- }
9982
- }
9983
- else {
9984
- if (typeof value === 'string') {
9985
- const channel = (_a = this.channels) === null || _a === void 0 ? void 0 : _a.find(c => c.id === value);
9986
- if (channel) {
9987
- this.value = [channel];
9988
- }
9989
- }
9990
- else if (value && value.id) {
9991
- this.value = [value];
9992
- }
9993
- }
9994
- }
9995
- }
9996
- ChannelAssignmentControlComponent.decorators = [
9997
- { type: Component, args: [{
9998
- selector: 'vdr-channel-assignment-control',
9999
- template: "<ng-select\r\n appendTo=\"body\"\r\n [addTag]=\"false\"\r\n [multiple]=\"multiple\"\r\n [ngModel]=\"value\"\r\n [clearable]=\"false\"\r\n [searchable]=\"false\"\r\n [disabled]=\"disabled\"\r\n [compareWith]=\"compareFn\"\r\n (focus)=\"focussed()\"\r\n (change)=\"valueChanged($event)\"\r\n>\r\n <ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\">\r\n <span aria-hidden=\"true\" class=\"ng-value-icon left\" (click)=\"clear(item)\"> \u00D7 </span>\r\n <vdr-channel-badge [channelCode]=\"item.code\"></vdr-channel-badge>\r\n <span class=\"channel-label\">{{ item.code | channelCodeToLabel | translate }}</span>\r\n </ng-template>\r\n <ng-option *ngFor=\"let item of channels$ | async\" [value]=\"item\" [disabled]=\"channelIsDisabled(item.id)\">\r\n <vdr-channel-badge [channelCode]=\"item.code\"></vdr-channel-badge>\r\n {{ item.code | channelCodeToLabel | translate }}\r\n </ng-option>\r\n</ng-select>\r\n\r\n",
10000
- changeDetection: ChangeDetectionStrategy.Default,
10001
- providers: [
10002
- {
10003
- provide: NG_VALUE_ACCESSOR,
10004
- useExisting: ChannelAssignmentControlComponent,
10005
- multi: true,
10006
- },
10007
- ],
10008
- styles: [":host{min-width:200px}:host.clr-input{border-bottom:none;padding:0}::ng-deep .ng-value>vdr-channel-badge,::ng-deep .ng-option>vdr-channel-badge{margin-bottom:-1px}::ng-deep .ng-value>vdr-channel-badge{margin-left:6px}.channel-label{margin-right:6px}\n"]
10009
- },] }
10010
- ];
10011
- ChannelAssignmentControlComponent.ctorParameters = () => [
10012
- { type: DataService }
10013
- ];
10014
- ChannelAssignmentControlComponent.propDecorators = {
10015
- multiple: [{ type: Input }],
10016
- includeDefaultChannel: [{ type: Input }],
10017
- disableChannelIds: [{ type: Input }]
10018
- };
10019
-
10020
- class ChannelBadgeComponent {
10021
- get isDefaultChannel() {
10022
- return this.channelCode === DEFAULT_CHANNEL_CODE;
10023
- }
10024
- }
10025
- ChannelBadgeComponent.decorators = [
10026
- { type: Component, args: [{
10027
- selector: 'vdr-channel-badge',
10028
- template: "<clr-icon shape=\"layers\" [style.color]=\"isDefaultChannel ? '#aaa' : (channelCode | stringToColor)\"></clr-icon>\r\n",
10029
- changeDetection: ChangeDetectionStrategy.OnPush,
10030
- styles: [":host{display:inline-block}button :host{margin-bottom:-1px}clr-icon{margin-right:6px}\n"]
10031
- },] }
10032
- ];
10033
- ChannelBadgeComponent.propDecorators = {
10034
- channelCode: [{ type: Input }]
10035
- };
10036
-
10037
- /**
10038
- * @description
10039
- * A chip component for displaying a label with an optional action icon.
10040
- *
10041
- * @example
10042
- * ```HTML
10043
- * <vdr-chip [colorFrom]="item.value"
10044
- * icon="close"
10045
- * (iconClick)="clear(item)">
10046
- * {{ item.value }}</vdr-chip>
10047
- * ```
10048
- * @docsCategory components
10049
- */
10050
- class ChipComponent {
10051
- constructor() {
10052
- this.invert = false;
10053
- /**
10054
- * @description
10055
- * If set, the chip will have an auto-generated background
10056
- * color based on the string value passed in.
10057
- */
10058
- this.colorFrom = '';
10059
- this.iconClick = new EventEmitter();
10060
- }
10061
- }
10062
- ChipComponent.decorators = [
10063
- { type: Component, args: [{
10064
- selector: 'vdr-chip',
10065
- template: "<div\r\n class=\"wrapper\"\r\n [class.with-background]=\"!invert && colorFrom\"\r\n [style.backgroundColor]=\"!invert && (colorFrom | stringToColor)\"\r\n [style.color]=\"invert && (colorFrom | stringToColor)\"\r\n [style.borderColor]=\"invert && (colorFrom | stringToColor)\"\r\n [ngClass]=\"colorType\"\r\n>\r\n <div class=\"chip-label\"><ng-content></ng-content></div>\r\n <div class=\"chip-icon\" *ngIf=\"icon\">\r\n <button (click)=\"iconClick.emit($event)\">\r\n <clr-icon\r\n [attr.shape]=\"icon\"\r\n [style.color]=\"invert && (colorFrom | stringToColor)\"\r\n [class.is-inverse]=\"!invert && colorFrom\"\r\n ></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n",
10066
- changeDetection: ChangeDetectionStrategy.OnPush,
10067
- styles: [":host{display:inline-block}.wrapper{display:flex;border:1px solid var(--color-component-border-300);border-radius:3px;margin:6px}.wrapper.with-background{color:var(--color-grey-100);border-color:transparent}.wrapper.with-background .chip-label{opacity:.9}.wrapper.warning{border-color:var(--color-chip-warning-border)}.wrapper.warning .chip-label{color:var(--color-chip-warning-text);background-color:var(--color-chip-warning-bg)}.wrapper.success{border-color:var(--color-chip-success-border)}.wrapper.success .chip-label{color:var(--color-chip-success-text);background-color:var(--color-chip-success-bg)}.wrapper.error{border-color:var(--color-chip-error-border)}.wrapper.error .chip-label{color:var(--color-chip-error-text);background-color:var(--color-chip-error-bg)}.chip-label{padding:3px 6px;line-height:1em;border-radius:3px;white-space:nowrap;display:flex;align-items:center}.chip-icon{border-left:1px solid var(--color-component-border-200);padding:0 3px;line-height:1em;display:flex}.chip-icon button{cursor:pointer;background:none;margin:0;padding:0;border:none}\n"]
10068
- },] }
10069
- ];
10070
- ChipComponent.propDecorators = {
10071
- icon: [{ type: Input }],
10072
- invert: [{ type: Input }],
10073
- colorFrom: [{ type: Input }],
10074
- colorType: [{ type: Input }],
10075
- iconClick: [{ type: Output }]
10076
- };
10077
-
10078
- /**
10079
- * ConfigArg values are always stored as strings. If they are not primitives, then
10080
- * they are JSON-encoded. This function unwraps them back into their original
10081
- * data type.
10082
- */
10083
- function getConfigArgValue(value) {
10084
- try {
10085
- return value ? JSON.parse(value) : undefined;
10086
- }
10087
- catch (e) {
10088
- return value;
10089
- }
10090
- }
10091
- function encodeConfigArgValue(value) {
10092
- return Array.isArray(value) ? JSON.stringify(value) : (value !== null && value !== void 0 ? value : '').toString();
10093
- }
10094
- /**
10095
- * Creates an empty ConfigurableOperation object based on the definition.
10096
- */
10097
- function configurableDefinitionToInstance(def) {
10098
- return Object.assign(Object.assign({}, def), { args: def.args.map(arg => {
10099
- return Object.assign(Object.assign({}, arg), { value: getDefaultConfigArgValue(arg) });
10100
- }) });
10101
- }
10102
- /**
10103
- * Converts an object of the type:
10104
- * ```
10105
- * {
10106
- * code: 'my-operation',
10107
- * args: {
10108
- * someProperty: 'foo'
10109
- * }
10110
- * }
10111
- * ```
10112
- * to the format defined by the ConfigurableOperationInput GraphQL input type:
10113
- * ```
10114
- * {
10115
- * code: 'my-operation',
10116
- * args: [
10117
- * { name: 'someProperty', value: 'foo' }
10118
- * ]
10119
- * }
10120
- * ```
10121
- */
10122
- function toConfigurableOperationInput(operation, formValueOperations) {
10123
- return {
10124
- code: operation.code,
10125
- arguments: Object.values(formValueOperations.args || {}).map((value, j) => ({
10126
- name: operation.args[j].name,
10127
- value: value.hasOwnProperty('value')
10128
- ? encodeConfigArgValue(value.value)
10129
- : encodeConfigArgValue(value),
10130
- })),
10131
- };
10132
- }
10133
- function configurableOperationValueIsValid(def, value) {
10134
- if (!def || !value) {
10135
- return false;
10136
- }
10137
- if (def.code !== value.code) {
10138
- return false;
10139
- }
10140
- for (const argDef of def.args) {
10141
- const argVal = value.args[argDef.name];
10142
- if (argDef.required && (argVal == null || argVal === '' || argVal === '0')) {
10143
- return false;
10144
- }
10145
- }
10146
- return true;
10147
- }
10148
- /**
10149
- * Returns a default value based on the type of the config arg.
10150
- */
10151
- function getDefaultConfigArgValue(arg) {
10152
- if (arg.list) {
10153
- return [];
10154
- }
10155
- if (arg.defaultValue) {
10156
- return arg.defaultValue;
10157
- }
10158
- const type = arg.type;
10159
- switch (type) {
10160
- case 'string':
10161
- case 'datetime':
10162
- case 'float':
10163
- case 'ID':
10164
- case 'int':
10165
- return null;
10166
- case 'boolean':
10167
- return false;
10168
- default:
10169
- assertNever(type);
10170
- }
10171
- }
10172
-
10173
- /**
10174
- * Interpolates the description of an ConfigurableOperation with the given values.
10175
- */
10176
- function interpolateDescription(operation, values) {
10177
- if (!operation) {
10178
- return '';
10179
- }
10180
- const templateString = operation.description;
10181
- const interpolated = templateString.replace(/{\s*([a-zA-Z0-9]+)\s*}/gi, (substring, argName) => {
10182
- const normalizedArgName = argName.toLowerCase();
10183
- const value = values[normalizedArgName];
10184
- if (value == null) {
10185
- return '_';
10186
- }
10187
- let formatted = value;
10188
- const argDef = operation.args.find(arg => arg.name === normalizedArgName);
10189
- if (argDef && argDef.type === 'int' && argDef.ui && argDef.ui.component === 'currency-form-input') {
10190
- formatted = value / 100;
10191
- }
10192
- if (argDef && argDef.type === 'datetime' && value instanceof Date) {
10193
- formatted = value.toLocaleDateString();
10194
- }
10195
- return formatted;
10196
- });
10197
- return interpolated;
10198
- }
10199
-
10200
- /**
10201
- * A form input which renders a card with the internal form fields of the given ConfigurableOperation.
10202
- */
10203
- class ConfigurableInputComponent {
10204
- constructor() {
10205
- this.readonly = false;
10206
- this.removable = true;
10207
- this.remove = new EventEmitter();
10208
- this.argValues = {};
10209
- this.form = new FormGroup({});
10210
- }
10211
- interpolateDescription() {
10212
- if (this.operationDefinition) {
10213
- return interpolateDescription(this.operationDefinition, this.form.value);
10214
- }
10215
- else {
10216
- return '';
10217
- }
10218
- }
10219
- ngOnChanges(changes) {
10220
- if ('operation' in changes || 'operationDefinition' in changes) {
10221
- this.createForm();
10222
- }
10223
- }
10224
- ngOnDestroy() {
10225
- if (this.subscription) {
10226
- this.subscription.unsubscribe();
10227
- }
10529
+ this.disabled = false;
10530
+ }
10531
+ ngOnInit() {
10532
+ this.channels$ = this.dataService.client.userStatus().single$.pipe(map(({ userStatus }) => userStatus.channels.filter(c => this.includeDefaultChannel ? true : c.code !== DEFAULT_CHANNEL_CODE)), tap(channels => {
10533
+ if (!this.channels) {
10534
+ this.channels = channels;
10535
+ this.mapIncomingValueToChannels(this.lastIncomingValue);
10536
+ }
10537
+ else {
10538
+ this.channels = channels;
10539
+ }
10540
+ }));
10228
10541
  }
10229
10542
  registerOnChange(fn) {
10230
10543
  this.onChange = fn;
10231
10544
  }
10232
10545
  registerOnTouched(fn) {
10233
- this.onTouch = fn;
10546
+ this.onTouched = fn;
10234
10547
  }
10235
10548
  setDisabledState(isDisabled) {
10236
- if (isDisabled) {
10237
- this.form.disable();
10238
- }
10239
- else {
10240
- this.form.enable();
10241
- }
10549
+ this.disabled = isDisabled;
10242
10550
  }
10243
- writeValue(value) {
10244
- if (value) {
10245
- this.form.patchValue(value);
10246
- }
10551
+ writeValue(obj) {
10552
+ this.lastIncomingValue = obj;
10553
+ this.mapIncomingValueToChannels(obj);
10247
10554
  }
10248
- trackByName(index, arg) {
10249
- return arg.name;
10555
+ focussed() {
10556
+ if (this.onTouched) {
10557
+ this.onTouched();
10558
+ }
10250
10559
  }
10251
- getArgDef(arg) {
10252
- var _a;
10253
- return (_a = this.operationDefinition) === null || _a === void 0 ? void 0 : _a.args.find(a => a.name === arg.name);
10560
+ channelIsDisabled(id) {
10561
+ return this.disableChannelIds.includes(id);
10254
10562
  }
10255
- createForm() {
10256
- var _a, _b;
10257
- if (!this.operation) {
10258
- return;
10563
+ valueChanged(value) {
10564
+ if (Array.isArray(value)) {
10565
+ this.onChange(value.map(c => c.id));
10259
10566
  }
10260
- if (this.subscription) {
10261
- this.subscription.unsubscribe();
10567
+ else {
10568
+ this.onChange([value ? value.id : undefined]);
10262
10569
  }
10263
- this.form = new FormGroup({});
10264
- this.form.__id = Math.random().toString(36).substr(10);
10265
- if (this.operation.args) {
10266
- for (const arg of ((_a = this.operationDefinition) === null || _a === void 0 ? void 0 : _a.args) || []) {
10267
- let value = (_b = this.operation.args.find(a => a.name === arg.name)) === null || _b === void 0 ? void 0 : _b.value;
10268
- if (value === undefined) {
10269
- value = getDefaultConfigArgValue(arg);
10270
- }
10271
- const validators = arg.list ? undefined : arg.required ? Validators.required : undefined;
10272
- this.form.addControl(arg.name, new FormControl(value, validators));
10570
+ }
10571
+ compareFn(c1, c2) {
10572
+ const c1id = typeof c1 === 'string' ? c1 : c1.id;
10573
+ const c2id = typeof c2 === 'string' ? c2 : c2.id;
10574
+ return c1id === c2id;
10575
+ }
10576
+ mapIncomingValueToChannels(value) {
10577
+ var _a;
10578
+ if (Array.isArray(value)) {
10579
+ if (typeof value[0] === 'string') {
10580
+ this.value = value
10581
+ .map(id => { var _a; return (_a = this.channels) === null || _a === void 0 ? void 0 : _a.find(c => c.id === id); })
10582
+ .filter(notNullOrUndefined);
10583
+ }
10584
+ else {
10585
+ this.value = value;
10273
10586
  }
10274
10587
  }
10275
- this.subscription = this.form.valueChanges.subscribe(value => {
10276
- if (this.onChange) {
10277
- this.onChange({
10278
- code: this.operation && this.operation.code,
10279
- args: value,
10280
- });
10588
+ else {
10589
+ if (typeof value === 'string') {
10590
+ const channel = (_a = this.channels) === null || _a === void 0 ? void 0 : _a.find(c => c.id === value);
10591
+ if (channel) {
10592
+ this.value = [channel];
10593
+ }
10281
10594
  }
10282
- if (this.onTouch) {
10283
- this.onTouch();
10595
+ else if (value && value.id) {
10596
+ this.value = [value];
10284
10597
  }
10285
- });
10286
- }
10287
- validate(c) {
10288
- if (this.form.invalid) {
10289
- return {
10290
- required: true,
10291
- };
10292
10598
  }
10293
- return null;
10294
10599
  }
10295
10600
  }
10296
- ConfigurableInputComponent.decorators = [
10601
+ ChannelAssignmentControlComponent.decorators = [
10297
10602
  { type: Component, args: [{
10298
- selector: 'vdr-configurable-input',
10299
- template: "<div class=\"card\" *ngIf=\"operation\">\r\n <div class=\"card-block\">{{ interpolateDescription() }}</div>\r\n <div class=\"card-block\" *ngIf=\"operation.args?.length\">\r\n <form [formGroup]=\"form\" *ngIf=\"operation\" class=\"operation-inputs\">\r\n <div *ngFor=\"let arg of operation.args; trackBy: trackByName\" class=\"arg-row\">\r\n <ng-container *ngIf=\"form.get(arg.name)\">\r\n <label>{{ getArgDef(arg)?.label || (arg.name | sentenceCase) }}</label>\r\n <vdr-dynamic-form-input\r\n [def]=\"getArgDef(arg)\"\r\n [readonly]=\"readonly\"\r\n [control]=\"form.get(arg.name)\"\r\n [formControlName]=\"arg.name\"\r\n ></vdr-dynamic-form-input>\r\n </ng-container>\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer\" *ngIf=\"!readonly && removable\">\r\n <button class=\"btn btn-sm btn-link btn-warning\" (click)=\"remove.emit(operation)\">\r\n <clr-icon shape=\"times\"></clr-icon>\r\n {{ 'common.remove' | translate }}\r\n </button>\r\n </div>\r\n</div>\r\n",
10300
- changeDetection: ChangeDetectionStrategy.OnPush,
10603
+ selector: 'vdr-channel-assignment-control',
10604
+ template: "<ng-select\r\n appendTo=\"body\"\r\n [addTag]=\"false\"\r\n [multiple]=\"multiple\"\r\n [ngModel]=\"value\"\r\n [clearable]=\"false\"\r\n [searchable]=\"false\"\r\n [disabled]=\"disabled\"\r\n [compareWith]=\"compareFn\"\r\n (focus)=\"focussed()\"\r\n (change)=\"valueChanged($event)\"\r\n>\r\n <ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\">\r\n <span aria-hidden=\"true\" class=\"ng-value-icon left\" (click)=\"clear(item)\"> \u00D7 </span>\r\n <vdr-channel-badge [channelCode]=\"item.code\"></vdr-channel-badge>\r\n <span class=\"channel-label\">{{ item.code | channelCodeToLabel | translate }}</span>\r\n </ng-template>\r\n <ng-option *ngFor=\"let item of channels$ | async\" [value]=\"item\" [disabled]=\"channelIsDisabled(item.id)\">\r\n <vdr-channel-badge [channelCode]=\"item.code\"></vdr-channel-badge>\r\n {{ item.code | channelCodeToLabel | translate }}\r\n </ng-option>\r\n</ng-select>\r\n\r\n",
10605
+ changeDetection: ChangeDetectionStrategy.Default,
10301
10606
  providers: [
10302
10607
  {
10303
10608
  provide: NG_VALUE_ACCESSOR,
10304
- useExisting: ConfigurableInputComponent,
10305
- multi: true,
10306
- },
10307
- {
10308
- provide: NG_VALIDATORS,
10309
- useExisting: forwardRef(() => ConfigurableInputComponent),
10609
+ useExisting: ChannelAssignmentControlComponent,
10310
10610
  multi: true,
10311
10611
  },
10312
10612
  ],
10313
- styles: [":host{display:block;margin-bottom:12px}:host>.card{margin-top:6px}.operation-inputs{padding-top:0}.operation-inputs .arg-row:not(:last-child){margin-bottom:24px}.operation-inputs .arg-row label{margin-right:6px}.operation-inputs .hidden{display:none}\n"]
10613
+ styles: [":host{min-width:200px}:host.clr-input{border-bottom:none;padding:0}::ng-deep .ng-value>vdr-channel-badge,::ng-deep .ng-option>vdr-channel-badge{margin-bottom:-1px}::ng-deep .ng-value>vdr-channel-badge{margin-left:6px}.channel-label{margin-right:6px}\n"]
10314
10614
  },] }
10315
10615
  ];
10316
- ConfigurableInputComponent.propDecorators = {
10317
- operation: [{ type: Input }],
10318
- operationDefinition: [{ type: Input }],
10319
- readonly: [{ type: Input }],
10320
- removable: [{ type: Input }],
10321
- remove: [{ type: Output }]
10616
+ ChannelAssignmentControlComponent.ctorParameters = () => [
10617
+ { type: DataService }
10618
+ ];
10619
+ ChannelAssignmentControlComponent.propDecorators = {
10620
+ multiple: [{ type: Input }],
10621
+ includeDefaultChannel: [{ type: Input }],
10622
+ disableChannelIds: [{ type: Input }]
10623
+ };
10624
+
10625
+ class ChannelBadgeComponent {
10626
+ get isDefaultChannel() {
10627
+ return this.channelCode === DEFAULT_CHANNEL_CODE;
10628
+ }
10629
+ }
10630
+ ChannelBadgeComponent.decorators = [
10631
+ { type: Component, args: [{
10632
+ selector: 'vdr-channel-badge',
10633
+ template: "<clr-icon shape=\"layers\" [style.color]=\"isDefaultChannel ? '#aaa' : (channelCode | stringToColor)\"></clr-icon>\r\n",
10634
+ changeDetection: ChangeDetectionStrategy.OnPush,
10635
+ styles: [":host{display:inline-block}button :host{margin-bottom:-1px}clr-icon{margin-right:6px}\n"]
10636
+ },] }
10637
+ ];
10638
+ ChannelBadgeComponent.propDecorators = {
10639
+ channelCode: [{ type: Input }]
10640
+ };
10641
+
10642
+ /**
10643
+ * @description
10644
+ * A chip component for displaying a label with an optional action icon.
10645
+ *
10646
+ * @example
10647
+ * ```HTML
10648
+ * <vdr-chip [colorFrom]="item.value"
10649
+ * icon="close"
10650
+ * (iconClick)="clear(item)">
10651
+ * {{ item.value }}</vdr-chip>
10652
+ * ```
10653
+ * @docsCategory components
10654
+ */
10655
+ class ChipComponent {
10656
+ constructor() {
10657
+ this.invert = false;
10658
+ /**
10659
+ * @description
10660
+ * If set, the chip will have an auto-generated background
10661
+ * color based on the string value passed in.
10662
+ */
10663
+ this.colorFrom = '';
10664
+ this.iconClick = new EventEmitter();
10665
+ }
10666
+ }
10667
+ ChipComponent.decorators = [
10668
+ { type: Component, args: [{
10669
+ selector: 'vdr-chip',
10670
+ template: "<div\r\n class=\"wrapper\"\r\n [class.with-background]=\"!invert && colorFrom\"\r\n [style.backgroundColor]=\"!invert && (colorFrom | stringToColor)\"\r\n [style.color]=\"invert && (colorFrom | stringToColor)\"\r\n [style.borderColor]=\"invert && (colorFrom | stringToColor)\"\r\n [ngClass]=\"colorType\"\r\n>\r\n <div class=\"chip-label\"><ng-content></ng-content></div>\r\n <div class=\"chip-icon\" *ngIf=\"icon\">\r\n <button (click)=\"iconClick.emit($event)\">\r\n <clr-icon\r\n [attr.shape]=\"icon\"\r\n [style.color]=\"invert && (colorFrom | stringToColor)\"\r\n [class.is-inverse]=\"!invert && colorFrom\"\r\n ></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n",
10671
+ changeDetection: ChangeDetectionStrategy.OnPush,
10672
+ styles: [":host{display:inline-block}.wrapper{display:flex;border:1px solid var(--color-component-border-300);border-radius:3px;margin:6px}.wrapper.with-background{color:var(--color-grey-100);border-color:transparent}.wrapper.with-background .chip-label{opacity:.9}.wrapper.warning{border-color:var(--color-chip-warning-border)}.wrapper.warning .chip-label{color:var(--color-chip-warning-text);background-color:var(--color-chip-warning-bg)}.wrapper.success{border-color:var(--color-chip-success-border)}.wrapper.success .chip-label{color:var(--color-chip-success-text);background-color:var(--color-chip-success-bg)}.wrapper.error{border-color:var(--color-chip-error-border)}.wrapper.error .chip-label{color:var(--color-chip-error-text);background-color:var(--color-chip-error-bg)}.chip-label{padding:3px 6px;line-height:1em;border-radius:3px;white-space:nowrap;display:flex;align-items:center}.chip-icon{border-left:1px solid var(--color-component-border-200);padding:0 3px;line-height:1em;display:flex}.chip-icon button{cursor:pointer;background:none;margin:0;padding:0;border:none}\n"]
10673
+ },] }
10674
+ ];
10675
+ ChipComponent.propDecorators = {
10676
+ icon: [{ type: Input }],
10677
+ invert: [{ type: Input }],
10678
+ colorFrom: [{ type: Input }],
10679
+ colorType: [{ type: Input }],
10680
+ iconClick: [{ type: Output }]
10322
10681
  };
10323
10682
 
10324
10683
  /**
@@ -11925,7 +12284,7 @@ class FormattedAddressComponent {
11925
12284
  FormattedAddressComponent.decorators = [
11926
12285
  { type: Component, args: [{
11927
12286
  selector: 'vdr-formatted-address',
11928
- template: "<ul class=\"address-lines\">\r\n <li *ngIf=\"address.fullName\">{{ address.fullName }}</li>\r\n <li *ngIf=\"address.streetLine1\">{{ address.streetLine1 }}</li>\r\n <li *ngIf=\"address.streetLine2\">{{ address.streetLine2 }}</li>\r\n <li *ngIf=\"address.city\">{{ address.city }}</li>\r\n <li *ngIf=\"address.province\">{{ address.province }}</li>\r\n <li *ngIf=\"address.postalCode\">{{ address.postalCode }}</li>\r\n <li *ngIf=\"address.country\">\r\n <clr-icon shape=\"world\" size=\"12\"></clr-icon>\r\n {{ getCountryName() }}\r\n </li>\r\n <li *ngIf=\"address.phoneNumber\">\r\n <clr-icon shape=\"phone-handset\" size=\"12\"></clr-icon>\r\n {{ address.phoneNumber }}\r\n </li>\r\n <li *ngFor=\"let customField of getCustomFields()\" class=\"custom-field\">\r\n <vdr-labeled-data [label]=\"customField.key\">{{ customField.value }}</vdr-labeled-data>\r\n </li>\r\n</ul>\r\n",
12287
+ template: "<ul class=\"address-lines\">\r\n <li *ngIf=\"address.fullName\">{{ address.fullName }}</li>\r\n <li *ngIf=\"address.company\">{{ address.company }}</li>\r\n <li *ngIf=\"address.streetLine1\">{{ address.streetLine1 }}</li>\r\n <li *ngIf=\"address.streetLine2\">{{ address.streetLine2 }}</li>\r\n <li *ngIf=\"address.city\">{{ address.city }}</li>\r\n <li *ngIf=\"address.province\">{{ address.province }}</li>\r\n <li *ngIf=\"address.postalCode\">{{ address.postalCode }}</li>\r\n <li *ngIf=\"address.country\">\r\n <clr-icon shape=\"world\" size=\"12\"></clr-icon>\r\n {{ getCountryName() }}\r\n </li>\r\n <li *ngIf=\"address.phoneNumber\">\r\n <clr-icon shape=\"phone-handset\" size=\"12\"></clr-icon>\r\n {{ address.phoneNumber }}\r\n </li>\r\n <li *ngFor=\"let customField of getCustomFields()\" class=\"custom-field\">\r\n <vdr-labeled-data [label]=\"customField.key\">{{ customField.value }}</vdr-labeled-data>\r\n </li>\r\n</ul>\r\n",
11929
12288
  changeDetection: ChangeDetectionStrategy.OnPush,
11930
12289
  styles: [".address-lines{list-style-type:none;line-height:1.2em}.custom-field{margin-top:6px}\n"]
11931
12290
  },] }
@@ -11941,7 +12300,7 @@ HelpTooltipComponent.decorators = [
11941
12300
  selector: 'vdr-help-tooltip',
11942
12301
  template: "<clr-tooltip>\r\n <clr-icon clrTooltipTrigger shape=\"help\" size=\"14\"></clr-icon>\r\n <clr-tooltip-content [clrPosition]=\"position\" clrSize=\"md\" *clrIfOpen>\r\n <span>{{ content }}</span>\r\n </clr-tooltip-content>\r\n</clr-tooltip>\r\n",
11943
12302
  changeDetection: ChangeDetectionStrategy.OnPush,
11944
- styles: [""]
12303
+ styles: ["clr-tooltip{display:inline-flex}\n"]
11945
12304
  },] }
11946
12305
  ];
11947
12306
  HelpTooltipComponent.propDecorators = {
@@ -12203,6 +12562,105 @@ PaginationControlsComponent.propDecorators = {
12203
12562
  pageChange: [{ type: Output }]
12204
12563
  };
12205
12564
 
12565
+ const ɵ0 = SingleSearchSelectionModelFactory;
12566
+ class ProductSearchInputComponent {
12567
+ constructor() {
12568
+ this.searchTermChange = new EventEmitter();
12569
+ this.facetValueChange = new EventEmitter();
12570
+ this.lastTerm = '';
12571
+ this.lastFacetValueIds = [];
12572
+ this.filterFacetResults = (term, item) => {
12573
+ if (!this.isFacetValueItem(item)) {
12574
+ return false;
12575
+ }
12576
+ const cix = term.indexOf(':');
12577
+ const facetName = cix > -1 ? term.toLowerCase().slice(0, cix) : null;
12578
+ const facetVal = cix > -1 ? term.toLowerCase().slice(cix + 1) : term.toLowerCase();
12579
+ if (facetName) {
12580
+ return (item.facetValue.facet.name.toLowerCase().includes(facetName) &&
12581
+ item.facetValue.name.toLocaleLowerCase().includes(facetVal));
12582
+ }
12583
+ return (item.facetValue.name.toLowerCase().includes(term.toLowerCase()) ||
12584
+ item.facetValue.facet.name.toLowerCase().includes(term.toLowerCase()));
12585
+ };
12586
+ this.isFacetValueItem = (input) => {
12587
+ return typeof input === 'object' && !!input && input.hasOwnProperty('facetValue');
12588
+ };
12589
+ }
12590
+ setSearchTerm(term) {
12591
+ if (term) {
12592
+ this.selectComponent.select({ label: term, value: { label: term } });
12593
+ }
12594
+ else {
12595
+ const currentTerm = this.selectComponent.selectedItems.find(i => !this.isFacetValueItem(i.value));
12596
+ if (currentTerm) {
12597
+ this.selectComponent.unselect(currentTerm);
12598
+ }
12599
+ }
12600
+ }
12601
+ setFacetValues(ids) {
12602
+ const items = this.selectComponent.items;
12603
+ this.selectComponent.selectedItems.forEach(item => {
12604
+ if (this.isFacetValueItem(item.value) && !ids.includes(item.value.facetValue.id)) {
12605
+ this.selectComponent.unselect(item);
12606
+ }
12607
+ });
12608
+ ids.map(id => {
12609
+ return items === null || items === void 0 ? void 0 : items.find(item => this.isFacetValueItem(item) && item.facetValue.id === id);
12610
+ })
12611
+ .filter(notNullOrUndefined)
12612
+ .forEach(item => {
12613
+ const isSelected = this.selectComponent.selectedItems.find(i => {
12614
+ const val = i.value;
12615
+ if (this.isFacetValueItem(val)) {
12616
+ return val.facetValue.id === item.facetValue.id;
12617
+ }
12618
+ return false;
12619
+ });
12620
+ if (!isSelected) {
12621
+ this.selectComponent.select({ label: '', value: item });
12622
+ }
12623
+ });
12624
+ }
12625
+ onSelectChange(selectedItems) {
12626
+ if (!Array.isArray(selectedItems)) {
12627
+ selectedItems = [selectedItems];
12628
+ }
12629
+ const searchTermItem = selectedItems.find(item => !this.isFacetValueItem(item));
12630
+ const searchTerm = searchTermItem ? searchTermItem.label : '';
12631
+ const facetValueIds = selectedItems.filter(this.isFacetValueItem).map(i => i.facetValue.id);
12632
+ if (searchTerm !== this.lastTerm) {
12633
+ this.searchTermChange.emit(searchTerm);
12634
+ this.lastTerm = searchTerm;
12635
+ }
12636
+ if (this.lastFacetValueIds.join(',') !== facetValueIds.join(',')) {
12637
+ this.facetValueChange.emit(facetValueIds);
12638
+ this.lastFacetValueIds = facetValueIds;
12639
+ }
12640
+ }
12641
+ addTagFn(item) {
12642
+ return { label: item };
12643
+ }
12644
+ isSearchHeaderSelected() {
12645
+ return this.selectComponent.itemsList.markedIndex === -1;
12646
+ }
12647
+ }
12648
+ ProductSearchInputComponent.decorators = [
12649
+ { type: Component, args: [{
12650
+ selector: 'vdr-product-search-input',
12651
+ template: "<ng-select\r\n [addTag]=\"addTagFn\"\r\n [placeholder]=\"'catalog.search-product-name-or-code' | translate\"\r\n [items]=\"facetValueResults\"\r\n [searchFn]=\"filterFacetResults\"\r\n [hideSelected]=\"true\"\r\n [multiple]=\"true\"\r\n [markFirst]=\"false\"\r\n (change)=\"onSelectChange($event)\"\r\n #selectComponent\r\n>\r\n <ng-template ng-header-tmp>\r\n <div\r\n class=\"search-header\"\r\n *ngIf=\"selectComponent.searchTerm\"\r\n [class.selected]=\"isSearchHeaderSelected()\"\r\n (click)=\"selectComponent.selectTag()\"\r\n >\r\n {{ 'catalog.search-for-term' | translate }}: {{ selectComponent.searchTerm }}\r\n </div>\r\n </ng-template>\r\n <ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\">\r\n <ng-container *ngIf=\"item.facetValue\">\r\n <vdr-facet-value-chip\r\n [facetValue]=\"item.facetValue\"\r\n [removable]=\"true\"\r\n (remove)=\"clear(item)\"\r\n ></vdr-facet-value-chip>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.facetValue\">\r\n <vdr-chip [icon]=\"'times'\" (iconClick)=\"clear(item)\">\"{{ item.label }}\"</vdr-chip>\r\n </ng-container>\r\n </ng-template>\r\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\">\r\n <ng-container *ngIf=\"item.facetValue\">\r\n <vdr-facet-value-chip [facetValue]=\"item.facetValue\" [removable]=\"false\"></vdr-facet-value-chip>\r\n </ng-container>\r\n </ng-template>\r\n</ng-select>\r\n",
12652
+ changeDetection: ChangeDetectionStrategy.OnPush,
12653
+ providers: [{ provide: SELECTION_MODEL_FACTORY, useValue: ɵ0 }],
12654
+ styles: [":host{margin-top:6px;display:block;width:100%}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{background:none;margin:0}:host ::ng-deep .ng-dropdown-panel-items div.ng-option:last-child{display:none}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-header{border:none;padding:0}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container{padding:0}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{padding-left:8px}ng-select{width:100%;min-width:300px;margin-right:12px}.search-header{padding:8px 10px;border-bottom:1px solid var(--color-component-border-100);cursor:pointer}.search-header.selected,.search-header:hover{background-color:var(--color-component-bg-200)}\n"]
12655
+ },] }
12656
+ ];
12657
+ ProductSearchInputComponent.propDecorators = {
12658
+ facetValueResults: [{ type: Input }],
12659
+ searchTermChange: [{ type: Output }],
12660
+ facetValueChange: [{ type: Output }],
12661
+ selectComponent: [{ type: ViewChild, args: ['selectComponent', { static: true },] }]
12662
+ };
12663
+
12206
12664
  /**
12207
12665
  * @description
12208
12666
  * A component for selecting product variants via an autocomplete-style select input.
@@ -13003,7 +13461,7 @@ RichTextEditorComponent.decorators = [
13003
13461
  },
13004
13462
  ProsemirrorService,
13005
13463
  ],
13006
- styles: ["@charset \"UTF-8\";::ng-deep .ProseMirror{position:relative}::ng-deep .ProseMirror{word-wrap:break-word;white-space:pre-wrap;-webkit-font-variant-ligatures:none;font-feature-settings:none;font-variant-ligatures:none}::ng-deep .ProseMirror pre{white-space:pre-wrap}::ng-deep .ProseMirror li{position:relative}::ng-deep .ProseMirror-hideselection *::selection{background:transparent}::ng-deep .ProseMirror-hideselection *::-moz-selection{background:transparent}::ng-deep .ProseMirror-hideselection{caret-color:transparent}::ng-deep .ProseMirror-selectednode{outline:2px solid var(--color-primary-500)}::ng-deep li.ProseMirror-selectednode{outline:none}::ng-deep li.ProseMirror-selectednode:after{content:\"\";position:absolute;left:-32px;right:-2px;top:-2px;bottom:-2px;border:2px solid var(--color-primary-500);pointer-events:none}::ng-deep .ProseMirror-textblock-dropdown{min-width:3em}::ng-deep .ProseMirror-menu{margin:0 -4px;line-height:1}::ng-deep .ProseMirror-tooltip .ProseMirror-menu{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;white-space:pre}::ng-deep .ProseMirror-menuitem{margin-right:3px;display:inline-block}::ng-deep .ProseMirror-menuseparator{border-right:1px solid var(--color-component-border-200);margin-right:3px}::ng-deep .ProseMirror-menu-dropdown,::ng-deep .ProseMirror-menu-dropdown-menu{font-size:90%;white-space:nowrap}::ng-deep .ProseMirror-menu-dropdown{vertical-align:1px;cursor:pointer;position:relative;padding-right:15px}::ng-deep .ProseMirror-menu-dropdown-wrap{padding:1px 0 1px 4px;display:inline-block;position:relative}::ng-deep .ProseMirror-menu-dropdown:after{content:\"\";border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid currentColor;opacity:.6;position:absolute;right:4px;top:calc(50% - 2px)}::ng-deep .ProseMirror-menu-dropdown-menu,::ng-deep .ProseMirror-menu-submenu{position:absolute;background:white;color:var(--color-grey-600);border:1px solid var(--color-component-border-200);padding:2px}::ng-deep .ProseMirror-menu-dropdown-menu{z-index:15;min-width:6em}::ng-deep .ProseMirror-menu-dropdown-item{cursor:pointer;padding:2px 8px 2px 4px}::ng-deep .ProseMirror-menu-dropdown-item:hover{background:var(--color-component-bg-100)}::ng-deep .ProseMirror-menu-submenu-wrap{position:relative;margin-right:-4px}::ng-deep .ProseMirror-menu-submenu-label:after{content:\"\";border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid currentColor;opacity:.6;position:absolute;right:4px;top:calc(50% - 4px)}::ng-deep .ProseMirror-menu-submenu{display:none;min-width:4em;left:100%;top:-3px}::ng-deep .ProseMirror-menu-active{background:var(--color-component-bg-100);border-radius:4px}::ng-deep .ProseMirror-menu-disabled{opacity:.3}::ng-deep .ProseMirror-menu-submenu-wrap:hover .ProseMirror-menu-submenu,::ng-deep .ProseMirror-menu-submenu-wrap-active .ProseMirror-menu-submenu{display:block}::ng-deep .ProseMirror-menubar{border-top-left-radius:inherit;border-top-right-radius:inherit;position:relative;min-height:1em;color:var(--color-grey-600);padding:1px 6px;top:0;left:0;right:0;background:var(--color-component-bg-100);z-index:10;box-sizing:border-box;overflow:visible}::ng-deep .ProseMirror-icon{display:inline-block;line-height:.8;vertical-align:-2px;padding:2px 8px;cursor:pointer}::ng-deep .ProseMirror-menu-disabled.ProseMirror-icon{cursor:default}::ng-deep .ProseMirror-icon svg{fill:currentColor;height:1em}::ng-deep .ProseMirror-icon span{vertical-align:text-top}::ng-deep .ProseMirror-gapcursor{display:none;pointer-events:none;position:absolute}::ng-deep .ProseMirror-gapcursor:after{content:\"\";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid black;animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}::ng-deep .ProseMirror-focused .ProseMirror-gapcursor{display:block}::ng-deep .ProseMirror ul,::ng-deep .ProseMirror ol{padding-left:30px;list-style-position:initial}::ng-deep .ProseMirror blockquote{padding-left:1em;border-left:3px solid var(--color-grey-100);margin-left:0;margin-right:0}::ng-deep .ProseMirror-prompt{background:white;padding:5px 10px 5px 15px;border:1px solid silver;position:fixed;border-radius:3px;z-index:11;box-shadow:-.5px 2px 5px #0003}::ng-deep .ProseMirror-prompt h5{margin:0;font-weight:normal;font-size:100%;color:var(--color-grey-500)}::ng-deep .ProseMirror-prompt input[type=text],::ng-deep .ProseMirror-prompt textarea{background:var(--color-component-bg-100);border:none;outline:none}::ng-deep .ProseMirror-prompt input[type=text]{padding:0 4px}::ng-deep .ProseMirror-prompt-close{position:absolute;left:2px;top:1px;color:var(--color-grey-400);border:none;background:transparent;padding:0}::ng-deep .ProseMirror-prompt-close:after{content:\"\\e2\\153\\2022\";font-size:12px}::ng-deep .ProseMirror-invalid{background:var(--color-warning-200);border:1px solid var(--color-warning-300);border-radius:4px;padding:5px 10px;position:absolute;min-width:10em}::ng-deep .ProseMirror-prompt-buttons{margin-top:5px;display:none}::ng-deep #editor,::ng-deep .editor{background:var(--color-form-input-bg);color:#000;background-clip:padding-box;border-radius:4px;border:2px solid rgba(0,0,0,.2);padding:5px 0;margin-bottom:23px}::ng-deep .ProseMirror p:first-child,::ng-deep .ProseMirror h1:first-child,::ng-deep .ProseMirror h2:first-child,::ng-deep .ProseMirror h3:first-child,::ng-deep .ProseMirror h4:first-child,::ng-deep .ProseMirror h5:first-child,::ng-deep .ProseMirror h6:first-child{margin-top:10px}::ng-deep .ProseMirror{padding:4px 8px 4px 14px;line-height:1.2;outline:none}::ng-deep .ProseMirror p{margin-bottom:.5rem;color:var(--color-grey-800)!important}:host{display:block;max-width:710px;margin-bottom:.5rem}:host.readonly ::ng-deep .ProseMirror-menubar{display:none}::ng-deep .ProseMirror-menubar{position:sticky;top:24px;margin-top:6px;border:1px solid var(--color-component-border-200);border-bottom:none;background-color:var(--color-component-bg-200);color:var(--color-icon-button);padding:6px 12px;display:flex;flex-wrap:wrap}::ng-deep .vdr-prosemirror{background:var(--color-form-input-bg);min-height:128px;min-width:200px;border:1px solid var(--color-component-border-200);border-radius:0 0 3px 3px;transition:border-color .2s;overflow:auto;text-align:initial}::ng-deep .vdr-prosemirror:focus{border-color:var(--color-primary-500)!important;box-shadow:0 0 1px 1px var(--color-primary-100)}::ng-deep .vdr-prosemirror hr{padding:2px 10px;border:none;margin:1em 0}::ng-deep .vdr-prosemirror hr:after{content:\"\";display:block;height:1px;background-color:silver;line-height:2px}::ng-deep .vdr-prosemirror img{cursor:default;max-width:100%}\n"]
13464
+ styles: ["@charset \"UTF-8\";::ng-deep .ProseMirror{position:relative}::ng-deep .ProseMirror{word-wrap:break-word;white-space:pre-wrap;-webkit-font-variant-ligatures:none;font-feature-settings:none;font-variant-ligatures:none}::ng-deep .ProseMirror pre{white-space:pre-wrap}::ng-deep .ProseMirror li{position:relative}::ng-deep .ProseMirror-hideselection *::selection{background:transparent}::ng-deep .ProseMirror-hideselection *::-moz-selection{background:transparent}::ng-deep .ProseMirror-hideselection{caret-color:transparent}::ng-deep .ProseMirror-selectednode{outline:2px solid var(--color-primary-500)}::ng-deep li.ProseMirror-selectednode{outline:none}::ng-deep li.ProseMirror-selectednode:after{content:\"\";position:absolute;left:-32px;right:-2px;top:-2px;bottom:-2px;border:2px solid var(--color-primary-500);pointer-events:none}::ng-deep .ProseMirror-textblock-dropdown{min-width:3em}::ng-deep .ProseMirror-menu{margin:0 -4px;line-height:1}::ng-deep .ProseMirror-tooltip .ProseMirror-menu{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;white-space:pre}::ng-deep .ProseMirror-menuitem{margin-right:3px;display:inline-block}::ng-deep .ProseMirror-menuseparator{border-right:1px solid var(--color-component-border-200);margin-right:3px}::ng-deep .ProseMirror-menu-dropdown,::ng-deep .ProseMirror-menu-dropdown-menu{font-size:90%;white-space:nowrap}::ng-deep .ProseMirror-menu-dropdown{vertical-align:1px;cursor:pointer;position:relative;padding-right:15px}::ng-deep .ProseMirror-menu-dropdown-wrap{padding:1px 0 1px 4px;display:inline-block;position:relative}::ng-deep .ProseMirror-menu-dropdown:after{content:\"\";border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid currentColor;opacity:.6;position:absolute;right:4px;top:calc(50% - 2px)}::ng-deep .ProseMirror-menu-dropdown-menu,::ng-deep .ProseMirror-menu-submenu{position:absolute;background:white;color:var(--color-grey-600);border:1px solid var(--color-component-border-200);padding:2px}::ng-deep .ProseMirror-menu-dropdown-menu{z-index:15;min-width:6em}::ng-deep .ProseMirror-menu-dropdown-item{cursor:pointer;padding:2px 8px 2px 4px}::ng-deep .ProseMirror-menu-dropdown-item:hover{background:var(--color-component-bg-100)}::ng-deep .ProseMirror-menu-submenu-wrap{position:relative;margin-right:-4px}::ng-deep .ProseMirror-menu-submenu-label:after{content:\"\";border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid currentColor;opacity:.6;position:absolute;right:4px;top:calc(50% - 4px)}::ng-deep .ProseMirror-menu-submenu{display:none;min-width:4em;left:100%;top:-3px}::ng-deep .ProseMirror-menu-active{background:var(--color-component-bg-100);border-radius:4px}::ng-deep .ProseMirror-menu-disabled{opacity:.3}::ng-deep .ProseMirror-menu-submenu-wrap:hover .ProseMirror-menu-submenu,::ng-deep .ProseMirror-menu-submenu-wrap-active .ProseMirror-menu-submenu{display:block}::ng-deep .ProseMirror-menubar{border-top-left-radius:inherit;border-top-right-radius:inherit;position:relative;min-height:1em;color:var(--color-grey-600);padding:1px 6px;top:0;left:0;right:0;background:var(--color-component-bg-100);z-index:10;box-sizing:border-box;overflow:visible}::ng-deep .ProseMirror-icon{display:inline-block;line-height:.8;vertical-align:-2px;padding:2px 8px;cursor:pointer}::ng-deep .ProseMirror-menu-disabled.ProseMirror-icon{cursor:default}::ng-deep .ProseMirror-icon svg{fill:currentColor;height:1em}::ng-deep .ProseMirror-icon span{vertical-align:text-top}::ng-deep .ProseMirror-gapcursor{display:none;pointer-events:none;position:absolute}::ng-deep .ProseMirror-gapcursor:after{content:\"\";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid black;animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}::ng-deep .ProseMirror-focused .ProseMirror-gapcursor{display:block}::ng-deep .ProseMirror ul,::ng-deep .ProseMirror ol{padding-left:30px;list-style-position:initial}::ng-deep .ProseMirror blockquote{padding-left:1em;border-left:3px solid var(--color-grey-100);margin-left:0;margin-right:0}::ng-deep .ProseMirror-prompt{background:white;padding:5px 10px 5px 15px;border:1px solid silver;position:fixed;border-radius:3px;z-index:11;box-shadow:-.5px 2px 5px #0003}::ng-deep .ProseMirror-prompt h5{margin:0;font-weight:normal;font-size:100%;color:var(--color-grey-500)}::ng-deep .ProseMirror-prompt input[type=text],::ng-deep .ProseMirror-prompt textarea{background:var(--color-component-bg-100);border:none;outline:none}::ng-deep .ProseMirror-prompt input[type=text]{padding:0 4px}::ng-deep .ProseMirror-prompt-close{position:absolute;left:2px;top:1px;color:var(--color-grey-400);border:none;background:transparent;padding:0}::ng-deep .ProseMirror-prompt-close:after{content:\"\\e2\\153\\2022\";font-size:12px}::ng-deep .ProseMirror-invalid{background:var(--color-warning-200);border:1px solid var(--color-warning-300);border-radius:4px;padding:5px 10px;position:absolute;min-width:10em}::ng-deep .ProseMirror-prompt-buttons{margin-top:5px;display:none}::ng-deep #editor,::ng-deep .editor{background:var(--color-form-input-bg);color:#000;background-clip:padding-box;border-radius:4px;border:2px solid rgba(0,0,0,.2);padding:5px 0;margin-bottom:23px}::ng-deep .ProseMirror p:first-child,::ng-deep .ProseMirror h1:first-child,::ng-deep .ProseMirror h2:first-child,::ng-deep .ProseMirror h3:first-child,::ng-deep .ProseMirror h4:first-child,::ng-deep .ProseMirror h5:first-child,::ng-deep .ProseMirror h6:first-child{margin-top:10px}::ng-deep .ProseMirror{padding:4px 8px 4px 14px;line-height:1.2;outline:none}::ng-deep .ProseMirror p{margin-bottom:.5rem;color:var(--color-grey-800)!important}:host{display:block;max-width:710px;margin-bottom:.5rem}:host.readonly ::ng-deep .ProseMirror-menubar{display:none}::ng-deep .ProseMirror-menubar{position:sticky;top:24px;margin-top:6px;border:1px solid var(--color-component-border-200);border-bottom:none;background-color:var(--color-component-bg-200);color:var(--color-icon-button);border-radius:var(--border-radius-input) var(--border-radius-input) 0 0;padding:6px 12px;display:flex;flex-wrap:wrap}::ng-deep .vdr-prosemirror{background:var(--color-form-input-bg);min-height:128px;min-width:200px;border:1px solid var(--color-component-border-200);border-radius:0 0 var(--border-radius-input) var(--border-radius-input);transition:border-color .2s;overflow:auto;text-align:initial}::ng-deep .vdr-prosemirror:focus{border-color:var(--color-primary-500)!important;box-shadow:0 0 1px 1px var(--color-primary-100)}::ng-deep .vdr-prosemirror hr{padding:2px 10px;border:none;margin:1em 0}::ng-deep .vdr-prosemirror hr:after{content:\"\";display:block;height:1px;background-color:silver;line-height:2px}::ng-deep .vdr-prosemirror img{cursor:default;max-width:100%}\n"]
13007
13465
  },] }
13008
13466
  ];
13009
13467
  RichTextEditorComponent.ctorParameters = () => [
@@ -13024,6 +13482,7 @@ class SelectToggleComponent {
13024
13482
  constructor() {
13025
13483
  this.size = 'large';
13026
13484
  this.selected = false;
13485
+ this.hiddenWhenOff = false;
13027
13486
  this.disabled = false;
13028
13487
  this.selectedChange = new EventEmitter();
13029
13488
  }
@@ -13031,14 +13490,15 @@ class SelectToggleComponent {
13031
13490
  SelectToggleComponent.decorators = [
13032
13491
  { type: Component, args: [{
13033
13492
  selector: 'vdr-select-toggle',
13034
- template: "<div\r\n class=\"toggle\"\r\n [class.disabled]=\"disabled\"\r\n [class.small]=\"size === 'small'\"\r\n [attr.tabindex]=\"disabled ? null : 0\"\r\n [class.selected]=\"selected\"\r\n (keydown.enter)=\"selectedChange.emit(!selected)\"\r\n (keydown.space)=\"$event.preventDefault(); selectedChange.emit(!selected)\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n <clr-icon shape=\"check\" [attr.size]=\"size === 'small' ? 16 : 32\"></clr-icon>\r\n</div>\r\n<div class=\"toggle-label\" [class.disabled]=\"disabled\" *ngIf=\"label\" (click)=\"selectedChange.emit(!selected)\">\r\n {{ label }}\r\n</div>\r\n",
13493
+ template: "<div\r\n class=\"toggle\"\r\n [class.hide-when-off]=\"hiddenWhenOff\"\r\n [class.disabled]=\"disabled\"\r\n [class.small]=\"size === 'small'\"\r\n [attr.tabindex]=\"disabled ? null : 0\"\r\n [class.selected]=\"selected\"\r\n (keydown.enter)=\"selectedChange.emit(!selected)\"\r\n (keydown.space)=\"$event.preventDefault(); selectedChange.emit(!selected)\"\r\n (click)=\"selectedChange.emit(!selected)\"\r\n>\r\n <clr-icon shape=\"check-circle\" [attr.size]=\"size === 'small' ? 24 : 32\"></clr-icon>\r\n</div>\r\n<div class=\"toggle-label\" [class.disabled]=\"disabled\" *ngIf=\"label\" (click)=\"selectedChange.emit(!selected)\">\r\n {{ label }}\r\n</div>\r\n",
13035
13494
  changeDetection: ChangeDetectionStrategy.OnPush,
13036
- styles: [":host{display:flex;align-items:center;justify-content:center}.toggle{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;background-color:var(--color-component-bg-100);border:2px solid var(--color-component-border-300);padding:0 6px;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:var(--color-grey-300);transition:background-color .2s,border .2s}.toggle.small{width:24px;height:24px}.toggle:not(.disabled):hover{border-color:var(--color-success-500);background-color:var(--color-success-400);opacity:.9}.toggle.selected{background-color:var(--color-success-500);border-color:var(--color-success-600);color:#fff}.toggle.selected:not(.disabled):hover{background-color:var(--color-success-500);border-color:var(--color-success-400);opacity:.9}.toggle:focus{outline:none;box-shadow:0 0 2px 2px var(--color-primary-500)}.toggle.disabled{cursor:default}.toggle-label{flex:1;margin-left:6px;text-align:left;font-size:12px}.toggle-label:not(.disabled){cursor:pointer}\n"]
13495
+ styles: [":host{display:flex;align-items:center;justify-content:center}.toggle{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;color:var(--color-grey-300);background-color:var(--color-component-bg-100);border-radius:50%;top:-12px;left:-12px;transition:opacity .2s,color .2s}.toggle.hide-when-off{opacity:0}.toggle.small{width:24px;height:24px}.toggle:not(.disabled):hover{color:var(--color-success-400);opacity:.9}.toggle.selected{opacity:1;color:var(--color-success-500)}.toggle.selected:not(.disabled):hover{color:var(--color-success-400);opacity:.9}.toggle:focus{outline:none;box-shadow:0 0 2px 2px var(--color-primary-500)}.toggle.disabled{cursor:default}.toggle-label{flex:1;margin-left:6px;text-align:left;font-size:12px}.toggle-label:not(.disabled){cursor:pointer}\n"]
13037
13496
  },] }
13038
13497
  ];
13039
13498
  SelectToggleComponent.propDecorators = {
13040
13499
  size: [{ type: Input }],
13041
13500
  selected: [{ type: Input }],
13501
+ hiddenWhenOff: [{ type: Input }],
13042
13502
  disabled: [{ type: Input }],
13043
13503
  label: [{ type: Input }],
13044
13504
  selectedChange: [{ type: Output }]
@@ -13792,7 +14252,7 @@ class RelationAssetInputComponent {
13792
14252
  this.dataService = dataService;
13793
14253
  }
13794
14254
  ngOnInit() {
13795
- this.asset$ = this.parentFormControl.valueChanges.pipe(startWith(this.parentFormControl.value), map(asset => asset === null || asset === void 0 ? void 0 : asset.id), distinctUntilChanged(), switchMap(id => {
14255
+ this.asset$ = this.formControl.valueChanges.pipe(startWith(this.formControl.value), map(asset => asset === null || asset === void 0 ? void 0 : asset.id), distinctUntilChanged(), switchMap(id => {
13796
14256
  if (id) {
13797
14257
  return this.dataService.product.getAsset(id).mapStream(data => data.asset || undefined);
13798
14258
  }
@@ -13811,14 +14271,14 @@ class RelationAssetInputComponent {
13811
14271
  })
13812
14272
  .subscribe(result => {
13813
14273
  if (result && result.length) {
13814
- this.parentFormControl.setValue(result[0]);
13815
- this.parentFormControl.markAsDirty();
14274
+ this.formControl.setValue(result[0]);
14275
+ this.formControl.markAsDirty();
13816
14276
  }
13817
14277
  });
13818
14278
  }
13819
14279
  remove() {
13820
- this.parentFormControl.setValue(null);
13821
- this.parentFormControl.markAsDirty();
14280
+ this.formControl.setValue(null);
14281
+ this.formControl.markAsDirty();
13822
14282
  }
13823
14283
  previewAsset(asset) {
13824
14284
  this.modalService
@@ -13830,6 +14290,7 @@ class RelationAssetInputComponent {
13830
14290
  .subscribe();
13831
14291
  }
13832
14292
  }
14293
+ RelationAssetInputComponent.id = 'asset-form-input';
13833
14294
  RelationAssetInputComponent.decorators = [
13834
14295
  { type: Component, args: [{
13835
14296
  selector: 'vdr-relation-asset-input',
@@ -13844,7 +14305,7 @@ RelationAssetInputComponent.ctorParameters = () => [
13844
14305
  ];
13845
14306
  RelationAssetInputComponent.propDecorators = {
13846
14307
  readonly: [{ type: Input }],
13847
- parentFormControl: [{ type: Input }],
14308
+ formControl: [{ type: Input, args: ['parentFormControl',] }],
13848
14309
  config: [{ type: Input }]
13849
14310
  };
13850
14311
 
@@ -15034,6 +15495,8 @@ const DECLARATIONS = [
15034
15495
  UiExtensionPointComponent,
15035
15496
  CustomDetailComponentHostComponent,
15036
15497
  AssetPreviewLinksComponent,
15498
+ ProductMultiSelectorDialogComponent,
15499
+ ProductSearchInputComponent,
15037
15500
  ];
15038
15501
  const DYNAMIC_FORM_INPUTS = [
15039
15502
  TextFormInputComponent,
@@ -15057,6 +15520,8 @@ const DYNAMIC_FORM_INPUTS = [
15057
15520
  TextareaFormInputComponent,
15058
15521
  RichTextFormInputComponent,
15059
15522
  JsonEditorFormInputComponent,
15523
+ ProductMultiSelectorFormInputComponent,
15524
+ CombinationModeFormInputComponent,
15060
15525
  ];
15061
15526
  class SharedModule {
15062
15527
  }
@@ -15594,7 +16059,7 @@ function patchObject(obj, patch) {
15594
16059
  }
15595
16060
 
15596
16061
  // Auto-generated by the set-version.js script.
15597
- const ADMIN_UI_VERSION = '1.5.2';
16062
+ const ADMIN_UI_VERSION = '1.6.2';
15598
16063
 
15599
16064
  /**
15600
16065
  * Responsible for registering dashboard widget components and querying for layouts.
@@ -15814,5 +16279,5 @@ function unicodePatternValidator(patternRe) {
15814
16279
  * Generated bundle index. Do not edit.
15815
16280
  */
15816
16281
 
15817
- export { ADDRESS_FRAGMENT, ADD_CUSTOMERS_TO_GROUP, ADD_MANUAL_PAYMENT_TO_ORDER, ADD_MEMBERS_TO_ZONE, ADD_NOTE_TO_CUSTOMER, ADD_NOTE_TO_ORDER, ADD_OPTION_GROUP_TO_PRODUCT, ADD_OPTION_TO_GROUP, ADMINISTRATOR_FRAGMENT, ADMIN_UI_VERSION, ALL_CUSTOM_FIELDS_FRAGMENT, ASSET_FRAGMENT, ASSIGN_PRODUCTS_TO_CHANNEL, ASSIGN_ROLE_TO_ADMINISTRATOR, ASSIGN_VARIANTS_TO_CHANNEL, ATTEMPT_LOGIN, AUTH_REDIRECT_PARAM, ActionBarComponent, ActionBarItemsComponent, ActionBarLeftComponent, ActionBarRightComponent, AddressFormComponent, AdjustmentType, AdministratorDataService, AffixedInputComponent, AppComponent, AppComponentModule, AppShellComponent, AssetFileInputComponent, AssetGalleryComponent, AssetPickerDialogComponent, AssetPreviewComponent, AssetPreviewDialogComponent, AssetPreviewLinksComponent, AssetPreviewPipe, AssetSearchInputComponent, AssetType, AuthDataService, AuthGuard, AuthService, BOOLEAN_CUSTOM_FIELD_FRAGMENT, BaseDataService, BaseDetailComponent, BaseEntityResolver, BaseListComponent, BooleanFormInputComponent, BreadcrumbComponent, CANCEL_JOB, CANCEL_ORDER, CHANNEL_FRAGMENT, COLLECTION_FRAGMENT, CONFIGURABLE_OPERATION_DEF_FRAGMENT, CONFIGURABLE_OPERATION_FRAGMENT, COUNTRY_FRAGMENT, CREATE_ADMINISTRATOR, CREATE_ASSETS, CREATE_CHANNEL, CREATE_COLLECTION, CREATE_COUNTRY, CREATE_CUSTOMER, CREATE_CUSTOMER_ADDRESS, CREATE_CUSTOMER_GROUP, CREATE_FACET, CREATE_FACET_VALUES, CREATE_FULFILLMENT, CREATE_PAYMENT_METHOD, CREATE_PRODUCT, CREATE_PRODUCT_OPTION_GROUP, CREATE_PRODUCT_VARIANTS, CREATE_PROMOTION, CREATE_ROLE, CREATE_SHIPPING_METHOD, CREATE_TAG, CREATE_TAX_CATEGORY, CREATE_TAX_RATE, CREATE_ZONE, CURRENT_USER_FRAGMENT, CUSTOMER_FRAGMENT, CUSTOMER_GROUP_FRAGMENT, CUSTOM_FIELD_CONFIG_FRAGMENT, CanDeactivateDetailGuard, ChannelAssignmentControlComponent, ChannelBadgeComponent, ChannelLabelPipe, ChannelSwitcherComponent, CheckJobsLink, ChipComponent, ClientDataService, CollectionDataService, ComponentRegistryService, ConfigurableInputComponent, CoreModule, CurrencyCode, CurrencyFormInputComponent, CurrencyInputComponent, CustomDetailComponentHostComponent, CustomDetailComponentService, CustomFieldComponentService, CustomFieldControlComponent, CustomFieldLabelPipe, CustomHttpTranslationLoader, CustomerDataService, CustomerGroupFormInputComponent, CustomerLabelComponent, DATE_TIME_CUSTOM_FIELD_FRAGMENT, DELETE_ADMINISTRATOR, DELETE_ASSETS, DELETE_CHANNEL, DELETE_COLLECTION, DELETE_COUNTRY, DELETE_CUSTOMER, DELETE_CUSTOMER_ADDRESS, DELETE_CUSTOMER_GROUP, DELETE_CUSTOMER_NOTE, DELETE_FACET, DELETE_FACET_VALUES, DELETE_ORDER_NOTE, DELETE_PAYMENT_METHOD, DELETE_PRODUCT, DELETE_PRODUCT_VARIANT, DELETE_PROMOTION, DELETE_ROLE, DELETE_SHIPPING_METHOD, DELETE_TAG, DELETE_TAX_CATEGORY, DELETE_TAX_RATE, DELETE_ZONE, DISCOUNT_FRAGMENT, DashboardWidgetService, DataModule, DataService, DataTableColumnComponent, DataTableComponent, DateFormInputComponent, DatetimePickerComponent, DatetimePickerService, DefaultInterceptor, DeletionResult, DialogButtonsDirective, DialogComponentOutletComponent, DialogTitleDirective, DisabledDirective, DropdownComponent, DropdownItemDirective, DropdownMenuComponent, DropdownTriggerDirective, DurationPipe, DynamicFormInputComponent, ERROR_RESULT_FRAGMENT, EditNoteDialogComponent, EmptyPlaceholderComponent, EntityInfoComponent, ErrorCode, ExtensionHostComponent, ExtensionHostConfig, ExtensionHostService, ExternalImageDialogComponent, FACET_VALUE_FRAGMENT, FACET_WITH_VALUES_FRAGMENT, FLOAT_CUSTOM_FIELD_FRAGMENT, FULFILLMENT_FRAGMENT, FacetDataService, FacetValueChipComponent, FacetValueFormInputComponent, FacetValueSelectorComponent, FetchAdapter, FileSizePipe, FocalPointControlComponent, FormFieldComponent, FormFieldControlDirective, FormItemComponent, FormattedAddressComponent, GET_ACTIVE_ADMINISTRATOR, GET_ACTIVE_CHANNEL, GET_ADJUSTMENT_OPERATIONS, GET_ADMINISTRATOR, GET_ADMINISTRATORS, GET_ASSET, GET_ASSET_LIST, GET_AVAILABLE_COUNTRIES, GET_CHANNEL, GET_CHANNELS, GET_CLIENT_STATE, GET_COLLECTION, GET_COLLECTION_CONTENTS, GET_COLLECTION_FILTERS, GET_COLLECTION_LIST, GET_COUNTRY, GET_COUNTRY_LIST, GET_CURRENT_USER, GET_CUSTOMER, GET_CUSTOMER_GROUPS, GET_CUSTOMER_GROUP_WITH_CUSTOMERS, GET_CUSTOMER_HISTORY, GET_CUSTOMER_LIST, GET_FACET_LIST, GET_FACET_WITH_VALUES, GET_GLOBAL_SETTINGS, GET_JOBS_BY_ID, GET_JOBS_LIST, GET_JOB_INFO, GET_JOB_QUEUE_LIST, GET_NEWTORK_STATUS, GET_ORDER, GET_ORDERS_LIST, GET_ORDER_HISTORY, GET_ORDER_SUMMARY, GET_PAYMENT_METHOD, GET_PAYMENT_METHOD_LIST, GET_PAYMENT_METHOD_OPERATIONS, GET_PENDING_SEARCH_INDEX_UPDATES, GET_PRODUCT_LIST, GET_PRODUCT_OPTION_GROUP, GET_PRODUCT_OPTION_GROUPS, GET_PRODUCT_SIMPLE, GET_PRODUCT_VARIANT, GET_PRODUCT_VARIANT_LIST, GET_PRODUCT_VARIANT_LIST_SIMPLE, GET_PRODUCT_VARIANT_OPTIONS, GET_PRODUCT_WITH_VARIANTS, GET_PROMOTION, GET_PROMOTION_LIST, GET_ROLE, GET_ROLES, GET_SERVER_CONFIG, GET_SHIPPING_METHOD, GET_SHIPPING_METHOD_LIST, GET_SHIPPING_METHOD_OPERATIONS, GET_TAG, GET_TAG_LIST, GET_TAX_CATEGORIES, GET_TAX_CATEGORY, GET_TAX_RATE, GET_TAX_RATE_LIST, GET_TAX_RATE_LIST_SIMPLE, GET_UI_STATE, GET_USER_STATUS, GET_ZONE, GET_ZONES, GLOBAL_SETTINGS_FRAGMENT, GlobalFlag, HasPermissionPipe, HealthCheckService, HelpTooltipComponent, HistoryEntryDetailComponent, HistoryEntryType, HttpLoaderFactory, I18nService, INT_CUSTOM_FIELD_FRAGMENT, IfDefaultChannelActiveDirective, IfDirectiveBase, IfMultichannelDirective, IfPermissionsDirective, InjectableTranslateMessageFormatCompiler, ItemsPerPageControlsComponent, JOB_INFO_FRAGMENT, JobQueueService, JobState, JsonEditorFormInputComponent, LOCALE_STRING_CUSTOM_FIELD_FRAGMENT, LOG_OUT, LabeledDataComponent, LanguageCode, LanguageSelectorComponent, LinkDialogComponent, LocalStorageService, LocaleBasePipe, LocaleCurrencyNamePipe, LocaleCurrencyPipe, LocaleDatePipe, LocaleLanguageNamePipe, LocaleRegionNamePipe, LogicalOperator, MODIFY_ORDER, MOVE_COLLECTION, MainNavComponent, ManageTagsDialogComponent, ModalDialogComponent, ModalService, NavBuilderService, NotificationComponent, NotificationService, NumberFormInputComponent, ORDER_ADDRESS_FRAGMENT, ORDER_DETAIL_FRAGMENT, ORDER_FRAGMENT, ORDER_LINE_FRAGMENT, ObjectTreeComponent, OmitTypenameLink, OrderDataService, OrderStateLabelComponent, OverlayHostComponent, OverlayHostService, PAYMENT_METHOD_FRAGMENT, PRODUCT_DETAIL_FRAGMENT, PRODUCT_OPTION_FRAGMENT, PRODUCT_OPTION_GROUP_FRAGMENT, PRODUCT_OPTION_GROUP_WITH_OPTIONS_FRAGMENT, PRODUCT_SELECTOR_SEARCH, PRODUCT_VARIANT_FRAGMENT, PROMOTION_FRAGMENT, PaginationControlsComponent, PasswordFormInputComponent, PercentageSuffixInputComponent, Permission, ProductDataService, ProductSelectorComponent, ProductSelectorFormInputComponent, PromotionDataService, ProsemirrorService, QueryResult, REFUND_FRAGMENT, REFUND_ORDER, REINDEX, RELATION_CUSTOM_FIELD_FRAGMENT, REMOVE_CUSTOMERS_FROM_GROUP, REMOVE_MEMBERS_FROM_ZONE, REMOVE_OPTION_GROUP_FROM_PRODUCT, REMOVE_PRODUCTS_FROM_CHANNEL, REMOVE_VARIANTS_FROM_CHANNEL, REQUEST_COMPLETED, REQUEST_STARTED, ROLE_FRAGMENT, RUN_PENDING_SEARCH_INDEX_UPDATES, RelationAssetInputComponent, RelationCardComponent, RelationCardDetailDirective, RelationCardPreviewDirective, RelationCustomerInputComponent, RelationFormInputComponent, RelationGenericInputComponent, RelationProductInputComponent, RelationProductVariantInputComponent, RelationSelectorDialogComponent, RichTextEditorComponent, RichTextFormInputComponent, SEARCH_PRODUCTS, SETTLE_PAYMENT, SETTLE_REFUND, SET_ACTIVE_CHANNEL, SET_AS_LOGGED_IN, SET_AS_LOGGED_OUT, SET_CONTENT_LANGUAGE, SET_DISPLAY_UI_EXTENSION_POINTS, SET_UI_LANGUAGE_AND_LOCALE, SET_UI_LOCALE, SET_UI_THEME, SHIPPING_METHOD_FRAGMENT, STRING_CUSTOM_FIELD_FRAGMENT, SelectFormInputComponent, SelectToggleComponent, SentenceCasePipe, ServerConfigService, SettingsDataService, SharedModule, ShippingMethodDataService, SimpleDialogComponent, SingleSearchSelectionModel, SingleSearchSelectionModelFactory, SortOrder, SortPipe, StateI18nTokenPipe, StatusBadgeComponent, StockMovementType, StringToColorPipe, TAG_FRAGMENT, TAX_CATEGORY_FRAGMENT, TAX_RATE_FRAGMENT, TEST_ELIGIBLE_SHIPPING_METHODS, TEST_SHIPPING_METHOD, TEXT_CUSTOM_FIELD_FRAGMENT, TRANSITION_FULFILLMENT_TO_STATE, TRANSITION_ORDER_TO_STATE, TRANSITION_PAYMENT_TO_STATE, TabbedCustomFieldsComponent, TableRowActionComponent, TagSelectorComponent, TextFormInputComponent, TextareaFormInputComponent, ThemeSwitcherComponent, TimeAgoPipe, TimelineEntryComponent, TitleInputComponent, UPDATE_ACTIVE_ADMINISTRATOR, UPDATE_ADMINISTRATOR, UPDATE_ASSET, UPDATE_CHANNEL, UPDATE_COLLECTION, UPDATE_COUNTRY, UPDATE_CUSTOMER, UPDATE_CUSTOMER_ADDRESS, UPDATE_CUSTOMER_GROUP, UPDATE_CUSTOMER_NOTE, UPDATE_FACET, UPDATE_FACET_VALUES, UPDATE_GLOBAL_SETTINGS, UPDATE_ORDER_CUSTOM_FIELDS, UPDATE_ORDER_NOTE, UPDATE_PAYMENT_METHOD, UPDATE_PRODUCT, UPDATE_PRODUCT_OPTION, UPDATE_PRODUCT_OPTION_GROUP, UPDATE_PRODUCT_VARIANTS, UPDATE_PROMOTION, UPDATE_ROLE, UPDATE_SHIPPING_METHOD, UPDATE_TAG, UPDATE_TAX_CATEGORY, UPDATE_TAX_RATE, UPDATE_USER_CHANNELS, UPDATE_ZONE, USER_STATUS_FRAGMENT, UiExtensionPointComponent, UiLanguageSwitcherDialogComponent, UserMenuComponent, ZONE_FRAGMENT, addActionBarItem, addCustomFields, addNavMenuItem, addNavMenuSection, blockQuoteRule, buildInputRules, buildKeymap, buildMenuItems, bulletListRule, canInsert, clientResolvers, codeBlockRule, configurableDefinitionToInstance, configurableOperationValueIsValid, createApollo, createResolveData, createUpdatedTranslatable, dayOfWeekIndex, defaultFormInputs, detailBreadcrumb, encodeConfigArgValue, findTranslation, flattenFacetValues, getAppConfig, getClientDefaults, getConfigArgValue, getDefaultConfigArgValue, getDefaultUiLanguage, getDefaultUiLocale, getLocales, getMarkRange, getServerLocation, headingRule, hostExternalFrame, initializeServerConfigService, insertImageItem, interpolateDescription, result as introspectionResult, isEntityCreateOrUpdateMutation, jsonValidator, linkItem, linkSelectPlugin, loadAppConfig, markActive, orderedListRule, registerCustomDetailComponent, registerCustomFieldComponent, registerDashboardWidget, registerDefaultFormInputs, registerFormInputComponent, removeReadonlyCustomFields, setDashboardWidgetLayout, stringToColor, toConfigurableOperationInput, transformRelationCustomFieldInputs, unicodePatternValidator, weekDayNames, ɵ1, ɵ10, ɵ2, ɵ3, ɵ4, ɵ5, ɵ6, ɵ7, ɵ8, ɵ9 };
16282
+ export { ADDRESS_FRAGMENT, ADD_CUSTOMERS_TO_GROUP, ADD_MANUAL_PAYMENT_TO_ORDER, ADD_MEMBERS_TO_ZONE, ADD_NOTE_TO_CUSTOMER, ADD_NOTE_TO_ORDER, ADD_OPTION_GROUP_TO_PRODUCT, ADD_OPTION_TO_GROUP, ADMINISTRATOR_FRAGMENT, ADMIN_UI_VERSION, ALL_CUSTOM_FIELDS_FRAGMENT, ASSET_FRAGMENT, ASSIGN_PRODUCTS_TO_CHANNEL, ASSIGN_ROLE_TO_ADMINISTRATOR, ASSIGN_VARIANTS_TO_CHANNEL, ATTEMPT_LOGIN, AUTH_REDIRECT_PARAM, ActionBarComponent, ActionBarItemsComponent, ActionBarLeftComponent, ActionBarRightComponent, AddressFormComponent, AdjustmentType, AdministratorDataService, AffixedInputComponent, AppComponent, AppComponentModule, AppShellComponent, AssetFileInputComponent, AssetGalleryComponent, AssetPickerDialogComponent, AssetPreviewComponent, AssetPreviewDialogComponent, AssetPreviewLinksComponent, AssetPreviewPipe, AssetSearchInputComponent, AssetType, AuthDataService, AuthGuard, AuthService, BOOLEAN_CUSTOM_FIELD_FRAGMENT, BaseDataService, BaseDetailComponent, BaseEntityResolver, BaseListComponent, BooleanFormInputComponent, BreadcrumbComponent, CANCEL_JOB, CANCEL_ORDER, CHANNEL_FRAGMENT, COLLECTION_FRAGMENT, CONFIGURABLE_OPERATION_DEF_FRAGMENT, CONFIGURABLE_OPERATION_FRAGMENT, COUNTRY_FRAGMENT, CREATE_ADMINISTRATOR, CREATE_ASSETS, CREATE_CHANNEL, CREATE_COLLECTION, CREATE_COUNTRY, CREATE_CUSTOMER, CREATE_CUSTOMER_ADDRESS, CREATE_CUSTOMER_GROUP, CREATE_FACET, CREATE_FACET_VALUES, CREATE_FULFILLMENT, CREATE_PAYMENT_METHOD, CREATE_PRODUCT, CREATE_PRODUCT_OPTION_GROUP, CREATE_PRODUCT_VARIANTS, CREATE_PROMOTION, CREATE_ROLE, CREATE_SHIPPING_METHOD, CREATE_TAG, CREATE_TAX_CATEGORY, CREATE_TAX_RATE, CREATE_ZONE, CURRENT_USER_FRAGMENT, CUSTOMER_FRAGMENT, CUSTOMER_GROUP_FRAGMENT, CUSTOM_FIELD_CONFIG_FRAGMENT, CanDeactivateDetailGuard, ChannelAssignmentControlComponent, ChannelBadgeComponent, ChannelLabelPipe, ChannelSwitcherComponent, CheckJobsLink, ChipComponent, ClientDataService, CollectionDataService, CombinationModeFormInputComponent, ComponentRegistryService, ConfigurableInputComponent, CoreModule, CurrencyCode, CurrencyFormInputComponent, CurrencyInputComponent, CustomDetailComponentHostComponent, CustomDetailComponentService, CustomFieldComponentService, CustomFieldControlComponent, CustomFieldLabelPipe, CustomHttpTranslationLoader, CustomerDataService, CustomerGroupFormInputComponent, CustomerLabelComponent, DATE_TIME_CUSTOM_FIELD_FRAGMENT, DELETE_ADMINISTRATOR, DELETE_ASSETS, DELETE_CHANNEL, DELETE_COLLECTION, DELETE_COUNTRY, DELETE_CUSTOMER, DELETE_CUSTOMER_ADDRESS, DELETE_CUSTOMER_GROUP, DELETE_CUSTOMER_NOTE, DELETE_FACET, DELETE_FACET_VALUES, DELETE_ORDER_NOTE, DELETE_PAYMENT_METHOD, DELETE_PRODUCT, DELETE_PRODUCT_VARIANT, DELETE_PROMOTION, DELETE_ROLE, DELETE_SHIPPING_METHOD, DELETE_TAG, DELETE_TAX_CATEGORY, DELETE_TAX_RATE, DELETE_ZONE, DISCOUNT_FRAGMENT, DashboardWidgetService, DataModule, DataService, DataTableColumnComponent, DataTableComponent, DateFormInputComponent, DatetimePickerComponent, DatetimePickerService, DefaultInterceptor, DeletionResult, DialogButtonsDirective, DialogComponentOutletComponent, DialogTitleDirective, DisabledDirective, DropdownComponent, DropdownItemDirective, DropdownMenuComponent, DropdownTriggerDirective, DurationPipe, DynamicFormInputComponent, ERROR_RESULT_FRAGMENT, EditNoteDialogComponent, EmptyPlaceholderComponent, EntityInfoComponent, ErrorCode, ExtensionHostComponent, ExtensionHostConfig, ExtensionHostService, ExternalImageDialogComponent, FACET_VALUE_FRAGMENT, FACET_WITH_VALUES_FRAGMENT, FLOAT_CUSTOM_FIELD_FRAGMENT, FULFILLMENT_FRAGMENT, FacetDataService, FacetValueChipComponent, FacetValueFormInputComponent, FacetValueSelectorComponent, FetchAdapter, FileSizePipe, FocalPointControlComponent, FormFieldComponent, FormFieldControlDirective, FormItemComponent, FormattedAddressComponent, GET_ACTIVE_ADMINISTRATOR, GET_ACTIVE_CHANNEL, GET_ADJUSTMENT_OPERATIONS, GET_ADMINISTRATOR, GET_ADMINISTRATORS, GET_ASSET, GET_ASSET_LIST, GET_AVAILABLE_COUNTRIES, GET_CHANNEL, GET_CHANNELS, GET_CLIENT_STATE, GET_COLLECTION, GET_COLLECTION_CONTENTS, GET_COLLECTION_FILTERS, GET_COLLECTION_LIST, GET_COUNTRY, GET_COUNTRY_LIST, GET_CURRENT_USER, GET_CUSTOMER, GET_CUSTOMER_GROUPS, GET_CUSTOMER_GROUP_WITH_CUSTOMERS, GET_CUSTOMER_HISTORY, GET_CUSTOMER_LIST, GET_FACET_LIST, GET_FACET_WITH_VALUES, GET_GLOBAL_SETTINGS, GET_JOBS_BY_ID, GET_JOBS_LIST, GET_JOB_INFO, GET_JOB_QUEUE_LIST, GET_NEWTORK_STATUS, GET_ORDER, GET_ORDERS_LIST, GET_ORDER_HISTORY, GET_ORDER_SUMMARY, GET_PAYMENT_METHOD, GET_PAYMENT_METHOD_LIST, GET_PAYMENT_METHOD_OPERATIONS, GET_PENDING_SEARCH_INDEX_UPDATES, GET_PRODUCT_LIST, GET_PRODUCT_OPTION_GROUP, GET_PRODUCT_OPTION_GROUPS, GET_PRODUCT_SIMPLE, GET_PRODUCT_VARIANT, GET_PRODUCT_VARIANT_LIST, GET_PRODUCT_VARIANT_LIST_SIMPLE, GET_PRODUCT_VARIANT_OPTIONS, GET_PRODUCT_WITH_VARIANTS, GET_PROMOTION, GET_PROMOTION_LIST, GET_ROLE, GET_ROLES, GET_SERVER_CONFIG, GET_SHIPPING_METHOD, GET_SHIPPING_METHOD_LIST, GET_SHIPPING_METHOD_OPERATIONS, GET_TAG, GET_TAG_LIST, GET_TAX_CATEGORIES, GET_TAX_CATEGORY, GET_TAX_RATE, GET_TAX_RATE_LIST, GET_TAX_RATE_LIST_SIMPLE, GET_UI_STATE, GET_USER_STATUS, GET_ZONE, GET_ZONES, GLOBAL_SETTINGS_FRAGMENT, GlobalFlag, HasPermissionPipe, HealthCheckService, HelpTooltipComponent, HistoryEntryDetailComponent, HistoryEntryType, HttpLoaderFactory, I18nService, INT_CUSTOM_FIELD_FRAGMENT, IfDefaultChannelActiveDirective, IfDirectiveBase, IfMultichannelDirective, IfPermissionsDirective, InjectableTranslateMessageFormatCompiler, ItemsPerPageControlsComponent, JOB_INFO_FRAGMENT, JobQueueService, JobState, JsonEditorFormInputComponent, LOCALE_STRING_CUSTOM_FIELD_FRAGMENT, LOG_OUT, LabeledDataComponent, LanguageCode, LanguageSelectorComponent, LinkDialogComponent, LocalStorageService, LocaleBasePipe, LocaleCurrencyNamePipe, LocaleCurrencyPipe, LocaleDatePipe, LocaleLanguageNamePipe, LocaleRegionNamePipe, LogicalOperator, MODIFY_ORDER, MOVE_COLLECTION, MainNavComponent, ManageTagsDialogComponent, ModalDialogComponent, ModalService, NavBuilderService, NotificationComponent, NotificationService, NumberFormInputComponent, ORDER_ADDRESS_FRAGMENT, ORDER_DETAIL_FRAGMENT, ORDER_FRAGMENT, ORDER_LINE_FRAGMENT, ObjectTreeComponent, OmitTypenameLink, OrderDataService, OrderStateLabelComponent, OverlayHostComponent, OverlayHostService, PAYMENT_METHOD_FRAGMENT, PREVIEW_COLLECTION_CONTENTS, PRODUCT_DETAIL_FRAGMENT, PRODUCT_OPTION_FRAGMENT, PRODUCT_OPTION_GROUP_FRAGMENT, PRODUCT_OPTION_GROUP_WITH_OPTIONS_FRAGMENT, PRODUCT_SELECTOR_SEARCH, PRODUCT_VARIANT_FRAGMENT, PROMOTION_FRAGMENT, PaginationControlsComponent, PasswordFormInputComponent, PercentageSuffixInputComponent, Permission, ProductDataService, ProductMultiSelectorDialogComponent, ProductMultiSelectorFormInputComponent, ProductSearchInputComponent, ProductSelectorComponent, ProductSelectorFormInputComponent, PromotionDataService, ProsemirrorService, QueryResult, REFUND_FRAGMENT, REFUND_ORDER, REINDEX, RELATION_CUSTOM_FIELD_FRAGMENT, REMOVE_CUSTOMERS_FROM_GROUP, REMOVE_MEMBERS_FROM_ZONE, REMOVE_OPTION_GROUP_FROM_PRODUCT, REMOVE_PRODUCTS_FROM_CHANNEL, REMOVE_VARIANTS_FROM_CHANNEL, REQUEST_COMPLETED, REQUEST_STARTED, ROLE_FRAGMENT, RUN_PENDING_SEARCH_INDEX_UPDATES, RelationAssetInputComponent, RelationCardComponent, RelationCardDetailDirective, RelationCardPreviewDirective, RelationCustomerInputComponent, RelationFormInputComponent, RelationGenericInputComponent, RelationProductInputComponent, RelationProductVariantInputComponent, RelationSelectorDialogComponent, RichTextEditorComponent, RichTextFormInputComponent, SEARCH_PRODUCTS, SETTLE_PAYMENT, SETTLE_REFUND, SET_ACTIVE_CHANNEL, SET_AS_LOGGED_IN, SET_AS_LOGGED_OUT, SET_CONTENT_LANGUAGE, SET_DISPLAY_UI_EXTENSION_POINTS, SET_UI_LANGUAGE_AND_LOCALE, SET_UI_LOCALE, SET_UI_THEME, SHIPPING_METHOD_FRAGMENT, STRING_CUSTOM_FIELD_FRAGMENT, SelectFormInputComponent, SelectToggleComponent, SelectionManager, SentenceCasePipe, ServerConfigService, SettingsDataService, SharedModule, ShippingMethodDataService, SimpleDialogComponent, SingleSearchSelectionModel, SingleSearchSelectionModelFactory, SortOrder, SortPipe, StateI18nTokenPipe, StatusBadgeComponent, StockMovementType, StringToColorPipe, TAG_FRAGMENT, TAX_CATEGORY_FRAGMENT, TAX_RATE_FRAGMENT, TEST_ELIGIBLE_SHIPPING_METHODS, TEST_SHIPPING_METHOD, TEXT_CUSTOM_FIELD_FRAGMENT, TRANSITION_FULFILLMENT_TO_STATE, TRANSITION_ORDER_TO_STATE, TRANSITION_PAYMENT_TO_STATE, TabbedCustomFieldsComponent, TableRowActionComponent, TagSelectorComponent, TextFormInputComponent, TextareaFormInputComponent, ThemeSwitcherComponent, TimeAgoPipe, TimelineEntryComponent, TitleInputComponent, UPDATE_ACTIVE_ADMINISTRATOR, UPDATE_ADMINISTRATOR, UPDATE_ASSET, UPDATE_CHANNEL, UPDATE_COLLECTION, UPDATE_COUNTRY, UPDATE_CUSTOMER, UPDATE_CUSTOMER_ADDRESS, UPDATE_CUSTOMER_GROUP, UPDATE_CUSTOMER_NOTE, UPDATE_FACET, UPDATE_FACET_VALUES, UPDATE_GLOBAL_SETTINGS, UPDATE_ORDER_CUSTOM_FIELDS, UPDATE_ORDER_NOTE, UPDATE_PAYMENT_METHOD, UPDATE_PRODUCT, UPDATE_PRODUCT_OPTION, UPDATE_PRODUCT_OPTION_GROUP, UPDATE_PRODUCT_VARIANTS, UPDATE_PROMOTION, UPDATE_ROLE, UPDATE_SHIPPING_METHOD, UPDATE_TAG, UPDATE_TAX_CATEGORY, UPDATE_TAX_RATE, UPDATE_USER_CHANNELS, UPDATE_ZONE, USER_STATUS_FRAGMENT, UiExtensionPointComponent, UiLanguageSwitcherDialogComponent, UserMenuComponent, ZONE_FRAGMENT, addActionBarItem, addCustomFields, addNavMenuItem, addNavMenuSection, blockQuoteRule, buildInputRules, buildKeymap, buildMenuItems, bulletListRule, canInsert, clientResolvers, codeBlockRule, configurableDefinitionToInstance, configurableOperationValueIsValid, createApollo, createResolveData, createUpdatedTranslatable, dayOfWeekIndex, defaultFormInputs, detailBreadcrumb, encodeConfigArgValue, findTranslation, flattenFacetValues, getAppConfig, getClientDefaults, getConfigArgValue, getDefaultConfigArgValue, getDefaultUiLanguage, getDefaultUiLocale, getLocales, getMarkRange, getServerLocation, headingRule, hostExternalFrame, initializeServerConfigService, insertImageItem, interpolateDescription, result as introspectionResult, isEntityCreateOrUpdateMutation, jsonValidator, linkItem, linkSelectPlugin, loadAppConfig, markActive, orderedListRule, registerCustomDetailComponent, registerCustomFieldComponent, registerDashboardWidget, registerDefaultFormInputs, registerFormInputComponent, removeReadonlyCustomFields, setDashboardWidgetLayout, stringToColor, toConfigurableOperationInput, transformRelationCustomFieldInputs, unicodePatternValidator, weekDayNames, ɵ1, ɵ10, ɵ2, ɵ3, ɵ4, ɵ5, ɵ6, ɵ7, ɵ8, ɵ9 };
15818
16283
  //# sourceMappingURL=vendure-admin-ui-core.js.map