@foxy.io/elements 1.14.0-beta.9 → 1.14.0

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 (84) hide show
  1. package/dist/cdn/foxy-access-recovery-form.js +1 -1
  2. package/dist/cdn/foxy-address-card.js +1 -1
  3. package/dist/cdn/foxy-address-form.js +1 -1
  4. package/dist/cdn/foxy-applied-tax-card.js +1 -1
  5. package/dist/cdn/foxy-attribute-card.js +1 -1
  6. package/dist/cdn/foxy-attribute-form.js +1 -1
  7. package/dist/cdn/foxy-cancellation-form.js +1 -1
  8. package/dist/cdn/foxy-collection-page.js +1 -1
  9. package/dist/cdn/foxy-collection-pages.js +1 -1
  10. package/dist/cdn/foxy-custom-field-card.js +1 -1
  11. package/dist/cdn/foxy-custom-field-form.js +1 -1
  12. package/dist/cdn/foxy-customer-card.js +1 -1
  13. package/dist/cdn/foxy-customer-form.js +1 -1
  14. package/dist/cdn/foxy-customer-portal-settings.js +1 -1
  15. package/dist/cdn/foxy-customer-portal.js +18 -15
  16. package/dist/cdn/foxy-customer.js +1 -1
  17. package/dist/cdn/foxy-customers-table.js +1 -1
  18. package/dist/cdn/foxy-discount-card.js +1 -1
  19. package/dist/cdn/foxy-donation.js +1 -1
  20. package/dist/cdn/foxy-email-template-form.js +1 -1
  21. package/dist/cdn/foxy-error-entry-card.js +1 -1
  22. package/dist/cdn/foxy-form-dialog.js +1 -1
  23. package/dist/cdn/foxy-i18n.js +1 -1
  24. package/dist/cdn/foxy-items-form.js +1 -1
  25. package/dist/cdn/foxy-payment-card.js +1 -1
  26. package/dist/cdn/foxy-payment-method-card.js +1 -1
  27. package/dist/cdn/foxy-query-builder.js +1 -1
  28. package/dist/cdn/foxy-sign-in-form.js +1 -1
  29. package/dist/cdn/foxy-spinner.js +1 -1
  30. package/dist/cdn/foxy-subscription-card.js +1 -1
  31. package/dist/cdn/foxy-subscription-form.js +3 -3
  32. package/dist/cdn/foxy-subscriptions-table.js +1 -1
  33. package/dist/cdn/foxy-table.js +1 -1
  34. package/dist/cdn/foxy-tax-card.js +1 -1
  35. package/dist/cdn/foxy-tax-form.js +1 -1
  36. package/dist/cdn/foxy-template-config-form.js +1 -1
  37. package/dist/cdn/foxy-template-form.js +1 -1
  38. package/dist/cdn/foxy-transaction-card.js +1 -1
  39. package/dist/cdn/foxy-transactions-table.js +1 -1
  40. package/dist/cdn/foxy-user-form.js +1 -1
  41. package/dist/cdn/foxy-users-table.js +1 -1
  42. package/dist/cdn/{shared-4ba926ca.js → shared-07abcd7b.js} +1 -1
  43. package/dist/cdn/{shared-ca7c3b9a.js → shared-322e60b1.js} +1 -1
  44. package/dist/cdn/shared-35dbd2c5.js +1 -0
  45. package/dist/cdn/{shared-5d94bacb.js → shared-5c8b531d.js} +1 -1
  46. package/dist/cdn/{shared-7007dedb.js → shared-5f54e916.js} +1 -1
  47. package/dist/cdn/{shared-00070cc4.js → shared-7a42073a.js} +5 -5
  48. package/dist/cdn/{shared-b24377bf.js → shared-8a7bee0d.js} +1 -1
  49. package/dist/cdn/{shared-da787055.js → shared-91e768be.js} +1 -1
  50. package/dist/cdn/{shared-d01035c5.js → shared-9a40309d.js} +1 -1
  51. package/dist/cdn/{shared-a3d2c48e.js → shared-b5147166.js} +1 -1
  52. package/dist/cdn/{shared-d05c93a5.js → shared-bc2bfe52.js} +1 -1
  53. package/dist/cdn/{shared-c5ae5d33.js → shared-ce1da35d.js} +1 -1
  54. package/dist/cdn/{shared-0f9809ab.js → shared-d01d809a.js} +1 -1
  55. package/dist/cdn/{shared-31d03530.js → shared-d8ffb279.js} +1 -1
  56. package/dist/cdn/{shared-daf6b763.js → shared-e5cbf291.js} +1 -1
  57. package/dist/cdn/{shared-007c4e34.js → shared-f1dc1c6c.js} +1 -1
  58. package/dist/cdn/translations/shared/de.json +94 -0
  59. package/dist/cdn/translations/shared/en.json +83 -83
  60. package/dist/cdn/translations/shared/es.json +93 -0
  61. package/dist/elements/public/CustomerPortal/InternalCustomerPortalLink.d.ts +1 -0
  62. package/dist/elements/public/CustomerPortal/InternalCustomerPortalLink.js +17 -8
  63. package/dist/elements/public/CustomerPortal/InternalCustomerPortalLink.js.map +1 -1
  64. package/dist/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.js +11 -3
  65. package/dist/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.js.map +1 -1
  66. package/dist/elements/public/ItemsForm/private/Picture.d.ts +1 -0
  67. package/dist/elements/public/ItemsForm/private/Picture.js +2 -0
  68. package/dist/elements/public/ItemsForm/private/Picture.js.map +1 -1
  69. package/dist/elements/public/SubscriptionForm/SubscriptionForm.js +12 -4
  70. package/dist/elements/public/SubscriptionForm/SubscriptionForm.js.map +1 -1
  71. package/dist/elements/public/TemplateConfigForm/CountriesList.d.ts +2 -4
  72. package/dist/elements/public/TemplateConfigForm/CountriesList.js +19 -20
  73. package/dist/elements/public/TemplateConfigForm/CountriesList.js.map +1 -1
  74. package/dist/elements/public/TemplateConfigForm/CountryCard.d.ts +1 -3
  75. package/dist/elements/public/TemplateConfigForm/CountryCard.js +21 -18
  76. package/dist/elements/public/TemplateConfigForm/CountryCard.js.map +1 -1
  77. package/dist/elements/public/TemplateConfigForm/TemplateConfigForm.js +163 -151
  78. package/dist/elements/public/TemplateConfigForm/TemplateConfigForm.js.map +1 -1
  79. package/dist/mixins/themeable.js +10 -8
  80. package/dist/mixins/themeable.js.map +1 -1
  81. package/dist/mixins/translatable.js +1 -1
  82. package/dist/mixins/translatable.js.map +1 -1
  83. package/package.json +1 -1
  84. package/dist/cdn/shared-fe8a7aa2.js +0 -1
@@ -105,12 +105,7 @@ export class TemplateConfigForm extends Base {
105
105
  const json = this.form.json ? JSON.parse(this.form.json) : getDefaultJSON();
106
106
  return html `
107
107
  <div class="relative" aria-busy=${this.in('busy')} aria-live="polite">
108
- <div
109
- class=${classMap({
110
- 'space-y-l transition-opacity': true,
111
- 'opacity-50': !this.in('idle'),
112
- })}
113
- >
108
+ <div class="space-y-l">
114
109
  ${hidden.matches('cart-type', true) ? '' : this.__renderCartType(json)}
115
110
  ${hidden.matches('foxycomplete', true) ? '' : this.__renderFoxycomplete(json)}
116
111
  ${hidden.matches('locations', true) ? '' : this.__renderLocations(json)}
@@ -197,32 +192,27 @@ export class TemplateConfigForm extends Base {
197
192
  }
198
193
  __renderFoxycomplete(json) {
199
194
  const { lang, ns } = this;
200
- const isDisabled = this.disabledSelector.matches('foxycomplete', true);
195
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('foxycomplete', true);
201
196
  const isReadonly = this.readonlySelector.matches('foxycomplete', true);
197
+ const config = json.foxycomplete;
202
198
  const items = ['combobox', 'search', 'disabled'];
203
- const value = json.foxycomplete.usage === 'none'
204
- ? 'disabled'
205
- : json.foxycomplete.show_combobox
206
- ? 'combobox'
207
- : 'search';
208
- const renderFlagsCheckbox = () => html `
199
+ const value = config.usage === 'none' ? 'disabled' : config.show_combobox ? 'combobox' : 'search';
200
+ const flagsCheckbox = html `
209
201
  <x-checkbox
202
+ data-testid="foxycomplete-flags-check"
210
203
  ?disabled=${isDisabled}
211
204
  ?readonly=${isReadonly}
212
- ?checked=${json.foxycomplete.show_flags}
205
+ ?checked=${config.show_flags}
213
206
  @change=${(evt) => {
214
- const newConfig = {
215
- ...json.foxycomplete,
216
- show_flags: evt.detail,
217
- };
218
- this.edit({ json: JSON.stringify({ ...json, foxycomplete: newConfig }) });
207
+ config.show_flags = evt.detail;
208
+ this.edit({ json: JSON.stringify(json) });
219
209
  }}
220
210
  >
221
211
  <foxy-i18n lang=${lang} key="show_country_flags" ns=${ns}></foxy-i18n>
222
212
  </x-checkbox>
223
213
  `;
224
214
  return html `
225
- <div>
215
+ <div data-testid="foxycomplete">
226
216
  ${this.renderTemplateOrSlot('foxycomplete:before')}
227
217
 
228
218
  <x-group frame>
@@ -236,6 +226,7 @@ export class TemplateConfigForm extends Base {
236
226
  </foxy-i18n>
237
227
 
238
228
  <x-choice
229
+ data-testid="foxycomplete-choice"
239
230
  .value=${value}
240
231
  .items=${items}
241
232
  ?disabled=${isDisabled}
@@ -243,12 +234,9 @@ export class TemplateConfigForm extends Base {
243
234
  @change=${(evt) => {
244
235
  if (!(evt instanceof ChoiceChangeEvent))
245
236
  return;
246
- const newConfig = {
247
- ...json.foxycomplete,
248
- usage: evt.detail === 'disabled' ? 'none' : 'required',
249
- show_combobox: evt.detail === 'combobox',
250
- };
251
- this.edit({ json: JSON.stringify({ ...json, foxycomplete: newConfig }) });
237
+ config.usage = evt.detail === 'disabled' ? 'none' : 'required';
238
+ config.show_combobox = evt.detail === 'combobox';
239
+ this.edit({ json: JSON.stringify(json) });
252
240
  }}
253
241
  >
254
242
  ${items.map(item => {
@@ -272,17 +260,15 @@ export class TemplateConfigForm extends Base {
272
260
  const field = action === 'open' ? 'combobox_open' : 'combobox_close';
273
261
  return html `
274
262
  <vaadin-text-field
263
+ data-testid="foxycomplete-${action}-icon"
275
264
  label=${this.t(`${action}_icon`)}
276
- .value=${json.foxycomplete[field]}
265
+ .value=${config[field]}
277
266
  ?disabled=${isDisabled}
278
267
  ?readonly=${isReadonly}
268
+ @keydown=${(evt) => evt.key === 'Enter' && this.submit()}
279
269
  @input=${(evt) => {
280
- const target = evt.currentTarget;
281
- const newConfig = {
282
- ...json.foxycomplete,
283
- [field]: target.value,
284
- };
285
- this.edit({ json: JSON.stringify({ ...json, foxycomplete: newConfig }) });
270
+ config[field] = evt.currentTarget.value;
271
+ this.edit({ json: JSON.stringify(json) });
286
272
  }}
287
273
  >
288
274
  </vaadin-text-field>
@@ -290,24 +276,21 @@ export class TemplateConfigForm extends Base {
290
276
  })}
291
277
  </div>
292
278
 
293
- ${renderFlagsCheckbox()}
279
+ ${flagsCheckbox}
294
280
  </div>
295
281
 
296
- <div slot="search" class="pb-s" ?hidden=${value !== 'search'}>
297
- ${renderFlagsCheckbox()}
298
- </div>
282
+ <div slot="search" class="pb-s" ?hidden=${value !== 'search'}>${flagsCheckbox}</div>
299
283
  </x-choice>
300
284
 
301
285
  <div class="border-t border-contrast-10 p-m">
302
286
  <x-checkbox
287
+ data-testid="foxycomplete-lookup-check"
303
288
  ?disabled=${isDisabled}
304
289
  ?readonly=${isReadonly}
305
290
  ?checked=${json.postal_code_lookup.usage === 'enabled'}
306
291
  @change=${(evt) => {
307
- const newConfig = {
308
- usage: evt.detail ? 'enabled' : 'none',
309
- };
310
- this.edit({ json: JSON.stringify({ ...json, postal_code_lookup: newConfig }) });
292
+ json.postal_code_lookup.usage = evt.detail ? 'enabled' : 'none';
293
+ this.edit({ json: JSON.stringify(json) });
311
294
  }}
312
295
  >
313
296
  <foxy-i18n lang=${lang} key="enable_postcode_lookup" ns=${ns}></foxy-i18n>
@@ -322,7 +305,7 @@ export class TemplateConfigForm extends Base {
322
305
  __renderLocations(json) {
323
306
  const { lang, ns } = this;
324
307
  const config = json.location_filtering;
325
- const isDisabled = this.disabledSelector.matches('locations', true);
308
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('locations', true);
326
309
  const isReadonly = this.readonlySelector.matches('locations', true);
327
310
  const shippingChoice = config.shipping_filter_type === 'blacklist' ? 'block' : 'allow';
328
311
  const billingChoice = config.usage === 'both'
@@ -353,81 +336,85 @@ export class TemplateConfigForm extends Base {
353
336
  }
354
337
  };
355
338
  return html `
356
- ${this.renderTemplateOrSlot('locations:before')}
357
-
358
- <x-group frame>
359
- <foxy-i18n
360
- class=${isDisabled ? 'text-disabled' : ''}
361
- slot="header"
362
- lang=${lang}
363
- key="location_plural"
364
- ns=${ns}
365
- >
366
- </foxy-i18n>
339
+ <div data-testid="locations">
340
+ ${this.renderTemplateOrSlot('locations:before')}
367
341
 
368
- <div class="grid sm-grid-cols-2 bg-contrast-10" style="gap: 1px">
369
- <x-group class="bg-base pt-m">
370
- <foxy-i18n
371
- class=${isDisabled ? 'text-disabled' : 'text-tertiary'}
372
- slot="header"
373
- lang=${lang}
374
- key="shipping"
375
- ns=${ns}
376
- >
377
- </foxy-i18n>
342
+ <x-group frame>
343
+ <foxy-i18n
344
+ class=${isDisabled ? 'text-disabled' : ''}
345
+ slot="header"
346
+ lang=${lang}
347
+ key="location_plural"
348
+ ns=${ns}
349
+ >
350
+ </foxy-i18n>
378
351
 
379
- <x-choice
380
- .items=${['allow', 'block']}
381
- .value=${shippingChoice}
382
- ?disabled=${isDisabled}
383
- ?readonly=${isReadonly}
384
- @change=${(evt) => {
352
+ <div class="grid sm-grid-cols-2 bg-contrast-10" style="gap: 1px">
353
+ <x-group class="bg-base pt-m">
354
+ <foxy-i18n
355
+ class=${isDisabled ? 'text-disabled' : 'text-tertiary'}
356
+ slot="header"
357
+ lang=${lang}
358
+ key="shipping"
359
+ ns=${ns}
360
+ >
361
+ </foxy-i18n>
362
+
363
+ <x-choice
364
+ data-testid="locations-shipping-choice"
365
+ .items=${['allow', 'block']}
366
+ .value=${shippingChoice}
367
+ ?disabled=${isDisabled}
368
+ ?readonly=${isReadonly}
369
+ @change=${(evt) => {
385
370
  if (config.usage !== 'both')
386
371
  config.usage = 'independent';
387
372
  config.shipping_filter_type = evt.detail === 'block' ? 'blacklist' : 'whitelist';
388
373
  normalize();
389
374
  this.edit({ json: JSON.stringify(json) });
390
375
  }}
391
- >
392
- <foxy-i18n slot="allow-label" lang=${lang} key="allowlist" ns=${ns}></foxy-i18n>
393
- <foxy-i18n slot="block-label" lang=${lang} key="blocklist" ns=${ns}></foxy-i18n>
394
-
395
- <x-countries-list
396
- countries=${JSON.stringify(config.shipping_filter_values)}
397
- regions=${this.regions}
398
- class="mb-m"
399
- href=${this.countries}
400
- slot=${shippingChoice}
401
- lang=${lang}
402
- ns=${ns}
403
- ?disabled=${isDisabled}
404
- ?readonly=${isReadonly}
405
- @update:countries=${(evt) => {
376
+ >
377
+ <foxy-i18n slot="allow-label" lang=${lang} key="allowlist" ns=${ns}></foxy-i18n>
378
+ <foxy-i18n slot="block-label" lang=${lang} key="blocklist" ns=${ns}></foxy-i18n>
379
+
380
+ <x-countries-list
381
+ data-testid="locations-shipping-list"
382
+ countries=${JSON.stringify(config.shipping_filter_values)}
383
+ regions=${this.regions}
384
+ class="mb-m"
385
+ href=${this.countries}
386
+ slot=${shippingChoice}
387
+ lang=${lang}
388
+ ns=${ns}
389
+ ?disabled=${isDisabled}
390
+ ?readonly=${isReadonly}
391
+ @update:countries=${(evt) => {
406
392
  config.shipping_filter_values = evt.currentTarget.countries;
407
393
  normalize();
408
394
  this.edit({ json: JSON.stringify(json) });
409
395
  }}
410
- >
411
- </x-countries-list>
412
- </x-choice>
413
- </x-group>
396
+ >
397
+ </x-countries-list>
398
+ </x-choice>
399
+ </x-group>
414
400
 
415
- <x-group class="bg-base pt-m">
416
- <foxy-i18n
417
- class=${isDisabled ? 'text-disabled' : 'text-tertiary'}
418
- slot="header"
419
- lang=${lang}
420
- key="billing"
421
- ns=${ns}
422
- >
423
- </foxy-i18n>
401
+ <x-group class="bg-base pt-m">
402
+ <foxy-i18n
403
+ class=${isDisabled ? 'text-disabled' : 'text-tertiary'}
404
+ slot="header"
405
+ lang=${lang}
406
+ key="billing"
407
+ ns=${ns}
408
+ >
409
+ </foxy-i18n>
424
410
 
425
- <x-choice
426
- .items=${['allow', 'block', 'copy']}
427
- .value=${billingChoice}
428
- ?disabled=${isDisabled}
429
- ?readonly=${isReadonly}
430
- @change=${(evt) => {
411
+ <x-choice
412
+ data-testid="locations-billing-choice"
413
+ .items=${['allow', 'block', 'copy']}
414
+ .value=${billingChoice}
415
+ ?disabled=${isDisabled}
416
+ ?readonly=${isReadonly}
417
+ @change=${(evt) => {
431
418
  if (evt.detail === 'copy') {
432
419
  config.usage = 'both';
433
420
  }
@@ -438,35 +425,38 @@ export class TemplateConfigForm extends Base {
438
425
  normalize();
439
426
  this.edit({ json: JSON.stringify(json) });
440
427
  }}
441
- >
442
- <foxy-i18n slot="allow-label" lang=${lang} key="allowlist" ns=${ns}></foxy-i18n>
443
- <foxy-i18n slot="block-label" lang=${lang} key="blocklist" ns=${ns}></foxy-i18n>
444
- <foxy-i18n slot="copy-label" lang=${lang} key="same_as_shipping" ns=${ns}></foxy-i18n>
445
-
446
- <x-countries-list
447
- countries=${JSON.stringify(config.billing_filter_values)}
448
- regions=${this.regions}
449
- class="mb-m"
450
- href=${this.countries}
451
- slot=${billingChoice}
452
- lang=${lang}
453
- ns=${ns}
454
- ?disabled=${isDisabled}
455
- ?readonly=${isReadonly}
456
- ?hidden=${billingChoice === 'copy'}
457
- @update:countries=${(evt) => {
428
+ >
429
+ <foxy-i18n slot="allow-label" lang=${lang} key="allowlist" ns=${ns}></foxy-i18n>
430
+ <foxy-i18n slot="block-label" lang=${lang} key="blocklist" ns=${ns}></foxy-i18n>
431
+ <foxy-i18n slot="copy-label" lang=${lang} key="same_as_shipping" ns=${ns}>
432
+ </foxy-i18n>
433
+
434
+ <x-countries-list
435
+ data-testid="locations-billing-list"
436
+ countries=${JSON.stringify(config.billing_filter_values)}
437
+ regions=${this.regions}
438
+ class="mb-m"
439
+ href=${this.countries}
440
+ slot=${billingChoice}
441
+ lang=${lang}
442
+ ns=${ns}
443
+ ?disabled=${isDisabled}
444
+ ?readonly=${isReadonly}
445
+ ?hidden=${billingChoice === 'copy'}
446
+ @update:countries=${(evt) => {
458
447
  config.billing_filter_values = evt.currentTarget.countries;
459
448
  normalize();
460
449
  this.edit({ json: JSON.stringify(json) });
461
450
  }}
462
- >
463
- </x-countries-list>
464
- </x-choice>
465
- </x-group>
466
- </div>
467
- </x-group>
451
+ >
452
+ </x-countries-list>
453
+ </x-choice>
454
+ </x-group>
455
+ </div>
456
+ </x-group>
468
457
 
469
- ${this.renderTemplateOrSlot('locations:after')}
458
+ ${this.renderTemplateOrSlot('locations:after')}
459
+ </div>
470
460
  `;
471
461
  }
472
462
  __renderHiddenFields(json) {
@@ -474,7 +464,7 @@ export class TemplateConfigForm extends Base {
474
464
  const suggestions = [];
475
465
  const fields = [];
476
466
  const config = json.cart_display_config;
477
- const isDisabled = this.disabledSelector.matches('hidden-fields', true);
467
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('hidden-fields', true);
478
468
  const isReadonly = this.readonlySelector.matches('hidden-fields', true);
479
469
  for (const key in config) {
480
470
  if (!key.startsWith('show_'))
@@ -500,8 +490,9 @@ export class TemplateConfigForm extends Base {
500
490
  };
501
491
  const radius = 'calc(var(--lumo-border-radius-l) / 1.2)';
502
492
  const inputRadius = fields.length === 0 ? [radius] : ['0', '0', radius, radius];
493
+ const isAddButtonDisabled = isDisabled || !this.__addHiddenFieldInputValue;
503
494
  return html `
504
- <div>
495
+ <div data-testid="hidden-fields">
505
496
  ${this.renderTemplateOrSlot('hidden-fields:before')}
506
497
 
507
498
  <x-group frame>
@@ -514,7 +505,7 @@ export class TemplateConfigForm extends Base {
514
505
  >
515
506
  </foxy-i18n>
516
507
 
517
- <div class="divide-y divide-contrast-10">
508
+ <div class="divide-y divide-contrast-10" data-testid="hidden-fields-list">
518
509
  ${fields.map(field => {
519
510
  return html `
520
511
  <div
@@ -529,6 +520,7 @@ export class TemplateConfigForm extends Base {
529
520
  : html `<span>${field}</span>`}
530
521
 
531
522
  <button
523
+ aria-label=${this.t('delete')}
532
524
  class=${classMap({
533
525
  'w-xs h-xs rounded-full transition-colors': true,
534
526
  'hover-bg-error-10 hover-text-error': !isDisabled,
@@ -556,6 +548,7 @@ export class TemplateConfigForm extends Base {
556
548
  </div>
557
549
 
558
550
  <div
551
+ data-testid="hidden-fields-new"
559
552
  style="border-radius: ${inputRadius.join(' ')}"
560
553
  class=${classMap({
561
554
  'h-m flex items-center ring-inset ring-primary-50 focus-within-ring-2': true,
@@ -570,6 +563,7 @@ export class TemplateConfigForm extends Base {
570
563
  list="hidden-fields-list"
571
564
  .value=${live(this.__addHiddenFieldInputValue)}
572
565
  ?disabled=${isDisabled}
566
+ ?readonly=${isReadonly}
573
567
  @keydown=${(evt) => evt.key === 'Enter' && addField()}
574
568
  @input=${(evt) => {
575
569
  this.__addHiddenFieldInputValue = evt.currentTarget.value;
@@ -587,12 +581,12 @@ export class TemplateConfigForm extends Base {
587
581
  class=${classMap({
588
582
  'w-xs h-xs mr-xs flex-shrink-0 ring-inset ring-success-50': true,
589
583
  'flex items-center justify-center rounded-full transition-colors': true,
590
- 'bg-contrast-5 text-disabled cursor-default': !this.__addHiddenFieldInputValue,
591
- 'bg-success-10 text-success cursor-pointer': !!this.__addHiddenFieldInputValue,
592
- 'hover-bg-success hover-text-success-contrast': !!this.__addHiddenFieldInputValue,
593
- 'focus-outline-none focus-ring-2': !!this.__addHiddenFieldInputValue,
584
+ 'bg-contrast-5 text-disabled cursor-default': isAddButtonDisabled,
585
+ 'bg-success-10 text-success cursor-pointer': !isAddButtonDisabled,
586
+ 'hover-bg-success hover-text-success-contrast': !isAddButtonDisabled,
587
+ 'focus-outline-none focus-ring-2': !isAddButtonDisabled,
594
588
  })}
595
- ?disabled=${!this.__addHiddenFieldInputValue}
589
+ ?disabled=${isAddButtonDisabled}
596
590
  @click=${addField}
597
591
  >
598
592
  <iron-icon icon="icons:add" class="icon-inline text-m"></iron-icon>
@@ -606,7 +600,7 @@ export class TemplateConfigForm extends Base {
606
600
  }
607
601
  __renderCards(json) {
608
602
  const { lang, ns } = this;
609
- const isDisabled = this.disabledSelector.matches('cards', true);
603
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('cards', true);
610
604
  const isReadonly = this.readonlySelector.matches('cards', true);
611
605
  const config = json.supported_payment_cards;
612
606
  let skipForSaved;
@@ -634,7 +628,7 @@ export class TemplateConfigForm extends Base {
634
628
  visa: 'Visa',
635
629
  };
636
630
  return html `
637
- <div>
631
+ <div data-testid="cards">
638
632
  ${this.renderTemplateOrSlot('cards:before')}
639
633
 
640
634
  <div class="space-y-xs">
@@ -682,16 +676,17 @@ export class TemplateConfigForm extends Base {
682
676
  type="checkbox"
683
677
  class="sr-only"
684
678
  ?disabled=${isDisabled}
679
+ ?readonly=${isReadonly}
685
680
  ?checked=${isChecked}
686
681
  @change=${(evt) => {
687
682
  if (isReadonly)
688
683
  return evt.preventDefault();
689
684
  evt.stopPropagation();
690
- if (isChecked) {
691
- config.splice(config.indexOf(type), 1);
685
+ if (evt.currentTarget.checked) {
686
+ config.push(type);
692
687
  }
693
688
  else {
694
- config.push(type);
689
+ config.splice(config.indexOf(type), 1);
695
690
  }
696
691
  this.edit({ json: JSON.stringify(json) });
697
692
  }}
@@ -704,6 +699,7 @@ export class TemplateConfigForm extends Base {
704
699
 
705
700
  <div class="flex flex-wrap p-s border-t border-contrast-10">
706
701
  <x-checkbox
702
+ data-testid="cards-saved-check"
707
703
  class="m-s"
708
704
  ?disabled=${isDisabled || json.csc_requirements === 'new_cards_only'}
709
705
  ?readonly=${isReadonly}
@@ -718,6 +714,7 @@ export class TemplateConfigForm extends Base {
718
714
  </x-checkbox>
719
715
 
720
716
  <x-checkbox
717
+ data-testid="cards-sso-check"
721
718
  class="m-s"
722
719
  ?disabled=${isDisabled}
723
720
  ?readonly=${isReadonly}
@@ -802,11 +799,11 @@ export class TemplateConfigForm extends Base {
802
799
  const tosConfig = json.tos_checkbox_settings;
803
800
  const mailConfig = json.newsletter_subscribe;
804
801
  const sdtaConfig = json.eu_secure_data_transfer_consent;
805
- const isDisabled = this.disabledSelector.matches('consent', true);
802
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('consent', true);
806
803
  const isReadonly = this.readonlySelector.matches('consent', true);
807
804
  const dividerStyle = 'margin-left: calc(1.125rem + (var(--lumo-space-m) * 2))';
808
805
  return html `
809
- <div>
806
+ <div data-testid="consent">
810
807
  ${this.renderTemplateOrSlot('consent:before')}
811
808
 
812
809
  <x-group frame>
@@ -820,6 +817,7 @@ export class TemplateConfigForm extends Base {
820
817
  </foxy-i18n>
821
818
 
822
819
  <x-checkbox
820
+ data-testid="consent-tos-check"
823
821
  ?disabled=${isDisabled}
824
822
  ?readonly=${isReadonly}
825
823
  ?checked=${tosConfig.usage === 'required' || tosConfig.usage === 'optional'}
@@ -845,6 +843,7 @@ export class TemplateConfigForm extends Base {
845
843
 
846
844
  <div slot="content" ?hidden=${tosConfig.usage === 'none'}>
847
845
  <vaadin-text-field
846
+ data-testid="consent-tos-field"
848
847
  label=${this.t('location_url')}
849
848
  class="w-full mt-m"
850
849
  placeholder="https://example.com/path/to/tos"
@@ -861,8 +860,10 @@ export class TemplateConfigForm extends Base {
861
860
 
862
861
  <div class="flex flex-wrap -mx-s -mb-s mt-s">
863
862
  <x-checkbox
863
+ data-testid="consent-tos-require-check"
864
864
  class="m-s"
865
865
  ?disabled=${isDisabled}
866
+ ?readonly=${isReadonly}
866
867
  ?checked=${tosConfig.usage === 'required'}
867
868
  @change=${(evt) => {
868
869
  tosConfig.usage = evt.detail ? 'required' : 'optional';
@@ -874,8 +875,10 @@ export class TemplateConfigForm extends Base {
874
875
  </x-checkbox>
875
876
 
876
877
  <x-checkbox
878
+ data-testid="consent-tos-state-check"
877
879
  class="m-s"
878
880
  ?disabled=${isDisabled}
881
+ ?readonly=${isReadonly}
879
882
  ?checked=${tosConfig.initial_state === 'checked'}
880
883
  @change=${(evt) => {
881
884
  tosConfig.initial_state = evt.detail ? 'checked' : 'unchecked';
@@ -892,6 +895,7 @@ export class TemplateConfigForm extends Base {
892
895
  <div style=${dividerStyle} class="border-b border-contrast-10"></div>
893
896
 
894
897
  <x-checkbox
898
+ data-testid="consent-mail-check"
895
899
  ?disabled=${isDisabled}
896
900
  ?readonly=${isReadonly}
897
901
  ?checked=${mailConfig.usage === 'required'}
@@ -916,6 +920,7 @@ export class TemplateConfigForm extends Base {
916
920
  <div style=${dividerStyle} class="border-b border-contrast-10"></div>
917
921
 
918
922
  <x-checkbox
923
+ data-testid="consent-sdta-check"
919
924
  ?disabled=${isDisabled}
920
925
  ?readonly=${isReadonly}
921
926
  ?checked=${sdtaConfig.usage === 'required'}
@@ -938,13 +943,13 @@ export class TemplateConfigForm extends Base {
938
943
  </x-checkbox>
939
944
  </x-group>
940
945
 
941
- ${this.renderTemplateOrSlot('consent:before')}
946
+ ${this.renderTemplateOrSlot('consent:after')}
942
947
  </div>
943
948
  `;
944
949
  }
945
950
  __renderFields(json) {
946
951
  const { lang, ns } = this;
947
- const isDisabled = this.disabledSelector.matches('fields', true);
952
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('fields', true);
948
953
  const isReadonly = this.readonlySelector.matches('fields', true);
949
954
  const config = json.custom_checkout_field_requirements;
950
955
  const options = {
@@ -963,7 +968,7 @@ export class TemplateConfigForm extends Base {
963
968
  billing_country: ['default', 'optional', 'required', 'hidden'],
964
969
  };
965
970
  return html `
966
- <div>
971
+ <div data-testid="fields">
967
972
  ${this.renderTemplateOrSlot('fields:before')}
968
973
 
969
974
  <x-group frame>
@@ -1015,6 +1020,7 @@ export class TemplateConfigForm extends Base {
1015
1020
  })}
1016
1021
  >
1017
1022
  <select
1023
+ data-testid="fields-${property}"
1018
1024
  class=${classMap({
1019
1025
  'h-s mr-xs text-right appearance-none bg-transparent font-medium': true,
1020
1026
  'focus-outline-none cursor-pointer': !isDisabled,
@@ -1064,10 +1070,10 @@ export class TemplateConfigForm extends Base {
1064
1070
  const config = json.analytics_config;
1065
1071
  const sioConfig = config.segment_io;
1066
1072
  const gaConfig = config.google_analytics;
1067
- const isDisabled = this.disabledSelector.matches('google-analytics', true);
1073
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('google-analytics', true);
1068
1074
  const isReadonly = this.readonlySelector.matches('google-analytics', true);
1069
1075
  return html `
1070
- <div>
1076
+ <div data-testid="google-analytics">
1071
1077
  ${this.renderTemplateOrSlot('google-analytics:before')}
1072
1078
 
1073
1079
  <x-group frame>
@@ -1075,6 +1081,7 @@ export class TemplateConfigForm extends Base {
1075
1081
 
1076
1082
  <div class="p-m space-y-m">
1077
1083
  <vaadin-text-field
1084
+ data-testid="google-analytics-field"
1078
1085
  class="w-full"
1079
1086
  label=${this.t('ga_account_id')}
1080
1087
  placeholder="UA-1234567-1"
@@ -1088,11 +1095,13 @@ export class TemplateConfigForm extends Base {
1088
1095
  gaConfig.account_id = evt.currentTarget.value;
1089
1096
  gaConfig.usage = gaConfig.account_id ? 'required' : 'none';
1090
1097
  config.usage = gaConfig.account_id || sioConfig.account_id ? 'required' : 'none';
1098
+ this.edit({ json: JSON.stringify(json) });
1091
1099
  }}
1092
1100
  >
1093
1101
  </vaadin-text-field>
1094
1102
 
1095
1103
  <x-checkbox
1104
+ data-testid="google-analytics-check"
1096
1105
  ?disabled=${isDisabled}
1097
1106
  ?readonly=${isReadonly}
1098
1107
  ?checked=${gaConfig.include_on_site}
@@ -1123,10 +1132,10 @@ export class TemplateConfigForm extends Base {
1123
1132
  const config = json.analytics_config;
1124
1133
  const sioConfig = config.segment_io;
1125
1134
  const gaConfig = config.google_analytics;
1126
- const isDisabled = this.disabledSelector.matches('segment-io', true);
1135
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('segment-io', true);
1127
1136
  const isReadonly = this.readonlySelector.matches('segment-io', true);
1128
1137
  return html `
1129
- <div>
1138
+ <div data-testid="segment-io">
1130
1139
  ${this.renderTemplateOrSlot('segment-io:before')}
1131
1140
 
1132
1141
  <x-group frame>
@@ -1134,6 +1143,7 @@ export class TemplateConfigForm extends Base {
1134
1143
 
1135
1144
  <div class="p-m">
1136
1145
  <vaadin-text-field
1146
+ data-testid="segment-io-field"
1137
1147
  class="w-full"
1138
1148
  label=${this.t('sio_account_id')}
1139
1149
  placeholder="MY-WRITE-KEY"
@@ -1147,6 +1157,7 @@ export class TemplateConfigForm extends Base {
1147
1157
  sioConfig.account_id = evt.currentTarget.value;
1148
1158
  sioConfig.usage = sioConfig.account_id ? 'required' : 'none';
1149
1159
  config.usage = gaConfig.account_id || sioConfig.account_id ? 'required' : 'none';
1160
+ this.edit({ json: JSON.stringify(json) });
1150
1161
  }}
1151
1162
  >
1152
1163
  </vaadin-text-field>
@@ -1160,10 +1171,10 @@ export class TemplateConfigForm extends Base {
1160
1171
  __renderTroubleshooting(json) {
1161
1172
  const { lang, ns } = this;
1162
1173
  const config = json.debug;
1163
- const isDisabled = this.disabledSelector.matches('troubleshooting', true);
1174
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('troubleshooting', true);
1164
1175
  const isReadonly = this.readonlySelector.matches('troubleshooting', true);
1165
1176
  return html `
1166
- <div>
1177
+ <div data-testid="troubleshooting">
1167
1178
  ${this.renderTemplateOrSlot('troubleshooting:before')}
1168
1179
 
1169
1180
  <x-group frame>
@@ -1178,6 +1189,7 @@ export class TemplateConfigForm extends Base {
1178
1189
 
1179
1190
  <div class="p-m space-y-m">
1180
1191
  <x-checkbox
1192
+ data-testid="troubleshooting-check"
1181
1193
  ?disabled=${isDisabled}
1182
1194
  ?readonly=${isReadonly}
1183
1195
  ?checked=${config.usage === 'required'}