From 0803b4cb11f30ee3b5507e5f330f2b64da78cd10 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Thu, 6 Feb 2025 12:59:40 -0300 Subject: [PATCH 01/22] fix: fix start/end/next/failure date priority in subscription summaries --- .../AdminSubscriptionCard.test.ts | 148 +----------------- .../AdminSubscriptionCard.ts | 39 +---- .../AdminSubscriptionForm.test.ts | 16 +- .../AdminSubscriptionForm.ts | 6 +- .../SubscriptionCard/SubscriptionCard.test.ts | 101 +----------- .../SubscriptionCard/SubscriptionCard.ts | 53 ++----- .../SubscriptionForm/SubscriptionForm.test.ts | 107 +------------ .../SubscriptionForm/SubscriptionForm.ts | 26 +-- .../SubscriptionsTable.test.ts | 29 +--- .../SubscriptionsTable/SubscriptionsTable.ts | 40 ++--- .../admin-subscription-card/en.json | 16 +- .../admin-subscription-form/en.json | 9 +- .../translations/customer-portal/en.json | 28 ++-- src/static/translations/customer/en.json | 28 ++-- .../translations/subscription-card/en.json | 17 +- .../translations/subscription-form/en.json | 14 +- .../translations/subscriptions-table/en.json | 16 +- src/utils/get-subscription-status.ts | 48 ++++++ 18 files changed, 192 insertions(+), 549 deletions(-) create mode 100644 src/utils/get-subscription-status.ts diff --git a/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.test.ts b/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.test.ts index abe22236..6e70ea27 100644 --- a/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.test.ts +++ b/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.test.ts @@ -12,6 +12,7 @@ import { getTestData } from '../../../testgen/getTestData'; import { FetchEvent } from '../NucleonElement/FetchEvent'; import { getByKey } from '../../../testgen/getByKey'; import { parseFrequency } from '../../../utils/parse-frequency'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; describe('AdminSubscriptionCard', () => { it('imports and registers foxy-i18n element', () => { @@ -488,7 +489,7 @@ describe('AdminSubscriptionCard', () => { expect(price?.options.amount.split(' ')[1]).to.equal('PKR'); }); - it('renders a special status in line 2 for failed subscriptions', async () => { + it('renders subscription status in line 2', async () => { const router = createRouter(); const href = 'https://demo.api/hapi/subscriptions/0'; const data = await getTestData>(href, router); @@ -501,150 +502,13 @@ describe('AdminSubscriptionCard', () => { `); - data.first_failed_transaction_date = new Date(2022, 1, 1).toISOString(); - data.start_date = new Date(2020, 1, 1).toISOString(); - data.is_active = true; - data.end_date = null; element.data = data; - - await waitUntil(() => element.isBodyReady, '', { timeout: 5000 }); - const price = await getByKey(element, 'subscription_failed'); - - expect(price).to.exist; - expect(price).to.have.attribute('infer', ''); - expect(price).to.have.nested.property('options.date', data.first_failed_transaction_date); - }); - - it('renders a special status in line 2 for active subscriptions with an end date in the future', async () => { - const router = createRouter(); - const href = 'https://demo.api/hapi/subscriptions/0'; - const data = await getTestData>(href, router); - - const element = await fixture(html` - router.handleEvent(evt)} - > - - `); - - data.first_failed_transaction_date = null; - data.start_date = new Date(2020, 1, 1).toISOString(); - data.is_active = true; - data.end_date = new Date(Date.now() + 2.628e9).toISOString(); - element.data = data; - - await waitUntil(() => element.isBodyReady, '', { timeout: 5000 }); - const price = await getByKey(element, 'subscription_will_be_cancelled'); - - expect(price).to.exist; - expect(price).to.have.attribute('infer', ''); - expect(price).to.have.nested.property('options.date', data.end_date); - }); - - it('renders a special status in line 2 for subscriptions that have ended', async () => { - const router = createRouter(); - const href = 'https://demo.api/hapi/subscriptions/0'; - const data = await getTestData>(href, router); - - const element = await fixture(html` - router.handleEvent(evt)} - > - - `); - - data.first_failed_transaction_date = null; - data.start_date = new Date(2020, 1, 1).toISOString(); - data.is_active = true; - data.end_date = new Date(2022, 1, 1).toISOString(); - element.data = data; - await waitUntil(() => element.isBodyReady, '', { timeout: 5000 }); - const price = await getByKey(element, 'subscription_cancelled'); + const status = await getByKey(element, `status_${getSubscriptionStatus(data)}`); - expect(price).to.exist; - expect(price).to.have.attribute('infer', ''); - expect(price).to.have.nested.property('options.date', data.end_date); - }); - - it('renders a special status in line 2 for inactive subscriptions', async () => { - const router = createRouter(); - const href = 'https://demo.api/hapi/subscriptions/0'; - const data = await getTestData>(href, router); - - const element = await fixture(html` - router.handleEvent(evt)} - > - - `); - - data.first_failed_transaction_date = null; - data.start_date = new Date(2020, 1, 1).toISOString(); - data.is_active = false; - data.end_date = null; - element.data = data; - - await waitUntil(() => element.isBodyReady, '', { timeout: 5000 }); - const price = await getByKey(element, 'subscription_inactive'); - - expect(price).to.exist; - expect(price).to.have.attribute('infer', ''); - }); - - it('renders a special status in line 2 for active subscriptions', async () => { - const router = createRouter(); - const href = 'https://demo.api/hapi/subscriptions/0'; - const data = await getTestData>(href, router); - - const element = await fixture(html` - router.handleEvent(evt)} - > - - `); - - data.first_failed_transaction_date = null; - data.start_date = new Date(2020, 1, 1).toISOString(); - data.is_active = true; - data.end_date = null; - element.data = data; - - await waitUntil(() => element.isBodyReady, '', { timeout: 5000 }); - const price = await getByKey(element, 'subscription_active'); - - expect(price).to.exist; - expect(price).to.have.attribute('infer', ''); - }); - - it('renders a special status in line 2 for subscriptions that start soon', async () => { - const router = createRouter(); - const href = 'https://demo.api/hapi/subscriptions/0'; - const data = await getTestData>(href, router); - - const element = await fixture(html` - router.handleEvent(evt)} - > - - `); - - data.first_failed_transaction_date = null; - data.start_date = new Date(Date.now() + 3600000).toISOString(); - data.is_active = true; - data.end_date = null; - element.data = data; - - await waitUntil(() => element.isBodyReady, '', { timeout: 5000 }); - const price = await getByKey(element, 'subscription_will_be_active'); - - expect(price).to.exist; - expect(price).to.have.attribute('infer', ''); + expect(status).to.exist; + expect(status).to.have.attribute('infer', ''); + expect(status).to.have.deep.property('options', data); }); it('renders customer email in line 3 from embedded fx:transaction_template', async () => { diff --git a/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.ts b/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.ts index 2e932ab3..f9690d6b 100644 --- a/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.ts +++ b/src/elements/public/AdminSubscriptionCard/AdminSubscriptionCard.ts @@ -5,6 +5,7 @@ import type { Resource } from '@foxy.io/sdk/core'; import type { Rels } from '@foxy.io/sdk/backend'; import type { Data } from './types'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; import { TranslatableMixin } from '../../../mixins/translatable'; import { ConfigurableMixin } from '../../../mixins/configurable'; import { parseFrequency } from '../../../utils/parse-frequency'; @@ -52,7 +53,6 @@ export class AdminSubscriptionCard extends Base { private readonly __storeLoaderId = 'storeLoader'; renderBody(): TemplateResult { - const isFailed = !!this.data?.first_failed_transaction_date; const customer = this.__customer; const cart = this.__transactionTemplate; @@ -60,8 +60,7 @@ export class AdminSubscriptionCard extends Base { const priceOptions = this.__priceOptions; const summaryOptions = this.__summaryOptions; const summaryKey = this.__summaryKey; - const statusKey = this.__statusKey; - const statusOptions = this.__statusOptions; + const status = getSubscriptionStatus(this.data); return html` { -
- ${statusOptions && statusKey - ? html`` +
+ ${this.data && status + ? html`` : html`​`}
@@ -315,18 +314,6 @@ export class AdminSubscriptionCard extends Base { if (items) return items.isApproximateCount ? 'summary_approximate' : 'summary'; } - private get __statusOptions() { - const data = this.data; - - if (data === null) return; - if (data.first_failed_transaction_date) return { date: data.first_failed_transaction_date }; - if (data.end_date) return { date: data.end_date }; - if (data.is_active === false) return {}; - if (new Date(data.start_date) > new Date()) return { date: data.start_date }; - - return { date: data.next_transaction_date }; - } - private get __currencyCode() { const cart = this.__transactionTemplate; @@ -361,22 +348,6 @@ export class AdminSubscriptionCard extends Base { }; } - private get __statusKey() { - const data = this.data; - - if (data === null) return; - if (data.first_failed_transaction_date) return 'subscription_failed'; - if (data.end_date) { - const hasEnded = new Date(data.end_date).getTime() > Date.now(); - return hasEnded ? 'subscription_will_be_cancelled' : 'subscription_cancelled'; - } - - if (data.is_active === false) return 'subscription_inactive'; - if (new Date(data.start_date) > new Date()) return 'subscription_will_be_active'; - - return 'subscription_active'; - } - private get __priceKey() { const frequency = this.data?.frequency; if (frequency) return `price_${frequency === '.5m' ? 'twice_a_month' : 'recurring'}`; diff --git a/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.test.ts b/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.test.ts index 0eada1a7..6abb24f4 100644 --- a/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.test.ts +++ b/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.test.ts @@ -3,7 +3,7 @@ import type { Data } from './types'; import { html, expect, fixture, waitUntil } from '@open-wc/testing'; import { AdminSubscriptionForm as Form } from './AdminSubscriptionForm'; - +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; import { createRouter } from '../../../server/index'; import { getTestData } from '../../../testgen/getTestData'; @@ -104,18 +104,14 @@ describe('AdminSubscriptionForm', () => { expect(form.hiddenSelector.matches('cancel-action', true)).to.be.false; }); - it('uses custom subtitle options based on the subscription status', async () => { - const form = new Form(); - expect(form.headerSubtitleOptions).to.deep.equal({ context: 'inactive' }); - + it('uses custom subtitle key based on the subscription status', async () => { const testData = await getTestData('./hapi/subscriptions/0?zoom=transaction_template'); - testData.is_active = true; - form.data = testData; - expect(form.headerSubtitleOptions).to.deep.equal({ context: 'active' }); + const status = getSubscriptionStatus(testData); - testData.is_active = false; + const form = new Form(); form.data = testData; - expect(form.headerSubtitleOptions).to.deep.equal({ context: 'inactive' }); + + expect(form.headerSubtitleKey).to.equal(`subtitle_${status}`); }); it('renders error message control', async () => { diff --git a/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.ts b/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.ts index 32e011b5..cfb78562 100644 --- a/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.ts +++ b/src/elements/public/AdminSubscriptionForm/AdminSubscriptionForm.ts @@ -2,6 +2,7 @@ import type { PropertyDeclarations } from 'lit-element'; import type { TemplateResult } from 'lit-html'; import type { Data } from './types'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; import { TranslatableMixin } from '../../../mixins/translatable'; import { BooleanSelector } from '@foxy.io/sdk/core'; import { InternalForm } from '../../internal/InternalForm/InternalForm'; @@ -29,8 +30,9 @@ export class AdminSubscriptionForm extends Base { return new BooleanSelector(alwaysMatch.join(' ').trim()); } - get headerSubtitleOptions(): Record { - return { context: this.data?.is_active ? 'active' : 'inactive' }; + get headerSubtitleKey(): string { + const status = getSubscriptionStatus(this.data); + return status ? `subtitle_${status}` : super.headerSubtitleKey; } renderBody(): TemplateResult { diff --git a/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts b/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts index 0ca78bdd..a8002ac1 100644 --- a/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts +++ b/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts @@ -11,6 +11,7 @@ import { getByTestId } from '../../../testgen/getByTestId'; import { getTestData } from '../../../testgen/getTestData'; import { unsafeHTML } from 'lit-html/directives/unsafe-html'; import { getByKey } from '../../../testgen/getByKey'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; describe('SubscriptionCard', () => { const OriginalResizeObserver = window.ResizeObserver; @@ -47,111 +48,17 @@ describe('SubscriptionCard', () => { expect(control).to.have.attribute('ns', 'subscription-card'); }); - it('once loaded, renders a special status for failed subscriptions', async () => { - const href = './hapi/subscriptions/0?zoom=transaction_template:items'; - const date = new Date().toISOString(); - const data = { ...(await getTestData(href)), first_failed_transaction_date: date }; - const layout = html``; - const element = await fixture(layout); - const control = await getByTestId(element, 'status'); - - expect(control).to.have.property('localName', 'foxy-i18n'); - expect(control).to.have.attribute('options', JSON.stringify({ date })); - expect(control).to.have.attribute('lang', 'es'); - expect(control).to.have.attribute('key', 'subscription_failed'); - expect(control).to.have.attribute('ns', 'subscription-card'); - }); - - it('once loaded, renders a special status for subscriptions that are about to end', async () => { - const href = './hapi/subscriptions/0?zoom=transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.end_date = new Date(Date.now() + 86400000).toISOString(); - - const layout = html``; - const element = await fixture(layout); - const control = await getByTestId(element, 'status'); - - expect(control).to.have.property('localName', 'foxy-i18n'); - expect(control).to.have.attribute('options', JSON.stringify({ date: data.end_date })); - expect(control).to.have.attribute('lang', 'es'); - expect(control).to.have.attribute('key', 'subscription_will_be_cancelled'); - expect(control).to.have.attribute('ns', 'subscription-card'); - }); - - it('once loaded, renders a special status for subscriptions that have ended', async () => { - const href = './hapi/subscriptions/0?zoom=transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.end_date = new Date(2020, 0, 1).toISOString(); - - const layout = html``; - const element = await fixture(layout); - const control = await getByTestId(element, 'status'); - - expect(control).to.have.property('localName', 'foxy-i18n'); - expect(control).to.have.attribute('options', JSON.stringify({ date: data.end_date })); - expect(control).to.have.attribute('lang', 'es'); - expect(control).to.have.attribute('key', 'subscription_cancelled'); - expect(control).to.have.attribute('ns', 'subscription-card'); - }); - - it('once loaded, renders a special status for active subscriptions', async () => { - const href = './hapi/subscriptions/0?zoom=transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.end_date = null; - - const layout = html``; - const element = await fixture(layout); - const control = await getByTestId(element, 'status'); - const options = { date: data.next_transaction_date }; - - expect(control).to.have.property('localName', 'foxy-i18n'); - expect(control).to.have.attribute('options', JSON.stringify(options)); - expect(control).to.have.attribute('lang', 'es'); - expect(control).to.have.attribute('key', 'subscription_active'); - expect(control).to.have.attribute('ns', 'subscription-card'); - }); - - it('once loaded, renders a special status for subscriptions that start soon', async () => { + it('once loaded, renders subscription status', async () => { const href = './hapi/subscriptions/0?zoom=transaction_template:items'; const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.start_date = new Date(Date.now() + 3600000).toISOString(); - data.end_date = null; - - const layout = html``; - const element = await fixture(layout); - const control = await getByTestId(element, 'status'); - const options = { date: data.start_date }; - - expect(control).to.have.property('localName', 'foxy-i18n'); - expect(control).to.have.attribute('options', JSON.stringify(options)); - expect(control).to.have.attribute('lang', 'es'); - expect(control).to.have.attribute('key', 'subscription_will_be_active'); - expect(control).to.have.attribute('ns', 'subscription-card'); - }); - - it('once loaded, renders a special status for inactive subscriptions', async () => { - const href = './hapi/subscriptions/0?zoom=transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.is_active = false; - data.end_date = null; - const layout = html``; const element = await fixture(layout); const control = await getByTestId(element, 'status'); expect(control).to.have.property('localName', 'foxy-i18n'); + expect(control).to.have.deep.property('options', data); expect(control).to.have.attribute('lang', 'es'); - expect(control).to.have.attribute('key', 'subscription_inactive'); + expect(control).to.have.attribute('key', `status_${getSubscriptionStatus(data)}`); expect(control).to.have.attribute('ns', 'subscription-card'); }); diff --git a/src/elements/public/SubscriptionCard/SubscriptionCard.ts b/src/elements/public/SubscriptionCard/SubscriptionCard.ts index 699e9300..fef5d263 100644 --- a/src/elements/public/SubscriptionCard/SubscriptionCard.ts +++ b/src/elements/public/SubscriptionCard/SubscriptionCard.ts @@ -8,6 +8,7 @@ import { ThemeableMixin } from '../../../mixins/themeable'; import { TranslatableMixin } from '../../../mixins/translatable'; import { classMap } from '../../../utils/class-map'; import { parseFrequency } from '../../../utils/parse-frequency'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; const NS = 'subscription-card'; const Base = ConfigurableMixin( @@ -22,8 +23,10 @@ const Base = ConfigurableMixin( */ export class SubscriptionCard extends Base { render(): TemplateResult { - const isActive = !!this.data?.is_active; - const isFailed = !!this.data?.first_failed_transaction_date; + const status = getSubscriptionStatus(this.data); + const isRed = status === 'failed'; + const isGreen = status === 'next_payment' || !!status?.startsWith('will_end'); + const isNormal = !isGreen && !isRed; return html`
@@ -36,14 +39,14 @@ export class SubscriptionCard extends Base {
@@ -65,17 +68,17 @@ export class SubscriptionCard extends Base {
​ @@ -138,18 +141,6 @@ export class SubscriptionCard extends Base { }; } - private __getStatusOptions() { - const data = this.data; - - if (data === null) return {}; - if (data.first_failed_transaction_date) return { date: data.first_failed_transaction_date }; - if (data.end_date) return { date: data.end_date }; - if (data.is_active === false) return {}; - if (new Date(data.start_date) > new Date()) return { date: data.start_date }; - - return { date: data.next_transaction_date }; - } - private __getPriceOptions() { if (this.data === null) return {}; @@ -157,20 +148,4 @@ export class SubscriptionCard extends Base { const amount = `${cart.total_order} ${cart.currency_code}`; return { ...parseFrequency(this.data.frequency), amount }; } - - private __getStatusKey() { - const data = this.data; - - if (data === null) return; - if (data.first_failed_transaction_date) return 'subscription_failed'; - if (data.end_date) { - const hasEnded = new Date(data.end_date).getTime() > Date.now(); - return hasEnded ? 'subscription_will_be_cancelled' : 'subscription_cancelled'; - } - - if (data.is_active === false) return 'subscription_inactive'; - if (new Date(data.start_date) > new Date()) return 'subscription_will_be_active'; - - return 'subscription_active'; - } } diff --git a/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts b/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts index fdabfe06..0db159dd 100644 --- a/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts +++ b/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts @@ -35,6 +35,7 @@ import { Choice } from '../../private/Choice/Choice'; import { links } from '../../../server/hapi/links'; import { I18n } from '../I18n/I18n'; import { stub } from 'sinon'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; const fromDefaults = (key: string, overrides: Record) => { return { ...defaults[key](new URLSearchParams(), {}), ...overrides }; @@ -379,108 +380,14 @@ describe('SubscriptionForm', () => { }); }); - it('once loaded, renders a special status for failed subscriptions in subtitle', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; - const date = new Date().toISOString(); - const data = { ...(await getTestData(href)), first_failed_transaction_date: date }; - const element = await fixture
(html` - - `); - - await waitUntil(() => !!element.headerSubtitleOptions.context, '', { timeout: 10000 }); - expect(element.headerSubtitleOptions).to.deep.equal({ context: 'failed', date }); - }); - - it('once loaded, renders a special status for subscriptions that are about to end in subtitle', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.end_date = new Date(Date.now() + 86400000).toISOString(); - - const element = await fixture(html` - - `); - - await waitUntil(() => !!element.headerSubtitleOptions.context, '', { timeout: 10000 }); - expect(element.headerSubtitleOptions).to.deep.equal({ - context: 'will_be_cancelled', - date: data.end_date, - }); - }); - - it('once loaded, renders a special status for subscriptions that have ended in subtitle', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.end_date = new Date(2020, 0, 1).toISOString(); + it('uses custom subtitle key based on the subscription status', async () => { + const testData = await getTestData('./hapi/subscriptions/0'); + const status = getSubscriptionStatus(testData); - const element = await fixture(html` - - `); - - await waitUntil(() => !!element.headerSubtitleOptions.context, '', { timeout: 10000 }); - expect(element.headerSubtitleOptions).to.deep.equal({ - context: 'cancelled', - date: data.end_date, - }); - }); - - it('once loaded, renders a special status for active subscriptions in subtitle', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.end_date = null; - - const element = await fixture(html` - - `); - - await waitUntil(() => !!element.headerSubtitleOptions.context, '', { timeout: 10000 }); - expect(element.headerSubtitleOptions).to.deep.equal({ - context: 'active', - date: data.next_transaction_date, - }); - }); - - it('once loaded, renders a special status for subscriptions with future start date in subtitle', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.start_date = new Date(Date.now() + 3600000).toISOString(); - data.end_date = null; - - const element = await fixture(html` - - `); - - await waitUntil(() => !!element.headerSubtitleOptions.context, '', { timeout: 10000 }); - expect(element.headerSubtitleOptions).to.deep.equal({ - context: 'will_be_active', - date: data.start_date, - }); - }); - - it('once loaded, renders a special status for inactive subscriptions in subtitle', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; - const data = await getTestData(href); - - data.first_failed_transaction_date = null; - data.is_active = false; - data.end_date = null; - - const element = await fixture(html` - - `); + const form = new Form(); + form.data = testData; - await waitUntil(() => !!element.headerSubtitleOptions.context, '', { timeout: 10000 }); - expect(element.headerSubtitleOptions).to.deep.equal({ - context: 'inactive', - date: null, - }); + expect(form.headerSubtitleKey).to.equal(`subtitle_${status}`); }); }); diff --git a/src/elements/public/SubscriptionForm/SubscriptionForm.ts b/src/elements/public/SubscriptionForm/SubscriptionForm.ts index cc720228..23a943c8 100644 --- a/src/elements/public/SubscriptionForm/SubscriptionForm.ts +++ b/src/elements/public/SubscriptionForm/SubscriptionForm.ts @@ -7,6 +7,7 @@ import type { NucleonElement } from '../NucleonElement/NucleonElement'; import type { Rels } from '@foxy.io/sdk/backend'; import { Choice, Group, Skeleton } from '../../private/index'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; import { ScopedElementsMixin } from '@open-wc/scoped-elements'; import { TranslatableMixin } from '../../../mixins/translatable'; import { BooleanSelector, Resource } from '@foxy.io/sdk/core'; @@ -382,28 +383,9 @@ export class SubscriptionForm extends Base { } } - get headerSubtitleOptions(): Record { - let context: string; - let date: string | null = null; - - if (this.data?.first_failed_transaction_date) { - context = 'failed'; - date = this.data.first_failed_transaction_date; - } else if (this.data?.end_date) { - const hasEnded = new Date(this.data.end_date).getTime() > Date.now(); - context = hasEnded ? 'will_be_cancelled' : 'cancelled'; - date = this.data.end_date; - } else if (!this.data?.is_active) { - context = 'inactive'; - } else if (new Date(this.data.start_date) > new Date()) { - context = 'will_be_active'; - date = this.data.start_date; - } else { - context = 'active'; - date = this.data.next_transaction_date; - } - - return { date, context }; + get headerSubtitleKey(): string { + const status = getSubscriptionStatus(this.data); + return status ? `subtitle_${status}` : super.headerSubtitleKey; } renderBody(): TemplateResult { diff --git a/src/elements/public/SubscriptionsTable/SubscriptionsTable.test.ts b/src/elements/public/SubscriptionsTable/SubscriptionsTable.test.ts index 1209e1a5..99cfa040 100644 --- a/src/elements/public/SubscriptionsTable/SubscriptionsTable.test.ts +++ b/src/elements/public/SubscriptionsTable/SubscriptionsTable.test.ts @@ -5,6 +5,7 @@ import { SubscriptionsTable } from './SubscriptionsTable'; import { expect } from '@open-wc/testing'; import { generateTests } from '../NucleonElement/generateTests'; import { parseFrequency } from '../../../utils/parse-frequency'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; type Refs = { frequencies: HTMLSpanElement[]; @@ -70,29 +71,11 @@ describe('SubscriptionsTable', () => { } { - let date: string; - let key: string; - - if (subscription.first_failed_transaction_date) { - date = subscription.first_failed_transaction_date; - key = 'subscription_failed'; - } else if (subscription.end_date) { - date = subscription.end_date; - const hasEnded = new Date(subscription.end_date).getTime() > Date.now(); - key = hasEnded ? 'subscription_will_be_cancelled' : 'subscription_cancelled'; - } else if (!subscription.is_active) { - date = ''; - key = 'subscription_inactive'; - } else if (new Date(subscription.start_date) > new Date()) { - date = subscription.start_date; - key = 'subscription_will_be_active'; - } else { - date = subscription.next_transaction_date; - key = 'subscription_active'; - } - - expect(statusRef).to.have.deep.property('options', { date }); - expect(statusRef).to.have.attribute('key', key); + expect(statusRef).to.have.deep.property('options', subscription); + expect(statusRef).to.have.attribute( + 'key', + `status_${getSubscriptionStatus(subscription)}` + ); } }); }, diff --git a/src/elements/public/SubscriptionsTable/SubscriptionsTable.ts b/src/elements/public/SubscriptionsTable/SubscriptionsTable.ts index 22a8f53a..92331a88 100644 --- a/src/elements/public/SubscriptionsTable/SubscriptionsTable.ts +++ b/src/elements/public/SubscriptionsTable/SubscriptionsTable.ts @@ -3,6 +3,8 @@ import { Data } from './types'; import { Table } from '../Table/Table'; import { TranslatableMixin } from '../../../mixins/translatable'; import { parseFrequency } from '../../../utils/parse-frequency'; +import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; +import { classMap } from '../../../utils/class-map'; export class SubscriptionsTable extends TranslatableMixin(Table, 'subscriptions-table') { static priceColumn: Column = { @@ -50,38 +52,24 @@ export class SubscriptionsTable extends TranslatableMixin(Table, 'subscriptions- static statusColumn: Column = { hideBelow: 'sm', cell: ({ ns, lang, data, html }) => { - let color = 'bg-contrast-5 text-secondary'; - let date: string; - let key: string; - - if (data.first_failed_transaction_date) { - color = 'bg-error-10 text-error'; - date = data.first_failed_transaction_date; - key = 'subscription_failed'; - } else if (data.end_date) { - date = data.end_date; - const hasEnded = new Date(data.end_date).getTime() > Date.now(); - key = hasEnded ? 'subscription_will_be_cancelled' : 'subscription_cancelled'; - } else if (!data.is_active) { - date = ''; - key = 'subscription_inactive'; - } else if (new Date(data.start_date) > new Date()) { - date = data.start_date; - key = 'subscription_will_be_active'; - } else { - color = 'bg-success-10 text-success'; - date = data.next_transaction_date; - key = 'subscription_active'; - } + const status = getSubscriptionStatus(data); + const isRed = status === 'failed'; + const isGreen = status === 'next_payment' || !!status?.startsWith('will_end'); + const isNormal = !isGreen && !isRed; return html` `; diff --git a/src/static/translations/admin-subscription-card/en.json b/src/static/translations/admin-subscription-card/en.json index 6c49156e..e6da841e 100644 --- a/src/static/translations/admin-subscription-card/en.json +++ b/src/static/translations/admin-subscription-card/en.json @@ -6,12 +6,14 @@ "monthly_plural": "/ {{count}} months", "price_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"admin-subscription-card\" })", "price_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"admin-subscription-card\" })", - "subscription_active": "Next payment on {{date, date}}", - "subscription_cancelled": "Ended on {{date, date}}", - "subscription_failed": "Payment failed on {{date, date}}", - "subscription_inactive": "Inactive", - "subscription_will_be_cancelled": "Ends on {{date, date}}", - "subscription_will_be_active": "Starts on {{date, date}}", + "status_failed_and_ended": "Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "status_failed": "Failed on {{ first_failed_transaction_date, date }}", + "status_will_start": "Starts on {{ start_date, date }}", + "status_will_end_after_payment": "Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "status_will_end": "Ends on {{ end_date, date }}", + "status_ended": "Ended on {{ end_date, date }}", + "status_next_payment": "Next payment on {{ next_transaction_date, date }}", + "status_inactive": "Inactive", "summary": "{{ firstItem.name }}", "summary_plural": "{{ firstItem.name }} + {{ countMinus1 }} more", "summary_approximate": "{{ firstItem.name }} + more", @@ -25,4 +27,4 @@ "loading_empty": "No data", "loading_error": "Unknown error" } -} +} \ No newline at end of file diff --git a/src/static/translations/admin-subscription-form/en.json b/src/static/translations/admin-subscription-form/en.json index 470dc3d8..b40d46ed 100644 --- a/src/static/translations/admin-subscription-form/en.json +++ b/src/static/translations/admin-subscription-form/en.json @@ -2,8 +2,13 @@ "header": { "title_existing": "Subscription #{{ id }}", "title_new": "", - "subtitle_inactive": "Inactive", - "subtitle_active": "Active", + "subtitle_failed_and_ended": "Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "subtitle_failed": "Failed on {{ first_failed_transaction_date, date }}", + "subtitle_will_start": "Starts on {{ start_date, date }}", + "subtitle_will_end_after_payment": "Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "subtitle_will_end": "Ends on {{ end_date, date }}", + "subtitle_ended": "Ended on {{ end_date, date }}", + "subtitle_next_payment": "Next payment on {{ next_transaction_date, date }}", "subtitle": "", "copy-id": { "failed_to_copy": "Failed to copy", diff --git a/src/static/translations/customer-portal/en.json b/src/static/translations/customer-portal/en.json index 8663256a..8b071489 100644 --- a/src/static/translations/customer-portal/en.json +++ b/src/static/translations/customer-portal/en.json @@ -921,12 +921,14 @@ "monthly_plural": "/ {{count}} months", "price_recurring": "{{amount, price}} $t(customer.subscription-card.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "price_twice_a_month": "{{amount, price}} $t(customer.subscription-card.twice_a_month, { \"ns\": \"customer-portal\" })", - "subscription_active": "Next payment on {{date, date}}", - "subscription_cancelled": "Ended on {{date, date}}", - "subscription_failed": "Payment failed on {{date, date}}", - "subscription_inactive": "Inactive", - "subscription_will_be_cancelled": "Ends on {{date, date}}", - "subscription_will_be_active": "Starts on {{date, date}}", + "status_failed_and_ended": "Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "status_failed": "Failed on {{ first_failed_transaction_date, date }}", + "status_will_start": "Starts on {{ start_date, date }}", + "status_will_end_after_payment": "Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "status_will_end": "Ends on {{ end_date, date }}", + "status_ended": "Ended on {{ end_date, date }}", + "status_next_payment": "Next payment on {{ next_transaction_date, date }}", + "status_inactive": "Inactive", "transaction_summary": "{{most_expensive_item.name}}", "fees_hint": "inc. shipping, taxes, etc.", "fees_explainer": "Taxes, shipping, and discounts may change the amount charged.", @@ -948,12 +950,14 @@ "title_existing": "Subscription", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_active": "Including shipping, taxes, etc. Next payment on {{date, date}}.", - "subtitle_cancelled": "Including shipping, taxes, etc. Ended on {{date, date}}.", - "subtitle_failed": "Including shipping, taxes, etc. Payment failed on {{date, date}}.", - "subtitle_inactive": "Including shipping, taxes, etc. Inactive.", - "subtitle_will_be_cancelled": "Including shipping, taxes, etc. Ends on {{date, date}}.", - "subtitle_will_be_active": "Including shipping, taxes, etc. Starts on {{date, date}}.", + "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}", + "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}", + "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}", + "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}", + "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}", + "subtitle": "Including shipping, taxes, etc.", "copy-id": { "failed_to_copy": "Failed to copy", "click_to_copy": "Copy ID", diff --git a/src/static/translations/customer/en.json b/src/static/translations/customer/en.json index 5fd5750e..48baaccb 100644 --- a/src/static/translations/customer/en.json +++ b/src/static/translations/customer/en.json @@ -1080,12 +1080,14 @@ "title_existing": "Subscription", "title_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"subscription-form\" })", "title_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"subscription-form\" })", - "subtitle_active": "Including shipping, taxes, etc. Next payment on {{date, date}}.", - "subtitle_cancelled": "Including shipping, taxes, etc. Ended on {{date, date}}.", - "subtitle_failed": "Including shipping, taxes, etc. Payment failed on {{date, date}}.", - "subtitle_inactive": "Including shipping, taxes, etc. Inactive.", - "subtitle_will_be_cancelled": "Including shipping, taxes, etc. Ends on {{date, date}}.", - "subtitle_will_be_active": "Including shipping, taxes, etc. Starts on {{date, date}}.", + "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}", + "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}", + "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}", + "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}", + "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}", + "subtitle": "Including shipping, taxes, etc.", "copy-id": { "failed_to_copy": "Failed to copy", "click_to_copy": "Copy ID", @@ -1293,12 +1295,14 @@ "monthly_plural": "Every {{count}} months", "price_recurring": "{{amount, price}} $t(subscriptions-table.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer\" })", "price_twice_a_month": "{{amount, price}} $t(subscriptions-table.twice_a_month, { \"ns\": \"customer\" })", - "subscription_active": "Next payment on {{date, date}}", - "subscription_cancelled": "Ended on {{date, date}}", - "subscription_failed": "Payment failed on {{date, date}}", - "subscription_inactive": "Inactive", - "subscription_will_be_cancelled": "Ends on {{date, date}}", - "subscription_will_be_active": "Starts on {{date, date}}", + "status_failed_and_ended": "Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "status_failed": "Failed on {{ first_failed_transaction_date, date }}", + "status_will_start": "Starts on {{ start_date, date }}", + "status_will_end_after_payment": "Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "status_will_end": "Ends on {{ end_date, date }}", + "status_ended": "Ended on {{ end_date, date }}", + "status_next_payment": "Next payment on {{ next_transaction_date, date }}", + "status_inactive": "Inactive", "transaction_summary": "{{most_expensive_item.name}}", "twice_a_month": "Twice a month", "update": "Update", diff --git a/src/static/translations/subscription-card/en.json b/src/static/translations/subscription-card/en.json index 895216f0..8cf0414f 100644 --- a/src/static/translations/subscription-card/en.json +++ b/src/static/translations/subscription-card/en.json @@ -6,13 +6,14 @@ "monthly_plural": "Every {{count}} months", "price_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"subscription-card\" })", "price_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"subscription-card\" })", - "subscription_active": "Next payment on {{date, date}}", - "subscription_cancelled": "Ended on {{date, date}}", - "subscription_failed": "Payment failed on {{date, date}}", - "subscription_inactive": "Inactive", - "subscription_plural": "Subscriptions", - "subscription_will_be_cancelled": "Ends on {{date, date}}", - "subscription_will_be_active": "Starts on {{date, date}}", + "status_failed_and_ended": "Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "status_failed": "Failed on {{ first_failed_transaction_date, date }}", + "status_will_start": "Starts on {{ start_date, date }}", + "status_will_end_after_payment": "Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "status_will_end": "Ends on {{ end_date, date }}", + "status_ended": "Ended on {{ end_date, date }}", + "status_next_payment": "Next payment on {{ next_transaction_date, date }}", + "status_inactive": "Inactive", "transaction_summary": "{{most_expensive_item.name}}", "fees_hint": "inc. shipping, taxes, etc.", "fees_explainer": "Taxes, shipping, and discounts may change the amount charged.", @@ -26,4 +27,4 @@ "loading_empty": "No data", "loading_error": "Unknown error" } -} +} \ No newline at end of file diff --git a/src/static/translations/subscription-form/en.json b/src/static/translations/subscription-form/en.json index a6c0de8e..67907941 100644 --- a/src/static/translations/subscription-form/en.json +++ b/src/static/translations/subscription-form/en.json @@ -4,12 +4,14 @@ "title_existing": "Subscription", "title_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"subscription-form\" })", "title_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"subscription-form\" })", - "subtitle_active": "Including shipping, taxes, etc. Next payment on {{date, date}}.", - "subtitle_cancelled": "Including shipping, taxes, etc. Ended on {{date, date}}.", - "subtitle_failed": "Including shipping, taxes, etc. Payment failed on {{date, date}}.", - "subtitle_inactive": "Including shipping, taxes, etc. Inactive.", - "subtitle_will_be_cancelled": "Including shipping, taxes, etc. Ends on {{date, date}}.", - "subtitle_will_be_active": "Including shipping, taxes, etc. Starts on {{date, date}}.", + "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}", + "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}", + "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}", + "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}", + "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}", + "subtitle": "Including shipping, taxes, etc.", "copy-id": { "failed_to_copy": "Failed to copy", "click_to_copy": "Copy ID", diff --git a/src/static/translations/subscriptions-table/en.json b/src/static/translations/subscriptions-table/en.json index cf9d0b9f..545820af 100644 --- a/src/static/translations/subscriptions-table/en.json +++ b/src/static/translations/subscriptions-table/en.json @@ -6,12 +6,14 @@ "monthly_plural": "Every {{count}} months", "price_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"subscriptions-table\" })", "price_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"subscriptions-table\" })", - "subscription_active": "Next payment on {{date, date}}", - "subscription_cancelled": "Ended on {{date, date}}", - "subscription_failed": "Payment failed on {{date, date}}", - "subscription_inactive": "Inactive", - "subscription_will_be_cancelled": "Ends on {{date, date}}", - "subscription_will_be_active": "Starts on {{date, date}}", + "status_failed_and_ended": "Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "status_failed": "Failed on {{ first_failed_transaction_date, date }}", + "status_will_start": "Starts on {{ start_date, date }}", + "status_will_end_after_payment": "Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "status_will_end": "Ends on {{ end_date, date }}", + "status_ended": "Ended on {{ end_date, date }}", + "status_next_payment": "Next payment on {{ next_transaction_date, date }}", + "status_inactive": "Inactive", "transaction_summary": "{{most_expensive_item.name}}", "twice_a_month": "Twice a month", "update": "Update", @@ -25,4 +27,4 @@ "loading_empty": "No data", "loading_error": "Unknown error" } -} +} \ No newline at end of file diff --git a/src/utils/get-subscription-status.ts b/src/utils/get-subscription-status.ts new file mode 100644 index 00000000..b0146b34 --- /dev/null +++ b/src/utils/get-subscription-status.ts @@ -0,0 +1,48 @@ +import type { Resource } from '@foxy.io/sdk/core'; +import type { Rels } from '@foxy.io/sdk/backend'; + +type Data = Pick< + Resource, + | 'is_active' + | 'first_failed_transaction_date' + | 'start_date' + | 'next_transaction_date' + | 'end_date' +>; + +type Status = + | 'will_start' + | 'will_end' + | 'will_end_after_payment' + | 'next_payment' + | 'ended' + | 'failed' + | 'failed_and_ended' + | 'inactive'; + +export function getSubscriptionStatus(data: Data | null): Status | null { + if (data === null) return null; + + const getTime = (date: string | null) => { + if (!date || date === '0000-00-00') return null; + return new Date(date).getTime(); + }; + + const isActive = data.is_active; + const failure = getTime(data.first_failed_transaction_date); + const start = getTime(data.start_date); + const next = getTime(data.next_transaction_date); + const end = getTime(data.end_date); + const now = Date.now(); + + if (failure) return end && end <= now ? 'failed_and_ended' : 'failed'; + if (start === null) return null; + + if (isActive && start > now) return 'will_start'; + if (next === null) return null; + + if (isActive && end && end > now) return next <= end ? 'will_end_after_payment' : 'will_end'; + if (isActive) return end ? 'ended' : 'next_payment'; + + return start <= now && end && end <= now ? 'ended' : 'inactive'; +} From ef99ec6ad82e709e0e126ed6b474a1228e032928 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Thu, 6 Feb 2025 19:26:28 -0300 Subject: [PATCH 02/22] feat: add support for `is_active` switch to webhook elements --- .../public/WebhookCard/WebhookCard.stories.ts | 3 ++ .../public/WebhookCard/WebhookCard.test.ts | 15 +++--- .../public/WebhookCard/WebhookCard.ts | 35 ++++++++------ src/elements/public/WebhookCard/types.ts | 3 +- .../public/WebhookForm/WebhookForm.stories.ts | 11 ++++- .../public/WebhookForm/WebhookForm.test.ts | 47 ++++++++++++------- .../public/WebhookForm/WebhookForm.ts | 18 ++++--- src/elements/public/WebhookForm/index.ts | 1 + src/server/hapi/createDataset.ts | 1 + src/server/hapi/defaults.ts | 1 + src/static/translations/transaction/en.json | 6 ++- src/static/translations/webhook-card/en.json | 2 + src/static/translations/webhook-form/en.json | 18 ++++++- 13 files changed, 109 insertions(+), 52 deletions(-) diff --git a/src/elements/public/WebhookCard/WebhookCard.stories.ts b/src/elements/public/WebhookCard/WebhookCard.stories.ts index 1a67a3f9..a0d2ae4f 100644 --- a/src/elements/public/WebhookCard/WebhookCard.stories.ts +++ b/src/elements/public/WebhookCard/WebhookCard.stories.ts @@ -12,9 +12,12 @@ const summary: Summary = { translatable: true, }; +const ext = `resource-uri="https://demo.api/hapi/transactions/0"`; + export default getMeta(summary); export const Playground = getStory({ ...summary, code: true }); +export const ResourceView = getStory({ ...summary, ext }); export const Empty = getStory(summary); export const Error = getStory(summary); export const Busy = getStory(summary); diff --git a/src/elements/public/WebhookCard/WebhookCard.test.ts b/src/elements/public/WebhookCard/WebhookCard.test.ts index cf8b83ab..2794bcb7 100644 --- a/src/elements/public/WebhookCard/WebhookCard.test.ts +++ b/src/elements/public/WebhookCard/WebhookCard.test.ts @@ -109,13 +109,8 @@ describe('WebhookCard', () => { `); - let status: HTMLElement | null = null; - - await waitUntil(() => { - status = card.renderRoot.querySelector('foxy-i18n[key^="status_"]') as HTMLElement; - return !status.classList.contains('hidden'); - }); - + await waitUntil(() => card.isBodyReady); + const status = card.renderRoot.querySelector('foxy-i18n[key^="status_"]') as HTMLElement; expect(status).to.have.attribute('infer', ''); const statusUri = 'https://demo.api/hapi/webhook_statuses/0'; @@ -131,5 +126,11 @@ describe('WebhookCard', () => { await card.requestUpdate(); expect(status).to.have.attribute('key', 'status_pending'); + + const webhookResource = await getTestData('./hapi/webhooks/0', router); + card.data = { ...webhookResource, is_active: false }; + await card.requestUpdate(); + + expect(status).to.have.attribute('key', 'status_inactive'); }); }); diff --git a/src/elements/public/WebhookCard/WebhookCard.ts b/src/elements/public/WebhookCard/WebhookCard.ts index 8af84086..961deeba 100644 --- a/src/elements/public/WebhookCard/WebhookCard.ts +++ b/src/elements/public/WebhookCard/WebhookCard.ts @@ -32,25 +32,33 @@ export class WebhookCard extends TranslatableMixin(InternalCard, 'webhook-card') */ resourceUri: string | null = null; + get isBodyReady(): boolean { + return !!this.__statusesLoader?.data && super.isBodyReady; + } + renderBody(): TemplateResult { - let statusesLink: string | undefined = undefined; + const resourceId = getResourceId(this.resourceUri ?? ''); + let statusesLink: string | undefined = this.data?._links['fx:statuses'].href; - try { - const resourceId = getResourceId(this.resourceUri ?? ''); - const url = new URL(this.data?._links['fx:statuses'].href ?? ''); + if (resourceId !== null) { + try { + const url = new URL(statusesLink ?? ''); - if (resourceId !== null) { url.searchParams.set('resource_id', String(resourceId)); url.searchParams.set('order', 'date_created desc'); url.searchParams.set('limit', '1'); + statusesLink = url.toString(); + } catch { + // ignore } - } catch { - // ignore } - const statusesLoader = this.__statusesLoader; - const lastStatus = statusesLoader?.data?._embedded['fx:webhook_statuses'][0]; + const isActive = this.data?.is_active; + const statuses = this.__statusesLoader?.data?._embedded['fx:webhook_statuses']; + const status = isActive ? (statuses ? statuses?.[0].status ?? 'none' : 'loading') : 'inactive'; + const isFailed = status === 'failed'; + const isSuccessful = status === 'successful'; return html`
@@ -60,14 +68,13 @@ export class WebhookCard extends TranslatableMixin(InternalCard, 'webhook-card')

diff --git a/src/elements/public/WebhookCard/types.ts b/src/elements/public/WebhookCard/types.ts index 84bd47f7..36971e9b 100644 --- a/src/elements/public/WebhookCard/types.ts +++ b/src/elements/public/WebhookCard/types.ts @@ -1,4 +1,5 @@ import type { Rels } from '@foxy.io/sdk/backend'; import type { Resource } from '@foxy.io/sdk/core'; -export type Data = Resource; +// TODO: simplify once SDK has types for `is_active` +export type Data = Resource & { is_active: boolean }; diff --git a/src/elements/public/WebhookForm/WebhookForm.stories.ts b/src/elements/public/WebhookForm/WebhookForm.stories.ts index beb11551..778a8e48 100644 --- a/src/elements/public/WebhookForm/WebhookForm.stories.ts +++ b/src/elements/public/WebhookForm/WebhookForm.stories.ts @@ -11,9 +11,16 @@ const summary: Summary = { localName: 'foxy-webhook-form', translatable: true, configurable: { - sections: ['timestamps', 'header', 'general'], - inputs: ['general:name', 'url', 'query', 'general:encryption-key', 'general:event-resource'], + sections: ['timestamps', 'header', 'group-one', 'group-two', 'group-three'], buttons: ['delete', 'create', 'submit', 'undo', 'header:copy-id', 'header:copy-json'], + inputs: [ + 'group-one:name', + 'group-two:url', + 'group-two:query', + 'group-two:encryption-key', + 'group-two:event-resource', + 'group-three:is-active', + ], }, }; diff --git a/src/elements/public/WebhookForm/WebhookForm.test.ts b/src/elements/public/WebhookForm/WebhookForm.test.ts index 8dcfce6e..748c1488 100644 --- a/src/elements/public/WebhookForm/WebhookForm.test.ts +++ b/src/elements/public/WebhookForm/WebhookForm.test.ts @@ -5,6 +5,7 @@ import type { Data } from './types'; import { InternalAsyncListControl } from '../../internal/InternalAsyncListControl/InternalAsyncListControl'; import { InternalPasswordControl } from '../../internal/InternalPasswordControl/InternalPasswordControl'; import { InternalSelectControl } from '../../internal/InternalSelectControl/InternalSelectControl'; +import { InternalSwitchControl } from '../../internal/InternalSwitchControl/InternalSwitchControl'; import { expect, fixture, html } from '@open-wc/testing'; import { InternalTextControl } from '../../internal/InternalTextControl/InternalTextControl'; import { InternalForm } from '../../internal/InternalForm/InternalForm'; @@ -25,6 +26,10 @@ describe('WebhookForm', () => { expect(customElements.get('foxy-internal-select-control')).to.exist; }); + it('imports and defines foxy-internal-switch-control element', () => { + expect(customElements.get('foxy-internal-switch-control')).to.exist; + }); + it('imports and defines foxy-internal-text-control element', () => { expect(customElements.get('foxy-internal-text-control')).to.exist; }); @@ -129,24 +134,20 @@ describe('WebhookForm', () => { expect(form.headerSubtitleOptions).to.have.property('context', form.data?.event_resource); }); - it('renders a General summary', async () => { - const form = await fixture(html``); - const control = form.renderRoot.querySelector('foxy-internal-summary-control[infer="general"]'); - expect(control).to.exist; - }); - - it('renders webhook name as text control inside of the General summary', async () => { + it('renders webhook name as text control inside of group one', async () => { const element = await fixture(html``); - const control = element.renderRoot.querySelector('[infer="general"] [infer="name"]'); + const control = element.renderRoot.querySelector('[infer="group-one"] [infer="name"]'); expect(control).to.exist; expect(control).to.be.instanceOf(InternalTextControl); expect(control).to.have.attribute('layout', 'summary-item'); }); - it('renders webhook event resource type as select control inside of the General summary', async () => { + it('renders webhook event resource type as select control inside of group two', async () => { const element = await fixture(html``); - const control = element.renderRoot.querySelector('[infer="general"] [infer="event-resource"]'); + const control = element.renderRoot.querySelector( + '[infer="group-two"] [infer="event-resource"]' + ); const options = [ { value: 'subscription', label: 'event_resource_subscription' }, { value: 'transaction', label: 'event_resource_transaction' }, @@ -159,27 +160,29 @@ describe('WebhookForm', () => { expect(control).to.have.attribute('layout', 'summary-item'); }); - it('renders webhook query as text control inside of the General summary', async () => { + it('renders webhook query as text control inside of group two', async () => { const element = await fixture(html``); - const control = element.renderRoot.querySelector('[infer="general"] [infer="query"]'); + const control = element.renderRoot.querySelector('[infer="group-two"] [infer="query"]'); expect(control).to.exist; expect(control).to.be.instanceOf(InternalTextControl); expect(control).to.have.attribute('layout', 'summary-item'); }); - it('renders webhook url as text control inside of the General summary', async () => { + it('renders webhook url as text control inside of group two', async () => { const element = await fixture(html``); - const control = element.renderRoot.querySelector('[infer="general"] [infer="url"]'); + const control = element.renderRoot.querySelector('[infer="group-two"] [infer="url"]'); expect(control).to.exist; expect(control).to.be.instanceOf(InternalTextControl); expect(control).to.have.attribute('layout', 'summary-item'); }); - it('renders webhook encryption key as password control inside of the General summary', async () => { + it('renders webhook encryption key as password control inside of group two', async () => { const element = await fixture(html``); - const control = element.renderRoot.querySelector('[infer="general"] [infer="encryption-key"]'); + const control = element.renderRoot.querySelector( + '[infer="group-two"] [infer="encryption-key"]' + ); expect(control).to.exist; expect(control).to.be.instanceOf(InternalPasswordControl); @@ -188,6 +191,14 @@ describe('WebhookForm', () => { expect(control).to.have.attribute('layout', 'summary-item'); }); + it('renders webhook is active switch inside of group three', async () => { + const element = await fixture(html``); + const control = element.renderRoot.querySelector('[infer="group-three"] [infer="is-active"]'); + + expect(control).to.exist; + expect(control).to.be.instanceOf(InternalSwitchControl); + }); + it('renders webhook statuses when an existing webhook is loaded', async () => { const webhook = await getTestData('./hapi/webhooks/0'); const element = await fixture(html``); @@ -281,10 +292,10 @@ describe('WebhookForm', () => { it('hides event resource selector when loaded', async () => { const webhook = await getTestData('./hapi/webhooks/0'); const element = await fixture(html``); - expect(element.hiddenSelector.matches('general:event-resource', true)).to.be.false; + expect(element.hiddenSelector.matches('group-two:event-resource', true)).to.be.false; element.data = webhook; - expect(element.hiddenSelector.matches('general:event-resource', true)).to.be.true; + expect(element.hiddenSelector.matches('group-two:event-resource', true)).to.be.true; }); it('hides logs and statuses in empty state', async () => { diff --git a/src/elements/public/WebhookForm/WebhookForm.ts b/src/elements/public/WebhookForm/WebhookForm.ts index 4685f3f4..b0366360 100644 --- a/src/elements/public/WebhookForm/WebhookForm.ts +++ b/src/elements/public/WebhookForm/WebhookForm.ts @@ -60,7 +60,7 @@ export class WebhookForm extends TranslatableMixin(InternalForm, 'webhook-form') const alwaysMatch: string[] = [super.hiddenSelector.toString()]; if (this.data) { - alwaysMatch.unshift('general:event-resource'); + alwaysMatch.unshift('group-two:event-resource'); } else { alwaysMatch.unshift('logs', 'statuses'); } @@ -106,9 +106,11 @@ export class WebhookForm extends TranslatableMixin(InternalForm, 'webhook-form') return html` ${this.renderHeader()} - + + + + + + + + + - - - - + + Dataset = () => ({ query: 'zoom=items', encryption_key: 'HNL978XVXXCM66DM5N2T78D5MT66BC6D', event_resource: 'transaction', + is_active: true, date_created: '2020-10-28T07:03:19-0700', date_modified: '2020-10-28T08:45:46-0700', }, diff --git a/src/server/hapi/defaults.ts b/src/server/hapi/defaults.ts index f81b5583..ed566ee1 100644 --- a/src/server/hapi/defaults.ts +++ b/src/server/hapi/defaults.ts @@ -735,6 +735,7 @@ export const defaults: Defaults = { query: '', encryption_key: '', event_resource: 'transaction', + is_active: false, date_created: new Date().toISOString(), date_modified: new Date().toISOString(), }), diff --git a/src/static/translations/transaction/en.json b/src/static/translations/transaction/en.json index ded85cc8..881b4268 100644 --- a/src/static/translations/transaction/en.json +++ b/src/static/translations/transaction/en.json @@ -843,13 +843,15 @@ "previous": "Previous", "card": { "status_successful": "OK", + "status_inactive": "Inactive", + "status_loading": "Loading", "status_pending": "Pending", "status_failed": "Failed", "status_none": "No runs yet", "spinner": { "loading_busy": "Loading", - "loading_empty": "No webhooks", - "loading_error": "Unknown error" + "loading_error": "Unknown error", + "loading_empty": "No webhooks" } } } diff --git a/src/static/translations/webhook-card/en.json b/src/static/translations/webhook-card/en.json index 36f7377f..dc02cb1c 100644 --- a/src/static/translations/webhook-card/en.json +++ b/src/static/translations/webhook-card/en.json @@ -1,5 +1,7 @@ { "status_successful": "OK", + "status_inactive": "Inactive", + "status_loading": "Loading", "status_pending": "Pending", "status_failed": "Failed", "status_none": "No runs yet", diff --git a/src/static/translations/webhook-form/en.json b/src/static/translations/webhook-form/en.json index 89f06d01..46a36703 100644 --- a/src/static/translations/webhook-form/en.json +++ b/src/static/translations/webhook-form/en.json @@ -21,7 +21,7 @@ "done": "Copied to clipboard" } }, - "general": { + "group-one": { "label": "", "helper_text": "", "name": { @@ -30,7 +30,11 @@ "helper_text": "", "v8n_required": "Webhook name is required", "v8n_too_long": "Webhook name cannot exceed 255 characters" - }, + } + }, + "group-two": { + "label": "", + "helper_text": "", "encryption-key": { "label": "Encryption key", "placeholder": "Required", @@ -59,6 +63,16 @@ "v8n_too_long": "Query cannot exceed 1000 characters" } }, + "group-three": { + "label": "", + "helper_text": "", + "is-active": { + "label": "Enable this webhook", + "helper_text": "Webhooks are disabled automatically when there are too many consecutive failed runs.", + "checked": "Yes", + "unchecked": "No" + } + }, "statuses": { "label": "Runs", "pagination": { From 15822f2726d784ee8564af4a8c951a4b53a83553 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Thu, 6 Feb 2025 19:27:44 -0300 Subject: [PATCH 03/22] chore: regenerate custom-elements.json --- custom-elements.json | 260 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) diff --git a/custom-elements.json b/custom-elements.json index 0ca1947c..aeba3d16 100644 --- a/custom-elements.json +++ b/custom-elements.json @@ -650,6 +650,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -1076,6 +1081,10 @@ "name": "foxy-admin-subscription-form", "path": "./src/elements/public/AdminSubscriptionForm/index.ts", "attributes": [ + { + "name": "uoe-settings-page", + "description": "URL of the UOE settings page in the admin. If set, displays a link to that page in the self-service links section." + }, { "name": "simplify-ns-loading", "type": "boolean", @@ -1163,6 +1172,11 @@ } ], "properties": [ + { + "name": "uoeSettingsPage", + "attribute": "uoe-settings-page", + "description": "URL of the UOE settings page in the admin. If set, displays a link to that page in the self-service links section." + }, { "name": "simplifyNsLoading", "attribute": "simplify-ns-loading", @@ -1212,6 +1226,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -2031,6 +2050,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -2839,6 +2863,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -3915,6 +3944,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -4382,6 +4416,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -5782,6 +5821,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -6078,6 +6122,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -6635,6 +6684,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -7189,6 +7243,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -8215,6 +8274,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -8539,6 +8603,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -8845,6 +8914,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -9150,6 +9224,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -10113,6 +10192,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -11910,6 +11994,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -12328,6 +12417,10 @@ "path": "./src/elements/public/EmailTemplateForm/index.ts", "description": "Form element for creating or editing email templates (`fx:email_template`).", "attributes": [ + { + "name": "default-subject", + "description": "Default email subject. Use this instead of i18next key when you need to use handlebars syntax." + }, { "name": "simplify-ns-loading", "type": "boolean", @@ -12415,6 +12508,11 @@ } ], "properties": [ + { + "name": "defaultSubject", + "attribute": "default-subject", + "description": "Default email subject. Use this instead of i18next key when you need to use handlebars syntax." + }, { "name": "simplifyNsLoading", "attribute": "simplify-ns-loading", @@ -12464,6 +12562,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -12976,6 +13079,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -13509,6 +13617,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -14190,6 +14303,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -14862,6 +14980,10 @@ } ], "properties": [ + { + "name": "getTransactionPageHref", + "description": "When set, the Cart Item section will display a link to transaction." + }, { "name": "getCustomerHref", "description": "Returns a `fx:customer` Resource URL for a Customer ID.", @@ -14916,6 +15038,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -15383,6 +15510,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -15543,6 +15675,10 @@ "path": "./src/elements/public/GiftCardForm/index.ts", "description": "Form element for creating or editing gift cards (`fx:gift_card`).", "attributes": [ + { + "name": "codes-filter", + "description": "When set, will apply as default filter in Codes section." + }, { "name": "simplify-ns-loading", "type": "boolean", @@ -15630,11 +15766,20 @@ } ], "properties": [ + { + "name": "getTransactionPageHref", + "description": "When set, the Cart Item section in Gift Card Code form will display a link to transaction." + }, { "name": "getCustomerHref", "description": "Returns a `fx:customer` Resource URL for a Customer ID.", "default": "\"id => {\\n return `https://api.foxycart.com/customers/${id}`;\\n }\"" }, + { + "name": "codesFilter", + "attribute": "codes-filter", + "description": "When set, will apply as default filter in Codes section." + }, { "name": "simplifyNsLoading", "attribute": "simplify-ns-loading", @@ -15684,6 +15829,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -16525,6 +16675,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -17364,6 +17519,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -17705,6 +17865,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -18266,6 +18431,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -19309,6 +19479,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -20159,6 +20334,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -21455,6 +21635,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -22035,6 +22220,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -22597,6 +22787,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -25510,6 +25705,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -25815,6 +26015,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -26409,6 +26614,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -26705,6 +26915,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -27829,6 +28044,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -28152,6 +28372,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -28448,6 +28673,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -29038,6 +29268,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -29367,6 +29602,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -30219,6 +30459,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -30786,6 +31031,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -31291,6 +31541,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", @@ -32068,6 +32323,11 @@ "description": "I18next options to pass to the header subtitle translation function. Note that subtitle is shown only when data is avaiable.", "type": "Record" }, + { + "name": "headerSubtitleBadges", + "description": "Getter that returns a list of the optional badges to put into the subtitle. The badges are shown only if subtitle is visible.", + "type": "{ key: string; }[]" + }, { "name": "headerCopyIdValue", "description": "ID that will be written to clipboard when Copy ID button in header is clicked.", From c33d5c9fd2b0c92686d14e123d612ba2f7bb8538 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Thu, 6 Feb 2025 19:39:17 -0300 Subject: [PATCH 04/22] fix(foxy-webhook-card): fix an error when loading freshly created webhook with no logs/runs --- src/elements/public/WebhookCard/WebhookCard.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elements/public/WebhookCard/WebhookCard.ts b/src/elements/public/WebhookCard/WebhookCard.ts index 961deeba..f763fc95 100644 --- a/src/elements/public/WebhookCard/WebhookCard.ts +++ b/src/elements/public/WebhookCard/WebhookCard.ts @@ -56,7 +56,7 @@ export class WebhookCard extends TranslatableMixin(InternalCard, 'webhook-card') const isActive = this.data?.is_active; const statuses = this.__statusesLoader?.data?._embedded['fx:webhook_statuses']; - const status = isActive ? (statuses ? statuses?.[0].status ?? 'none' : 'loading') : 'inactive'; + const status = isActive ? (statuses ? statuses?.[0]?.status ?? 'none' : 'loading') : 'inactive'; const isFailed = status === 'failed'; const isSuccessful = status === 'successful'; From 52cc17f5d8d51f0904d5825c30813f27eaa06616 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Fri, 7 Feb 2025 12:09:37 -0300 Subject: [PATCH 05/22] fix(foxy-webhook-card): show latest run status instead of the first one --- .../public/WebhookCard/WebhookCard.ts | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/elements/public/WebhookCard/WebhookCard.ts b/src/elements/public/WebhookCard/WebhookCard.ts index f763fc95..18dcfda0 100644 --- a/src/elements/public/WebhookCard/WebhookCard.ts +++ b/src/elements/public/WebhookCard/WebhookCard.ts @@ -37,21 +37,19 @@ export class WebhookCard extends TranslatableMixin(InternalCard, 'webhook-card') } renderBody(): TemplateResult { - const resourceId = getResourceId(this.resourceUri ?? ''); - let statusesLink: string | undefined = this.data?._links['fx:statuses'].href; + let statusesLink: string | undefined; - if (resourceId !== null) { - try { - const url = new URL(statusesLink ?? ''); + try { + const url = new URL(this.data?._links['fx:statuses'].href ?? ''); + url.searchParams.set('order', 'date_created desc'); + url.searchParams.set('limit', '1'); - url.searchParams.set('resource_id', String(resourceId)); - url.searchParams.set('order', 'date_created desc'); - url.searchParams.set('limit', '1'); + const resourceId = getResourceId(this.resourceUri ?? ''); + if (resourceId !== null) url.searchParams.set('resource_id', String(resourceId)); - statusesLink = url.toString(); - } catch { - // ignore - } + statusesLink = url.toString(); + } catch { + statusesLink = undefined; } const isActive = this.data?.is_active; From ab42b51fb8dceaaacf590ec0cef4b41797e3b391 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Fri, 7 Feb 2025 13:06:11 -0300 Subject: [PATCH 06/22] feat(foxy-webhook-card): show last run date --- .../public/WebhookCard/WebhookCard.test.ts | 23 ++-------- .../public/WebhookCard/WebhookCard.ts | 45 ++++++++++--------- .../admin-subscription-form/en.json | 10 +++-- src/static/translations/transaction/en.json | 12 ++--- src/static/translations/webhook-card/en.json | 12 ++--- 5 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/elements/public/WebhookCard/WebhookCard.test.ts b/src/elements/public/WebhookCard/WebhookCard.test.ts index 2794bcb7..6f043268 100644 --- a/src/elements/public/WebhookCard/WebhookCard.test.ts +++ b/src/elements/public/WebhookCard/WebhookCard.test.ts @@ -52,17 +52,6 @@ describe('WebhookCard', () => { expect(card.renderRoot).to.include.text(webhook.name); }); - it('renders webhook format when loaded', async () => { - const webhook = await getTestData('./hapi/webhooks/0'); - const layout = html``; - const card = await fixture(layout); - - card.data = webhook; - await card.requestUpdate(); - - expect(card.renderRoot).to.include.text(webhook.format); - }); - it('renders webhook url when loaded', async () => { const webhook = await getTestData('./hapi/webhooks/0'); const layout = html``; @@ -85,7 +74,7 @@ describe('WebhookCard', () => { expect(card.renderRoot).to.include.text(webhook.event_resource); }); - it('hides webhook format and event resource type when resourceUri is set', async () => { + it('hides webhook event resource type when resourceUri is set', async () => { const webhook = await getTestData('./hapi/webhooks/0'); const card = await fixture(html` @@ -93,8 +82,6 @@ describe('WebhookCard', () => { card.data = webhook; await card.requestUpdate(); - - expect(card.renderRoot).not.to.include.text(webhook.format); expect(card.renderRoot).not.to.include.text(webhook.event_resource); }); @@ -120,17 +107,13 @@ describe('WebhookCard', () => { await card.requestUpdate(); expect(status).to.have.attribute('key', 'status_successful'); + expect(status).to.have.deep.property('options', statusResource); statusResource.status = 'pending'; WebhookCard.Rumour('').share({ source: statusUri, data: statusResource }); await card.requestUpdate(); expect(status).to.have.attribute('key', 'status_pending'); - - const webhookResource = await getTestData('./hapi/webhooks/0', router); - card.data = { ...webhookResource, is_active: false }; - await card.requestUpdate(); - - expect(status).to.have.attribute('key', 'status_inactive'); + expect(status).to.have.deep.property('options', statusResource); }); }); diff --git a/src/elements/public/WebhookCard/WebhookCard.ts b/src/elements/public/WebhookCard/WebhookCard.ts index 18dcfda0..dc2180a1 100644 --- a/src/elements/public/WebhookCard/WebhookCard.ts +++ b/src/elements/public/WebhookCard/WebhookCard.ts @@ -52,11 +52,10 @@ export class WebhookCard extends TranslatableMixin(InternalCard, 'webhook-card') statusesLink = undefined; } - const isActive = this.data?.is_active; - const statuses = this.__statusesLoader?.data?._embedded['fx:webhook_statuses']; - const status = isActive ? (statuses ? statuses?.[0]?.status ?? 'none' : 'loading') : 'inactive'; - const isFailed = status === 'failed'; - const isSuccessful = status === 'successful'; + const recentStatuses = this.__statusesLoader?.data?._embedded['fx:webhook_statuses']; + const lastStatus = recentStatuses?.[0]; + const cardStatus = recentStatuses ? lastStatus?.status ?? 'none' : 'loading'; + const isActive = !!this.data?.is_active; return html`
@@ -64,28 +63,30 @@ export class WebhookCard extends TranslatableMixin(InternalCard, 'webhook-card') ${this.data?.name}​ + + + + +

+ +

${this.data?.url}​

+ +

+ ${this.resourceUri + ? '' + : html`${this.data?.event_resource} •`}

- -

${this.data?.url}​

- - ${this.resourceUri === null - ? html` -

- ${this.data?.format} • ${this.data?.event_resource}​ -

- ` - : ''}
Date: Fri, 7 Feb 2025 13:09:02 -0300 Subject: [PATCH 07/22] fix(foxy-webhook-status-card): add missing language string for `initializing` status --- src/static/translations/admin-subscription-form/en.json | 1 + src/static/translations/transaction/en.json | 1 + src/static/translations/webhook-form/en.json | 1 + src/static/translations/webhook-status-card/en.json | 1 + 4 files changed, 4 insertions(+) diff --git a/src/static/translations/admin-subscription-form/en.json b/src/static/translations/admin-subscription-form/en.json index 0afe1212..d5883dd0 100644 --- a/src/static/translations/admin-subscription-form/en.json +++ b/src/static/translations/admin-subscription-form/en.json @@ -1084,6 +1084,7 @@ "pagination": "{{from}}-{{to}} out of {{total}}", "previous": "Previous", "card": { + "status_initializing": "Initializing", "status_successful": "Successful", "status_pending": "Pending", "status_failed": "Failed", diff --git a/src/static/translations/transaction/en.json b/src/static/translations/transaction/en.json index 681d77e1..7e773738 100644 --- a/src/static/translations/transaction/en.json +++ b/src/static/translations/transaction/en.json @@ -792,6 +792,7 @@ "pagination": "{{from}}-{{to}} out of {{total}}", "previous": "Previous", "card": { + "status_initializing": "Initializing", "status_successful": "Successful", "status_pending": "Pending", "status_failed": "Failed", diff --git a/src/static/translations/webhook-form/en.json b/src/static/translations/webhook-form/en.json index 46a36703..8ed224e8 100644 --- a/src/static/translations/webhook-form/en.json +++ b/src/static/translations/webhook-form/en.json @@ -82,6 +82,7 @@ "pagination": "{{from}}-{{to}} out of {{total}}", "previous": "Previous", "card": { + "status_initializing": "Initializing", "status_successful": "Successful", "status_pending": "Pending", "status_failed": "Failed", diff --git a/src/static/translations/webhook-status-card/en.json b/src/static/translations/webhook-status-card/en.json index 7b822478..dcf01811 100644 --- a/src/static/translations/webhook-status-card/en.json +++ b/src/static/translations/webhook-status-card/en.json @@ -1,4 +1,5 @@ { + "status_initializing": "Initializing", "status_successful": "Successful", "status_pending": "Pending", "status_failed": "Failed", From 3cc08e620802dcb49c26f790d026150f1784a5ee Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Mon, 10 Feb 2025 19:26:13 -0300 Subject: [PATCH 08/22] fix(foxy-store-shipping-method-form): hide account fields for UPS --- .../StoreShippingMethodForm.test.ts | 15 ++++++++++- .../StoreShippingMethodForm.ts | 25 +++++++++++++++++-- .../store-shipping-method-form/en.json | 7 +++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.test.ts b/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.test.ts index e5e0a561..c3a4eae8 100644 --- a/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.test.ts +++ b/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.test.ts @@ -344,8 +344,21 @@ describe('StoreShippingMethodForm', () => { }); expect(form.hiddenSelector.toString()).to.equal( - 'endpoint custom-code services account:accountid account:password account:authentication-key account:meter-number undo submit delete timestamps' + 'endpoint custom-code account:accountid account:password account:authentication-key account:meter-number services undo submit delete timestamps' + ); + + form.edit({ meter_number: '123' }); + await form.requestUpdate(); + + expect(form.hiddenSelector.toString()).to.equal( + 'endpoint custom-code account:accountid account:password account:authentication-key services undo submit delete timestamps' ); + + expect( + form.renderRoot.querySelector( + '[infer="account"] foxy-i18n[key="ups_use_legacy_admin_message"]' + ) + ).to.exist; }); it('hides custom account fields by default when they are empty', async () => { diff --git a/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.ts b/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.ts index 012c1842..5ee48b26 100644 --- a/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.ts +++ b/src/elements/public/StoreShippingMethodForm/StoreShippingMethodForm.ts @@ -10,7 +10,7 @@ import { TranslatableMixin } from '../../../mixins/translatable'; import { BooleanSelector } from '@foxy.io/sdk/core'; import { InternalForm } from '../../internal/InternalForm/InternalForm'; import { ifDefined } from 'lit-html/directives/if-defined'; -import { html } from 'lit-html'; +import { html, svg } from 'lit-html'; const NS = 'store-shipping-method-form'; const Base = TranslatableMixin(InternalForm, NS); @@ -99,7 +99,7 @@ export class StoreShippingMethodForm extends Base { 'CUSTOM': 'general account endpoint custom-code', 'FedEx': 'endpoint custom-code', 'USPS': 'account endpoint custom-code', - 'UPS': 'endpoint custom-code', + 'UPS': 'endpoint custom-code account:accountid account:password account:authentication-key', }; if (codeToHiddenControls[code]) hiddenControls = codeToHiddenControls[code]; @@ -175,6 +175,27 @@ export class StoreShippingMethodForm extends Base { + ${this.__useCustomAccountGetValue() && this.__shippingMethod?.code === 'UPS' + ? html` +
+ ${svg``} +

+ +
+ + admin.foxycart.com + +

+
+ ` + : ''}
diff --git a/src/static/translations/store-shipping-method-form/en.json b/src/static/translations/store-shipping-method-form/en.json index 875eb6eb..49a4f252 100644 --- a/src/static/translations/store-shipping-method-form/en.json +++ b/src/static/translations/store-shipping-method-form/en.json @@ -160,8 +160,9 @@ "account": { "label": "Account", "helper_text": "", + "ups_use_legacy_admin_message": "Connecting to a UPS account is currently restricted from this admin. Please utilise the Integrations page in our legacy administration to connect to your UPS account.", "use-custom-account": { - "label": "Use custom credentials", + "label": "Use my own account", "helper_text": "", "checked": "Yes", "unchecked": "No" @@ -173,10 +174,10 @@ "v8n_too_long": "Authentication key must be 50 characters or less." }, "meter-number": { - "label": "Meter Number", + "label": "Account Number", "placeholder": "N/A", "helper_text": "", - "v8n_too_long": "Meter number must be 50 characters or less." + "v8n_too_long": "Account number must be 50 characters or less." }, "accountid": { "label": "Account ID", From 6ba8b965e05fcb04a944e54e0296d48448b5b323 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Tue, 11 Feb 2025 16:49:56 -0300 Subject: [PATCH 09/22] refactor(foxy-customer-portal): update subscriptions ui --- src/elements/private/Group/Group.ts | 4 ++-- .../public/CustomerPortal/InternalCustomerPortalLink.ts | 4 ++-- .../CustomerPortal/InternalCustomerPortalSubscriptions.ts | 8 ++------ src/elements/public/SubscriptionForm/SubscriptionForm.ts | 6 +++--- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/elements/private/Group/Group.ts b/src/elements/private/Group/Group.ts index f4ab24d0..50db5c39 100644 --- a/src/elements/private/Group/Group.ts +++ b/src/elements/private/Group/Group.ts @@ -25,11 +25,11 @@ export class Group extends LitElement { public frame = false; public render(): TemplateResult { - const frameClass = 'border border-contrast-10 overflow-hidden'; + const frameClass = 'bg-contrast-5 overflow-hidden'; return html`
-

+

diff --git a/src/elements/public/CustomerPortal/InternalCustomerPortalLink.ts b/src/elements/public/CustomerPortal/InternalCustomerPortalLink.ts index cefd0cdc..ccd5f1cd 100644 --- a/src/elements/public/CustomerPortal/InternalCustomerPortalLink.ts +++ b/src/elements/public/CustomerPortal/InternalCustomerPortalLink.ts @@ -21,8 +21,8 @@ export class InternalCustomerPortalLink extends ThemeableMixin(LitElement) { render(): TemplateResult { const actionClass = classMap({ - 'flex-auto font-medium tracking-wide text-s rounded-s transition-colors': true, - 'hover-text-primary hover-cursor-pointer': !this.disabled, + 'flex-auto leading-m font-medium tracking-wide text-m rounded-s transition-colors': true, + 'text-primary hover-underline hover-cursor-pointer': !this.disabled, 'focus-outline-none focus-ring-2 ring-primary-50 ring-offset-2': !this.disabled, 'text-disabled cursor-default': this.disabled, }); diff --git a/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts b/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts index ee9cf967..abfbc86b 100644 --- a/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts +++ b/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts @@ -51,7 +51,6 @@ export class InternalCustomerPortalSubscriptions extends Base { @@ -78,7 +77,6 @@ export class InternalCustomerPortalSubscriptions extends Base { @@ -96,10 +94,7 @@ export class InternalCustomerPortalSubscriptions extends Base { @@ -261,6 +256,7 @@ export class InternalCustomerPortalSubscriptions extends Base { lang=${this.lang} ns=${this.ns} id="subscription-dialog" + alert .form=${this.__renderForm} .templates=${this.getNestedTemplates('list:form')} > diff --git a/src/elements/public/SubscriptionForm/SubscriptionForm.ts b/src/elements/public/SubscriptionForm/SubscriptionForm.ts index 23a943c8..0c39216f 100644 --- a/src/elements/public/SubscriptionForm/SubscriptionForm.ts +++ b/src/elements/public/SubscriptionForm/SubscriptionForm.ts @@ -100,12 +100,12 @@ export class SubscriptionForm extends Base { private readonly __renderItemsActions = () => { return html` -
+
${this.renderTemplateOrSlot('items:actions:before')} {
${this.renderTemplateOrSlot('customer:before')} - + Date: Wed, 12 Feb 2025 15:58:53 -0300 Subject: [PATCH 10/22] build: temporarily bundle unreleased sdk --- package-lock.json | 9 +++++---- package.json | 2 +- vendor/foxy.io-sdk-0.0.0.tgz | Bin 0 -> 189031 bytes 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 vendor/foxy.io-sdk-0.0.0.tgz diff --git a/package-lock.json b/package-lock.json index b52a8612..081b7b56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@foxy.io/sdk": "^1.13.0", + "@foxy.io/sdk": "file:vendor/foxy.io-sdk-0.0.0.tgz", "@open-wc/lit-helpers": "^0.3.12", "@open-wc/scoped-elements": "^1.2.1", "@polymer/iron-icons": "^3.0.1", @@ -2264,9 +2264,10 @@ } }, "node_modules/@foxy.io/sdk": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@foxy.io/sdk/-/sdk-1.13.0.tgz", - "integrity": "sha512-8LbZ+eWR9zTVo3XEtWkjtdqKyJGLgB7Tlb8yAfSCwc6jVxlPN8Yie42lzBahUlK2LpDwEsBfxe1tgMONX/D5Kg==", + "version": "0.0.0", + "resolved": "file:vendor/foxy.io-sdk-0.0.0.tgz", + "integrity": "sha512-pd8D0udwPi6e5LhBdOX179JOaxnnQA2sm63zfl/xJOXm4am1777Md3MxToakTlz/EpiE7ZTEHj0bLqe9cfbXmw==", + "license": "MIT", "dependencies": { "@types/jsdom": "^16.2.5", "@types/traverse": "^0.6.32", diff --git a/package.json b/package.json index eee244e1..f24941d4 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "prepack": "npm run lint && rimraf dist && node ./.build/compile-for-npm.js && rollup -c" }, "dependencies": { - "@foxy.io/sdk": "^1.13.0", + "@foxy.io/sdk": "file:vendor/foxy.io-sdk-0.0.0.tgz", "@open-wc/lit-helpers": "^0.3.12", "@open-wc/scoped-elements": "^1.2.1", "@polymer/iron-icons": "^3.0.1", diff --git a/vendor/foxy.io-sdk-0.0.0.tgz b/vendor/foxy.io-sdk-0.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..e05935920d0615217a8b2e015676e641a5129d29 GIT binary patch literal 189031 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¥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
Gi@EW)0a`)3q4+5gierGPp2 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 Date: Wed, 12 Feb 2025 16:00:49 -0300 Subject: [PATCH 11/22] feat(foxy-subscription-form): apply cart display config in customer portal mode --- .../SubscriptionForm/SubscriptionForm.test.ts | 240 ++++++++++++------ .../SubscriptionForm/SubscriptionForm.ts | 28 +- src/server/portal/index.ts | 11 + .../translations/customer-portal/de.json | 24 +- .../translations/customer-portal/en.json | 24 +- .../translations/customer-portal/es.json | 22 +- .../translations/customer-portal/fr.json | 24 +- .../translations/customer-portal/nl.json | 24 +- .../translations/customer-portal/pl.json | 24 +- .../translations/customer-portal/sv.json | 24 +- .../translations/customer-portal/zh-hk.json | 26 +- src/static/translations/customer/en.json | 28 +- .../translations/subscription-form/en.json | 24 +- src/utils/get-subscription-status.ts | 37 ++- 14 files changed, 400 insertions(+), 160 deletions(-) diff --git a/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts b/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts index 0db159dd..c2aafcc2 100644 --- a/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts +++ b/src/elements/public/SubscriptionForm/SubscriptionForm.test.ts @@ -1,6 +1,7 @@ import type { FetchEvent } from '../NucleonElement/FetchEvent'; import type { Resource } from '@foxy.io/sdk/core'; -import type { Rels } from '@foxy.io/sdk/backend'; +import type { Rels as BackendRels } from '@foxy.io/sdk/backend'; +import type { Rels as CustomerRels } from '@foxy.io/sdk/customer'; import type { Data } from './types'; import './index'; @@ -148,7 +149,7 @@ describe('SubscriptionForm', () => { }); it('has a reactive property "getTransactionPageHref"', () => { - type Data = Resource; + type Data = Resource; const data = { _links: { 'fx:receipt': { href: 'test' } } } as unknown as Data; const definition = { attribute: false }; expect(Form).to.have.deep.nested.property('properties.getTransactionPageHref', definition); @@ -380,6 +381,42 @@ describe('SubscriptionForm', () => { }); }); + it('once loaded, renders only price in title if settings disable frequency display', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_sub_frequency = false; + + const router = createBaseRouter({ + defaults, + dataset: { + subscriptions: [fromDefaults('subscriptions', { id: 0, frequency: '.5m' })], + stores: [fromDefaults('stores', { id: 0, use_international_currency_symbol: false })], + carts: [fromDefaults('carts', { id: 0, total_order: 25.99, currency_code: 'EUR' })], + }, + links, + }); + + const element = await fixture(html` + router.handleEvent(evt)} + > + + `); + + await waitUntil(() => !!element.headerTitleOptions.context, '', { timeout: 10000 }); + + expect(element.headerTitleOptions).to.deep.equal({ + currencyDisplay: 'symbol', + context: 'existing', + amount: '25.99 EUR', + units: 'monthly', + count: 0.5, + }); + }); + it('uses custom subtitle key based on the subscription status', async () => { const testData = await getTestData('./hapi/subscriptions/0'); const status = getSubscriptionStatus(testData); @@ -529,6 +566,7 @@ describe('SubscriptionForm', () => { describe('items', () => { it('once loaded, renders subscription items', async () => { + const settings = await getTestData('./portal/customer_portal_settings'); const router = createBaseRouter({ defaults, dataset: { @@ -541,6 +579,7 @@ describe('SubscriptionForm', () => { const element = await fixture(html` router.handleEvent(evt)} @@ -563,7 +602,11 @@ describe('SubscriptionForm', () => { const control = items.querySelector('[infer="items"]')!; expect(control).to.have.property('localName', 'foxy-internal-async-list-control'); - expect(control).to.have.deep.property('itemProps', { 'locale-codes': element.localeCodes }); + expect(control).to.have.deep.property('itemProps', { + 'locale-codes': 'https://demo.api/hapi/property_helpers/7', + '.settings': settings, + }); + expect(control).to.have.attribute('item', 'foxy-item-card'); expect(control).to.have.attribute( 'first', @@ -696,25 +739,37 @@ describe('SubscriptionForm', () => { }); it('is hidden when settings are present but the form is still loading data', async () => { + const settings = await getTestData('./portal/customer_portal_settings'); const element = await fixture(html` - + `); expect(await getByTestId(element, 'frequency')).not.to.exist; }); it('is hidden if settings prohibit frequency modification', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = []; + settings.subscriptions.allow_next_date_modification = true; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` - + + + `); + + expect(await getByTestId(element, 'frequency')).not.to.exist; + }); + + it('is hidden if settings prohibit frequency display', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_sub_frequency = false; + + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; + const element = await fixture(html` + `); @@ -829,18 +884,15 @@ describe('SubscriptionForm', () => { }); it('when visible, renders radio list if settings have up to 4 frequency options', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); const values = ['1y', '1m', '.5m', '1w']; + settings.subscriptions.allow_next_date_modification = []; + settings.subscriptions.allow_frequency_modification = [{ jsonata_query: '*', values }]; + + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` - (href)} - .settings=${{ - subscriptions: { - allow_frequency_modification: [{ jsonata_query: '*', values }], - allow_next_date_modification: [], - }, - }} - > + (href)} .settings=${settings}> `); @@ -862,18 +914,15 @@ describe('SubscriptionForm', () => { }); it('when visible, renders dropdown if settings have 5+ frequency options', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); const values = ['2y', '1y', '4m', '2w', '5d']; + settings.subscriptions.allow_next_date_modification = []; + settings.subscriptions.allow_frequency_modification = [{ jsonata_query: '*', values }]; + + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` - (href)} - .settings=${{ - subscriptions: { - allow_frequency_modification: [{ jsonata_query: '*', values }], - allow_next_date_modification: [], - }, - }} - > + (href)} .settings=${settings}> `); @@ -903,17 +952,17 @@ describe('SubscriptionForm', () => { }); it('binds dropdown value to form.frequency', async () => { - const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); const values = ['2y', '1y', '4m', '2w', '5d']; + settings.subscriptions.allow_next_date_modification = []; + settings.subscriptions.allow_frequency_modification = [{ jsonata_query: '*', values }]; + + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` (href)), frequency: '4m' }} - .settings=${{ - subscriptions: { - allow_frequency_modification: [{ jsonata_query: '*', values }], - allow_next_date_modification: [], - }, - }} + .settings=${settings} > `); @@ -933,14 +982,13 @@ describe('SubscriptionForm', () => { ['1y', '1m', '.5m', '1w', '1d'], ].forEach(values => { const target = values.length > 4 ? 'dropdown' : 'radio list'; - const settings = { - subscriptions: { - allow_frequency_modification: [{ jsonata_query: '*', values }], - allow_next_date_modification: [], - }, - }; it(`${target} is disabled if form is disabled`, async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = [{ jsonata_query: '*', values }]; + settings.subscriptions.allow_next_date_modification = []; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` { }); it(`${target} is disabled if disabledcontrols includes "frequency"`, async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = [{ jsonata_query: '*', values }]; + settings.subscriptions.allow_next_date_modification = []; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` { }); it(`${target} is readonly if form is readonly`, async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = [{ jsonata_query: '*', values }]; + settings.subscriptions.allow_next_date_modification = []; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` { }); it(`${target} is readonly if readonlycontrols includes "frequency"`, async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = [{ jsonata_query: '*', values }]; + settings.subscriptions.allow_next_date_modification = []; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` { }); it('is hidden when settings are present but the form is still loading data', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); const element = await fixture(html` - + `); expect(await getByTestId(element, 'start-date')).not.to.exist; }); it('is hidden if settings prohibit next date modification', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = []; + settings.subscriptions.allow_next_date_modification = false; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` - + + + `); + + expect(await getByTestId(element, 'start-date')).not.to.exist; + }); + + it('is hidden if settings prohibit start date display', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_sub_startdate = false; + + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; + const element = await fixture(html` + `); @@ -1251,25 +1327,38 @@ describe('SubscriptionForm', () => { }); it('is hidden when settings are present but the form is still loading data', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); const element = await fixture(html` - + `); expect(await getByTestId(element, 'next-transaction-date')).not.to.exist; }); it('is hidden if settings prohibit next date modification', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = []; + settings.subscriptions.allow_next_date_modification = false; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` - + + + `); + + expect(await getByTestId(element, 'next-transaction-date')).not.to.exist; + }); + + it('is hidden if settings prohibit next date display', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_sub_nextdate = false; + + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; + const element = await fixture(html` + `); @@ -1449,17 +1538,14 @@ describe('SubscriptionForm', () => { }); it('disables dates matching rules in the settings, if provided', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.subscriptions.allow_frequency_modification = []; + settings.subscriptions.allow_next_date_modification = [{ jsonata_query: '*', min: '1y' }]; + const href = './hapi/subscriptions/0?zoom=last_transaction,transaction_template:items'; const element = await fixture(html` - (href)} - .settings=${{ - subscriptions: { - allow_frequency_modification: [], - allow_next_date_modification: [{ jsonata_query: '*', min: '1y' }], - }, - }} - > + (href)} .settings=${settings}> `); @@ -1503,8 +1589,10 @@ describe('SubscriptionForm', () => { }); it('is hidden when settings are present', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); const element = await fixture(html` - + `); expect(await getByTestId(element, 'end-date')).not.to.exist; diff --git a/src/elements/public/SubscriptionForm/SubscriptionForm.ts b/src/elements/public/SubscriptionForm/SubscriptionForm.ts index 0c39216f..f861cf20 100644 --- a/src/elements/public/SubscriptionForm/SubscriptionForm.ts +++ b/src/elements/public/SubscriptionForm/SubscriptionForm.ts @@ -7,7 +7,6 @@ import type { NucleonElement } from '../NucleonElement/NucleonElement'; import type { Rels } from '@foxy.io/sdk/backend'; import { Choice, Group, Skeleton } from '../../private/index'; -import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; import { ScopedElementsMixin } from '@open-wc/scoped-elements'; import { TranslatableMixin } from '../../../mixins/translatable'; import { BooleanSelector, Resource } from '@foxy.io/sdk/core'; @@ -19,6 +18,11 @@ import { ifDefined } from 'lit-html/directives/if-defined'; import { classMap } from '../../../utils/class-map'; import { html } from 'lit-html'; +import { + getExtendedSubscriptionStatus, + getSubscriptionStatus, +} from '../../../utils/get-subscription-status'; + import { getNextTransactionDateConstraints, getAllowedFrequencies, @@ -137,7 +141,7 @@ export class SubscriptionForm extends Base { first=${ifDefined(itemsHref)} infer="items" item="foxy-item-card" - .itemProps=${{ 'locale-codes': this.localeCodes }} + .itemProps=${{ 'locale-codes': this.localeCodes, '.settings': this.settings }} >
@@ -371,11 +375,13 @@ export class SubscriptionForm extends Base { const total = transactionTemplate?.total_order; const amount = `${total} ${this.__currencyCode}`; const currencyDisplay = this.__currencyDisplay; - const context = this.__currencyCode - ? this.data.frequency === '.5m' - ? 'twice_a_month' - : 'recurring' - : 'existing'; + const showSubFrequency = this.settings?.cart_display_config.show_sub_frequency ?? true; + const context = + this.__currencyCode && showSubFrequency + ? this.data.frequency === '.5m' + ? 'twice_a_month' + : 'recurring' + : 'existing'; return { ...frequency, amount, currencyDisplay, context }; } else { @@ -384,7 +390,10 @@ export class SubscriptionForm extends Base { } get headerSubtitleKey(): string { - const status = getSubscriptionStatus(this.data); + const status = this.settings + ? getExtendedSubscriptionStatus(this.data, this.settings) + : getSubscriptionStatus(this.data); + return status ? `subtitle_${status}` : super.headerSubtitleKey; } @@ -572,6 +581,7 @@ export class SubscriptionForm extends Base { if (this.data === null) return false; if (this.data.end_date && new Date(this.data.end_date).getTime() <= Date.now()) return false; if (this.data.is_active === false) return false; + if (this.settings?.cart_display_config.show_sub_nextdate === false) return false; if (this.settings === null) return true; const rules = this.settings.subscriptions.allow_next_date_modification; @@ -580,6 +590,7 @@ export class SubscriptionForm extends Base { private get __isStartDateVisible() { if (this.hiddenSelector.matches('start-date', true)) return false; + if (this.settings?.cart_display_config.show_sub_startdate === false) return false; return this.__isNextTransactionDateVisible; } @@ -615,6 +626,7 @@ export class SubscriptionForm extends Base { if (this.data === null) return false; if (this.data.end_date && new Date(this.data.end_date).getTime() <= Date.now()) return false; if (this.data.is_active === false) return false; + if (this.settings?.cart_display_config.show_sub_frequency === false) return false; if (this.settings === null) return true; const allowedFrequencies = getAllowedFrequencies({ diff --git a/src/server/portal/index.ts b/src/server/portal/index.ts index ec0a554b..86f99470 100644 --- a/src/server/portal/index.ts +++ b/src/server/portal/index.ts @@ -41,6 +41,17 @@ export function createRouter(): Router { date_modified: '2021-09-01T00:00:00Z', date_created: '2021-09-01T00:00:00Z', sso: true, + cart_display_config: { + show_product_weight: true, + show_product_category: true, + show_product_code: true, + show_product_options: true, + show_sub_frequency: true, + show_sub_startdate: true, + show_sub_nextdate: true, + show_sub_enddate: true, + hidden_product_options: [], + }, tos_checkbox_settings: { usage: 'optional' as const, url: 'https://foxy.io/terms-of-service/', diff --git a/src/static/translations/customer-portal/de.json b/src/static/translations/customer-portal/de.json index 407f827d..08be5e8e 100644 --- a/src/static/translations/customer-portal/de.json +++ b/src/static/translations/customer-portal/de.json @@ -945,15 +945,25 @@ "subscription-form": { "header": { "title_new": "Abonnement", - "title_existing": "Abonnement", + "title_existing": "Abonnement • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subscription_active": "Inklusive Versand, Steuern usw. Nächste Zahlung am {{date, date}}.", - "subscription_cancelled": "Inklusive Versand, Steuern usw. Endet am {{date, date}}.", - "subscription_failed": "Einschließlich Versand, Steuern usw. Die Zahlung ist fehlgeschlagen {{date, date}}.", - "subscription_inactive": "Inklusive Versand, Steuern usw. Inaktiv.", - "subscription_will_be_cancelled": "Inklusive Versand, Steuern usw. Endet am {{date, date}}.", - "subscription_will_be_active": "Inklusive Versand, Steuern usw. Beginnt am {{date, date}}.", + "subtitle_failed_and_ended": "Inklusive Versand, Steuern usw. Endete am {{ end_date, date }} (fehlgeschlagen am {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Inklusive Versand, Steuern usw. Endete (fehlgeschlagen am {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Inklusive Versand, Steuern usw. Fehlgeschlagen am {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Inklusive Versand, Steuern usw. Beginnt am {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Inklusive Versand, Steuern usw. Geplant zu beginnen.", + "subtitle_will_end_after_payment": "Inklusive Versand, Steuern usw. Nächste Zahlung am {{ next_transaction_date, date }}, endet am {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Inklusive Versand, Steuern usw. Aktiv, endet am {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Inklusive Versand, Steuern usw. Nächste Zahlung am {{ next_transaction_date, date }}.", + "subtitle_will_end": "Inklusive Versand, Steuern usw. Endet am {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Inklusive Versand, Steuern usw. Aktiv, geplant zu enden.", + "subtitle_ended": "Inklusive Versand, Steuern usw. Endete am {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Inklusive Versand, Steuern usw. Endete.", + "subtitle_next_payment": "Inklusive Versand, Steuern usw. Nächste Zahlung am {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Inklusive Versand, Steuern usw. Aktiv.", + "subtitle_inactive": "Inklusive Versand, Steuern usw. Inaktiv.", + "subtitle": "Inklusive Versand, Steuern usw.", "copy-id": { "failed_to_copy": "Kopieren fehlgeschlagen", "click_to_copy": "ID kopieren", diff --git a/src/static/translations/customer-portal/en.json b/src/static/translations/customer-portal/en.json index 8b071489..6a1ea6c1 100644 --- a/src/static/translations/customer-portal/en.json +++ b/src/static/translations/customer-portal/en.json @@ -947,16 +947,24 @@ "subscription-form": { "header": { "title_new": "Subscription", - "title_existing": "Subscription", + "title_existing": "Subscription • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", - "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}", - "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}", - "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", - "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}", - "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}", - "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}", + "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Including shipping, taxes, etc. Ended (failed on {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Including shipping, taxes, etc. Scheduled to start.", + "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Including shipping, taxes, etc. Active, ending {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}.", + "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Including shipping, taxes, etc. Active, scheduled to end.", + "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Including shipping, taxes, etc. Ended.", + "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Including shipping, taxes, etc. Active.", + "subtitle_inactive": "Including shipping, taxes, etc. Inactive.", "subtitle": "Including shipping, taxes, etc.", "copy-id": { "failed_to_copy": "Failed to copy", diff --git a/src/static/translations/customer-portal/es.json b/src/static/translations/customer-portal/es.json index bbd3876e..10d25e26 100644 --- a/src/static/translations/customer-portal/es.json +++ b/src/static/translations/customer-portal/es.json @@ -945,15 +945,25 @@ "subscription-form": { "header": { "title_new": "Suscripción", - "title_existing": "Suscripción", + "title_existing": "Suscripción • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_active": "Incluye envío, impuestos, etc. Próximo pago el {{date, date}}.", - "subtitle_cancelled": "Incluye envío, impuestos, etc. Terminó el {{date, date}}.", - "subtitle_failed": "Incluye envío, impuestos, etc. El pago falló el {{date, date}}.", + "subtitle_failed_and_ended": "Incluye envío, impuestos, etc. Terminó el {{ end_date, date }} (falló el {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Incluye envío, impuestos, etc. Terminó (falló el {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Incluye envío, impuestos, etc. Falló el {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Incluye envío, impuestos, etc. Comienza el {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Incluye envío, impuestos, etc. Programado para comenzar.", + "subtitle_will_end_after_payment": "Incluye envío, impuestos, etc. Próximo pago el {{ next_transaction_date, date }}, terminando el {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Incluye envío, impuestos, etc. Activo, terminando el {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Incluye envío, impuestos, etc. Próximo pago el {{ next_transaction_date, date }}.", + "subtitle_will_end": "Incluye envío, impuestos, etc. Termina el {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Incluye envío, impuestos, etc. Activo, programado para terminar.", + "subtitle_ended": "Incluye envío, impuestos, etc. Terminó el {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Incluye envío, impuestos, etc. Terminó.", + "subtitle_next_payment": "Incluye envío, impuestos, etc. Próximo pago el {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Incluye envío, impuestos, etc. Activo.", "subtitle_inactive": "Incluye envío, impuestos, etc. Inactivo.", - "subtitle_will_be_cancelled": "Incluye envío, impuestos, etc. Termina el {{date, date}}.", - "subtitle_will_be_active": "Incluye envío, impuestos, etc. Comienza el {{date, date}}.", + "subtitle": "Incluye envío, impuestos, etc.", "copy-id": { "failed_to_copy": "Error al copiar", "click_to_copy": "Copiar ID", diff --git a/src/static/translations/customer-portal/fr.json b/src/static/translations/customer-portal/fr.json index c76fd863..cb9ba18d 100644 --- a/src/static/translations/customer-portal/fr.json +++ b/src/static/translations/customer-portal/fr.json @@ -945,15 +945,25 @@ "subscription-form": { "header": { "title_new": "Abonnement", - "title_existing": "Abonnement", + "title_existing": "Abonnement • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_active": "Incluant les frais d'expédition, les taxes, etc. Prochain paiement le {{date, date}}.", - "subtitle_cancelled": "Incluant les frais d'expédition, les taxes, etc. Terminé le {{date, date}}.", - "subtitle_failed": "Incluant les frais d'expédition, les taxes, etc. Le paiement a échoué le {{date, date}}.", - "subtitle_inactive": "Incluant les frais d'expédition, les taxes, etc. Inactif.", - "subtitle_will_be_cancelled": "Incluant les frais d'expédition, les taxes, etc. Se termine le {{date, date}}.", - "subtitle_will_be_active": "Incluant les frais d'expédition, les taxes, etc. Commence le {{date, date}}.", + "subtitle_failed_and_ended": "Y compris les frais de port, taxes, etc. Terminé le {{ end_date, date }} (échoué le {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Y compris les frais de port, taxes, etc. Terminé (échoué le {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Y compris les frais de port, taxes, etc. Échoué le {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Y compris les frais de port, taxes, etc. Commence le {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Y compris les frais de port, taxes, etc. Prévu pour commencer.", + "subtitle_will_end_after_payment": "Y compris les frais de port, taxes, etc. Prochain paiement le {{ next_transaction_date, date }}, fin le {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Y compris les frais de port, taxes, etc. Actif, fin le {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Y compris les frais de port, taxes, etc. Prochain paiement le {{ next_transaction_date, date }}.", + "subtitle_will_end": "Y compris les frais de port, taxes, etc. Se termine le {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Y compris les frais de port, taxes, etc. Actif, prévu pour se terminer.", + "subtitle_ended": "Y compris les frais de port, taxes, etc. Terminé le {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Y compris les frais de port, taxes, etc. Terminé.", + "subtitle_next_payment": "Y compris les frais de port, taxes, etc. Prochain paiement le {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Y compris les frais de port, taxes, etc. Actif.", + "subtitle_inactive": "Y compris les frais de port, taxes, etc. Inactif.", + "subtitle": "Y compris les frais de port, taxes, etc.", "copy-id": { "failed_to_copy": "Échec de la copie", "click_to_copy": "Copier l'ID", diff --git a/src/static/translations/customer-portal/nl.json b/src/static/translations/customer-portal/nl.json index c91330e0..744e8ead 100644 --- a/src/static/translations/customer-portal/nl.json +++ b/src/static/translations/customer-portal/nl.json @@ -945,15 +945,25 @@ "subscription-form": { "header": { "title_new": "Abonnement", - "title_existing": "Abonnement", + "title_existing": "Abonnement • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_active": "Inclusief verzendkosten, belastingen etc. Volgende betaling op {{date, date}}.", - "subtitle_cancelled": "Inclusief verzendkosten, belastingen, etc. Beëindigd op {{date, date}}.", - "subtitle_failed": "Inclusief verzendkosten, belastingen etc. Betaling mislukt op {{date, date}}.", - "subtitle_inactive": "Inclusief verzendkosten, belastingen etc. Inactief.", - "subtitle_will_be_cancelled": "Inclusief verzendkosten, belastingen etc. Eindigt op {{date, date}}.", - "subtitle_will_be_active": "Inclusief verzendkosten, belastingen etc. Begint op {{date, date}}.", + "subtitle_failed_and_ended": "Inclusief verzendkosten, belastingen, etc. Beëindigd op {{ end_date, date }} (mislukt op {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Inclusief verzendkosten, belastingen, etc. Beëindigd (mislukt op {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Inclusief verzendkosten, belastingen, etc. Mislukt op {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Inclusief verzendkosten, belastingen, etc. Begint op {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Inclusief verzendkosten, belastingen, etc. Gepland om te beginnen.", + "subtitle_will_end_after_payment": "Inclusief verzendkosten, belastingen, etc. Volgende betaling op {{ next_transaction_date, date }}, eindigt {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Inclusief verzendkosten, belastingen, etc. Actief, eindigt {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Inclusief verzendkosten, belastingen, etc. Volgende betaling op {{ next_transaction_date, date }}.", + "subtitle_will_end": "Inclusief verzendkosten, belastingen, etc. Eindigt op {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Inclusief verzendkosten, belastingen, etc. Actief, gepland om te eindigen.", + "subtitle_ended": "Inclusief verzendkosten, belastingen, etc. Beëindigd op {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Inclusief verzendkosten, belastingen, etc. Beëindigd.", + "subtitle_next_payment": "Inclusief verzendkosten, belastingen, etc. Volgende betaling op {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Inclusief verzendkosten, belastingen, etc. Actief.", + "subtitle_inactive": "Inclusief verzendkosten, belastingen, etc. Inactief.", + "subtitle": "Inclusief verzendkosten, belastingen, etc.", "copy-id": { "failed_to_copy": "Kopiëren mislukt", "click_to_copy": "ID kopiëren", diff --git a/src/static/translations/customer-portal/pl.json b/src/static/translations/customer-portal/pl.json index f30b4acb..6f818448 100644 --- a/src/static/translations/customer-portal/pl.json +++ b/src/static/translations/customer-portal/pl.json @@ -945,15 +945,25 @@ "subscription-form": { "header": { "title_new": "Subskrypcja", - "title_existing": "Subskrypcja", + "title_existing": "Subskrypcja • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_active": "Obejmuje wysyłkę, podatki itp. Następna płatność w dniu {{date, date}}.", - "subtitle_cancelled": "Obejmuje wysyłkę, podatki itp. Zakończono dnia {{date, date}}.", - "subtitle_failed": "Obejmuje wysyłkę, podatki itp. Płatność nie powiodła się {{date, date}}.", - "subtitle_inactive": "Łącznie z przesyłką, podatkami itp. Nieaktywne.", - "subtitle_will_be_cancelled": "Łącznie z przesyłką, podatkami itp. Kończy się dnia {{date, date}}.", - "subtitle_will_be_active": "Obejmuje wysyłkę, podatki itp. Rozpoczyna się w dniu {{date, date}}.", + "subtitle_failed_and_ended": "W tym wysyłka, podatki itp. Zakończono dnia {{ end_date, date }} (niepowodzenie dnia {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "W tym wysyłka, podatki itp. Zakończono (niepowodzenie dnia {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "W tym wysyłka, podatki itp. Niepowodzenie dnia {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "W tym wysyłka, podatki itp. Rozpoczyna się dnia {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "W tym wysyłka, podatki itp. Zaplanowano rozpoczęcie.", + "subtitle_will_end_after_payment": "W tym wysyłka, podatki itp. Następna płatność dnia {{ next_transaction_date, date }}, zakończenie dnia {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "W tym wysyłka, podatki itp. Aktywne, zakończenie dnia {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "W tym wysyłka, podatki itp. Następna płatność dnia {{ next_transaction_date, date }}.", + "subtitle_will_end": "W tym wysyłka, podatki itp. Zakończenie dnia {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "W tym wysyłka, podatki itp. Aktywne, zaplanowane zakończenie.", + "subtitle_ended": "W tym wysyłka, podatki itp. Zakończono dnia {{ end_date, date }}.", + "subtitle_ended_no_enddate": "W tym wysyłka, podatki itp. Zakończono.", + "subtitle_next_payment": "W tym wysyłka, podatki itp. Następna płatność dnia {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "W tym wysyłka, podatki itp. Aktywne.", + "subtitle_inactive": "W tym wysyłka, podatki itp. Nieaktywny.", + "subtitle": "W tym wysyłka, podatki itp.", "copy-id": { "failed_to_copy": "Nie udało się skopiować", "click_to_copy": "Skopiuj ID", diff --git a/src/static/translations/customer-portal/sv.json b/src/static/translations/customer-portal/sv.json index 6b8a6078..9c4ec706 100644 --- a/src/static/translations/customer-portal/sv.json +++ b/src/static/translations/customer-portal/sv.json @@ -945,15 +945,25 @@ "subscription-form": { "header": { "title_new": "Prenumeration", - "title_existing": "Prenumeration", + "title_existing": "Prenumeration • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_active": "Inklusive frakt, skatter etc. Nästa betalning på {{date, date}}.", - "subtitle_cancelled": "Inklusive frakt, skatter etc. Slutade den {{date, date}}.", - "subtitle_failed": "Inklusive frakt, skatter etc. Betalning misslyckades den {{date, date}}.", - "subtitle_inactive": "Inklusive frakt, skatter etc. Inaktiv.", - "subtitle_will_be_cancelled": "Inklusive frakt, skatter etc. Slutar på {{date, date}}.", - "subtitle_will_be_active": "Inklusive frakt, skatter etc. Börjar på {{date, date}}.", + "subtitle_failed_and_ended": "Inklusive frakt, skatter, etc. Slutade den {{ end_date, date }} (misslyckades den {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Inklusive frakt, skatter, etc. Slutade (misslyckades den {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Inklusive frakt, skatter, etc. Misslyckades den {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Inklusive frakt, skatter, etc. Startar den {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Inklusive frakt, skatter, etc. Planerad att starta.", + "subtitle_will_end_after_payment": "Inklusive frakt, skatter, etc. Nästa betalning den {{ next_transaction_date, date }}, slutar den {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Inklusive frakt, skatter, etc. Aktiv, slutar den {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Inklusive frakt, skatter, etc. Nästa betalning den {{ next_transaction_date, date }}.", + "subtitle_will_end": "Inklusive frakt, skatter, etc. Slutar den {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Inklusive frakt, skatter, etc. Aktiv, planerad att sluta.", + "subtitle_ended": "Inklusive frakt, skatter, etc. Slutade den {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Inklusive frakt, skatter, etc. Slutade.", + "subtitle_next_payment": "Inklusive frakt, skatter, etc. Nästa betalning den {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Inklusive frakt, skatter, etc. Aktiv.", + "subtitle_inactive": "Inklusive frakt, skatter, etc. Inaktiv.", + "subtitle": "Inklusive frakt, skatter, etc.", "copy-id": { "failed_to_copy": "Misslyckades att kopiera", "click_to_copy": "Kopiera ID", diff --git a/src/static/translations/customer-portal/zh-hk.json b/src/static/translations/customer-portal/zh-hk.json index dc505be0..072e396b 100644 --- a/src/static/translations/customer-portal/zh-hk.json +++ b/src/static/translations/customer-portal/zh-hk.json @@ -944,16 +944,26 @@ }, "subscription-form": { "header": { - "title_new": "訂閱", - "title_existing": "訂閱", + "title_new": "订阅", + "title_existing": "订阅 • {{amount, price}}", "title_recurring": "{{amount, price}} $t(customer.subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer-portal\" })", "title_twice_a_month": "{{amount, price}} $t(customer.subscription-form.twice_a_month, { \"ns\": \"customer-portal\" })", - "subtitle_active": "包括運費、稅金等。下次付款日期 {{date, date}}。", - "subtitle_cancelled": "包括運費、稅金等。結束於 {{date, date}}。", - "subtitle_failed": "包括運費、稅金等。付款失敗於 {{date, date}}。", - "subtitle_inactive": "包括運費、稅金等。不活躍。", - "subtitle_will_be_cancelled": "包括運費、稅金等。結束於 {{date, date}}。", - "subtitle_will_be_active": "包括運費、稅金等。開始於 {{date, date}}。", + "subtitle_failed_and_ended": "包括运费、税费等。于 {{ end_date, date }} 结束(于 {{ first_failed_transaction_date, date }} 失败)。", + "subtitle_failed_and_ended_no_enddate": "包括运费、税费等。已结束(于 {{ first_failed_transaction_date, date }} 失败)。", + "subtitle_failed": "包括运费、税费等。于 {{ first_failed_transaction_date, date }} 失败。", + "subtitle_will_start": "包括运费、税费等。于 {{ start_date, date }} 开始。", + "subtitle_will_start_no_startdate": "包括运费、税费等。计划开始。", + "subtitle_will_end_after_payment": "包括运费、税费等。下次付款日期为 {{ next_transaction_date, date }},结束于 {{ end_date, date }}。", + "subtitle_will_end_after_payment_no_nextdate": "包括运费、税费等。活跃,结束于 {{ end_date, date }}。", + "subtitle_will_end_after_payment_no_enddate": "包括运费、税费等。下次付款日期为 {{ next_transaction_date, date }}。", + "subtitle_will_end": "包括运费、税费等。于 {{ end_date, date }} 结束。", + "subtitle_will_end_no_enddate": "包括运费、税费等。活跃,计划结束。", + "subtitle_ended": "包括运费、税费等。于 {{ end_date, date }} 结束。", + "subtitle_ended_no_enddate": "包括运费、税费等。已结束。", + "subtitle_next_payment": "包括运费、税费等。下次付款日期为 {{ next_transaction_date, date }}。", + "subtitle_next_payment_no_nextdate": "包括运费、税费等。活跃。", + "subtitle_inactive": "包括运费、税费等。不活跃。", + "subtitle": "包括运费、税费等。", "copy-id": { "failed_to_copy": "複製失敗", "click_to_copy": "複製 ID", diff --git a/src/static/translations/customer/en.json b/src/static/translations/customer/en.json index 48baaccb..115ef802 100644 --- a/src/static/translations/customer/en.json +++ b/src/static/translations/customer/en.json @@ -1077,16 +1077,24 @@ "subscription-form": { "header": { "title_new": "Subscription", - "title_existing": "Subscription", - "title_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"subscription-form\" })", - "title_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"subscription-form\" })", - "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", - "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}", - "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}", - "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", - "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}", - "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}", - "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}", + "title_existing": "Subscription • {{amount, price}}", + "title_recurring": "{{amount, price}} $t(subscription-form.frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"customer\" })", + "title_twice_a_month": "{{amount, price}} $t(subscription-form.twice_a_month, { \"ns\": \"customer\" })", + "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Including shipping, taxes, etc. Ended (failed on {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Including shipping, taxes, etc. Scheduled to start.", + "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Including shipping, taxes, etc. Active, ending {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}.", + "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Including shipping, taxes, etc. Active, scheduled to end.", + "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Including shipping, taxes, etc. Ended.", + "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Including shipping, taxes, etc. Active.", + "subtitle_inactive": "Including shipping, taxes, etc. Inactive.", "subtitle": "Including shipping, taxes, etc.", "copy-id": { "failed_to_copy": "Failed to copy", diff --git a/src/static/translations/subscription-form/en.json b/src/static/translations/subscription-form/en.json index 67907941..a73d08d6 100644 --- a/src/static/translations/subscription-form/en.json +++ b/src/static/translations/subscription-form/en.json @@ -1,16 +1,24 @@ { "header": { "title_new": "Subscription", - "title_existing": "Subscription", + "title_existing": "Subscription • {{amount, price}}", "title_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"subscription-form\" })", "title_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"subscription-form\" })", - "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", - "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}", - "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}", - "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", - "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}", - "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}", - "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}", + "subtitle_failed_and_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }}).", + "subtitle_failed_and_ended_no_enddate": "Including shipping, taxes, etc. Ended (failed on {{ first_failed_transaction_date, date }}).", + "subtitle_failed": "Including shipping, taxes, etc. Failed on {{ first_failed_transaction_date, date }}.", + "subtitle_will_start": "Including shipping, taxes, etc. Starts on {{ start_date, date }}.", + "subtitle_will_start_no_startdate": "Including shipping, taxes, etc. Scheduled to start.", + "subtitle_will_end_after_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_nextdate": "Including shipping, taxes, etc. Active, ending {{ end_date, date }}.", + "subtitle_will_end_after_payment_no_enddate": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}.", + "subtitle_will_end": "Including shipping, taxes, etc. Ends on {{ end_date, date }}.", + "subtitle_will_end_no_enddate": "Including shipping, taxes, etc. Active, scheduled to end.", + "subtitle_ended": "Including shipping, taxes, etc. Ended on {{ end_date, date }}.", + "subtitle_ended_no_enddate": "Including shipping, taxes, etc. Ended.", + "subtitle_next_payment": "Including shipping, taxes, etc. Next payment on {{ next_transaction_date, date }}.", + "subtitle_next_payment_no_nextdate": "Including shipping, taxes, etc. Active.", + "subtitle_inactive": "Including shipping, taxes, etc. Inactive.", "subtitle": "Including shipping, taxes, etc.", "copy-id": { "failed_to_copy": "Failed to copy", diff --git a/src/utils/get-subscription-status.ts b/src/utils/get-subscription-status.ts index b0146b34..3a80b4bb 100644 --- a/src/utils/get-subscription-status.ts +++ b/src/utils/get-subscription-status.ts @@ -1,5 +1,5 @@ import type { Resource } from '@foxy.io/sdk/core'; -import type { Rels } from '@foxy.io/sdk/backend'; +import type { Rels } from '@foxy.io/sdk/customer'; type Data = Pick< Resource, @@ -20,6 +20,16 @@ type Status = | 'failed_and_ended' | 'inactive'; +type ExtendedStatus = + | Status + | 'will_start_no_startdate' + | 'will_end_no_enddate' + | 'will_end_after_payment_no_nextdate' + | 'will_end_after_payment_no_enddate' + | 'ended_no_enddate' + | 'next_payment_no_nextdate' + | 'failed_and_ended_no_enddate'; + export function getSubscriptionStatus(data: Data | null): Status | null { if (data === null) return null; @@ -46,3 +56,28 @@ export function getSubscriptionStatus(data: Data | null): Status | null { return start <= now && end && end <= now ? 'ended' : 'inactive'; } + +export function getExtendedSubscriptionStatus( + data: Data | null, + settings: Resource +): ExtendedStatus | null { + const status = getSubscriptionStatus(data); + const config = settings.cart_display_config; + + const showStartDate = config?.show_sub_startdate ?? true; + const showNextDate = config?.show_sub_nextdate ?? true; + const showEndDate = config?.show_sub_enddate ?? true; + + if (status === 'failed_and_ended' && !showEndDate) return `${status}_no_enddate` as const; + if (status === 'next_payment' && !showNextDate) return `${status}_no_nextdate` as const; + if (status === 'will_start' && !showStartDate) return `${status}_no_startdate` as const; + if (status === 'will_end' && !showEndDate) return `${status}_no_enddate` as const; + if (status === 'ended' && !showEndDate) return `${status}_no_enddate` as const; + if (status === 'will_end_after_payment') { + if (!showEndDate && !showNextDate) return `next_payment_no_nextdate`; + if (!showNextDate) return `${status}_no_nextdate` as const; + if (!showEndDate) return `${status}_no_enddate` as const; + } + + return status; +} From 7805326e1cf565040b3e875849b1411477a1a9e4 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Wed, 12 Feb 2025 16:28:15 -0300 Subject: [PATCH 12/22] feat(foxy-item-card): apply cart display config in customer portal mode --- src/elements/public/ItemCard/ItemCard.test.ts | 152 ++++++++++++++++++ src/elements/public/ItemCard/ItemCard.ts | 23 ++- src/elements/public/ItemCard/types.ts | 6 +- 3 files changed, 174 insertions(+), 7 deletions(-) diff --git a/src/elements/public/ItemCard/ItemCard.test.ts b/src/elements/public/ItemCard/ItemCard.test.ts index d8d057a6..256ea965 100644 --- a/src/elements/public/ItemCard/ItemCard.test.ts +++ b/src/elements/public/ItemCard/ItemCard.test.ts @@ -1,5 +1,9 @@ +import type { Resource } from '@foxy.io/sdk/core'; +import type { Rels } from '@foxy.io/sdk/customer'; + import { expect, fixture, html, waitUntil } from '@open-wc/testing'; import { createRouter } from '../../../server/index'; +import { getTestData } from '../../../testgen/getTestData'; import { FetchEvent } from '../NucleonElement/FetchEvent'; import { ItemCard } from './index'; import { Data } from './types'; @@ -22,6 +26,11 @@ describe('ItemCard', () => { expect(new ItemCard()).to.have.property('ns', 'item-card'); }); + it('has a reactive property "settings"', () => { + expect(new ItemCard()).to.have.property('settings', null); + expect(ItemCard.properties).to.have.deep.property('settings', { type: Object }); + }); + it('renders item image', async () => { const router = createRouter(); const element = await fixture(html` @@ -114,6 +123,103 @@ describe('ItemCard', () => { }); }); + it('renders item code', async () => { + const router = createRouter(); + const element = await fixture(html` + router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + + element.data!.code = 'FOOBAR123'; + element.data = { ...element.data! }; + await element.requestUpdate(); + + expect(element.renderRoot).to.include.text('FOOBAR123'); + }); + + it('hides item code if cart display config in settings prohibits code display', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_product_code = false; + + const router = createRouter(); + const element = await fixture(html` + router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + + element.data!.code = 'FOOBAR123'; + element.data = { ...element.data! }; + await element.requestUpdate(); + + expect(element.renderRoot).to.not.include.text('FOOBAR123'); + }); + + it('renders item frequency', async () => { + const router = createRouter(); + const element = await fixture(html` + router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + + element.data!.subscription_frequency = '2w'; + element.data = { ...element.data! }; + await element.requestUpdate(); + + const frequency = element.renderRoot.querySelector('foxy-i18n[key="subinfo_recurring"]'); + + expect(frequency).to.exist; + expect(frequency).to.have.property('infer', ''); + expect(frequency).to.have.deep.property('options', { + amount: '158.99 USD', + count: 2, + currencyDisplay: 'code', + startDate: '2015-04-15', + units: 'weekly', + }); + }); + + it('hides item frequency if cart display config in settings prohibits frequency display', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_sub_frequency = false; + + const router = createRouter(); + const element = await fixture(html` + router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + + element.data!.subscription_frequency = '2w'; + element.data = { ...element.data! }; + await element.requestUpdate(); + + const frequency = element.renderRoot.querySelector('foxy-i18n[key="subinfo_recurring"]'); + expect(frequency).to.not.exist; + }); + it('when resource has item options embedded in it, renders them also', async () => { const router = createRouter(); const element = await fixture(html` @@ -150,4 +256,50 @@ describe('ItemCard', () => { } } }); + + it("filters out hidden item options when it's specified in settings", async () => { + const router = createRouter(); + const element = await fixture(html` + router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + const data = element.data as Data; + expect(data._embedded['fx:item_options']).to.not.be.empty; + + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.hidden_product_options = [ + data._embedded['fx:item_options'][0].name, + ]; + + element.settings = settings; + await element.requestUpdate(); + + const options = element.renderRoot.querySelectorAll('[data-testclass="option"]'); + expect(options).to.have.length(data._embedded['fx:item_options'].length - 1); + + for (let i = 0; i < options.length - 1; ++i) { + const domOption = options[i]; + const apiOption = data._embedded['fx:item_options'][i + 1]; + + expect(domOption).to.include.text(apiOption.name); + expect(domOption).to.include.text(apiOption.value); + + if (apiOption.price_mod) { + const domPriceMod = domOption.querySelector('foxy-i18n[key="price"]'); + + expect(domPriceMod).to.have.property('infer', ''); + expect(domPriceMod).to.have.deep.property('options', { + amount: `${apiOption.price_mod} USD`, + currencyDisplay: 'code', + signDisplay: 'exceptZero', + }); + } + } + }); }); diff --git a/src/elements/public/ItemCard/ItemCard.ts b/src/elements/public/ItemCard/ItemCard.ts index b777ca00..d33e4fd1 100644 --- a/src/elements/public/ItemCard/ItemCard.ts +++ b/src/elements/public/ItemCard/ItemCard.ts @@ -1,9 +1,9 @@ import type { PropertyDeclarations } from 'lit-element'; import type { NucleonElement } from '../NucleonElement/NucleonElement'; import type { TemplateResult } from 'lit-html'; +import type { Data, Settings } from './types'; import type { Resource } from '@foxy.io/sdk/core'; import type { Rels } from '@foxy.io/sdk/backend'; -import type { Data } from './types'; import { TranslatableMixin } from '../../../mixins/translatable'; import { ConfigurableMixin } from '../../../mixins/configurable'; @@ -27,11 +27,14 @@ export class ItemCard extends Base { return { ...super.properties, localeCodes: { type: String, attribute: 'locale-codes' }, + settings: { type: Object }, }; } localeCodes: string | null = null; + settings: Settings | null = null; + private static readonly __placeholder = 'data:image/svg+xml,%3Csvg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"%3E%3Crect width="40" height="40" fill="%23E8E8E8"/%3E%3Cpath d="M31.5143 0H24.5476L0 24.5476V31.5143L11.7046 19.8097L11.9841 17.0782C12.0983 15.9624 13.0131 15.1154 14.1038 15.1154H15.7373V12.1923C15.7373 10.9815 16.6915 10 17.8687 10H21.5143L31.5143 0Z" fill="white"/%3E%3Cpath d="M11.5434 21.3852L0 32.9285V39.8953L11.5822 28.3131C11.172 27.8663 10.9438 27.2444 11.012 26.5782L11.5434 21.3852Z" fill="white"/%3E%3Cpath d="M12.4305 28.879L1.30951 40H8.27631L19.2763 29H13.1316C12.8853 29 12.6495 28.9573 12.4305 28.879Z" fill="white"/%3E%3Cpath d="M28.3113 19.965L28.0159 17.0782C27.9116 16.0591 27.1395 15.2642 26.1754 15.1341L40 1.3095V8.27627L28.3113 19.965Z" fill="white"/%3E%3Cpath d="M20.6905 29L9.69049 40H16.6572L27.9755 28.6817C27.6541 28.8832 27.2756 29 26.8684 29H20.6905Z" fill="white"/%3E%3Cpath d="M28.6572 28C28.9128 27.5952 29.0415 27.1003 28.988 26.5782L28.4426 21.2479L40 9.69053V16.6572L28.6572 28Z" fill="white"/%3E%3Cpath d="M25.0381 40H18.0715L40 18.0715V25.0381L25.0381 40Z" fill="white"/%3E%3Cpath d="M26.4524 40H33.4191L40 33.4191V26.4524L26.4524 40Z" fill="white"/%3E%3Cpath d="M40 40H34.8333L40 34.8333V40Z" fill="white"/%3E%3Cpath d="M16.1666 0H23.1334L0 23.1334V16.1666L16.1666 0Z" fill="white"/%3E%3Cpath d="M14.7524 0H7.78571L0 7.78573V14.7524L14.7524 0Z" fill="white"/%3E%3Cpath d="M0 0H6.37152L0 6.37151V0Z" fill="white"/%3E%3Cpath d="M21.467 11.4615H17.8687C17.4763 11.4615 17.1582 11.7887 17.1582 12.1923V15.1154H22.8418V12.1923C22.8418 11.7887 22.5237 11.4615 22.1313 11.4615H21.467Z" fill="white"/%3E%3Cpath d="M24.7798 15.1154H24.2627V12.1923C24.2627 11.227 23.6562 10.4075 22.8138 10.1148L32.9286 0H39.89L24.7798 15.1154Z" fill="white"/%3E%3C/svg%3E'; @@ -50,10 +53,13 @@ export class ItemCard extends Base { private readonly __cartLoaderId = 'cartLoader'; renderBody(): TemplateResult { + const displayConfig = this.settings?.cart_display_config; const quantity = this.data?.quantity ?? 0; - const options = this.data?._embedded?.['fx:item_options']; + const options = this.__filteredOptions; const price = this.data?.price ?? 0; + const code = this.data?.code ?? ''; + const displayedCode = displayConfig ? (displayConfig.show_product_code ? code : '') : code; const currencyDisplay = this.__currencyDisplay; const currencyCode = this.__currencyCode; @@ -154,11 +160,12 @@ export class ItemCard extends Base {
- ${this.data?.code || undefined} - ${this.data?.subscription_frequency && + ${displayedCode} + ${(displayConfig?.show_sub_frequency ?? true) && + this.data?.subscription_frequency && !this.hiddenSelector.matches('autorenew-icon', true) ? html` - + ${displayedCode ? html`` : ''} { const frequency = this.data?.subscription_frequency; if (frequency) return `subinfo_${frequency === '.5m' ? 'twice_a_month' : 'recurring'}`; } + + private get __filteredOptions() { + const allOptions = this.data?._embedded?.['fx:item_options']; + const hiddenOptions = this.settings?.cart_display_config?.hidden_product_options ?? []; + return allOptions?.filter(option => !hiddenOptions.includes(option.name)); + } } diff --git a/src/elements/public/ItemCard/types.ts b/src/elements/public/ItemCard/types.ts index 0ddde602..20a76b09 100644 --- a/src/elements/public/ItemCard/types.ts +++ b/src/elements/public/ItemCard/types.ts @@ -1,4 +1,6 @@ -import type { Rels } from '@foxy.io/sdk/backend'; +import type { Rels as CustomerRels } from '@foxy.io/sdk/customer'; +import type { Rels as BackendRels } from '@foxy.io/sdk/backend'; import type { Resource } from '@foxy.io/sdk/core'; -export type Data = Resource; +export type Settings = Resource; +export type Data = Resource; From 2730aadccdc1c693b5db33f1cba5248e65fb50e9 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Wed, 12 Feb 2025 18:26:50 -0300 Subject: [PATCH 13/22] feat(foxy-subscription-card): apply cart display config in customer portal mode --- .../SubscriptionCard/SubscriptionCard.test.ts | 36 +++++++++++++++++++ .../SubscriptionCard/SubscriptionCard.ts | 32 ++++++++++++++--- src/elements/public/SubscriptionCard/types.ts | 6 ++-- .../translations/subscription-card/en.json | 8 +++++ 4 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts b/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts index a8002ac1..bc4b5b17 100644 --- a/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts +++ b/src/elements/public/SubscriptionCard/SubscriptionCard.test.ts @@ -1,3 +1,6 @@ +import type { Resource } from '@foxy.io/sdk/core'; +import type { Rels } from '@foxy.io/sdk/customer'; + import { expect, fixture, html, waitUntil } from '@open-wc/testing'; import { Data } from './types'; @@ -28,6 +31,11 @@ describe('SubscriptionCard', () => { expect(document.createElement('foxy-subscription-card')).to.be.instanceOf(NucleonElement); }); + it('has a reactive property "settings"', () => { + expect(new SubscriptionCard()).to.have.property('settings', null); + expect(SubscriptionCard.properties).to.have.deep.property('settings', { type: Object }); + }); + it('once loaded, renders subscription summary', async () => { const href = './hapi/subscriptions/0?zoom=transaction_template:items'; const data = await getTestData(href); @@ -102,6 +110,34 @@ describe('SubscriptionCard', () => { expect(control).to.have.attribute('ns', 'subscription-card'); }); + it('once loaded, renders subscription price without frequency if specified in cart display settings in customer mode', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_sub_frequency = false; + + const href = './hapi/subscriptions/0?zoom=transaction_template:items'; + const data = await getTestData(href); + + data._embedded['fx:transaction_template'].total_order = 25; + data._embedded['fx:transaction_template'].currency_code = 'eur'; + data.frequency = '3w'; + + const layout = html` + + + `; + + const element = await fixture(layout); + const control = await getByTestId(element, 'price'); + const options = { count: 3, units: 'weekly', amount: '25 eur' }; + + expect(control).to.have.property('localName', 'foxy-i18n'); + expect(control).to.have.attribute('options', JSON.stringify(options)); + expect(control).to.have.attribute('lang', 'es'); + expect(control).to.have.attribute('key', 'price'); + expect(control).to.have.attribute('ns', 'subscription-card'); + }); + it('once loaded, renders a hint about fees and taxes included in the price', async () => { const href = './hapi/subscriptions/0?zoom=transaction_template:items'; const data = await getTestData(href); diff --git a/src/elements/public/SubscriptionCard/SubscriptionCard.ts b/src/elements/public/SubscriptionCard/SubscriptionCard.ts index fef5d263..3fbfbcb7 100644 --- a/src/elements/public/SubscriptionCard/SubscriptionCard.ts +++ b/src/elements/public/SubscriptionCard/SubscriptionCard.ts @@ -1,14 +1,20 @@ +import type { PropertyDeclarations } from 'lit-element'; +import type { Data, Settings } from './types'; + import { TemplateResult, html } from 'lit-html'; import { ConfigurableMixin } from '../../../mixins/configurable'; -import { Data } from './types'; import { NucleonElement } from '../NucleonElement/NucleonElement'; import { ResponsiveMixin } from '../../../mixins/responsive'; import { ThemeableMixin } from '../../../mixins/themeable'; import { TranslatableMixin } from '../../../mixins/translatable'; import { classMap } from '../../../utils/class-map'; import { parseFrequency } from '../../../utils/parse-frequency'; -import { getSubscriptionStatus } from '../../../utils/get-subscription-status'; + +import { + getExtendedSubscriptionStatus, + getSubscriptionStatus, +} from '../../../utils/get-subscription-status'; const NS = 'subscription-card'; const Base = ConfigurableMixin( @@ -22,10 +28,22 @@ const Base = ConfigurableMixin( * @since 1.4.0 */ export class SubscriptionCard extends Base { + static get properties(): PropertyDeclarations { + return { + ...super.properties, + settings: { type: Object }, + }; + } + + settings: Settings | null = null; + render(): TemplateResult { - const status = getSubscriptionStatus(this.data); + const status = this.settings + ? getExtendedSubscriptionStatus(this.data, this.settings) + : getSubscriptionStatus(this.data); + const isRed = status === 'failed'; - const isGreen = status === 'next_payment' || !!status?.startsWith('will_end'); + const isGreen = status?.startsWith('next_payment') || !!status?.startsWith('will_end'); const isNormal = !isGreen && !isRed; return html` @@ -93,7 +111,11 @@ export class SubscriptionCard extends Base { options=${JSON.stringify(this.__getPriceOptions())} class="text-xxs sm-text-l font-tnum tracking-wide sm-tracking-normal uppercase sm-normal-case font-medium text-secondary sm-text-body sm-block" lang=${this.lang} - key="price_${this.data?.frequency === '.5m' ? 'twice_a_month' : 'recurring'}" + key="price${ + this.settings?.cart_display_config.show_sub_frequency ?? true + ? `_${this.data?.frequency === '.5m' ? 'twice_a_month' : 'recurring'}` + : '' + }" ns=${this.ns} > diff --git a/src/elements/public/SubscriptionCard/types.ts b/src/elements/public/SubscriptionCard/types.ts index 3aa77b0d..756cddf3 100644 --- a/src/elements/public/SubscriptionCard/types.ts +++ b/src/elements/public/SubscriptionCard/types.ts @@ -1,5 +1,7 @@ +import type { Rels as CustomerRels } from '@foxy.io/sdk/customer'; +import type { Rels as BackendRels } from '@foxy.io/sdk/backend'; import type { Resource } from '@foxy.io/sdk/core'; -import type { Rels } from '@foxy.io/sdk/backend'; -export type Rel = Rels.Subscription; +export type Settings = Resource; export type Data = Resource; +export type Rel = BackendRels.Subscription; diff --git a/src/static/translations/subscription-card/en.json b/src/static/translations/subscription-card/en.json index 8cf0414f..38f0f406 100644 --- a/src/static/translations/subscription-card/en.json +++ b/src/static/translations/subscription-card/en.json @@ -4,15 +4,23 @@ "frequency": "$t({{units}}, { \"count\": {{count}}, \"ns\": \"subscription-card\" })", "monthly": "Monthly", "monthly_plural": "Every {{count}} months", + "price": "{{amount, price}}", "price_recurring": "{{amount, price}} $t(frequency, { \"count\": \"{{count}}\", \"units\": \"{{units}}\", \"ns\": \"subscription-card\" })", "price_twice_a_month": "{{amount, price}} $t(twice_a_month, { \"ns\": \"subscription-card\" })", "status_failed_and_ended": "Ended on {{ end_date, date }} (failed on {{ first_failed_transaction_date, date }})", + "status_failed_and_ended_no_enddate": "Ended (failed on {{ first_failed_transaction_date, date }})", "status_failed": "Failed on {{ first_failed_transaction_date, date }}", "status_will_start": "Starts on {{ start_date, date }}", + "status_will_start_no_startdate": "Scheduled to start", "status_will_end_after_payment": "Next payment on {{ next_transaction_date, date }}, ending {{ end_date, date }}", + "status_will_end_after_payment_no_nextdate": "Active, ending {{ end_date, date }}", + "status_will_end_after_payment_no_enddate": "Next payment on {{ next_transaction_date, date }}", "status_will_end": "Ends on {{ end_date, date }}", + "status_will_end_no_enddate": "Active, scheduled to end", "status_ended": "Ended on {{ end_date, date }}", + "status_ended_no_enddate": "Ended", "status_next_payment": "Next payment on {{ next_transaction_date, date }}", + "status_next_payment_no_nextdate": "Active", "status_inactive": "Inactive", "transaction_summary": "{{most_expensive_item.name}}", "fees_hint": "inc. shipping, taxes, etc.", From 16884625855644d711ce654b634d10dfbc8e57dc Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Wed, 12 Feb 2025 18:30:01 -0300 Subject: [PATCH 14/22] feat(foxy-customer-portal): apply cart display config to subscription cards --- ...nternalCustomerPortalSubscriptions.test.ts | 1 + .../InternalCustomerPortalSubscriptions.ts | 1 + .../translations/customer-portal/de.json | 22 ++++++++++++++----- .../translations/customer-portal/en.json | 8 +++++++ .../translations/customer-portal/es.json | 22 ++++++++++++++----- .../translations/customer-portal/fr.json | 22 ++++++++++++++----- .../translations/customer-portal/nl.json | 22 ++++++++++++++----- .../translations/customer-portal/pl.json | 22 ++++++++++++++----- .../translations/customer-portal/sv.json | 22 ++++++++++++++----- .../translations/customer-portal/zh-hk.json | 22 ++++++++++++++----- 10 files changed, 122 insertions(+), 42 deletions(-) diff --git a/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.test.ts b/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.test.ts index 7c02c119..4476b318 100644 --- a/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.test.ts +++ b/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.test.ts @@ -189,6 +189,7 @@ describe('InternalCustomerPortalSubscriptions', () => { expect(card).to.have.attribute('lang', 'es'); expect(card).to.have.attribute('href', subscription._links.self.href); + expect(card).to.have.deep.property('settings', settings); expect(card).to.have.property('templates'); expect(card.templates).to.have.key('default'); } diff --git a/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts b/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts index abfbc86b..0c7cf574 100644 --- a/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts +++ b/src/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.ts @@ -194,6 +194,7 @@ export class InternalCustomerPortalSubscriptions extends Base { > Date: Wed, 12 Feb 2025 18:38:10 -0300 Subject: [PATCH 15/22] test(foxy-customer-form): fix tests --- src/elements/public/CustomerForm/CustomerForm.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/elements/public/CustomerForm/CustomerForm.test.ts b/src/elements/public/CustomerForm/CustomerForm.test.ts index d3dec668..2b6b8056 100644 --- a/src/elements/public/CustomerForm/CustomerForm.test.ts +++ b/src/elements/public/CustomerForm/CustomerForm.test.ts @@ -22,6 +22,17 @@ const portalSettings = { allow_next_date_modification: false, }, session_lifespan_in_minutes: 40320, + cart_display_config: { + show_product_weight: true, + show_product_category: true, + show_product_code: true, + show_product_options: true, + show_sub_frequency: true, + show_sub_startdate: true, + show_sub_nextdate: true, + show_sub_enddate: true, + hidden_product_options: [], + }, tos_checkbox_settings: { usage: 'optional' as const, url: 'https://foxy.io/terms-of-service/', From 82a5ba66aa109f84be900b2d0aad3bc4d7ac39a6 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Wed, 12 Feb 2025 20:35:52 -0300 Subject: [PATCH 16/22] build: update to latest sdk --- package-lock.json | 9 ++++----- package.json | 2 +- vendor/foxy.io-sdk-0.0.0.tgz | Bin 189031 -> 0 bytes 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 vendor/foxy.io-sdk-0.0.0.tgz diff --git a/package-lock.json b/package-lock.json index 081b7b56..63966827 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@foxy.io/sdk": "file:vendor/foxy.io-sdk-0.0.0.tgz", + "@foxy.io/sdk": "^1.14.0", "@open-wc/lit-helpers": "^0.3.12", "@open-wc/scoped-elements": "^1.2.1", "@polymer/iron-icons": "^3.0.1", @@ -2264,10 +2264,9 @@ } }, "node_modules/@foxy.io/sdk": { - "version": "0.0.0", - "resolved": "file:vendor/foxy.io-sdk-0.0.0.tgz", - "integrity": "sha512-pd8D0udwPi6e5LhBdOX179JOaxnnQA2sm63zfl/xJOXm4am1777Md3MxToakTlz/EpiE7ZTEHj0bLqe9cfbXmw==", - "license": "MIT", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@foxy.io/sdk/-/sdk-1.14.0.tgz", + "integrity": "sha512-wUpMbe2/0ydHEnyD0WCNVwFRA6oQdvfwYHz5HHDqH2vydM9hSyI1E6h0PabZRT0/q4fRFlxcL8g9oIXWcgeqdA==", "dependencies": { "@types/jsdom": "^16.2.5", "@types/traverse": "^0.6.32", diff --git a/package.json b/package.json index f24941d4..c0c59cae 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "prepack": "npm run lint && rimraf dist && node ./.build/compile-for-npm.js && rollup -c" }, "dependencies": { - "@foxy.io/sdk": "file:vendor/foxy.io-sdk-0.0.0.tgz", + "@foxy.io/sdk": "^1.14.0", "@open-wc/lit-helpers": "^0.3.12", "@open-wc/scoped-elements": "^1.2.1", "@polymer/iron-icons": "^3.0.1", diff --git a/vendor/foxy.io-sdk-0.0.0.tgz b/vendor/foxy.io-sdk-0.0.0.tgz deleted file mode 100644 index e05935920d0615217a8b2e015676e641a5129d29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189031 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¥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
Gi@EW)0a`)3q4+5gierGPp2 ze+N1H-}ct#&Q7)eKVSWSDRsVJ&(GfM%bNO9jV!y*r?*hu(_8l=DB!w}WmS~w;B<*# zzD_GxG}NN2gk(xuPIhQB6z9Tx_dJMvW~@ZJ_UtZZuPaN#;foqe)pUb4Q)4f0`m5A^ z7v%pR5C3IrcYiCV|G}e5{`&;{e_8w&+w@X+5xjsb=oNjNm&7s$kidXso7V6kC5?YH zZ<9riom(6$|b2^G($m>ki=II58PNr@N3IGfFkQ?m0b zI=gVOU>JeZ9V$0OXrN#snFR>ujRy5alGiWljEi_CdQ)$G0{TcbUgp(>caDV36w#Lvcb7`nV>*gLY0-2}=94%CG_b>Qz$9_l8_xLrX zHi81Fk8PmDUchIbo;=fP1DBiVfUvawL19m9I69aIESibmCe=={WELW*X!=N@GbrsVA88?DG#SPoY{9fZ zMv7}%{@~5eGO?!QzB`OmBQ0|qS7hIY}}xHKi)&|7SVmDWYOi;WU6EvMu@SN+TtLoMOiw3zzvq`WG;r8!re`wqL_ z2eFeSbeV_&N?!k*!0}D$iF=MoNd`>N8mP4E4!aY|4Mn|3?q(y*1HQnHNr1`_7gPogQkjV0SuvY_(Aq#C`~QOML9n8ko{5Wadj31-(#c9sCclN_X%QQ+T? z_#ACH9V_EBYWHVJC)?7Gw~w|u1%uJw%@LIDZd~b{=!`QH(Rs+{H8XqP0wl%v!UIsY zCHbp|BC1YY$m-KCFeWH)Nh$1Y3D>cQW=|Rkh+7T%&vqlaoPhWW5@x|P*_~cQq|`-N zK;jz*gm_8EcWHUhWg7z~$)PKS%Yw;<(#b?Ubw);)>azM${K2={>s}A9VRwb4vabHnr;H=PadwL z>%j?=ihu)!Kt`Tg!9J`!gTa4CwI+H8u~$(%#QsC`3+K40kQ<Y;Fb6`2d-UUEl92jBL^UKZ#%+J_`QR=Fa9p9{*{pivRk&_J6wI8}uhg!~~>{ z89ahYFTxuO!y+SXpEXJT zJY#3G+)rJ{SJzx~)AvNMCpBHpmGkc1L5mibv}fG^e~Pw(OCO%x(^w|J%_i zU&Ep!hPcp>eYMx~#Lo@uHEjgwSAbWsXg@>8-^A4D#bSTHBI^Pa%D8A?o$$fV{^q70 zebQ%~A>9hIYVwPja&cL1x+CA;bVigyet6$7+Tf7bIE9MUv4_}#N}}H&S$#R`%$+*ZuhmwcFCF9 z78aKTrH=gPQcXXYX*|@P@cWk4iOh;bYUl}!>P;8faHRamqvR8Inhwfa&|{~oC}4kd z+Mp>L`Q4LbVa`>1he{sZWTWc+K{}mrjK@YB$@&x35PKaPE-xMu6S8X#VV6ciO|act zPDhUetCJmQkEU~ngHM0!j@c2b=>;318b-X_sd?i5B=hv)fn;XW@eJga4Z@g}Ia7OF z18eSk7ZXY6C^_8zDr{eVb}>^uefx-J`sCTaHNRs)uW1W<_4ioXCUErjOa070G|Cvovw)rQ%^;d7OP%Tu|lE=4b(mZ;>a)1ucX_l8!tS z_^irA5_jRWX|1Gk*_XTAdQp4e!CSx33Fdc?XjZ`g_0fN42f!Tu4_rUT|Mzw)`_Jdh z|G!Ai{(IoZ6-%rBeKh$$`Y8TCdj<0U?p}re^eOy*K9c{R#rG}WqBN7gjVD4ZVbl0M=iD0(tt-SE4DjGR^jl&jeH+SOKR5xZ_4< zgcOI3Q%$a&ec!j^Vc1UBO3|{WC|K7c}BUxG&u+*Bhb-PD2ou z1SM8>3@)P?13xPs#W;v!!lCM^(mCKV?ec^xhT+VrMGBR4V_-t&i#mXB^Be^gm+KE3{b8wFst{J*n}x!yAJ z|89l<{sqhbpS5KFQ3di!e5%B!N_?usr%HUPti)fF{Wm#`Z;%Cip8e-wKPUg~Rrw#j zI{Qx|{pF=gOVqnNDN`*eXR1XlLRJe)n}sZi^mE{F%jb!X_YLop+_PjRGJ(WW#Z?j*-7*OzPHrbp zp8XizTf_Wa)s(ErXP8hIN($(BF+;Q})x6!do?-i&Abs*wc07C7}YpwwH$sE%aVf{PcT z#g%dBh2xSS&Qpvwy9W#|rALr+R9+++U8~H0R9>tG^T8vB3g8T!Sw43o2a6_9N_$wq z(2dxwM5;E`Ah@HVo&sjHm|B#a|8w-}rN}X!7D>kCQetVW8E>yJM~HOfAAOk{9WGEvi zk3L56c_h30%)fkIMS;2k{f8s$hGRMA6$F50`hU2;SFQhj*!zFpYWlyrPv>hwpCgI! z9qGJ@a~GrW#sC^UJ-J&X1YE_2Y%;m2}n z(tnduU%+7x$ug7)m(6e%V+D=JSn**p@fTDXFviH|N91jpFOZrHx5=IyXoD3+0bV7+ zG$_hmy#G)v$tzKaf+ml$01ndmo<4j=*|?&~@&#FM*md-KBH`TNC2Z{zVAIX_B7DR- z(rbpywI*m1a*Ir#S~HET8|z2DnQC;##fIfH0NmfPwn|ZV1G<0VesV%TnnD{`nLB7y z#~fygw$@Lve2F|V>Zpk-HdIEA9ZXA!f5eD3<7B!;H!=M2Sr&iMMztfVN~8wC*XL7v z$)vLIMk)YO3W9G}W*p&8fz#9Zq7+4Gp>#T_x?`d@}jA6=K z*u*F}3HYnFg}?gbkPB?X39J-h!P2ZI69E#Dk#N&_hTg0)$yRFM%z)i~!{9WdVyT?v z2F_8GVJbCw$|Pzq`=;V)lRWg(^4{C9ccdoxhcu;XPYSe9UfD&R#Z#4K4HqzoJwZ$I zP!=KNWNBEiOYDwb)@JAY*!lnd@Bb_7GsUzdDb``Z;&7R>_MGZ*n5YsMW94_m|IFGTsth2<5y7eP;KQ)ZdAQwQ;VISk=%v6Ex`1z0B{ z<}~j+|Ae1=FJ9bx^5iahhbL|{H6L$o>P?u6siJOhE;ce}5llYfg3~dOE6&N0QF67`(W#*=VPwXe z>d7g_`BVVp;@F<26Orv+0a8qZs!en9#5n6{#_BmhnXgm&8}T6g&HZ+;E4SA426MXu7H_L1HrJ+}1uxpF>lz5AFr z3RDWsHs61pXZ-TWo}SWqodjntZwnpw|M~STAwR`=q1Nc0K~4dl_yX4N;g?iQU3?pKW(O~oCcVxrSGtA~POa0NiWeONV+*_)F8GF47rdPpy;VPKR(xQw*p+*@8(Rf~` zNO>a5VNi6I>)>B0_ne#sXa~en1Sjz)(izN9#1;vTnYR^A6FkQW9A9xwxP>DgTM~=F zQzPap)7?w8_3P&!u0s?3`Kt|`mHIywNPLk( zf9u76?HpF>{|yg!djH>R`4Lry{sIVq!FiSvk<5nMFap@k8(ae{KH%7a$BR`u}aL^=qDgXx{7pZ$SV5D1+PN1mz*kx6@S* z+X6fNrqE8y=OSt0UpYZWH9EAEL8CTERKR)7ijWt6Hj6zA7@;T`Hjlp~QgqkcFt zvBo+isYFL=uhG#Qo6*gXb0L@9hN4ScE0Xy&Kj~a@Nkd=`O3(lr z-)l%c(!Q#SYigp%O%_X6S0N-dON2B7G&azjp0Twf69pP!7E$`PELPfK992(mHA&V+ zs`L?3&B&+6fL?RJM%IJb*hwkBj;3n|6G0JiK3cj z0fOuYnM2w{a9vluE$AAd;(f1b&S|!)U zk8qghei&8;ImYqWM@o@;W^t&S94HRQHqam~%vsJPUM!U^Rc0O+X|A1Wh@azTg;^9Y zI6@x`&P$XLI>^v;&i%Mcg-sYRH}%bqq<(B5N(oECNaIU0IZ6_9V_rvCzQP=rFFdYP zox^u764H=utfB6q@|U@o!o<*FIoT88D_c&f`Ytc1 zJQ@lN9Q-NOuk?eYi2URl)Bn!>l!hx>0b8t^43I9$d11UFzUf=VF$~Db8%bjr2+21xeCU|asTVMYIcaIm-C>;G;b|I^jxf4j1@;vKz? zyXSXXC$HNVNkm)Ef6YyHdHLVA_lCQb{11Em`M;6#e@%%R?TY`#GhA;AC{DCF`u7|3 zeB*)N^;BZ*@jn+Q04?W#ckiH@|E16We68od;po#zmUqG%KTOv+(PiM5ceb5B z!Pq$VTO2R-({h#fsynq%eA9aiwCY;9phCwCo0r*SfuVO_d5kkx>1 zV`29}%^_zEw0y`FI|EA%O6+nxnbhb6C$N5`SWG-rNPGT?{EMAM4ehrl-SW%o;}}(y z`q&5pDlXkKO$Ruc7&`Wgz{u zAODOCz&dW-JX2#p#{nVqhc)$V^x3dwQLKncpUCDLR>>CDKNovUGG!<#jDRP3CJUmH zZ4?#nY&o;wqdrdV{$bS+{m7ZSDaJ6If#_`JP}D|`?$=}~M3-M>uik?(PlGJ2b~I+7 zjrw1s10X1Yuyb+1jqsR%@xoy=)%$?PV`{Y)d+k=s-~Lk$wdlk=SfVd_3(z(2|LYTgHv7;1u#*36IPBxUzC`;^-HGmK09xm4 zS1mx52(F$HxP<#371`_gfVG|fs{hyF-u_O1{%@81e?glLf6(oM7qHaHr*Ca{xp>i+ zgS&?FFH_B|;Ro8H|J%WLrTV|SC=>MO|JwO~H_4tylQ8#uS#8k}0x+vk!0!u$sJeSX zv)a!aJ`+)R)=$N|hR=-}k!fvN(hEduuT=ET{Pc}K@q>kRY6-tG23Si*3jm!+sR46c z9joe7&y6O^nW2HPpbTb_P-C-4CRS8Iaqy-cR(S_Y1wrlA`Yx|npE*#mUo}Im?&hen z`IdE*0jM==S;hWQ^|;h*k2tSQ+f+T$BP%Jm{>p_t>wW|BzwXO_8Tp`E>c8$Bl;!{7 z-r-K~|9!pkf9V!v?oYdl=pwVmOuXe!jSK04^CJ-lb;(TBm*Tjy#LnOTAX+}doB_@P z@UaMQE`LXP1m*^ zjg#T4FnW>gnb#wj2U-2d(vQJnfsS+tL3|RQo~FL`&F4Pj*R{)kK{|=^C>wiz20Yg~ z_dyH&KiIG2|2jN8=>7k1v;OBf98&GFz%#pMaw{!al08e6T^tfv`Gkt2t{wdVv_cHm%Z#zNtDEyBYGuXMyK?2EZ;}#rhg{9gM!hM#`#| zWJb@QXg6NI!15tX81zI%Hb+*jdg6xiGtBJ6{-^4;sLWZ<{$oOO=QKgir_7TrCd$wP z%4Q>LuTc9jh#L)Ql)gbvhE?hRIs!pk{P#h{{=Yrk@9lp#q5r#@`0o<6{;Vf;Es^Gn zI29PZq$^zt?UCUn=qtpBm+y{SrO@bn{;w+kE5?8AS@OU3_P-lB|8zBLdUtwIRn^nu z$CwAY+?L7!TvY~$>t`^#QIQMrlx@7AjWKEpG2=btazbvZLVTvuZP*G-Z1hNcZgHhP zpTz=JJrKL|w2evCK&;KB8uLZ8TW`{gu_FzsTUg*SCre$oaI#z+qnVSnviwj*S{@-%=1ZKQT+7$2_3T^ZZ#g}>hk?kg9u&f3c zban-8IsXSc)%cISgMM02N@m5!qS$1~yr_y$Hqs)*QVmGZ>L}TO-R;amZKo@6 z5BijEfHtmn{udxl&OjPojS*<^|32KS#(xg?`tyGi=YIt?t&aUVW3N5F7$LY({{n3m zuLaVtKuP2|Sx+x)>AO(zyzxV-oxr}mx`}&r7Xy6@lI!}w#AF>bK4?(L&B+EXbf4Y<95vts%8ihW# zv|7|xXX}6t|C~s3~OSXE8m=77=VPTDEx)SKn}5j)+?DSCE0O{9WGod z2&QwFWgIt{-$fEkd^rUuX$o)0wf72_;|FOSk$^Wt2 z$Nzst_TS4@6*Y5rD`ole_y$SuE4D$KhwobiE?9LbL=@Wj3f}vr{2WkwZuB3w}Kma{p#o~6@5j9jn<2G zWwI}of*824Nep9;vhggNhiD8xrUJ9-F&5RP$E6GnxCbNN8>>92x>`+!R4a!ItY=DA zhuzS<8rv~4cCAHPQ{$tm;j(VA%%j1HKhpf6gwT9`Pw(4jJinITy*3GF!KyEDJSZk1v60i ziGzr0@tO#wMjVBxpmixdGDrc0i9(_~CagIo9EahBlz;=X>uC~P(W8B3-o5#yX;qwA zOjVIFoiH{*`IUtgePoOLBn&1n+oIe&iiL$_qmGSrWVjaH_Kk3B#eKWrW?kz(Wt4=V zZJ#WwaOL|X$yP7yiIVMy)P0+r>n{Qu?%PP%ZM`&Q8Vu_h7i)*Z;eL^Z)b{C4777!-YR^ zp5x(48NL63$@5;F4xC?uY&LNIPaMx*Mf%yyGmfGz=X8W~pq+U7yZxZcq7&w#J-fs=85gBQRU0o%pSF*A%qWI8br3<^E~4lqtU z{4xwa0?YQh^Pbv#7@-O3jmVqyKS!@#irKPQ#~GB^%n@iSiGWDq9|Jeau+z=&kYl0o z%Y#SfuAEy77ymvz8aNxj(YziEoVUC%vJw3yzI*`8P9BL=h?tbivZwcfUa`RT{tYZe z5b+8M2on5*517dC-#IYEa#-)h5I#J>4?oyPNlUfyfZ#jML(voeynl=@vBze}?*)_( zA4ZH(_cb6+%g2LKTU_w_)MP{AacQapbVPdaK>O~&59*K4;Y)YV~^maiE-7lgfaECrdV5T-}RGyUnUuQD!W(N#RTU(mIIUd z%WC$PPBU~RciGw6a_--QpFh~(I0cb7!ZW3=NuIkrW#2JQh)t2(CpLQ^_PT_JMJN38 zhd8Pj*}3p1fg8$YE{?0}er%pxnzTH%o8R%ib~tmTA>7kP^Bj|)Z6M)5jS9$7_zekE zssf{$cJ-*MY1Vh4rmei7kVZ}O&`qeX%JiAe)lPljY;JC9^Jlzn>%Vqb&tbzO5SS?% zcj6L}o5x%W%Q;qoHKL5{Gr2j!2dI~6{dv+Fx zwY;F_M?!Cn_A+p}UF)O4T}9`kCi^8&y%o;?a$P2%MgKD#R^z{i2fh9OcHRH$I$mpM zzvJ0lu4kUtj-ACuPT(B^uiKyWL`7Cpd4pN|S^R0qDZtO!{*MAZbyFllDm*0X>|^|e zD1E@?5(0|2IcJsBV&O-cMT?ioQYoQ;n5P&qGey&*Fn9_17i;;l2~!UcB8bH}Q>^ib zAKQVSB=I@IPyAE(5PqSm8trgpdpp$UuN_&eO?*w0SYh13Le`9{GZ*Ky_d0l$*C{iH z(4{j0&r(b{4CxE9@_KIOI;qdrVd^&t8^FJe$$!?LVAd(B**l9v4@Syx^2rR#Rtt}9 znRR{OOw!2!4b&K>bk6!E7zAd)I`L)s4^QQdM_7g1bev{mE{sw?m7kt|0W+EU^%FTN zSIov=W`Sp+4Mfl~dAeP14u=uIxfwclD5@shvFGj*2j)^C6O5WWXRr0S8{uI_Eil}r zQG6cy-c+m&C&wpCycsWn;~7(vK2cczbA$Zfsr%8thqwvPFQfcRoBX$ZSjqpox4+xV zf7kNk`IFEE8VyG~4}IW)w9VfjhDUI8(r4<3-}T4+t3CfD%aaje>sjE3-i2#Gwbg&E zfAL;G{_sFJB5XWBe;Ts+kHpvP`?B!?CNu)@D0@aVQxWv}HcaM}h9aiJe-slE zFS|@h@1S`)EBVd{_Y^EzNMbK8h8PIU^-u7Z4NJ=Y9F}&*6{%WQeTm$P2NCKJ+^Fy$ zxr83t5!z)@`%skMGj3*c6qn##WLt8WE<=J}#JYcHyVC8WQTQ=v+T_A1ho>VAabu;?=zjFVt=o8#x|JmI=sO0|~?)38i4cz~i?*CglyH=*)27H1w z-r>vg4lbR+w%c2}2(Nm3fALh z=tO*5y@-29;#6ibr|2vD&rEwZYiyAa!P# zZ;+gl8g5-(>|9OfO^}7oTXH{~gb|f#Se-BA4a* zABTPXN3Z|CBK?0i^(u=WD=JjwkSv0^QigUFzTmwQ*`7k;xL%7YdPkLilZ(W*u*M2yi%Np4H!|7bSv=ZzMJL=GJP-v zKf)vJm3y%*{HVHBZQ0sH&TIQTMR(W;mV6#W)Pi~MIG%?77)YqQ0Pfor>K)AL3|rz) zX8zVR=V1fTkGZI^EEhmH1jE}LUY}4-J@`*{?!z6jO;-o-Ih*h+c{BsHC3OybPS_?J z@LSXjI{_jQ^%2I?DLUJpu^Kz<4=2`Z zPWarr7=N?;fAjsnhBsha{O93r<^JE@@9+N`xc{#x{MKEWdvmd>V+Xw&>sBYr$yzw#p2vNd-}mp{ex54c!Qk z;m$NT%_x{J#k8`^yXL|b>jqenppYUye5fy6&*9xB`akuvM<{6c-m}F2ckV}%;41RJ z4tIB}{NMI&pa1bD_&-sD=`}oa!y_p|7yKIY1hQ1qctP#PQr50;Z&DqqUnypKQTa<% zLzJHsdVyj9Z+tQd%CI#~nV4hMj~{DBufjy$Z=@PbdO(7-#O~z_l07FxJ2yU*I$_F( z-SCYi=d2sr4EQ6%iOF&5`x@~KG@l`1Q2XJ#GSrdtY93_wm6};!CG@0b;~!~Wl!L?u zu&Dq___w_gj%O|(ZCF@!wl%f4-X|$1RCO-i@}l@Bz(lZrS-@31cj5)m`=j#5dSj(I zm#cf4M=TXs>CGL4IFhS>cOhRZV;FsnIu}e?n)d>WQMxX5ML4fc@RA`l_Ycb zQ|SrX`j|A~EK>FM{Re)pUM|yDr@#9CN2L<6ws;Xo+01BCQ1WL1YT&qRZ-kYAH1i2NiJkEI` z;eOfFKI9SMj$4L1A^UETp{ex(64#1;$7MS$ z)QOLJ$7l-I)5+2p$iRuIXc>no=+g|!uI#P1Su^FmgDX5TmUzI6Cpd?@BLiRmC^AZw zF1Z%||57f17XP1NrT)jx&Oz`0*Yp1u7%@dK<9oC6J8V(yXWPl&JMHzy4l4OShKC0S zeg2Q@Jpa$(N=J8$RJmYtQe>Cip0Q>y@FK@HlsLxp=ajc%k;G>KCIuk&B#+X3f%vcK zahF!M1pZA^7{Zww21`CK z(=3=Hr$xz=G`F025Qacx0IZjCa%st%8snyQdhzf=WDtd|z@JPsz)gy+{P0_{Mi~SVXKF6I-zlSaBB@INTm6p%i~aYo_y4>B{m)OZ z*^eZml>B>DcOe{{j+$Voqza*CQ4K2;X6m|3jAN&HZdN!P$x+Y?9x0BvjA>K8O1iB59N)@%n7EKqC#EGPZXSFY8K(lO!`6_pTGE(h~VX#ik!99{+HB}e4h z;Wx+T!M~KxS9eK@Sf|Lq*~=l|yH|Jn(aw#V8- zy|S!G=dy_eq_KJh)|ro!_oxt5MaJ)oXHsYx!T`APW$t zW*`)WCJb=q`iz|NEE`l;r+FBXPsO`8&t)#RViC$70VT~!pbyl-xN1JrKeYC009&tT zV;$;y|MK$ZcBlXA2Z1!x|AW1Qiv8zcf3K(iH$eX%Wq>p%IXVp&l-E@ct5<-L0#ds) z%K0Aa^#S#!piX>bPy?XKz+JLMss0}7c=ufBwrMd5!5={8f@wr<=v}TEZRc@FzOWpa zb^;BIh7=?1V@;d>>gX-ylr%y!6F2f;9ZeN_YTjTb?u<+%)6>1HvVcn0!R}YJgD&Hj zsiUcdZQdU^9X0&9yI80!^WuW8?X--OqZ)*6xmY82Zm|W44D@7bIq@+lcoDiwxsQ4b zX_`-F=-2-}u@>0<_h{+)o-yfh;(I~%eRrb}4#$#=pAi*gcF^XIuzaI z(H4Pzff(!{g1gXowUG+#69AoKc`x5^Uc{BzEyhV^CarH@eO%IIO_t+2vlfik^8wa8 zi2PJqw{#}PuxkKH6gyI!j^p9{7`9>e z9RJ4w96ZTp-+8$LOGF*1m$`4N2%tL;eJf(;Bwxbqp^t2*d0^?symkohWYH1jWgxx$tGAur zWXyRDMn+k|BcCwx7z1>VX;K)PMP+bvxF_I%PMCZeoi*IAGNB!Qu75KsG6WR8zX+mW zp3hYl>9RA6v^xB1@hCvzN~MR{@D58pa4;Heks#?KazZ(;art3sh(siW(*H*KBMF4S zYBhQ>6lvKQ1JO5K1jNYQPuDbZ#EUhC?S3+c{dp}1^TJ63y#t)9bU$eAYE8Fu=J6g{ zdAwSl>|qN}_SIRqy37CR+6sU+|L>iu{C_y?^FMuk_MeNYmFs2hu7;iNmYj8rH(wxq zsLTIC^Sof*myYLu_pnm`WpB9OpZ{z5sh%ixeiGpq$Op+tI;LLHNrG3>hw%OzDxj+J z>vDzC2gWyarW(Ex6{JgF(NV+e86g^P==yIPgI-t_A@{B-&FBARJ_-Fe+M4DUy864= ze|M_+Uk-pO^ymK??|;1dBQL-k?lmd^kt0@j@F!TJtg0D@FEY4w2hP(o^vTu&DG-e| zC~2Vczeo73Luka>zJ;5nQj;@b5I}w=VU9WqB`9G2xlLQH7|i_wVp95q64X^kecv3` zgSCdS09FDe4UXz19a#5~J%tgaS2i?KQ?dSxQuL(FW1%LOH5kk-@X_A{D(gEwZ8{}l zM7cI{Tuk0xKbRo>$A3jM9O|#zkb3%jk`G1GI zJ^yzj{y!_$|Ne=w!BYHN;E7de`D{%bC#LZ*bn-51I^DZXxP`eB-R( zn&&?q&-`%VC!Od(^ZDPiod4b7cJKdjtIt0i9zV&JKNA+{E*J~(Mj%MqnF6E?YaK$6 zuH{S7Fo;5r{SP+@;v9AKzK|XrIYZXPr{w@pbM~Y1QZ*R&A30>o8aT6j4h$6vxMT!} zN9kBNmd3`RF@BFF*RrVs<>) z!ie-9-pXD+=(UZkZVJ3_d5*{+g_#azps?u3)&aKDk{8wY z0W-T;C)(23dMQlt(m~M^ai+??*3d)XjWrM}^@9`Z-VwBJ@9EbWUv7N6xnMhcjHiTQ|>UaT5F{JWB$QM##`~N^kyi z;x4j0@$I9)7Gn+xwv0kY8W=+2k>!1PaRee@V*<7^GL;9?eZxz=wr~CmH~Cn1wo?`# zQ2>l$2Yr=cyHwgu6Qfh;3KOKVMX_WrR-P2LO-|TJi43cODoxCu9aI!0Q%+GRNn=Vi z4#bBqPU4&$A4rImMGbsPSwKnnS?Mn_xsnY%m#%gVt5}R=OiNFtp`rgjjQVdUVLbU* zsR?JJPGW_^;LNwI4H^4gipi_{SdPN%s=l*2QY?@J7=XHW8p1rRZ$sy0O!rA$BTmnT zO5NYh!8pce&Sx33sOsdI4~#!Q%U|_kdY^m#e=Yw1^5TEC532Q_hrR#zS7rb0DppuE z1BGl+s|M&OVXP}#G+T_VU9Dg}wtatXRH^m+2a)H0x=Q=c&dyH7{#Gf^zLJ{EKdR^-&_9t(o|XTBYS?)xIfraM22r``X=4h>l3A zLIo!a(o#`J{1cs`F*XfRj%K!q0ai80Lz=iv6@*wQc0)yeUOJ~w*(h`giV5zpSa}@m zES{T5u8K_<6-{dbKNu|>7Z_KMD*Mi|c}Rmtxro#dxF|orc=VXPXW@fnN!*{&r$Dcf zK)fH!HRWBbhPk9N&LuS+6GavakpP-X7a$lE_TaHB2bRS^2D`-0ym|y5qQ^9CC&7zP zP}aaDM9bJ@g1(&p3DU|bjAh1h7Hnd5 zV}kJ(KfH7I*qMX)8*&CFgSgW}k;iZ=MRT#}B4o!G1g>EabD|K83HRWfF zUaIx9Ou#{E8Hb)S!S=ocgFW+)j$XZc^NXIxReQ`|bSmmCz}f{l77;3~2u@!H@{9KW z0|Ibq7eI^tXS*Cq!o=YP0e$^V2=LH+r^ z#`7<3?&_{((0QEo$zi+>C|L^Sd=l_d1|7Fg<@>OlyzvsS@ z4vzj_RpKDIMZ~J8HZpdFaoCiO{>ldQBOfg?hIm$bQx*A&lFg=2r`1U}zj>3-QNyOK z1wF8itHOTit#07_n`?NL_1_P6hE@B|!ET@b`&xcPrDS=8D02;EUsPO!5quNi6RgO21to7QcSWl4=C#l7om6L6j(if zochUGF!9sP)Q`N^ahe^QT?A26CvZS7-VZ?bf+SngqROvkKtgFbcnjO<9GOnkc`EEAz=RIP-k34O{yHId`ToHu6D zS!rpNSDgfV;-8|WOj~IA#%=p7x(&*kGG|LylbDu4)6imNuJVDnDi5;8Bm$> zDJ)G|VCku!A^DxsNDQz)`5CQF7`t9k?w6Of_@0Xy*}kXafB;R3uNh+}tvY>^0<;$5oee(S6v2zD+ zY;v8xi*xckCX=u}lt8Lv2JuMIVBvMfAkS(*!4&xKP&L7pmq0f1Sy95V(!aet{nk!GzQKh&)9?F z?7t$c=MB6gdgtq19Es5vT__rM&!L6YqrW9S4&YIiC$s<8A>0Pm|^A++I&4&05F*-YfSFxORvbNE+v;~EOcYJTliu2JyYzpgjkzQ(V5|MFD*x~H z`oEjd|JCW_`g8KFo&Sql{kot3{XI+mpWgrL2F`!8{=Ppg-_ZHjO%)ep0M@ww_lLv& z{9ohwuQgWneEGL`{zavTOA7#NKL7jM+m-si2gAcY|I@YnT&(`jV}UAoChz3H&il1-;38@Z_2%&tzu`yLJGP09{XX>CF%>t_FQa_wj zw5T0V_u@kN$qUME&LKzdl2DIL%TGk^bACI{lh6i%f`Y1_QqWJ`H!4m)HNPsJSH9A` z&h?Kn?J>s46~S>5IhvzxC7P_2!bf&ttz%S_b z0F4zlL(Po67@2$42vZ$51D@qHj;hC3uiv8p$_ytm!3Q571A5H~8(B|gV<+OM%UM`^ zDU*Ydoscy4BhPSSN0oy~}?}Mb9i?VN{b4wm&K%LBGaGwiKBAR(LN^V6e#DMRSs7vC8}# zXd}U{uEQfIb3eh};Oa_*C`w$_0fTQUX=%QcTAAg-B6URJVKY&vAzBX`iI$z7K5U|= z#eG)3&M2a`Fu|y6*_AhPAF9>Me>VB=n&Q6>_bc@u_J_N@{pWi1KW*{9Ut&zIE`rIZ z_G^m56%-n)!aRjbQWrObx79Q65ruJim?Qvc{tKsshq zLy?E$r41K#kW-9}fR5OY7v1~+g+-X7d`@vkfmh4}$1sMCwP_^s zC;jKp_WxpMI~7VXeJR8b*RgAsjDh9eI;Q3F%SH> zNYQ@r#n53^Ct>T|lDqn{22q>2x;&OiJYTrc@={kqhuN+7JP9wma{$?`?=YUmm)$wS zZ0kMB+)Ktl9cH)QS&w?j-Pb5k_5KT$F%dwe|Lr;yBFy-YWf)XpdVJCa{Z^WOr#>rl z@3Z-Rx%|If&2j1ZUxxcTht>QqyM6wro8bS2VE!6;weZNN$i}p+Vk%rah^Gt3sc2}) z;am16-7L8mYwo4>P70L)=$1_QQdSzIPajjI2It3`$*96#?>9^vJ3OGEPDFadblvoc zWx|Y3UJ2)k9|aR_sb(M-MK8Qy^jNOQP}}=R%&Ah!K>SCCI&xmkgY3Rs*8BQ0J{UL~ zV=j#5`~koEsC@*=y@B;`ss1Ad4?RX3A#kXt!q`c6wLAZWpL;J}+l-;p%`lp0@r;7)C{1%1^QdyCiMTAKOdt%)ih4fqI>!IANQ;AUx$YWeg3DLp#L{q z|K~X%+hfKxJq%UHL3_C$?L%}+Xf_U*7~NXm$ArB?VIO@qw^a|a()nMmX8~+H|HGY~ zgG&DA!@a%U|K|qI|5Mc8y_Jb!wCX85llrG|s>Xh_I~osJcG|;Gcri45l~<7NlkOjjSNnXe7&0HFanK>xK2_)`G_rhrYx^io(P z0t_|Db^W?}r{-WcieBz;RY_IFhnr(oa-euW-`TA} zTtXO2%VKv(L}f*4S{`ZbFQC2Q%z)me^h76P(s2}LVxXuE|^327}kPoSL6>Wpac?jT^gd!|c%2Z252`iv<^5b;80Bo22R&DU5 zL1R&5T;mzs4j|H=!b@KK2(TA$SB?(jhOTxlM_2$1E5l)+4p)zZQB1-dk!=Vv^3wUy z+1cZf4&ceJzW)&(4G;dSc=jTWvKc%)INXsB5BMP}N%ppP#bf)*;pXA;1#wOM4=+K= z!{d{i0=&>u;yqCT8P_G#rP0$mbT$Z8Dr*v3qmM+~*ts7}XB2V=t4C{FhKkfNis7*r zoCRKv1*x%__%IMLL`5Wu2=(Ci_Rht(Ip78MJonu+Pkai-qjjMA*02hxFZ^rPSp;(+ zW9$qL>@R;kqC@z%pN=-nL4|%ah5f#sL2+ktP|sh|m>$0<4auFyId=vpA(=AYfON${ zx>AhboLy>s=eSCwIE}C(Mg=`naX;!^b+dkkQw_ZnQD;kkwR0Zi!0`jBU@wUL`7FkS zhl$5U?Xh&CJDJf}w4~yKq6Q5^8duA66HB>(d+QX=zB6+pj{+=DeWAw$bj4cr=jfYd z-whlMrL!%4PG)~Gfgl0iDbRRa*>VgmCH0Tu$S-I;(n^|-`3T2gJei;qTlv8l-OR?w zPtEgr2@T9aGENkpVPzE42Wmflq89>3s55cHNgfs%PidF&?ZQurEqnFG`G4?a@TO)l zDlo}8t`6sa#S-+GXpyJ{xfdq(^%Ntr57(H!SS}FpHKv15zp_EclH_CV!Qwmn2#WXB zK|BZckPt4wgud9BWG%cPozQj=*RK1+>5NZt`bBezKZFJU&H+<{Y&qtgHJ=s3VlDzv zQg6r)v{oH>C^d}gxaznnj>lwSD`705WUuP_r$q^{nk#Cud4Pf)rO@4c!3i~suAjvi zNbdr>=?|Qpdz<^)e+;+p?f$X9eQzI$Z3ye-kvoDPn{bHd=GefnB1-j4IF z>Jh%onC#w{@MiS?tPHuD_@AAf?OjX!Pw)S61N#4!40R;~-MTt^%@%LXDpaebXWM%R z9euo5KM+Xuqp`O*cOq&Gm;!gQ48*l+;0`SegQ+U`m2w6ZL21XBAEklU)~z~xGbfRm zlBh-7ZScS}z}UF zeg5}v*8k^K+2ylzhd1y7X=i4jo7azkx}wXE`2 zzjFRp{$`k7mGB5*=a0NBa)sLx#}}O7dDDVnz@|KF<3Lp z>`3m=NbO%aqo|g2k2)zCG*-(uYZL6+CSkO-Poq%`EUlf6RE=F@FVd7G_bZ@cT5K9` zOf_0ysF~KbIv^5~+SY&@*(Xl~X+&hIfc_6R3F2I4s}%B7YD#exAzqzr{f^gD%qm-H z1%XT6dM0(La{`oP&pp9(ox+OHiex34Ix>lG9rVI3(FVUldPikCy@o5D>Gb5LX*>z^ z{H^7I7z6LRrh>sPuZx_j z09G>-3w;4%XmNl=-W7Cq!}562u%&s8v4bR5qD!z)W`-WIF56Sz9D2kmId4=hNsseGaA;E)^Q{ASy;w|4`_ z&nBC9Tl^Yd1GWmc6w&EBy0OIp)pmsiFx5kV$+l1O$kW_{7X)nF#e>pEN+=Gs@>vM* zNOGZGa+AP1n-=QQ>Kx!3o|g8GidzKB+PV!c2-oErAt?U3!#)z0b)sWc^SXi_k!K{q zVQq4;$838yl$NcAaykp1>2?{PW|DC+I39Tv0f#1-4c}uOuBg<@<>zI>Ye57~&??Lt zQQXorpUg1G&~xs1?(*)yId|@y`~FAxZSLHeqbnr*iUwZi&eC@iK>vTjfgztxv^b-# zcXNNvtjIauF0Mmg!AN4hMwa^8oRaCgsH&YB!IO9v=ebnNvOk)cbv{V^Nv6?t{q6Wv zW=FN-aGV6w08e(I5H^6H_){1f3{Wg9rXwf6aplW)nrAr%B3%E}P~^`V627aL)q=&X zVoH)n>}GNkGoTP*jTfky%yU|BzH(~ziRJ>r9V2`76=r9{sY+T0h;1JddOp;SqDD+$ z6fk?egX?BKlDGypBH~ZJAh(E&r2`F@?hd%4!u3@7krdoxI_Ab01MQQyp~Xq#oxCRJ zd6)%wSCZcerRUQogU_U|+eFEpf@fqjkYiyl4|e*{FPh>b&8ahs8v-P#XG|F;1A3IF z4-Drl@XvK)QG~NBvgsvZ6W}?y2{u7Se-mnDnxxELsD-^B;WTXFu&I1Nf;V)CM0F9O z@?jQ-o-nWpQ~?rM)J-5@H8#4yyR?1?*41}2t6{kw;mwmr!6y!I$lUot;JNTIT*N_C zItgXrTpVQzIY4JVSsoo7&?JU(m35KTw-R_#n^^FRtmRN*93EQbSjREt>4#Q%+7L${ z+T?j%fAFxPKe$;NXovc57d8Mi+y4&thSmCS7%bB3|8JB3&kbsZ>oucS;qKC_iF!3r zuO{l%M7^4*R}=MWqFznZtBHCwQLiTI)kM9T=&M%~eS^N}o%}!3tJME&?;TYAKM(hY zz5eIh^#87gmDyEK9h|+pd3mqu-~Cn5iEjGeixGg;&;P;Bu&@8npa1^+-~9a_y3sU; z7Gul;k_6rw1pr#(zjrG6|91}h`j59c{`(h!6|V$R=%El5j7irG4Hp?UFdc{%upskp zfY@#&4&|{m(}~Jx*D_d@`?Q8N$gUjO)mmv?ReD~Py`&1aCU(MDx{ez9UMAJ^$75&eIYNOP7TBvbIsk7i(-p&-(;@n*h9JGe3Nx&RK`KMk<>x}1W@gl+J* zmFbPjYtdL{J)HwzJ#c3E+{Ls_B1bo@4@}Z6Dq*AbQx1YVD)No{X==5b{m;>>mri_w z^{-PII%(ry^962(bX!2~R3!YKyV<1lks1UVfG8pH!VQwLn_Gp7I>*SR9@AIHI*)p6 zCW3;+dE=ws*nJ+|p!}!e7`rrk06#rfc~$iP0xIAZ`cJgJr2p;ne|!`4za!gpT{{22y*J#e^8bDP z$6HPR*UKgJ3*eIeWef2)5l@%QH6ZUdxR&h)O$;|)i*mm|6ft1NYkG#SzfDTjZvVeH z0cbh@yOsQJJKKA^z5ee8&i~~eYyH^;54ZCt7#;F;qe^c*lX2PS-zd;rL3W&T*X?X6H&U;t~%R9=}bkI6Bb@LN67{#pU}?#(aKJ73vC)lk^mTC>2< z692S-aBGUgcRK%9>;HSOvt9N7-9PBh|1IGE=|R;@hX`Kq2l!{D&9A7G&>-a*r)vF< zvL(h5oCJzPmQg;&F-l0Kz%jL|C>c>EI=fbil-_^K!#AXg2SBJw&v9h;>CwOu{KW$} zpbv%aM!LbkbM)~@MDV#Bo2b||;e_Z?7veZ$shx7(zoqpFB2>G;%(#2S%6u4!^%3WvR#{O@q;hn4*AJ3D>-m#OGx!NZa2_t*teb% zxajHIQ3KPQ$y4kyHNnT)W*qnG;ICW$dznu{KaRHM?qr5Rn^zeBv3qz>vHuNsdj9VQ z=s)mf8PMZ_^YqNevYJO3N^zPd2oVJ6upsE3KM9eFOpu*(1geZ2hI!}vPbq%>{oPFh z^MYUB7k%6>(Fwr;Jy5^tkKAY}##Hy&12NbYz&`k)Cr0i3A6`*s{uuA>Y2vP>0B+&` zb`Goh-~C~)|GCZlUtIu4mDPJm`18C#pJs-yif(JMeU)CV0U6wxqjiS*D?dU84b%2C zhhsDZFmUE9Dh?-Hm^2peEYNGX%Li5F?h&(h0szq1%nc%0a-0JiaxrSj(Sc+-L7o;m zcSEhDL3N^9_yYp!g9m#0-jgTvnbeBP@peqw^k`44lo)P3BzQfB3*X%i3|!_wRopQz7(*N9{Aq(P$QllPYj*@;nMM zVR@CAFHz?gmzb&u<6(iZk|Ql;A`C@{FHc=de2M9+iaAuOojvn0KmgY!Kzpv4nsM%a z#5Hnr;7%!PEE`Qq`9e<-#K`$Ih`jjx{RaKXzF9KWFYN3YrAeJ2A1(Vq(C>fsPl)?Q zZ&Vn?hda`o?D=PYi0a7AdHh=thVEvZOt<{#-n*kMFP@}Z@Fh_+`0rRi7{lLMUQz6B zB%y1G%pJ+;F{6#l ziF_{b#h<8QrU*s~DLj%qqNKXZINtyqJjvnq;xUO3WkiHY7-0A_oeYd#K6>)E&F?hp zoYD{xL`2~lD;=XWDvW{&DaonC98jT(LKz6vgCDG|OJre0=LY6fdS3f6kqG@OdT=Gk z0IWg=JOUjNF@SLuK`#IN+4{Y$XVSVxHRtqF>7b=wJ8jhH^&Jq+vymdwce%mT&+gnM zYtcMNQ8&pbCCNV=im6}$oYFcn1Sdtjuzk4eYMSe`@S!gCaEiL!}$y4Y~q!vPDEmevb0YL)#%fe0ExpNYGOF(PH zoJ=$Gv*l`2HBS62PvB~NE{=G_m{Ga2@?2?~kT5fEf;!d5ZWyZG z=6*JdJ-U0@)d;?j-vgh5*TpH^d7K+nViDa1oIXYy@CG~ek%m=*h}^SaN(#-`39xo* zJQ3FXNUm%R!f_vTnb08UQtFCnEGd-MRy+I1AQEIb9&@p|v-^+Lbz}8WdT>W*NFLuE z>0Fy?@c!|K1_V@tp*t64Fjov}GUH6xn1MD(;QIBMmyij2a62V9%6m;o`%#oygR_9I z?$%&Q!CuAxlWc;${^yqZf7beT(tAQ0 zA+)`fj#7W~mx|U1p+P`+!) z15~(j{!t=|;x<-q--y9J!aQR4t!<%|z6{nj4<0Cp?QO|RG{WL3mrD^^?LRW9{slt7 z+TuTVD)FDg?VUdV%Wby*uNNrxO5jrG7*HGX^>LtAegB*BpBE1{13x}{`}wW`~Nj#g%S86 z9#z`DOMTsVo5P=0G9q9$a|EInolg92c>W0}KPbOF>Tg7&FdvT9h}BmzkfY?*N73qG z4CKZrU1j*VX>D@X+M@8x8wZ~0aM$WVcV*6SUC;kTLO|Q%zlW9huY1AB(Kz>yUxw^M9~2tona$5BvOoxBLDl ztaw2tmLoqi83D!^w!dJlf%F3L1EQy&L^l1Fqi*2pT9E^0f90@&JXPi;c_2EJY!EP| zMG9A>4U%mUN7ZF-h(mZ{Ns>`2S5R2sRMTo8z(1%0VEIejM>SwBE^IAlQ2q|79r1DKxBQ-P_|;LMMzl^3w=gD}`=X-4j)ZseWBpD5i3RVqX;otYcn zJ3$kVpKOW$ZqBlK_#drbmScg-^ii#`dhod%*6SPx-dLOFG0#t}rdXm1li0eZD5ib8 ziwd*vvZ~Om#YkC9Ha3c1-7p-(guPUIHg|pKIUb{(#@2L&JI4NIX}vShhlH%4UAHV~pfR0U~FOPki9YX-yX$?NLm71wRtN@E*WwhXd;7eQyrhzc{k{Zw^ zySh>bIF$}Plo$wm7r)MY0GVI}LKJ5PFquRwEkrcuG>;}MrUaSUn{2F!ZO%4a^usm! z!*HfJ34R0QLhnHI<%WYo^-1B)e@@&*rpt>)_t=7@H*5DgMwHmjHL;_S1#8*J@(4O? zY6FL8@A`$Ce5@SKlw%4pMlXsTtQw0sONyLvI-aJ`2av`I^MzVw-lC7^r{+cqxjEIO zTG&LG*PJMvNWx3GcSV8|B`~`uah}oQ0O#mB=d%EWW{h5>w45iH0)=cdBAihO-G2Ro zSp;k3JpnZedgeGMVLbVmj*Mq`MyqQo)+7X3!?GG2r|l=6rtt!ThxJ!1(jC{8gqz?ZtuH%l}_~ z{g?fN{c8R9?cV5Li8k*51Nur%0;WarR*|*N=U*5iVbuew z!hUJ;|L(3${@?4*|4p2K;rgweJn0QyIjc|jwEs1rkjqD&mteMt;zP+#oN$A&%Ps2Q z7^ZCt7!wcICoy%N2c=f|iQ<^_Nu~PpCMv}9cq&dyH(FFWVi(bHnBD8S95|bOY9x2= z;=`a&<9rsIV!rTdIPp<>&?;UqIE6nW1)>1@i^{+t8ezU_ZH3K&8EZc>_ozBhfF_4{wo~O#;1v!dt(vE-XR*Sng0W3uOk2L4g30kH^Kis!<~JtHdbSN%6ooc z8Bh5zHhPX;+;LR(Q=Z!@ESU}KFV3D-2W8DtZTb_{uvs-+8^L#qL7Tt~2$lJboZ8V< z9as<#ak#?jRpnE$-DzoAv>b?)eFvnl zUw^hSl>uLTMCEO%A5VWB_dhps|F`Lc+u}d>hL!t&w~zn$hV{R-cXku2V7;JM@A2?dJRS|h}LiH~uewsqR7!HV``Fb-oXM4Cy z%YK z|LNubR)au0tF*EJzq+J;5vlyfCGf82|LXET?+^D5Ecu`J`tyH_<-cxG6zipvmuzd7 zgL@IlrYg|58GJPH11t-rvy)u}8EKW%W@op}>C-oo+_&(=l4qi|EsIH;n5HrJf!&KH zVeUa|WH^F}a|c_pH~d!N1)ts>I3|}gKu8NW960XW{Vk5h^K+p5%!>}3cp68*IwFtC z&Bp%3O#ZkbI;0vsCTM;{pV6;H2lOZRLBCQrT65@S!|uzjr=heg2JJuBymbJ7IbWN{ z#hoco8U5aGAQM!L)Kp`@OFv`m!mUhLRgtRfVH9s?O0aL3YBiTga zGc*el<8TqcQ$O*s2ph*&=p|gaPnD{#IyMlHRGtH@2W!iaf<$SWR8kelLD`cU)Xr-o zRZGw?(y>T@U|-GGuLJ`7NH2?#%U~JD%V}*VGk@|C6DSY?s1d*DzSj!w8pqb&zX*%b z<7;^BF{p2 z-d!asr(-9T0G(BOqA;BmI@05HD*ZgKNd$}%w&rRsbt-OEf0Zs_iRS~&+c`xJp}O-@ zwSZNY(LKc1G;9^8W`bc4KLdDxT|pggy{4O@7Nz+fAsE(Vk8deW50+&BQlj*MdO8+S z8Z@ctzobno^{*#ssp~$AGnjxor__?AII|)vD806?Q18ys|6HQ{r|N$RJ{igBQ@}cJ zT^X`zeUksCl8{^E60%F3>K~P(0RMZSS zMR-mClpiC2{~70w7h|2=nR`acVqhN-B1b#{sUb}=e^i0RPzKHk@HcQ{3JQ&tt><_Z zsWD{;k;H_UE?G1&G9e(Cl?E>|&YZlX}esm)L zys~0lP4hvMUwTVFNo>h4C1Y`Au;9;;T~O}&`1WA!25Byv%7&`f4=*J=-WMa z1JU0mT>y8yc#_k_fR)3k9StfD{mn3*-r0B?fApi##=!VA!-v6d{++w@#g>%0Js(yY z7mU`sJe5NJl;x2hMZ7k!X^|KD35(3A^yiZG$TnbISruF+ zM*kG9q@0!cmx9vn;hF}%t21_oe;d_p;)qUyr3^fyJ#*69d63IU%ZEw*YKyZ!!bxI5bg7gRh2_&!j zjyQjWYZEj%VuO4kh$mk*eo`VcdBhaHZdqU8+qCv#jkLt)Nen3FhdxUX&rkI!!7UkL zve~6W-2n>A4uV2v6JtSv9@Bf&AQg4PD5dv^$jHKs)~&*^4x5Zuh%sU@7<0XNwXoxn z^OSqm_8OP4y3>zgGm_Lq!eV<(s`4_v7cbD{Xj~!`3%lY5gDcAqq**WO_e{Y%n*K+(AGxRiU zzcOC59LNTY+UT`~xAgq4cH~z%|HH$o{}+7GpZ_o8{I7K8`(yqEo`1tR;L`Jd@9z%} zs`TKnB*apSd;!_S8pj|i7qw-+kX5rPKz|Wx$s>}^^^r@3<(LKc zwDwcmN0!#{#0~w&v1hiYr{f7eZi(@#PPOYC-}uu~WLLsZs$PY&V6iCD;Fggh6|ZIb z+!}O{P}s@V3V_{xYeKUA!6{$UvU}rLl{R&FYgDzX=b6lJO!l~UM-GrnI7V!HlXY@V{cJLGVk+mu=YA>Li89y6 z55;3bwIAFxCEyiv6qWMUIr0 zg}QR1WieNVuiTN0VKDB9rsgaQ8aXOxXx$i;1w$Kz(UELmpKn1LMg{4p_T`45<`&2F z!3+j7XvRnT6q^yODW7Yj;cfzR~flTQ1{H zv#(j{+8deoqvhc?v zZ^|FEI`^W8m%9GtR-=RKKw-mxeY+PN1WCEWtvT8YR$)}(Eb1^$Tu99bXT84ci(Yfn zjjT6hF{qzwB0D8rf{lBPF5Z6)Ft0uPb3Zwc!_e)JrYWt-(^R|v;xJ0bRLRLX$jP-F z&3f*y=AbsQi=%puv%%&5jdXp};yjxQFMgqZZZ`if)aA?RZ;{ITBGEtX^QXDfXJl*cI$>o}2a z$iS2&>{U>dWDUf{DR^t@laTfPTb_o&QxBZCJZkxr{t`_eIDa^KBuc(MaDH@35O5;* z1(*$@6dMnmtu5#NJ^1+p4eV;zKzEpypjrK4BOtONX@D;K=MVOE$u`h2ZlVlXZ10yt zdoSkm;mU?#8(4;1k&2>#-K9aWL4DM`Q&&37Kb%)6#GD5hC?A~4#X}h;)NqsJox(?+ zZy)F1I8L>?H0t*oT;mazSI*{*?|SIU^C(H&<^3Q+xASMz=#u94hbWafLubs0#5VG= zbVa>M$Hkt7*9VOBbujsOzl00}=jo>mJ*4jQ&<0qP6i#TV*@KG=xr7De-UPBLyDn(> zKp1gDxC&<*xObOaRD9x1q8QNtZhetJ0mFU766yHN)NKC4cQ-qJNd%-zjhq6bs^hU6 zWQs1i-{Cm(=wlS0M?YNS0JV`m3nEy%WwDY`oXsdujDyGM@UasZN_PTBdL8~%@P95+Jn#p_$(= zKs^9hk$=WwvjRu{=v}~xkV_j3zKs9~Z`}pwcX|rq_Jv0j!seu1pqR{&@YgMX_BP|| zxBm*InNo{gy8U+enPw$Q6v9wlOWD1Bbo5?lYWFt73`vWy_aWU4WOyfJwI~N zxf_N9XO_?1hzy~mmxN^q-AGG?6r{xZ7|>QnAVL1o1`H8e+RD$c!T2-v{>IoW|ZECo;p zm+s7`5v7d)Wov&dr_I3Me<+U*zUOqxo)4eQgNX7Eq5GV`K2C|0&f;@S;6&MwFxL{Q zmjR2sdv1Df8Rz%tSa51wVfMy8 z*$^(O|E!=QZlM2f{4l++?@ufJM_=#lGX3A%>+QeS^CL*}pB4S)Ti^BIEQ~2gMpwDk zwO%a3!1pl7Z4pOfVGQoxIBjp8xt}^UYJ`;m6*$QoXCj+4fH?t*pvC5NZrB7<8ro}L zFEB%9Q-dUHemfRUl^wRz+B|J(-w|v_a80jOP+ohF<))p$ilE}Uc45HzsOsKpaqsm_ z7F7GB@qNoN(i)A;iYlvpkaqf_y%mRVc5K!TE`Ti?PhiWYahJt3+ArH$H-RH_?znZA zxfz`4w0Y6FU7nKPV_hRsxQ@wluUo6Mtyz0_e$r0B$}RmaZM$9?Eh!#azk;`JIF`v< z+rMaNB11nrQ+D}*Sw5`2eL1eP!xzF8s-;;60tXx((Wdqmt!KH^utTR!P2%$?j9EnL z)~Y*kFus!IO}aI2fZ7$q&2~)yqh?y~CrONTEL-lCqFDn4ESKKs-m;gsts+uGBUr2E zx1AQh{vuT@$CnYCbrrd_}mseW2oHa1DKZVX{5`At5~qX){(N zK0a<|$k0`{4NBuFQB8z+;(rR#EbY>sQxJJEd=_>5tf4{bM;;HMt&u>Ere+{aG!r!0 zq6LUGr&?QkbfShOX`*G-wp{>wfb=wqRoZp|+$N-1vct8tL=W>|;&*S^1hiSwV?69W z8C&zTbNlv*S=+aEAX0gCY}N*@>3x2}wRoCIhfcV=wd$a8(3>|jYgB2&%kEN2x$&~G zX(J>VZNn+cIy7u#ILfhEbK3aDAq#In2VLLZ$RjkbbN=ep|C3Iuqr(IyYD zXhh>|Ni0A!iZSaW4OLpdJj`6?5oHva7_^)L?4?O(2?Ox4qHyLP%T#BnqY)XI3VYzB z`F!r8j5Bc9bHT~cD->T8#1LH}{R!L%DQEP>8pxYP65aF|-3rlNl9!rtRLgf%@|d>? zm_7d-lR)U-j>GIsA0!pcJ@rvw6ONNu6F@dsev0U#2|FdHx#9c)e<(Y=@fY^6QMk80 z7o{JmQl=|cn6reZP8v)jx_i(;av%z=3T1)0$j;ndVm1Yp6+otEAa_f+7c!~}o%kq1 zo^hfE(spJN-oS}DX)$y&Kn1Kb)nERvwZ@O*bN zqqXtsM=AYv`7>C=p|(1Y**Vl<8K8_-uj4cg(9u}rRhDV=j$z!n?;Q`EV=@sRGoBn% z%7`LC2m^&4xjAhUwWr^xu{M-PlzJb&nJ;AV(c^!@&%GBf?mc4`ez?eP4Uz@HX9yu#RRzsK-$bDfL^h&D34xD z4@)eB!AGo5D+~P+P9E>{&y_hy?KJTngVz6Q^YS||2#majJ=BI0eo%NJ*7Mp z9y?mwHl;du82&e(Ipdq+|H_t=mH5FH`G0%2lK*44d$8a0f44aP=Zzu}dWw$140jRM z4@k2a`I|ji4t2W^MJ|qd-VFbGmGbb zsr-#xN^M-16me8pfUl>RLH~1=^xt9$?{*Ee(f|Dl{ogq}==Hx}5B;yp@7Qny&?ip_ z*H*g+?EV@TxDF~Ksa^`4&9QnJ@F==uckJ(j{^yp{|MgYCZT7$2s{Z$2r?3C>MbLkp zQ@30NWwyKqN|oB%VAYWJ`b(taopG`IK~w#pR>yUIdiqvWhKZbGn*T8u+`vLd?i>Tn z>C*5i{2Ln4RB*T?T=2w-_;!N8Dn0w1V6JhSAX6EntWe48+I6UW<(0=;0@XBV+h(@i zy8Uf;Q}q7|^S^BGZ&&<34tBSD{m%{1|C`VMN`IA!e*=~8Bo}na>`LucO6bZK#xI;w z)Ybn1F@$PBhB>alQ#1puO#<5F|2+%;ci7AS*YX4R=XZ|ab;#I<#^P+2V6t_p8Wu-> zVHYC7R@A>%S1EoUMDSqYW|%i8%M+~m>_l;NZ|8siR~joR4Uor0kTa3`Jy96uh@hBF zg!Y^=!fybB5ugDXJ+SaARcVhtJM$B?ibrXHMTWF80+Y~9Qv`#yZMMhzdQUV>>PQuj z^nCaTx}#5>65cBc!+&Xfhsrq5-_3ohfkSm~-3AAD2a3SUy+`3X(DT3#>of` znp!F!(bMbavV4Fql0QlA&9cg>Th*WZ7ReU>_QQ9jj_*|4-0h|QZ;}5q>;KAMt}g%Y z!Tv#o{_h?3`G0SK|9c7q%&7my57w>!M!b~YN-Vhi&u+GdgT577b;vNhwxeFh=?#q&XC|f zkAe(N^5de-YpEtn?_&#qI92o7lu#eMAAWHDq%n?shGbG+lvAM2v=yc}pN8)*N zEV+~s6YD7sTyc1`NF(Q0;B({i_Zz%sA9TACbIPJ(n88lJ|J6SsI~3NFf>C_9LxrP8 zTOi1v`5}g$Z_eZ2f-rP9<7B$!NB7T*nzFU-7!tO>Ax~6@c zx#(5*USM0%EBxzyn%4VKmciuTfB4|wZ}ck^zz?_fAMQN_-nF}}x`yoz zynn(@fCJ&5i?g#ZJ!Vq*3+N}EJwx}qzfc1@4*hgIp}nX-GhK5N8p+8CKKP z^|38iyLXk9Ip@g1-gI3$f`ei}$HhH00AApK^Zp&P9ukVP>4lr>T#M*X#ua4pQz)&@ z*P^^M1aJmkARwT$G#@W=^_}!gm?c^6A=`q*67fuZQAQU1hqT`mC%IvLkmY%9e$SG4 z^B!Si&my2B`}i-*u#eHEAc*nLkKc9Xg}bW%FJ`cQ;-4!j0QK_!!LH^1wX+WgYA65S z!u?MOa>i3Q`|%F2r!?UnpE*FpDLj|&^&Gqcf<;OCZ|CTY&j!)yC@zfDc1HrPA)Sq%CSet;1?i3{ICE1Kj}DyBLUv<-I6z3 zO!EkiC6A!hydR$Y{NIStQ*9V)bsl1CSSRxL_hC3E;cSM2RJM%Avi~OuF#nuGWiXIM zgnNxd&R?#c`v`KB7|ViYS7g*BaSUT}`Z=!I=DkxPjrEE=u0^e)29eWMuU=G&)oBTa z`x)+sqSC&sfx>Fi1;+!8?ZB9sD85MEV`kg@ zL!X<$fvR&_j!Lc-Usk|gfyQIps8YP8VCoAsg*|v6ZV1qiJXW(WC1*sOz&nHlWX@^m z!+zRC#|v!*QD9*y3!N{b_$;|6d+`JYC^rBKxY-zlo`5BCNnS$wgYA^yJT6Hnr|iLn z$qYY;`9?>UCXoksKi&yZUodb`22jOG&QUluVm7y5=)cSt^joH!vQI}Dss~}5EY2q^ z9pOyzO6!{vq|0Q6LNqMJvhtEe<2D0NXy@9q?}T(0U0{{NpC3xYB9lT zFR)cnO&)HeOln*+K~73|o8!fD8qr|jv_;|062DGQPvx)o@8jmAASqI>_-V=qGSlCm z@~OwEmoe(;-G&r>!w){n$fOUPB}umNTMsK8t9xxwK#z(Vcnkxt^85SS8@-}9E)S?J zupJZlX5^Cf7UQ!~4<6V-VDl$5{LOSaPDQpf_Sy zs0px+tvI*}N*n{LMv{@0;PxwXwo)Kts`kCbJwR=d72!Fs6uszCATTm3VAVkq5`RFR zzf>Gw5g(q&m_B{MY3%jBA*l*BQXEBTauEd_{7Ip^l-k8l&lfW-Vp|HTltf3MeY59Tlq!t~cDyxi2EYn6P2nZOhC&vLzCS{y7eXF^}l*euqLq4qC;XC6~R z_D!SWT1w?j6^R7!C%DAEf3_!+C*=*AVIaxFN}>Yw<*5nO!WHh?AuCnC7F~c zgO3nFY9?v(Zjc=sm@+qzupy)C=8;))5whV<9+~QtQ8rWjcGKVk@&FX4=WrNhh38Xc z5xGYy3eZ{iA%ZhHgfph15Xb+%#(h;?&2%XWbe;&eXrTYy1Iz#C;e!Vq{?q3`|NjyjqXh@h zKqpHv9BFt465Np9%3O&uRU-ibb)ks2NdE#u{KowM4t5^c`F|fg=={HLf&QN;Oi#^f zZvcIk?hEKf_ywgT)4nLDDsz2gAcAN~%iLw3Fr2326Afu|&7hMb#M;zqme`x67v>LuA1MckkLVRdLbPcK1) zL6eG|=wI@T54dRA-vF&elf?WQuZkkFi-qLgY1F1R(?HdrhwNuLClsEl+A;}Xrp>%L zGPTad)MWPD=n#I+8PZpFps&6?=8en~8{0WHwd)6E60zJhmy*BVOcmihWMm>nJE9)l2zC#I>vzqb3}B<#mlekG3*D4o1m` z{#o*2iMfU8?q=dow?=7l2^HNJ|Mn;OZ2GsxFC}BM^2K=N2Ok}{p5+k?qrglLuaFPJ z0^n5=Q+YYHILY#rx+}k|t6iIf>WXTHeAm%1;lF<*$xI!%#>s!^I{AwO{IGn0dpz%lni$vV z>R*ojpWPJx&-VV#LkIp(7yow~{(rZO|DaS`TgR?dg|l|La5D~ss&EA)h(cNZ44GXk z`nMAVUMK$Vu7&@F_`lm7{og73za6uSnMr@(#H1R%I&zk}=@vJYP}om!OEr_QGf(Au z#;tPWg`D-PpGL_d1KJN|c#j;Cz|}V_8rEpwynYlqvCz5E6=RjZ~E+Y-}?xok=lYPJB>LO_fWLW=~$qwA$t^= zgLR{l*%vd1lG~^ogr>>QT|>25xJ%R0{j7cduWSiw!hhO+Xr2ED2fN+*|8?4b%p0caW8;=O)3)&&&}W1ux~?)~e%@&^ck=vS#|^Z}|MOtq zlK*$Q{J&qb{NKX1*L1dKD;=)wrG8QS8Zy5;gYOi7Xixv*n7nrS-`&}@_5Ypy&j0fZ zm;Z0eelKLZmh3_7`YQ?FqQz?4ePsZxF4lfUR{NDDPZ1vi>!c03{3D5k6T%|Hsk!I^O;((*N$x zgNGLW)Bbjs|NE2D|DWEE$Io8u6!hRPN_~JiVmOCz?1g@|WUzcc5O5ld4zS2D9YB%p zK?2?XBVXi68i6b&ks2BLtfODJwqz{@XDA z_Hn=8e{>(8J>KA!u_z*tynXX?RZTCVX}J0A{R=<6e|dRHU*FHtF>u%Z{U{E?4}@s( zZO9XV5}b>u=NP=C`;8umn)mx2|qiBn063t4N21tN8rG zc)AEMN{mHJi3V6x_H_#C#|Qfp9pFFBp zd9R)<^2x5uNG2ZQreAU{hCDn^<;K>~pY<$KqGu&J+s-I;j2WenW|&OrD}_yclzW#6 z0@REMQYMQ~{X;Z!SObJEhw(twsCH6RAgMA&4c9ch0wi0kK4zLwoB)P>5yn&({EAt_ zV#nkZWX283nYlL*mD*Dyw&UdlR4LxmSqvv}Y}^bQ9NJduQC5R{YL%1jT5%nqWAJvIC?Zq!eqP1eEk1KZ%Wj7WrsI|g8G5kW{!Xf3$ygvFD#bS%Y zTO~~3lie3~9^~{gr4XfX!HkS#Wx@L0yLFKgjlDpOEc`r*k%c>ZL0bR;{!LlJO^RZj zT>~%H8_zB7KwCnj%|Q}Q1@)0p>ZP(wh2o2l6BL%|gk}d8GQiB2_($K)2LhixrDF6e zPIYBz#=|?J7U}oexv|Gm%nXiTQ@5S<3`)2uOklHj4DMUhQH>pO4Ki^q3N)!|N zD?a{YGwN#t0;xWutSZ!APaqh^LG6SWAaS9rs_$BpSX+~dass5WqKsn(?Rr>1Gv-ti z+Tbg(*p;(^>B^>(ov6ev%tgpS9yE>9e}8^*TI46K*@$8+vY!6xb7#znT~8$=b2QmF zH)u5gxmI`U?LR$=7L$a1ZjPr@!k)Z#CFBY9iOl z{g8(rp1=X#Zp=_Pca{DG0H3@LwCX6X4DwhHP%+E2Q3AUS_%vtuD zCa0DrDqC)x8y=r?W{@DvdFkt~eN6etb`C!XIJ8D#qZF8U2yDo;C{DsRgi4@Acu{|v zC3=hwDPpM~MDTQx=dPT*#?+hrtdNRsejO^NtHnCJnj4VEWir*LqVK)YCx#GcToVtI z016(-pixRaqXMH(OkxA zoVHV~lBA!@YfLGkQ|?I+%j4pRm2wBM5r#~La}|weuU{RX$m6x{bj{_}uGr2YzRT&1 zh9{z1IJdgws_A~vaGC;f(e?Q|F3(cWZ>=U)rJTxe7E$PAdy+NFZ$bnLzQCNB+A@m` zNy;rI=}u=oF%Q1ze8u3g=yOTQFb9&V3%n-Brji%yWdWCGNn3F#-rxF$EX2^& zW-Ar5@mhV~V1dE$Hk>f!DbYWv;&zQB^8zZdy7tdSH04~Ka{XjLAk*i!xPQLY*bJBA zg^h%m9qY*%-CG+2GyP1|S~jOiUL|wDBVsvv5y(%S$ zFSoWl(AVRfeHPHx9z;2Lf6#Z$3XPhN@Em%YXF{serfo{K zCv8J^Z^IL$#tUAuIJBBF`sP*oY989M)l)?M!=d}$1dawZ7pM`SO>-%imF?((D4=4- z8TK9|uyDM{F{kxBnqyLMuKg@QIRU;JExm&W-X#3s2jMuHA$q-p%C~kc3C7ap|KBjT zD=me%uL}!qM7#3e{!PEo;JY6jQzq9FPYFNQ(hi96g=n*kMZ@Iv} zA+A=;306jTwL%6m8gsJ*;cy4-_pE-ziAd?{XIx~($v6*5RwNqk{1z(O{nqW z#UCw7#u93fjF~~6rT)2)Gkk3-V$Dh#c&FIM(~6mas%V&YmHPhC6osNMHBxMHW=THl z%@9m=@Dy4^@h7Vk&8*J%4eE?CQ&-h5yt0~kk(bE$yR5lR=FsbHDcZ?uYixjY-7i2= z`z3W8lk*ZU8KIHuB6+V|7}&-^mzopUoue>})hQu!o#0EXVHC<&UdY*MgbRbZ%O%xc zy84pY5xodrfDTr6Iygll0X9m#k@}mu_7s)$WG&U+2c&RoMzAOdrxa+tp@i`6EE2sYTBjb;4{8?Nu zc}uc#FnmkQ;{y6>oz@E8P=~SBFnOOa@Za5m8w~yz2@0+ZvQWV?25x545d1|+^`5*w z0!8%5N{S}PQR$Z;+Aq>_+JwwbjK<#$ffH3EM{Ln(vGp69f9{Vb*7xLVHSsSnciBef zC6}>lm)U(+@38xa>-WDPrt9y2u}SUzt9@9}|D!W;jpdIiNuif<4BnUm>9U@O8DNFa zscKM`jRFr{()vX$WD$J&_W0!0FI&%FK70M@=;g^4UQwMY%}T2f&Z>C=CmNYOxF(st zl3R#^!^+UQEA@QtXW3N$PrJ79T?K>V6%wKd&^~VP2C)C&Y#(+w*LWSw1 z#x&K+`jD+*erOR9>}Y6}s9=|=;*&C@Rq1~n6rcwDpMwXE{EuD!ug}8%dy5v(dT@YG zU_5PLJMD0WoYZx7v!?|)w7%W53|3TSZo3*xk!4-2txnEU4aU;lu&Z7#6zS(^8nbYb zuHV9B8L`XrSv`WU9!+V@^M54;ph^DUv+#d*_V>H{->(t>$8~@K-Z z@o5`c7L~0pPK&l0#Xb_MW!D`SplVcRy|;v;`Gc8l-sruAO;Fj|`EiZ>M;^v3`;Df_ zIfBffM}0O^ANrm;%6YDP1`l1zH`*%tb|}D1mcEO3A$2} z16!(5Se)UoY0iu9^Ar_CEd-*;-Tg-9uvQs<>gp!4N&l!U%6ESt@Cpt~i zQSyPKzG$Dy2vhCyV;YT8KVA07Zxo$+^_Pf{JeJ#C^rfa!syMT7m#VAy(N)9mFqVwQQdJRrCZ>S!KwxHZ>aAL_smmmNPuIS2 z5_6CTebD2DkiaGw5jC6VOLn@h=*>{HIrydk!TQU4_nYzOpW0utyE<@1(RHI0{;|Po z&59(yYg3n#TFvS-O44R@0z?~9)Qs;vefH8(wMAO;=cD{n{PM9%Ba$2j6{7iKG>yj7 zrQ`}hnc)oaJEuc{Q5RxyEm90Vgt{&wMz<2~*J^9{!7Kv0djhl>&5%sg8;r-E`imG8 zPG5QZj>6oRQ-nqdU}uVU3#?wznB!ivwvXr&9tB~Fp61+AnJ+@!_`HMv?SAf@{GY9* z05swM?(bOg|3R1k>#NoO<$+hB8Z>GK*$S#bOYL6PysB2O^oKjk7TeMP)j)u2>3?tU zz^4EGhx;A=?=8^(6B*&JE9NTf-zIDnqK;ULIRROkq$TZ3(l>;bGt6ZHXDyYV*MC+n z?kI(^X34_cfOuEeNV1rlc8W1Su}hM#S(v_tXa4j!%yWvM);<&khI1-0%tVpOnp_{- zrJp62@ibvwUjHJ{pIcu&pZU?$H76mysF{%G=%w~N#t2~JGkiP@`MLGci_~8Pz#(&H znEHoj_-Z&W-r1)|be6+f8<)lB@C*TcgDV_1KakGz+9wyie}}d6tD2qhCd9wYZ|KRo$9(A{Z2%7HGR9X) zT6!f_U)x`u_#ce9$nkHxl$e>)O3Ddyui;7R$C+60<8s?jS%OdtB< zx$~o=_#(>va$EFWRJ?M2TK>Q;CAOYkP;9eS4q;i7M_7$XxP`#Cz75zm{?b9iRtCJ- zCjm(}&hkMt-~-D3oTiU$eY{$QFNIYVPxXM8z^;lmBH9$rqVq*6Okx#P@unT{X11#m zv|3k#ByKCyS9Tcar zT@{`}9-Tt12CN-ggW^=H>R|!5RM%5YI2&lFWItv;YjLK2F zU~-66(0W4}jB#M_PwiqvH-9?oF^`R=n;Xt6!E`4HzjoJ~Y;|C8U%PtaAdzOdnprjv zo`HEl+0~Pn;p@_cO5SzKDJvITh<&{qN!tV32m-j8xGxXU@MDuD?%_= z?rrV)olB%2*h+xrd8zRNPl~j4Ex2Xifm3v@piOxvxdx5eivGZ9AaF3vl2@kV_Oy!a zyL>hs!lm7&xbc$9DYZLA05#KGr5Fy}DrM33Q?XAts?j*nHZmoccx)eV3M7{8U{GOq zC>kXQR!-=F&|O)`xf;9xmUU^IS5n*}+`BUwd|9`n>vYROjee?KrU$`Ro@~+H!>dUN zIeDD>aRB0x2YV)FVR;$)DPlE6)2Z&EKvEE}oeL5rXj5=W^ag-l{Hf~#)dlr?%N05` zOX7Ueu2-UHi*D&9+w|*6aDnNG)|)I}eB6H4Twko&%@w9kwc36jou6<|D_yB!qelXk z%g5)^U}=0HinCr2uQlK7?vOq)Tr{`?1Oo+@LRKaaLD*h-`1gPFK&;!n3m zX>tkY_kHm%CFlBEOsI1z#TINmQ z7;ldB(9h7Dg+5&ZSDlqwugdYu>*srmIQq|p<^%vd zDoAFC@29d<;pFv{*udU1Li8Z-5sa;-)L-cACAG5SY*uoTH>Ni>%& z(7QnH8*G?g;Ifs*#4j9~hqajR%Sjkh&xnZNDPp2m^^S&-6<_zXwGgd&Gx(C+Vf0=b z!Q5#$1IbSH&gqvR+)AkWB!=A{md*=q)9Ik~&!s1>4mH<|j0`%(X24r1=@m6cz`8U% z10@HQIYR71eB5bBShl`52d!>GP8CP6exV=GzzMAnXTvYR2rO&|DSP5#M)4x7a!f1u z1S=eV5TvM68vDI(jLq;qB7jH2=oBBSZ7D-^s2`cyiQMHSt`mGVq*jYzQC0y2t)vy5 z<`Kdk8a)G1jxiJpaP`rWa6e}=Ur&odJ8U!_4}rGjY;a8x!=0Aal-}7>^fnVxl-jY3 zQ;=vQ38FJtM24P(sSv6gV#^mZ0g_Q^hKnjwy$giY=mTfb^*}Xv)#+mPDhO@Dc`FTs z1ws-eo)uzriqvK@fk|#KF3xPnNghU11R(`RGeWq@WFBdZ&N({OP1gcc!9h5BOrbKk z*B5hc?b*xYLWdwY2qlNxo6H2P!Xe7!o%cas*dn#E79cyWLj$42r z(QjsAxCO_Y7+pO&e&y}$92{)zZ28mq#NXO2rid|PaSoRHNdSGFCSzeoyrIsEX5A}_ ztxv=6C`w@Wl(~q-%X_LjlPG}Bh`NVdcLNYlsbe>P)8}z3pF8p5%?rl`uV(!TEl*J;-fxJM0&e~cv z^10kn#U2v1xZL##zC0;!+w(-|JjiUclyF8dWy{hw>v>WgtS}c+X`s$1W$Q6z1hvB9 z2T;Ev1c~pd6%bQH=U3vLBQ#U-0n8G@HASfom_-*2WWqtMnq(CDffgnqEuPDH*h2P! zf5~A66@ZZI#RG>eU4p@nN&7fIw!FH;QTHG03I^Kll5X;(!tbWC@q{ z`Ri$T?gP1Ez%^DRlCE;rXEL^kDg|Vk)jciJqmqpwt0*cgvZq(^Zd_Kf{uV{sNU3Cs zxLx9Lbzh66Da&COT#vCq~eCHdJ*qi)4IEh7_y`@>iU1 z;oXO?S*J;Ekxmh$GW*N}yi+)r;agC|q@}dbfW-ayP}DyZMTfFvr3x!0dKAU8;+~zw zkTLs{qi;sWvKDEvSwsnUG&3w72QuSc;r_wuEXp#HnaNNi50mqx>bM-UbuA;S_B1*R zv$+py#eWDM3;iaL4Qyo_t9c)Wb0O8Tz$PrkdQ{Vcz1{6?)Nd0s+HLOadJ||WyT^L( z%>NM07BfyKh=*S^3(fC$_x}&0f`>%~65?|{ABs*7@%w>5Ds|YK0>mes6?qwnre)lx zWJ}VRR9L*KH7FZbM0{N(Ng3Fh$TaZ}SW3EKC;rCiC-czk6z4W24hgH2lCfx#CX4e4 z=RQneRi=3;ybb&q*Lo=pgc~Uf_`>c1wCukR`N%xe0vc837UUD!o+P7{Onm|;&={#5 z#OhHvHLhq0U=v@#97wA(KMR(iUGp*9LnVjQOujN^B&$NStvf&G$ev} zm6=xLw!_3NAQI`8S|&eEHEDl|-{SFa+3smmcS#Lfp@6f;J|k zDdTcNq|S8(8;U;4_S|xp4{Ma+oEw0@4x=MmXL&*s76m+%1^ldhXM$bAHxoXHk$&OC z5Q$M`Gld`%Qz+k%_&RwDE!D~62)-!B`c2tv925w+}gY++yD^f6$3n@&5YQE+)lczDQ{Ln=w+P5TT+am>)QV)?>@9K3F!cD zi+~;B4Xo)=pfrA&rj7Si1Gz_V_7^o`7;0VctumcOn7HX8oF;Sf^I(}j;y}CSr{6O(4R*`R>SqDpi>ope*DhS`0*^CvqqvdF0T;us$ASx-W%x8 z@S?%^4%%zz13L;mW6pFGSltmU&)Av7`}B602O2FCFEsi~JW+q5(ZcX|SYNaf3g1-e zec@`|{7~FmCaJk65vzl>g`t2kFGF1Dl^|67*q@^=fxaVV=L;+Y{gV}oLy<)sv@Ly+ zL^Wlls|x(@R^vajD+Pcy#D70{SjK&XANz1_us-!1$%2MI1lzi1odZ8~irN5@Xu=n!M>9Q{jm z?%Ei@8uY)r|FEO~j{du!J8}N!2|QTi;BQC&K=l^>(}RPK{yziyKf#UBityDI>L~s* zJpZr80M?-YhYvdZ=Z^lnpF45>+cCx0DF5#`@E<$*|L)QM+J-t8Y*Q1va3VRaf!|Xb z_r6X_q>8Z7qmp~?MrK|ls!KeM6paIN@hDIOl$%Y8QEr4XfFSCN(DP^L-IO~~iB~eCEtY?d<3~?t1o0*s3)w7Ro)p#vS?=>F?S?8$Np#b2J_WWzzjMgBRlY0)ljtA*Ct#v zIg|{uBEB`ksLuFz;S$5q7g+hXqb1(t%P^I1VM3SeBTqp+#d+p)B7$+xV)m0#L4!g@Sejdkgnw(=c@{R0$G#^H1 z!|(&_rc6+rENedBXtNn*WSHm<`IFH(C7v_$;`xvfR_J?({#xE92TO@%_eTkbyyD#6 zqfIGLCFK4o?MAr_6k37f!~OLwj!;gl^iQHmMe6ug!1f7NCF%ZKwanx{M!Wkd`6vAy zZ%^@;y@zstqqkGKDD7}O?s!8ApU|T7lC?)NBLU1DFRe_M9Y_`~8$G2kQq^#ePE?(a zj0Vt^6y%A7V=#R^R@&MJVxTrPJV${~MU!6(*8!5IXz+qlBX*uAysZW6iADId;b2xU zAsL{p^K;=PMaS60pU*>quVp$>O3yF@pslongfE^5yWidJ0Ve}qw!6&(5aA<)5fBH( zIT<5cDz&B$G1Fooc(nY0zU0T`6nPP<@%O!B1lyphcJ>9UgEsdYd!p8wTB5{f2^=ue z2MmtZC`RYdYDV};j~eHCmln9R{#EPkT43Sap5-dtq+gc3`Yc8i+!;B#k}!MFGjxrP zM3AMNKhbR&*OKYNjhbT)g0Gut5rqJ(?&j zckINc17#F~K#FI+)Hh}zkD&YWJ)3BJOXL0#kocM-4 z_4faVJKJ{tm%Y6Qo&E3A+y7S1{~%9XJ5j;-I(zTgL6&1`Fb;Md-Ls; zt+tNLo5dC_f*1^2<|^pe>)3!re6ig6my<-{JlFR|kwyX9sf`bh7TY{oSD!@=gEH+j zz<@V5(Fz1yr#1xyzEa)AejT_rdC}A>klwjkiaZ8UQ@|vmpo6&6h<9b1;$){_KPM9C zjxvjv7uXn=7TZ_^N0 zq%h;`23hw-A@^JdDMWE!Cxq(ckL zI`;@~Z0T(xkn6qTMnEEuc>VnuQ^#dQHz}sYK-sk`@^lJg70uU~V~p@AD%6||GiIY! zkM$)saLr)kL{U;>0);#fKy61tk)poBvV^QyTGo9O+u0N?mx++^Mb*xp`|is-=>9Ci zr4VLZVRe?Bqk9N4NREVE-_U>f<^Ut#E%pQx1R9y98M1jdFjcu8Y@NA??k>m6*0Tib zmaeQx9=TQrO$B^4DYf!|VHM<3sU5~Ps=%;ei8*3>D2Ih|aIVy~18M23Z^5%w6nWt>sGq|;P34s_(!DmjNmz|U-hJxl}g1O~S;?{S2EiAyLLPoJVl zrQN|8ybL&`y%3?*E@Qk*arq<}3|SSDSpti2sUvk2@Qwm%N0}Ddgr7P$L6nKk`uGx& zuYCj!HuoE0l&RhD+F!ngBjfo8v`x{)HChFt0L@geD5+upFrZhdg(0;-@yefL09CK(2u3fs{uf+fJ ziUy#1`wzU@we$b(bn#!e=Klr!&tcfXD~b=FtyQP9*L-4oO=lnJ>?60Xx7t!Sc$c=}(#Z$R@1rJwNXOo8{sD{eoY@MR0;8GHNYNcy(A+f!-tgc*sW zmM|BG$kmB?7tl~dp@|b%;&c`Uk&kA+jm+bvmwACP-VR#KRJN1fF*kL*0A(Z^V=9Nj zmZy)*oq^mv3Vn@ksqeTOD|4oIflS@cT|57;1peN5{y*5=wc@|_A8dE>|6M-+U;22F zas)HUIM0>m3G}mk#ug`1Ru(9% zu@CIovK!&0@${w9JW;~*02i#l-Zg9fh(%y*(L#BsDM6VmVl+JAZz4~& z06saFk12!ohS?pN$=e*@%+E2Pn|(O4yo_6*($4X>FbS&re8sQc)C{0DnYT!UzDceF zluZ)vEq%_t$>z!g+cPqPaTX|nGEfYjr%-<4 zKxbQIdR#uWFqFlCE_|roPyI5+Pvf-EhAU=S5_mN?# z3kkQUU>8cc&-pIepr6!8?2So%xlm;W!BT$F@B`t0Ab3t0JBGP=P++SNhz^t-stm8h z!-L91g>vq4W6~6_MzM@0U}yV(@6jN4whJ;MKMp(HTc=)hKWoVUS4{uZnE&bEfhGTU z_|IRf{lA^3qMGSncwC7*rt5Hmdivjau($2NfA8?0@3Q{iQhgVD z=NQvXYjiEQ6o_gSI=d*rIVu}S-Q1w-sq#j9*Q(XaFa{i}@_j`CPQDOyWvKVY1PzRN zY|yWRuyCM|Ij*ak(#lq(Cyp4SuT;Sz^$lNZl1lY#+M@p7vnpM#6GJ~g{tv5tBlutY z5BK+M{I8u({<{tN&rkECcsyMMp(9|Ck|js{x;kPJ>!|v;`XiBX-1VV&RsHdE#0_+O z$#{a5pREwO%K6G)U4&^G1%?$`<}x29@}>3p8wNCVbWlJYR(El=V^*A&j)S&18Y_=l zv~9FIXMqu1>5zq%t_6ULpp&g|O8vk!qf3nqI5769hGR@Htt(Vp+GGQBH|hgr{LB@q zwzkKhyqC1u5LB|#j98R4un18Pz~!Cpsh!@U2?u!$Y~IWG(HRHCfDRjmogZS(s0ffQ;kq8c;g7=wgGt zYv{_2jQO_aqX3cx6>P$3lR|sbC1c-Zi#Z-vnfL7Zizjb?KDnpea0OwDZfFWlzq@;&zsGD>`H8LIs2Xf1GNpvNTdEt?qHU^uST%=NR{Oa0ml46}WOau%=ZeLg4y(@8GBY`>INeR^KXeKh#$j-1 z%Qn?2?MnLJO~wE1Ir6`D{y$%%{a;f?-1fpI9VTn9#I(2{(CS^~nm|`{?zkzbnf{|$ z_(u|7s-7UPWY9ZVCAN2pjKII zJ$r-vx)2$D^;1fXH3tbTJR|=c*Y#&)(L_VddfociEp?}K-@y{M_|&Mc zQiz8IeD@pw`tj@YLTTpz8Yai@uqhDELu{J1Cqh&F=YbXfz5Af!|6h>&rva|~$Xn<+ zIpMjn5cOTQTt$|&j~QpX?yykv;Hlp9!sW46Y^-YbF@M`2MHX_Td)ls*KdnvwE5v~| z#DDJX?pgG|)7}5w2K{S0?&svZfO09Z&oiLor8w{ND4&>SQw2B|9$G3Ow(ILHb9*+r{N65{ShTNCvg@=`U+wBE~6~e0Tmg2 zj)EQ7*bZVpH?awlIR*5D={-|eW}~qNL`P;)d)O=3bX(bV#bz;Vuw`U8*lHydH+`>l z9^^N7{=>`l`G04x!+-k{{6E`^6Sc=VeEf{IU4yyExmDM*9XT2| zomSE-fj5+n)(Y5&7UyfF@rlx?s|3NCxv2=0Bn0D3;J0EgNbJGezcUTs_LKrm!yw8} zwTp22a>${QHu3_Tcp+X!(piJxtjR3&-bXQ=;b`L$=9rNTM^h(9sV`I!!ntZqi>fOw z7-^}p!q32u&vj1~tQyW!vY#=Yw019QTv~n|XUUrUf2G@iCi~BxrT^{hZ+HCvYrOw+ z@%+kTLu2r*PLFJz3<>^h}Zg{|QHxHf%H zD?3#S8i8+fzvc3q3*3jxDP{ z6Y@WM8cN|`n>=H_q%PtIvxsu;OrE?xva}Jd1zx1A5kq0!;|K7olrT=g5b@#uwLH`(rVa9B( zLd>-^siLh~)1?*`SD>nXvGJQugY=yK;OF8BiJ#LS_`JIvYNr2E{*S9OfLi+B z+1}Z+>3{cOhyQVF_dhq1{}+)dvl3KzcB4GwN(#3fEy@FsXwk?TEv)TKU~Fe?(%@P( zROru@@ubRApp;b;U4ir5CuBrbC+bc@xzoHWCVm`DB?dOk@&$$ps(3u5DM3rGUmc&2 z3xBFvw{;FI4=&9?%KuK+C#%LDAIh&jSH%#}k6^}x>* z#v$SblAeD?sD(2aT7=ID^Hue(q=^r!(N51JSS;?D9nk6MW~l+r0a;yrhAvBM)=g>o zs;eg7oOrob)#BTV_*crUIYp35SS(o;lngQIwW3Dxe5Ya>!f_G@s!qL&?dsjF0W+2U z>Xn0a;*V04>t#ZDQh`^6X%Qz%7_OP5=C^T#b9; z;J&MoD2q2>$QOPzMc=BPLf0f;e1ZLnD{qa3y5=5?28LQmWTo2plVNoju!Q+srP5m1 z-1#Jl+jnnb1unQ)Ntt_HGcPGKxAmEc-O+LrS79g3wO@guG*`X?OHq|o(0+Nw+cT9_ zYhH(~6eIou_=+0LYK*0MJFLZ8+U&Bn%%w#atJ#Y)<%tf7psq+z!t0@kgiTNUjD1nF zc{nzM=Jkl#YV-$%fFQ%_1kkn7_9(<*EixU8pc)4u!L<`<#txoYqd=<=59%mhB5P#J*(jOz)OFN<>3RR(|I_pS*Z=r`dtR82 z?K=5`F9Zt1og@V~FZ(Rg{di&qOLr4Dao&EjJ{`cwae^1zFfC07( zTb;6Rt0;{jw`QqU8-Br&NMtd|*410cRorB)#JqJRA~Ek|WWSbac_n%V*aT*HGhgW;gI_66vGFfHZrn zL}&R^KMkIOL}FfppTnCWh*1GaE6zwvoFK7K))a|l%C2(neshuC)zR9`wM7nAQJTiA zb{?~9%SEm`GPb?8xaw_1Aqk?L-UEf4635`~5|9|$DX!l+(Ec0HuDnjvb5l{PYP{mg z#25mzf%uE}Y14Ce}Tm+W28W+Hn%m#)4SFsAT2B_AHlMNH^ z7G9(6Rz)3(1LN$hU-$LfEQ?Hol60jh^=6Duc%b;2S zYJinyV_ONZ07Lh!3~(wrUy0FN5~Il}7*u;KQ(32rSmjt0IS3`L@Hw0z6x4qE3>oh0u)Li!l-$+RB&6Lh`ba z6nfY9{zE{Q(On#w%9g7CGrXfA=-W69wbb5$pZi0Yf-^L#Ib8|JN|!j6Ae&$+PB9S* z8ciCPCH8M9f>wotLq-P9zaMPx5bDLoctgGy7CoGZ*FU`Wg76}oBFb7;06plNF{r#m z(Xogf{ni1A35#N!%$G*DH!`k+=m`#FH9$wmL|cqv!{tQ3ylhvy^8aYMw$xosgS8h6=UX~;WZZ?p_xc=OL>Op zRC!;r81a3C^ghp*Jp?+!b7E>Y?`Oi@L`b=%GfFrPj$ufc4;b}I5f4{fE^%uE0p5dY zf{R~S?}hobo`r$-2&6G!hUTLMY>71b!*~b^eo(4Rc1JIjCa`yB_IJax)L#U{G`xty zOYL(@}NAX!gf9fqb{&^VZPX79ZAcQrdgDFQRzJ_kz z(@&31?*DRhQg9HC44eX`rFYrH|afoqwYxoo%&bL-b8@paba z&br)LmpkinXI<{B%bj((vo3em<<7eNrCOIi&*+_XjaOalPZ$3KJozTEw4T5-%5yoYr_3~2E1@3`~OYl|F-FW|KVOo{~i5z^nV-lk8AmI zF`kA=%#YSj{oUgJ52)Uv|9$wSqyJCwgZhV9YleC8Wm^2cfG!8*;M552&q4zyr z5hZExh!u~Xw}{`z$z=>g@(tAYjaOAA-dq5E_Mrq8`UhT7P4XOw>i+!?RJ8wl)=$#& z`$00!?w>C}was`7lIqx>cH5 zDapPROU06KWRx~4q1^l4Q$I!{%_(Y|r|{buMhQkaS>k;(8AEdk<$l6vL8zN=a6JZM zjS790uJO<&uktmCTd7rgpraMmc7%I^39T}8o=Ee^pYjYoF7@d}k`mCqu|Qe#x?{s+ zhm$MF7N5di$`uX7;&A$LzG*F$_t5Nud*Sp97VT8f(zT@LbN6TK213bR9oG89sY*@?_&X#~$@QnuXsy zfAQw|@edp2=g*%Vou~>*JF8Um?aODctnXhuKY41``t147&rhCPkB{H}^A~8&Yh1;5 zH2L`Gx6RepPko%-Q#;|#GFx*G5JK5C@J60@VPU0Pa+D@H^AtZ6!yK3lSvK(4`>(KU zHXVv&ryrg5j~3Z-z502_*3|u{hn3?P!W_5A`GzchV=a*hboG{)l89Tm8TNPUbcPJt z>vo1-TxW0ST)JX!+Bdrq1=H}x_7zqRZOD`Q(+o*A`=^#}W@C)b5zzkCmza0o)w=Vi zNBx0*5!a%A-L;-Y@m=fNMi8a>@>&-0Ds<|aH0s$kFXv75@p>2b>b=}h813sH2J6g? zZ1#%W!8nbsqc_*Z9B!~ShHH~2TvK*EoZ*vn@mg24T_?Zm?uI`P`|q2@ z3{qtgG{`_oc3Rdset|#Brz!PLnHn{Jtkk* zf#N^v`6La`Ob?om(oLke%AwX(gWtDm5W_33)ZX#LPs2wi$}*s}FMl=cqHm7KMNZl* zGS5FdBR4L#NJN>(j#9$xrg|g{bcYyN!H=G#slOD)^T*_>BN~t{cwA9XjJn^kTWDSdJF^&^`N`(@qaFWVaqTE| zLk-eJ*rS*V5#t$AlmKV0Bd#TbK;SULa1wRtEdDft=2os0GnnKF{)U3n7D`Tiydie* zD2h(u>dIZ>ba(l3${C%c3|11!te!rZ&qF^&uX*eTUKhx45vproFjQE&t*t32a9bH1 z@8Q;L!<=ICZC3FX?EtBt!&%};(`8+W+TIo=vc?jXgPNz&%ukmvdDA3qD1%m-Rt2d{{W4H$s#cZC z9o<}Vlmsp6qif!_#dsujyG}1xH)0IC*#cSOe3I8}F;Gn$z54jr@Lr*yW6WGdz8``u zAcG*T(D!}-f{zm~B)yR%)I)jBdT);eL1Rj!qLGinsS4x1QVcJlz-?b(4rA032XZTi z56e69srHQ&x1O7EnWemG7?wO9D}m1QtUyf8Y>Htrxi^Q;FM+sZIB6Q5FQ$I#Wzl)O z6~#R=JtisasiG*QtxI6yNrI#hAMv$M!P5v^kX(eR*`dyXVX#9J&Hy|H~|^w+@pYhK7h}|I84#C z#P{G34U$<=nTl!^Tb{h_;GjS$ptSqyI%h^YiyrQ58(r*qQY3TJ)klYK^D!cf!OG&E zg07Ckq3q2NVUz^w}b`(o_> zY*M6~pY;tv4e=j4+XrR)&%wc77yt1o?f)2mjG7Dl7uc7!>Wb+3FA+?d#6anbF>r^? zdmXiZVf1gte=?*cNo6;Z|80BMVgG%&L;rU4|B2(jS_f*i%acVqOHl~7k~4q{%ROPi zzczeJ+ly;qu@&vu;AU928`zAx%^zPaM^Xi**b`^gUZXz(kSUf30m6bkiRL1!G6;n4 zQGFu)t?;n!@x33fiXW2!D?^Ymy3LdTT)!_+SYLo38;!k41DvAycINzb_t~6`Tk14* z!rf~ZNZ8DOFMt=g_qtBbPn3p$(}9Roe(udc;Ldcsq+BHnSJf;Df{$V~a)P=#r^!g_ zz{sL(C>kG9J#{!=cNl%5lL)@V^FO?)_;36Cf3Vlx|K7s+f7|ijnjm0`4ce(+BRz!e z<%h62{#&nih4^n>$hiA_upRwJ@kNyT>q0;`$o~iX<@oR2?d^{KzcTs%NNuqeG+gXQ zor?dog#Dt@@2bW5ihQOFij0}-Hpmse=z@4EFRBTp7zm!glZ}Gnsa}vHd+i$OsafzM zc^}#Z>8W-(UQ#E>$&fCm5w13iaul0?HU)I@kx@EEgm>OBO%y|HNzoSknbrUymabW| z3$s+Kn$78J*6qX%)hgf27NdJXGD8sMHJjkCYuYHTRSboWS|}=3wc1dzB{^NITHUR* zs@Xz_t*+RZ^x8_BX4piOEU2~TogyOgDWzNyS9X0QMNSwgFh@>f-ZW*Vt3ukh`W4w4(o;#D4-wfA4`E|MT#mqyJA& z|EuPIdBzl9)&>j{=K9>=wV!40!=>Jrxp?GONV2j9fXL#3YGB?=3 z*oSu4Sen-sT~#bHUzGc(?}9Q5Z^{ls>#wJcsFCr%bA2gNK~xLy&aVvrBat>El3?qZ zynv{>f2f%1ngk4@+4%(Xh?H{S&_mZ}P(MbIkZdeGs)gI%LU=a{jQ~TBK^gE6RsIZ9 zp-?6iJrfSA1%ZdRa7D}h*;zD2PsU+IKAvK?qsJGn;Cbp}RzdG_l6aSCgjB&EU>^B_ zlW!vGBhcK!M`*HX^ghI_Cq1wK^7%>6d%esjsM-AJU-&)m&0@49IC1Spr)Z@rw~Wy# zU`TQ9g_s&Z=2g*qCwr75a*ycF4=2C;4077>agXlDX8sbVHvtt9dv(lkPFjzsi6JyG zR86ehHT3V4JxkK}q_tgwVs(ZNm>@NtBX^9(qGZNB6Qn5EX=dJgagD7y;(M40a)P&m zm_Uix1@B~_-DG-EAW$JfIZp~~$|WzV&`Z&!morLY{6Z8PSv|6$Y~hQ(gKH)KT`>r- zLH~Pzv3@1_@8LnG|9z$UUt5E53k9#8Vz;U~_eEWASNVS~@@RS;vA@mq|6td~|9-H$ zzuVFOC!~LiMw$B;1p24aoQ`xGw zhzX7LjN(aBk>W73+W8e9%a%^wiQ0avtB(EniED&uzQi8b^}Z3sv~fKDKzY?3$tM5w z-u;B4ifj{c7z#WE0yX%l2YveKx5qHvpJ1#!=8umN$-jOU>np3N5Ub4tJwY;&pctlpe^$r``%{8E+fSj)vNOYiV z%%kypOzs)7&dqBYg_tG{6Pl3%j(*%i_~qICNoob;=?3Dk5r(4o@?TLtc?8Y;q-II1 zHum&2wEakKY3Lgidt6Wc$t-;qJy69Ao?L)3iV=s}9ujTdh`$0gSVZ$Etu;{k4zgl_y2}3j^alr z_%D$38>mZ8r_E^UO6XG_5MefpXWvtl%fy zC!EaFato(qL&4}zO2ka-<(}DB@gwNY2_LwI4BNx!e9p?}^w%RUjBqxJlTulIWyId6 zlJ7QX?Kgh=h8D@Jl8D@>x93s$4W2={`c#B#+W3vP!Q)cD3T|LF`}iG}hJVD@q_fu7 zOhv>R>8sVbXx`TS&&A*4>rnt2^#ARL4{Z7Wpo{3TjJf8+6AZHB=iGihf2e77+pyGC^V*A@)w1(w*1oVPLjc1^QQ>Z>231+ zdn$Pv!iTkJVeT(6?VG#)FdnB%vT>uGq;PkcBW&K7@T$u7K{*}JMi`A4(J9P|SOM`J zda0zIKcAC_R?%G_O-uoLub`Vc3t3o_olGdFpLZOF-aCAF8NH8+BwhGd{|x4T4881+ zliB@?`@8+^`=Z6{Z!*_gd_IJp48;uGqv6dcD_?w;sH|ONJXGDK#B!Ch%ELpan@r0n zN7Zm5uFN~Z0P0A1X2{RTJB`06mfSFd$phzX5wk7b&1N=5jRUza?`durQabI@3EU+A zXa5hp7P(RX-|d|T2e$w3euw|_DfPc*M-AHv<5#>etM$Ray|dAw0esfWvY8NYfycluXQ8Vx-(;lytF5dh?3b{pTvA>-h zPL%#RIj`q)8jY;w`d_qDl8QxCswQBG$jZn;WsZ`=4^2c7-5lmG9E{C~`HRV&^ia^_q?3*go|MW9mz zZc`Bu$vve>=jE>f;pcA(oVLZK=rf5bfc5azlifc{8acq+g<+O zuUGyT2d=FG6sK$bSsku)T8FK*0a^R%8i733KRf&%c_v-q3a|nH=fKAQKiJ*x;=k|K z{ogt=y{?%%_4%xx1BBH)Aguh<@l7qqXvHb6BG7C2^R^hTi9Mc%179P%OH>=oSt-XS z99lvLppBXW)t{`kE=&?0Vd^z0?J?v&r`t8e!mQL=u`Gk~8oHZhrWu{E#P{Rbmr%<3x3apun%R=rpYD!{)a!0EU_OQdPLl< zS^4oKSxh-^!6;M`skexyh~tF#Hlz(?^KgvG+%O3##hx)*5pHI5!|E%1B=)+37Isy4 zMcZz1zCa6g4|#WgUrSVmkSbFh45b=x%_2-n#Nm=pULSFoE6ygO3`H@;MY1E5Xo>nkncmVsgqxDv7CSm^A_&a6 zclrl~^I=^H)SSxoq9k*bLpTOCkRW*&k%ubzKB8bp`tN`vv9q338Bf))DORv{;6EO} zdRY)Vx=#s*HpaObhiQ&rwpo-fWDad&P3Y@}dfPNh7zzpotmVQ}9$NUE{jdaFX&#=Z zQNEPgrI_&M6)gPhhMNDJb4-?Y4t)?hxl)!j)jYfa#xsFg-#F(8-oSp_-{%LI-`LAP=6TsV~t6Oln1Zf;S@TJ(t4r$8;uY zum|{10zvRYpi))6QQWS-1a4D;D$wdNTCnRu#*&J@dhdQh*($c%fBf6wfS%T%Bfz)V z@W+CysXkP;UV2U_4vZS%iHZyOh8FWD9_lOexWirO{C{QsUm?fR5pbjUk9+$z{=>oc z?smujKOz7B(-SP;fGle~0cx0k6>eM!IPPhI5N9B4kzyz^MoLv)VY=qY++&C%p`W@S zlKL*}oy^Hzd#zD-7#NL_jBF5}3Z4vHnf{AEf0aSuN=Jit|GxKVYn7kBl%)gBYBF_Y zI2(llMwh8}H*3eZaKeGDoHso&Nl05v2ihwkr*H`!987i582BkP4%I;0r`~1(ekRe{V51=V+`ScM zrJ@7XGxV3Y=a`jZK6*eMAMm%_`{ Date: Thu, 13 Feb 2025 16:52:18 -0300 Subject: [PATCH 17/22] feat(foxy-store-form): add support for switching between string and json store secret configurations --- .../public/StoreForm/StoreForm.stories.ts | 12 +- .../public/StoreForm/StoreForm.test.ts | 347 +++++++----------- src/elements/public/StoreForm/StoreForm.ts | 209 ++++++----- src/server/hapi/createDataset.ts | 2 +- src/static/translations/store-form/en.json | 66 ++-- 5 files changed, 305 insertions(+), 331 deletions(-) diff --git a/src/elements/public/StoreForm/StoreForm.stories.ts b/src/elements/public/StoreForm/StoreForm.stories.ts index 101a2ed1..1d353730 100644 --- a/src/elements/public/StoreForm/StoreForm.stories.ts +++ b/src/elements/public/StoreForm/StoreForm.stories.ts @@ -27,8 +27,13 @@ const summary: Summary = { 'essentials:postal-code', 'essentials:currency-style', - 'api-legacy', - 'api-legacy:webhook-key-api-legacy', + 'store-secrets', + 'store-secrets:use-single-secret', + 'store-secrets:webhook-key', + 'store-secrets:webhook-key-api-legacy', + 'store-secrets:webhook-key-xml-datafeed', + 'store-secrets:webhook-key-cart-signing', + 'store-secrets:webhook-key-sso', 'emails', 'emails:from-email', @@ -49,7 +54,6 @@ const summary: Summary = { 'cart:app-session-time', 'cart:products-require-expires-property', 'cart:use-cart-validation', - 'cart:webhook-key-cart-signing', 'checkout', 'checkout:checkout-type', @@ -58,7 +62,6 @@ const summary: Summary = { 'checkout:unified-order-entry-password', 'checkout:use-single-sign-on-url', 'checkout:single-sign-on-url', - 'checkout:webhook-key-sso', 'receipt', 'receipt:receipt-continue-url', @@ -80,7 +83,6 @@ const summary: Summary = { 'xml-datafeed', 'xml-datafeed:use-webhook', 'xml-datafeed:webhook-url', - 'xml-datafeed:webhook-key-xml-datafeed', ], }, }; diff --git a/src/elements/public/StoreForm/StoreForm.test.ts b/src/elements/public/StoreForm/StoreForm.test.ts index 89b6aac2..162b89de 100644 --- a/src/elements/public/StoreForm/StoreForm.test.ts +++ b/src/elements/public/StoreForm/StoreForm.test.ts @@ -357,6 +357,19 @@ describe('StoreForm', () => { expect(form.errors).to.not.include('logo-url:v8n_too_long'); }); + it('produces the webhook-url:v8n_required error if legacy webhook is enabled and the url is empty', () => { + const form = new Form(); + + form.edit({ use_webhook: false, webhook_url: '' }); + expect(form.errors).to.not.include('webhook-url:v8n_required'); + + form.edit({ use_webhook: true, webhook_url: '' }); + expect(form.errors).to.include('webhook-url:v8n_required'); + + form.edit({ use_webhook: true, webhook_url: 'A'.repeat(300) }); + expect(form.errors).to.not.include('webhook-url:v8n_required'); + }); + it('produces the webhook-url:v8n_too_long error if legacy webhook is enabled and the url exceeds 300 characters', () => { const form = new Form(); @@ -381,8 +394,6 @@ describe('StoreForm', () => { it('produces the webhook-key:v8n_required error if legacy webhook is enabled and key is empty', () => { const form = new Form(); - - form.edit({ use_webhook: false, webhook_key: '' }); expect(form.errors).to.not.include('webhook-key:v8n_required'); form.edit({ use_webhook: true, webhook_key: '' }); @@ -391,36 +402,100 @@ describe('StoreForm', () => { it('produces the webhook-key:v8n_required error if hmac for carts is enabled and key is empty', () => { const form = new Form(); - - form.edit({ use_cart_validation: false, webhook_key: '' }); expect(form.errors).to.not.include('webhook-key:v8n_required'); form.edit({ use_cart_validation: true, webhook_key: '' }); expect(form.errors).to.include('webhook-key:v8n_required'); }); - it('produces the webhook-key:v8n_too_long error if legacy webhook is enabled and the key exceeds 200 characters', () => { + it('produces the webhook-key:v8n_too_long error if legacy webhook is enabled and the key exceeds 500 characters', () => { const form = new Form(); form.edit({ use_webhook: false, webhook_key: '' }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); - form.edit({ use_webhook: false, webhook_key: 'A'.repeat(200) }); + form.edit({ use_webhook: false, webhook_key: 'A'.repeat(500) }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); - form.edit({ use_webhook: false, webhook_key: 'A'.repeat(201) }); - expect(form.errors).to.not.include('webhook-key:v8n_too_long'); + form.edit({ use_webhook: false, webhook_key: 'A'.repeat(501) }); + expect(form.errors).to.include('webhook-key:v8n_too_long'); form.edit({ use_webhook: true, webhook_key: '' }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); - form.edit({ use_webhook: true, webhook_key: 'A'.repeat(200) }); + form.edit({ use_webhook: true, webhook_key: 'A'.repeat(500) }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); - form.edit({ use_webhook: true, webhook_key: 'A'.repeat(201) }); + form.edit({ use_webhook: true, webhook_key: 'A'.repeat(501) }); expect(form.errors).to.include('webhook-key:v8n_too_long'); }); + [ + 'use-webhook:v8n_webhook_key_required', + 'webhook-key-xml-datafeed:v8n_required', + 'webhook-key:v8n_required', + ].forEach(code => { + it(`produces the ${code} error when XML datafeed is enabled but webhook key is empty`, () => { + const form = new Form(); + expect(form.errors).to.not.include(code); + + form.edit({ use_webhook: true, webhook_key: '' }); + expect(form.errors).to.include(code); + + form.edit({ webhook_key: 'abc' }); + expect(form.errors).to.not.include(code); + + const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; + form.edit({ webhook_key: JSON.stringify(props) }); + expect(form.errors).to.include(code); + + form.edit({ webhook_key: JSON.stringify({ ...props, xml_datafeed: 'abc' }) }); + expect(form.errors).to.not.include(code); + }); + }); + + [ + 'use-cart-validation:v8n_webhook_key_required', + 'webhook-key-cart-signing:v8n_required', + 'webhook-key:v8n_required', + ].forEach(code => { + it(`produces the ${code} error when cart signing is enabled but webhook key is empty`, () => { + const form = new Form(); + expect(form.errors).to.not.include(code); + + form.edit({ use_cart_validation: true, webhook_key: '' }); + expect(form.errors).to.include(code); + + form.edit({ webhook_key: 'abc' }); + expect(form.errors).to.not.include(code); + + const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; + form.edit({ webhook_key: JSON.stringify(props) }); + expect(form.errors).to.include(code); + + form.edit({ webhook_key: JSON.stringify({ ...props, cart_signing: 'abc' }) }); + expect(form.errors).to.not.include(code); + }); + }); + + (['xml_datafeed', 'cart_signing', 'api_legacy', 'sso'] as const).forEach(prop => { + const code = `webhook-key-${prop.replace(/_/g, '-')}:v8n_too_long`; + it(`produces the ${code} error when ${prop} in webhook_key JSON is more than 100 characters long`, () => { + const form = new Form(); + expect(form.errors).to.not.include(code); + + const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; + form.edit({ webhook_key: JSON.stringify(props) }); + expect(form.errors).to.not.include(code); + + form.edit({ webhook_key: JSON.stringify({ ...props, [prop]: 'a'.repeat(100) }) }); + expect(form.errors).to.not.include(code); + + form.edit({ webhook_key: JSON.stringify({ ...props, [prop]: 'a'.repeat(101) }) }); + expect(form.errors).to.include(code); + }); + }); + it('produces the single-sign-on-url:v8n_required error if sso is enabled and url is empty', () => { const form = new Form(); @@ -916,55 +991,79 @@ describe('StoreForm', () => { expect(control?.getValue()).to.equal('010'); }); - it('renders a summary control for Legacy API section', async () => { + it('renders a summary control for Store Secrets section', async () => { const element = await fixture(html``); const control = element.renderRoot.querySelector( - 'foxy-internal-summary-control[infer="legacy-api"]' + 'foxy-internal-summary-control[infer="store-secrets"]' ); expect(control).to.exist; }); - it('renders a password control for the legacy api key inside of the Legacy API section (JSON keys)', async () => { + it('renders a switch control for toggling between string and json webhook key inside of the Store Secrets section', async () => { const element = await fixture(html``); - const control = element.renderRoot.querySelector( - '[infer="legacy-api"] foxy-internal-password-control[infer="webhook-key-api-legacy"]' + const control = element.renderRoot.querySelector( + '[infer="store-secrets"] foxy-internal-switch-control[infer="use-single-secret"]' ); expect(control).to.exist; - expect(control).to.have.attribute('layout', 'summary-item'); - expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - element.edit({ webhook_key: JSON.stringify({ api_legacy: 'test' }) }); - expect(control?.getValue()).to.equal('test'); + control?.setValue(true); + expect(control?.getValue()).to.be.true; + expect(element).to.have.nested.property('form.webhook_key', ''); - control?.setValue('foo'); + control?.setValue(false); + expect(control?.getValue()).to.be.false; expect(element).to.have.nested.property( 'form.webhook_key', - JSON.stringify({ api_legacy: 'foo' }) + JSON.stringify({ + cart_signing: '', + xml_datafeed: '', + api_legacy: '', + sso: '', + }) ); }); - it('renders a password control for the legacy api key inside of the Legacy API section (string key)', async () => { + it('renders a password control for the universal api key inside of the Store Secrets section (string key)', async () => { const element = await fixture(html``); const control = element.renderRoot.querySelector( - '[infer="legacy-api"] foxy-internal-password-control[infer="webhook-key-api-legacy"]' + '[infer="store-secrets"] foxy-internal-password-control[infer="webhook-key"]' ); expect(control).to.exist; expect(control).to.have.attribute('layout', 'summary-item'); expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - - element.edit({ webhook_key: 'test' }); - expect(control?.getValue()).to.equal('test'); - - control?.setValue('foo'); - expect(element).to.have.nested.property( - 'form.webhook_key', - JSON.stringify({ cart_signing: 'test', xml_datafeed: 'test', api_legacy: 'foo', sso: 'test' }) - ); + expect(control).to.have.deep.property('generatorOptions', { length: 128, separator: '' }); + }); + + ['cart_signing', 'xml_datafeed', 'api_legacy', 'sso'].forEach(key => { + const scope = key.replace('_', '-'); + const name = key.replace('_', ' '); + + it(`renders a password control for the ${name} key inside of the Store Secrets section (JSON keys)`, async () => { + const element = await fixture(html``); + element.edit({ + webhook_key: JSON.stringify({ + cart_signing: '', + xml_datafeed: '', + api_legacy: '', + sso: '', + }), + }); + + await element.requestUpdate(); + const control = element.renderRoot.querySelector( + `[infer="store-secrets"] foxy-internal-password-control[infer="webhook-key-${scope}"]` + ); + + expect(control).to.exist; + expect(control).to.have.attribute('layout', 'summary-item'); + expect(control).to.have.attribute('show-generator'); + expect(control).to.have.deep.property('generatorOptions', { length: 64, separator: '' }); + expect(control).to.have.attribute('property', 'webhook_key'); + expect(control).to.have.attribute('json-path', key); + }); }); it('renders a summary control for Emails section', async () => { @@ -1328,56 +1427,6 @@ describe('StoreForm', () => { expect(control).to.have.attribute('helper-text-as-tooltip'); }); - it('renders a password control for the cart signing key in the Cart section (JSON keys)', async () => { - const element = await fixture(html``); - const control = element.renderRoot.querySelector( - '[infer="cart"] foxy-internal-password-control[infer="webhook-key-cart-signing"]' - ); - - expect(control).to.exist; - expect(control).to.have.attribute('layout', 'summary-item'); - expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - - element.edit({ - webhook_key: JSON.stringify({ - cart_signing: 'test', - xml_datafeed: 'test', - api_legacy: 'test', - sso: 'test', - }), - }); - - expect(control?.getValue()).to.equal('test'); - - control?.setValue('foo'); - expect(element).to.have.nested.property( - 'form.webhook_key', - JSON.stringify({ cart_signing: 'foo', xml_datafeed: 'test', api_legacy: 'test', sso: 'test' }) - ); - }); - - it('renders a password control for the cart signing key in the Cart section (string key)', async () => { - const element = await fixture(html``); - const control = element.renderRoot.querySelector( - '[infer="cart"] foxy-internal-password-control[infer="webhook-key-cart-signing"]' - ); - - expect(control).to.exist; - expect(control).to.have.attribute('layout', 'summary-item'); - expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - - element.edit({ webhook_key: 'test' }); - expect(control?.getValue()).to.equal('test'); - - control?.setValue('foo'); - expect(element).to.have.nested.property( - 'form.webhook_key', - JSON.stringify({ cart_signing: 'foo', xml_datafeed: 'test', api_legacy: 'test', sso: 'test' }) - ); - }); - it('renders a summary control for Checkout section', async () => { const element = await fixture(html``); const control = element.renderRoot.querySelector( @@ -1492,71 +1541,6 @@ describe('StoreForm', () => { expect(control).to.have.attribute('layout', 'summary-item'); }); - it('renders a password control for SSO key in the Checkout section when SSO is enabled (JSON keys)', async () => { - const element = await fixture(html``); - expect( - element.renderRoot.querySelector( - '[infer="checkout"] [infer="webhook-key-sso"]' - ) - ).to.not.exist; - - element.edit({ - use_single_sign_on: true, - webhook_key: JSON.stringify({ - cart_signing: 'test', - xml_datafeed: 'test', - api_legacy: 'test', - sso: 'test', - }), - }); - - await element.requestUpdate(); - const control = element.renderRoot.querySelector( - '[infer="checkout"] [infer="webhook-key-sso"]' - ); - - expect(control).to.exist; - expect(control).to.be.instanceOf(InternalPasswordControl); - expect(control).to.have.attribute('layout', 'summary-item'); - expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - expect(control?.getValue()).to.equal('test'); - - control?.setValue('foo'); - expect(element).to.have.nested.property( - 'form.webhook_key', - JSON.stringify({ cart_signing: 'test', xml_datafeed: 'test', api_legacy: 'test', sso: 'foo' }) - ); - }); - - it('renders a password control for SSO key in the Checkout section when SSO is enabled (string key)', async () => { - const element = await fixture(html``); - expect( - element.renderRoot.querySelector( - '[infer="checkout"] [infer="webhook-key-sso"]' - ) - ).to.not.exist; - - element.edit({ use_single_sign_on: true, webhook_key: 'test' }); - await element.requestUpdate(); - const control = element.renderRoot.querySelector( - '[infer="checkout"] [infer="webhook-key-sso"]' - ); - - expect(control).to.exist; - expect(control).to.be.instanceOf(InternalPasswordControl); - expect(control).to.have.attribute('layout', 'summary-item'); - expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - expect(control?.getValue()).to.equal('test'); - - control?.setValue('foo'); - expect(element).to.have.nested.property( - 'form.webhook_key', - JSON.stringify({ cart_signing: 'test', xml_datafeed: 'test', api_legacy: 'test', sso: 'foo' }) - ); - }); - it('renders a summary control for Receipt section', async () => { const element = await fixture(html``); const control = element.renderRoot.querySelector( @@ -2270,71 +2254,6 @@ describe('StoreForm', () => { expect(control).to.have.attribute('layout', 'summary-item'); }); - it('renders a password control for XML Datafeed key in the XML Datafeed section when Use Webhook is enabled (JSON keys)', async () => { - const element = await fixture(html``); - expect( - element.renderRoot.querySelector( - '[infer="xml-datafeed"] [infer="webhook-key-xml-datafeed"]' - ) - ).to.not.exist; - - element.edit({ - use_webhook: true, - webhook_key: JSON.stringify({ - cart_signing: 'test', - xml_datafeed: 'test', - api_legacy: 'test', - sso: 'test', - }), - }); - - await element.requestUpdate(); - const control = element.renderRoot.querySelector( - '[infer="xml-datafeed"] [infer="webhook-key-xml-datafeed"]' - ); - - expect(control).to.exist; - expect(control).to.be.instanceOf(InternalPasswordControl); - expect(control).to.have.attribute('layout', 'summary-item'); - expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - expect(control?.getValue()).to.equal('test'); - - control?.setValue('foo'); - expect(element).to.have.nested.property( - 'form.webhook_key', - JSON.stringify({ cart_signing: 'test', xml_datafeed: 'foo', api_legacy: 'test', sso: 'test' }) - ); - }); - - it('renders a password control for XML Datafeed key in the XML Datafeed section when Use Webhook is enabled (string key)', async () => { - const element = await fixture(html``); - expect( - element.renderRoot.querySelector( - '[infer="xml-datafeed"] [infer="webhook-key-xml-datafeed"]' - ) - ).to.not.exist; - - element.edit({ use_webhook: true, webhook_key: 'test' }); - await element.requestUpdate(); - const control = element.renderRoot.querySelector( - '[infer="xml-datafeed"] [infer="webhook-key-xml-datafeed"]' - ); - - expect(control).to.exist; - expect(control).to.be.instanceOf(InternalPasswordControl); - expect(control).to.have.attribute('layout', 'summary-item'); - expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 32, separator: '' }); - expect(control?.getValue()).to.equal('test'); - - control?.setValue('foo'); - expect(element).to.have.nested.property( - 'form.webhook_key', - JSON.stringify({ cart_signing: 'test', xml_datafeed: 'foo', api_legacy: 'test', sso: 'test' }) - ); - }); - it('renders default slot', async () => { const element = await fixture(html``); expect(element.renderRoot.querySelector('slot:not([name])')).to.exist; diff --git a/src/elements/public/StoreForm/StoreForm.ts b/src/elements/public/StoreForm/StoreForm.ts index 1cb3482d..52cc1d02 100644 --- a/src/elements/public/StoreForm/StoreForm.ts +++ b/src/elements/public/StoreForm/StoreForm.ts @@ -26,6 +26,14 @@ import merge from 'lodash-es/merge'; const NS = 'store-form'; const Base = ResponsiveMixin(TranslatableMixin(InternalForm, NS)); +function parseWebhookKey(webhookKey: string): ParsedWebhookKey | null { + try { + return JSON.parse(webhookKey); + } catch { + return null; + } +} + /** * Form element for store settings (`fx:store`). * @@ -50,7 +58,7 @@ export class StoreForm extends Base { }; } - static get v8n(): NucleonV8N { + static get v8n(): NucleonV8N { return [ ({ store_name: v }) => !!v || 'store-name:v8n_required', ({ store_name: v }) => (v && v.length <= 50) || 'store-name:v8n_too_long', @@ -93,17 +101,44 @@ export class StoreForm extends Base { ({ country: v }) => !!v || 'country:v8n_required', ({ logo_url: v }) => !v || v.length <= 200 || 'logo-url:v8n_too_long', + ({ webhook_url: v, use_webhook }) => !use_webhook || !!v || 'webhook-url:v8n_required', ({ webhook_url: v, use_webhook }) => { return !use_webhook || !v || v.length <= 300 || 'webhook-url:v8n_too_long'; }, - ({ webhook_key: v, use_webhook: on, use_cart_validation: hmac }) => { - return (!on && !hmac) || !!v || 'webhook-key:v8n_required'; + ({ webhook_key: v }) => v === void 0 || v.length > 0 || 'webhook-key:v8n_required', + ({ webhook_key: v }, host) => { + // TODO remove the line below when API limit is corrected to match the legacy admin + if (host.data?.webhook_key === v) return true; + return !v || v.length <= 500 || 'webhook-key:v8n_too_long'; }, - ({ webhook_key: v, use_webhook: on, use_cart_validation: hmac }) => { - return (!on && !hmac) || !v || v.length <= 200 || 'webhook-key:v8n_too_long'; - }, + ...[ + 'use-webhook:v8n_webhook_key_required', + 'webhook-key-xml-datafeed:v8n_required', + 'webhook-key:v8n_required', + ].map(code => ({ webhook_key: v, use_webhook: on }: Partial) => { + const parsedV = parseWebhookKey(v ?? ''); + return !on || !!(parsedV ? parsedV.xml_datafeed : v) || code; + }), + + ...[ + 'use-cart-validation:v8n_webhook_key_required', + 'webhook-key-cart-signing:v8n_required', + 'webhook-key:v8n_required', + ].map(code => ({ webhook_key: v, use_cart_validation: on }: Partial) => { + const parsedV = parseWebhookKey(v ?? ''); + return !on || !!(parsedV ? parsedV.cart_signing : v) || code; + }), + + ...(['xml_datafeed', 'cart_signing', 'api_legacy', 'sso'] as const).map( + prop => + ({ webhook_key: v }: Partial) => { + const parsedV = parseWebhookKey(v ?? ''); + const code = `webhook-key-${prop.replace(/_/g, '-')}:v8n_too_long`; + return !parsedV || parsedV[prop].length <= 100 || code; + } + ), ({ single_sign_on_url: v, use_single_sign_on: on }) => { return !on || !!v || 'single-sign-on-url:v8n_required'; @@ -351,38 +386,32 @@ export class StoreForm extends Base { { label: 'option_none', value: '' }, ]; - private readonly __webhookKeyGeneratorOptions = { length: 32, separator: '' }; - - private readonly __webhookKeyApiLegacyGetValue = () => { - return this.__getWebhookKey().api_legacy; - }; - - private readonly __webhookKeyApiLegacySetValue = (newValue: string) => { - this.__setWebhookKey('api_legacy', newValue); - }; - - private readonly __webhookKeyCartSigningGetValue = () => { - return this.__getWebhookKey().cart_signing; - }; + private readonly __singleWebhookKeyGeneratorOptions = { length: 128, separator: '' }; - private readonly __webhookKeyCartSigningSetValue = (newValue: string) => { - this.__setWebhookKey('cart_signing', newValue); - }; + private readonly __jsonWebhookKeyGeneratorOptions = { length: 64, separator: '' }; - private readonly __webhookKeyXmlDatafeedGetValue = () => { - return this.__getWebhookKey().xml_datafeed; - }; - - private readonly __webhookKeyXmlDatafeedSetValue = (newValue: string) => { - this.__setWebhookKey('xml_datafeed', newValue); + private readonly __useSingleWebhookKeyGetValue = () => { + try { + JSON.parse(this.form.webhook_key ?? ''); + return false; + } catch { + return true; + } }; - private readonly __webhookKeySsoGetValue = () => { - return this.__getWebhookKey().sso; - }; + private readonly __useSingleWebhookKeySetValue = (newValue: boolean) => { + if (newValue) { + this.edit({ webhook_key: '' }); + } else { + const parsedKey: ParsedWebhookKey = { + cart_signing: '', + xml_datafeed: '', + api_legacy: '', + sso: '', + }; - private readonly __webhookKeySsoSetValue = (newValue: string) => { - this.__setWebhookKey('sso', newValue); + this.edit({ webhook_key: JSON.stringify(parsedKey) }); + } }; private __hCaptchaToken: string | null = null; @@ -536,16 +565,65 @@ export class StoreForm extends Base { - - + - + + + ${this.__useSingleWebhookKeyGetValue() + ? html` + + + ` + : html` + + + + + + + + + + + + `} @@ -649,16 +727,6 @@ export class StoreForm extends Base { - - - @@ -708,15 +776,6 @@ export class StoreForm extends Base { ? html` - - ` : ''} @@ -905,15 +964,6 @@ export class StoreForm extends Base { ? html` - - ` : ''} @@ -1057,25 +1107,6 @@ export class StoreForm extends Base { return this.renderRoot.querySelector('h-captcha'); } - private __getWebhookKey() { - let parsedKey: ParsedWebhookKey; - - try { - parsedKey = JSON.parse(this.form.webhook_key ?? ''); - } catch { - const v = this.form.webhook_key ?? ''; - parsedKey = { cart_signing: v, xml_datafeed: v, api_legacy: v, sso: v }; - } - - return parsedKey; - } - - private __setWebhookKey(key: keyof ParsedWebhookKey, value: string) { - const parsedKey = this.__getWebhookKey(); - parsedKey[key] = value; - this.edit({ webhook_key: JSON.stringify(parsedKey) }); - } - private __getCustomDisplayIdConfig() { const defaultConfig: ParsedCustomDisplayIdConfig = { enabled: false, diff --git a/src/server/hapi/createDataset.ts b/src/server/hapi/createDataset.ts index 0394ef4f..b295a0bc 100644 --- a/src/server/hapi/createDataset.ts +++ b/src/server/hapi/createDataset.ts @@ -619,7 +619,7 @@ export const createDataset: () => Dataset = () => ({ use_webhook: false, webhook_url: '', webhook_key: '', - use_cart_validation: true, + use_cart_validation: false, use_single_sign_on: false, single_sign_on_url: '', customer_password_hash_type: 'phpass', diff --git a/src/static/translations/store-form/en.json b/src/static/translations/store-form/en.json index b7fb293f..d8a65db0 100644 --- a/src/static/translations/store-form/en.json +++ b/src/static/translations/store-form/en.json @@ -100,13 +100,47 @@ "helper_text": "" } }, - "legacy-api": { - "label": "Legacy API", + "store-secrets": { + "label": "Store secrets", "helper_text": "", + "use-single-secret": { + "label": "Use a universal store secret", + "helper_text": "When enabled, we will use the same secret for cart signing, legacy API, XML datafeed and SSO. Note that changing this setting will invalidate all existing secrets.", + "checked": "Yes", + "unchecked": "No" + }, + "webhook-key": { + "label": "Universal store secret", + "placeholder": "None", + "helper_text": "", + "v8n_required": "Please create a universal store secret.", + "v8n_too_long": "Please shorten this value to 500 characters or less." + }, "webhook-key-api-legacy": { - "label": "API key", + "label": "Legacy API key", "placeholder": "None", - "helper_text": "" + "helper_text": "", + "v8n_too_long": "Please shorten this value to 100 characters or less." + }, + "webhook-key-xml-datafeed": { + "label": "Legacy XML datafeed encryption key", + "placeholder": "None", + "helper_text": "", + "v8n_required": "This key is required because the legacy XML datafeed is enabled.", + "v8n_too_long": "Please shorten this value to 100 characters or less." + }, + "webhook-key-sso": { + "label": "SSO secret", + "placeholder": "None", + "helper_text": "", + "v8n_too_long": "Please shorten this value to 100 characters or less." + }, + "webhook-key-cart-signing": { + "label": "Cart signing key", + "placeholder": "None", + "helper_text": "", + "v8n_required": "This key is required because cart signing is enabled.", + "v8n_too_long": "Please shorten this value to 100 characters or less." } }, "emails": { @@ -197,16 +231,12 @@ "day": "Day", "day_plural": "Days" }, - "webhook-key-cart-signing": { - "label": "HMAC encryption key", - "placeholder": "None", - "helper_text": "" - }, "use-cart-validation": { "label": "Prevent product link and form tampering", "helper_text": "Enabling this option will require all cart links and forms to pass HMAC-based verification before products can be added to the cart. You will need to sign your HTML to use this feature.", "checked": "Yes", - "unchecked": "No" + "unchecked": "No", + "v8n_webhook_key_required": "Please create a cart signing key or a universal store secret to enable this feature." }, "products-require-expires-property": { "label": "My products have limited availability", @@ -247,11 +277,6 @@ "helper_text": "", "v8n_required": "Please enter your SSO endpoint URL", "v8n_too_long": "Please shorten this URL to 300 characters or less" - }, - "webhook-key-sso": { - "label": "SSO secret", - "placeholder": "None", - "helper_text": "" } }, "receipt": { @@ -344,18 +369,15 @@ "label": "Enable datafeed", "helper_text": "This is a deprecated webhook that should only be used for third-party integrations that still require it. For any new integrations where you need to trigger a webhook for each transaction on your store, we strongly recommend using the JSON webhooks.", "checked": "Yes", - "unchecked": "No" + "unchecked": "No", + "v8n_webhook_key_required": "Please create a legacy XML datafeed encryption key or a universal store secret to enable this feature." }, "webhook-url": { "label": "Webhook URL", "placeholder": "https://example.com/my-xml-datafeed", "helper_text": "", - "v8n_too_long": "Please shorten this URL to 300 characters or less" - }, - "webhook-key-xml-datafeed": { - "label": "Encryption key", - "placeholder": "None", - "helper_text": "" + "v8n_too_long": "Please shorten this URL to 300 characters or less.", + "v8n_required": "Please enter a URL." } }, "hcaptcha": { From 5e2e658cd17b0e1fbe9fdd035bf5d21fcc4a9d74 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Thu, 13 Feb 2025 17:31:15 -0300 Subject: [PATCH 18/22] fix(foxy-customer-portal): hide password reset screen on success Closes #200 --- .../InternalCustomerPortalPasswordResetView.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/elements/public/CustomerPortal/InternalCustomerPortalPasswordResetView.ts b/src/elements/public/CustomerPortal/InternalCustomerPortalPasswordResetView.ts index d3a32258..cdf5bbd1 100644 --- a/src/elements/public/CustomerPortal/InternalCustomerPortalPasswordResetView.ts +++ b/src/elements/public/CustomerPortal/InternalCustomerPortalPasswordResetView.ts @@ -89,4 +89,17 @@ export class InternalCustomerPortalPasswordResetView extends TranslatableMixin(I this.edit({ password_old: this.passwordOld ?? '' }); super.submit(); } + + protected async _fetch(...args: Parameters): Promise { + const request = new Request(...args); + if (request.method !== 'PATCH') return super._fetch(...args); + + const body = await request.json(); + const data = await super._fetch(...args); + + data.password_old = body.password_old; + data.password = body.password; + + return data as unknown as TResult; + } } From 1c3f0cf6cd61a6da6a89be409c87e3febe3f8c9f Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Fri, 14 Feb 2025 12:09:30 -0300 Subject: [PATCH 19/22] fix(foxy-item-card): hide all product options when cart display config specifies that --- src/elements/public/ItemCard/ItemCard.test.ts | 23 +++++++++++++++++++ src/elements/public/ItemCard/ItemCard.ts | 5 +++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/elements/public/ItemCard/ItemCard.test.ts b/src/elements/public/ItemCard/ItemCard.test.ts index 256ea965..e8192580 100644 --- a/src/elements/public/ItemCard/ItemCard.test.ts +++ b/src/elements/public/ItemCard/ItemCard.test.ts @@ -302,4 +302,27 @@ describe('ItemCard', () => { } } }); + + it('hides all item options when settings prohibit item option display', async () => { + type Settings = Resource; + const settings = await getTestData('./portal/customer_portal_settings'); + settings.cart_display_config.show_product_options = false; + + const router = createRouter(); + const element = await fixture(html` + router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + const data = element.data as Data; + const options = element.renderRoot.querySelectorAll('[data-testclass="option"]'); + + expect(data._embedded['fx:item_options']).to.not.be.empty; + expect(options).to.have.length(0); + }); }); diff --git a/src/elements/public/ItemCard/ItemCard.ts b/src/elements/public/ItemCard/ItemCard.ts index d33e4fd1..d3570b14 100644 --- a/src/elements/public/ItemCard/ItemCard.ts +++ b/src/elements/public/ItemCard/ItemCard.ts @@ -373,8 +373,11 @@ export class ItemCard extends Base { } private get __filteredOptions() { + const config = this.settings?.cart_display_config; + if (config?.show_product_options === false) return []; + const allOptions = this.data?._embedded?.['fx:item_options']; - const hiddenOptions = this.settings?.cart_display_config?.hidden_product_options ?? []; + const hiddenOptions = config?.hidden_product_options ?? []; return allOptions?.filter(option => !hiddenOptions.includes(option.name)); } } From aea932e88207a3a9f8d2f9aa36c1a6c09e804688 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Fri, 14 Feb 2025 13:06:56 -0300 Subject: [PATCH 20/22] fix(foxy-store-form): adjust store secret validations and add read-only values back to ui --- .../public/StoreForm/StoreForm.test.ts | 121 ++++++++++-------- src/elements/public/StoreForm/StoreForm.ts | 89 ++++++++++--- src/elements/public/StoreForm/index.ts | 1 + src/server/hapi/createDataset.ts | 2 +- src/static/translations/store-form/en.json | 44 ++++++- 5 files changed, 181 insertions(+), 76 deletions(-) diff --git a/src/elements/public/StoreForm/StoreForm.test.ts b/src/elements/public/StoreForm/StoreForm.test.ts index 162b89de..537d3e5f 100644 --- a/src/elements/public/StoreForm/StoreForm.test.ts +++ b/src/elements/public/StoreForm/StoreForm.test.ts @@ -392,107 +392,122 @@ describe('StoreForm', () => { expect(form.errors).to.include('webhook-url:v8n_too_long'); }); - it('produces the webhook-key:v8n_required error if legacy webhook is enabled and key is empty', () => { + it('produces the webhook-key:v8n_required error if key is empty', () => { const form = new Form(); expect(form.errors).to.not.include('webhook-key:v8n_required'); - form.edit({ use_webhook: true, webhook_key: '' }); + form.edit({ webhook_key: '' }); expect(form.errors).to.include('webhook-key:v8n_required'); - }); - it('produces the webhook-key:v8n_required error if hmac for carts is enabled and key is empty', () => { - const form = new Form(); + form.edit({ webhook_key: 'abc' }); expect(form.errors).to.not.include('webhook-key:v8n_required'); - - form.edit({ use_cart_validation: true, webhook_key: '' }); - expect(form.errors).to.include('webhook-key:v8n_required'); }); - it('produces the webhook-key:v8n_too_long error if legacy webhook is enabled and the key exceeds 500 characters', () => { + it('produces the webhook-key:v8n_too_long error if legacy webhook is enabled and the key exceeds 100 characters', () => { const form = new Form(); form.edit({ use_webhook: false, webhook_key: '' }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); - form.edit({ use_webhook: false, webhook_key: 'A'.repeat(500) }); + form.edit({ use_webhook: false, webhook_key: 'A'.repeat(100) }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); - form.edit({ use_webhook: false, webhook_key: 'A'.repeat(501) }); + form.edit({ use_webhook: false, webhook_key: 'A'.repeat(101) }); expect(form.errors).to.include('webhook-key:v8n_too_long'); form.edit({ use_webhook: true, webhook_key: '' }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); - form.edit({ use_webhook: true, webhook_key: 'A'.repeat(500) }); + form.edit({ use_webhook: true, webhook_key: 'A'.repeat(100) }); expect(form.errors).to.not.include('webhook-key:v8n_too_long'); form.edit({ use_webhook: true, webhook_key: 'A'.repeat(501) }); expect(form.errors).to.include('webhook-key:v8n_too_long'); }); - [ - 'use-webhook:v8n_webhook_key_required', - 'webhook-key-xml-datafeed:v8n_required', - 'webhook-key:v8n_required', - ].forEach(code => { - it(`produces the ${code} error when XML datafeed is enabled but webhook key is empty`, () => { - const form = new Form(); - expect(form.errors).to.not.include(code); + it(`produces the use-webhook:v8n_webhook_key_required error when XML datafeed is enabled but webhook key is empty`, () => { + const form = new Form(); + expect(form.errors).to.not.include('use-webhook:v8n_webhook_key_required'); - form.edit({ use_webhook: true, webhook_key: '' }); - expect(form.errors).to.include(code); + form.edit({ use_webhook: true, webhook_key: '' }); + expect(form.errors).to.include('use-webhook:v8n_webhook_key_required'); - form.edit({ webhook_key: 'abc' }); - expect(form.errors).to.not.include(code); + form.edit({ webhook_key: 'abc' }); + expect(form.errors).to.not.include('use-webhook:v8n_webhook_key_required'); - const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; - form.edit({ webhook_key: JSON.stringify(props) }); - expect(form.errors).to.include(code); + const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; + form.edit({ webhook_key: JSON.stringify(props) }); + expect(form.errors).to.include('use-webhook:v8n_webhook_key_required'); - form.edit({ webhook_key: JSON.stringify({ ...props, xml_datafeed: 'abc' }) }); - expect(form.errors).to.not.include(code); - }); + form.edit({ webhook_key: JSON.stringify({ ...props, xml_datafeed: 'abc' }) }); + expect(form.errors).to.not.include('use-webhook:v8n_webhook_key_required'); }); - [ - 'use-cart-validation:v8n_webhook_key_required', - 'webhook-key-cart-signing:v8n_required', - 'webhook-key:v8n_required', - ].forEach(code => { - it(`produces the ${code} error when cart signing is enabled but webhook key is empty`, () => { - const form = new Form(); - expect(form.errors).to.not.include(code); + it(`produces the use-cart-validation:v8n_webhook_key_required error when XML datafeed is enabled but webhook key is empty`, () => { + const form = new Form(); + expect(form.errors).to.not.include('use-cart-validation:v8n_webhook_key_required'); + + form.edit({ use_cart_validation: true, webhook_key: '' }); + expect(form.errors).to.include('use-cart-validation:v8n_webhook_key_required'); - form.edit({ use_cart_validation: true, webhook_key: '' }); - expect(form.errors).to.include(code); + form.edit({ webhook_key: 'abc' }); + expect(form.errors).to.not.include('use-cart-validation:v8n_webhook_key_required'); - form.edit({ webhook_key: 'abc' }); - expect(form.errors).to.not.include(code); + const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; + form.edit({ webhook_key: JSON.stringify(props) }); + expect(form.errors).to.include('use-cart-validation:v8n_webhook_key_required'); + + form.edit({ webhook_key: JSON.stringify({ ...props, cart_signing: 'abc' }) }); + expect(form.errors).to.not.include('use-cart-validation:v8n_webhook_key_required'); + }); + + it(`produces the use-single-sign-on:v8n_webhook_key_required error when XML datafeed is enabled but webhook key is empty`, () => { + const form = new Form(); + expect(form.errors).to.not.include('use-single-sign-on:v8n_webhook_key_required'); + + form.edit({ use_single_sign_on: true, webhook_key: '' }); + expect(form.errors).to.include('use-single-sign-on:v8n_webhook_key_required'); + + form.edit({ webhook_key: 'abc' }); + expect(form.errors).to.not.include('use-single-sign-on:v8n_webhook_key_required'); + + const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; + form.edit({ webhook_key: JSON.stringify(props) }); + expect(form.errors).to.include('use-single-sign-on:v8n_webhook_key_required'); + + form.edit({ webhook_key: JSON.stringify({ ...props, sso: 'abc' }) }); + expect(form.errors).to.not.include('use-single-sign-on:v8n_webhook_key_required'); + }); + + (['xml_datafeed', 'cart_signing', 'api_legacy', 'sso'] as const).forEach(prop => { + const requiredCode = `webhook-key-${prop.replace(/_/g, '-')}:v8n_required`; + const tooLongCode = `webhook-key-${prop.replace(/_/g, '-')}:v8n_too_long`; + + it(`produces the ${requiredCode} error when ${prop} in webhook_key JSON is empty`, () => { + const form = new Form(); + expect(form.errors).to.not.include(requiredCode); const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; form.edit({ webhook_key: JSON.stringify(props) }); - expect(form.errors).to.include(code); + expect(form.errors).to.include(requiredCode); - form.edit({ webhook_key: JSON.stringify({ ...props, cart_signing: 'abc' }) }); - expect(form.errors).to.not.include(code); + form.edit({ webhook_key: JSON.stringify({ ...props, [prop]: 'abc' }) }); + expect(form.errors).to.not.include(requiredCode); }); - }); - (['xml_datafeed', 'cart_signing', 'api_legacy', 'sso'] as const).forEach(prop => { - const code = `webhook-key-${prop.replace(/_/g, '-')}:v8n_too_long`; - it(`produces the ${code} error when ${prop} in webhook_key JSON is more than 100 characters long`, () => { + it(`produces the ${tooLongCode} error when ${prop} in webhook_key JSON is more than 100 characters long`, () => { const form = new Form(); - expect(form.errors).to.not.include(code); + expect(form.errors).to.not.include(tooLongCode); const props = { cart_signing: '', xml_datafeed: '', api_legacy: '', sso: '' }; form.edit({ webhook_key: JSON.stringify(props) }); - expect(form.errors).to.not.include(code); + expect(form.errors).to.not.include(tooLongCode); form.edit({ webhook_key: JSON.stringify({ ...props, [prop]: 'a'.repeat(100) }) }); - expect(form.errors).to.not.include(code); + expect(form.errors).to.not.include(tooLongCode); form.edit({ webhook_key: JSON.stringify({ ...props, [prop]: 'a'.repeat(101) }) }); - expect(form.errors).to.include(code); + expect(form.errors).to.include(tooLongCode); }); }); diff --git a/src/elements/public/StoreForm/StoreForm.ts b/src/elements/public/StoreForm/StoreForm.ts index 52cc1d02..128d0bc5 100644 --- a/src/elements/public/StoreForm/StoreForm.ts +++ b/src/elements/public/StoreForm/StoreForm.ts @@ -47,6 +47,7 @@ export class StoreForm extends Base { reportingStoreDomainExists: { attribute: 'reporting-store-domain-exists' }, customerPasswordHashTypes: { attribute: 'customer-password-hash-types' }, shippingAddressTypes: { attribute: 'shipping-address-types' }, + storeSecretsPageUrl: { attribute: 'store-secrets-page-url' }, hCaptchaSiteKey: { attribute: 'h-captcha-site-key' }, storeVersions: { attribute: 'store-versions' }, checkoutTypes: { attribute: 'checkout-types' }, @@ -110,35 +111,41 @@ export class StoreForm extends Base { ({ webhook_key: v }, host) => { // TODO remove the line below when API limit is corrected to match the legacy admin if (host.data?.webhook_key === v) return true; - return !v || v.length <= 500 || 'webhook-key:v8n_too_long'; + return !v || v.length <= 100 || 'webhook-key:v8n_too_long'; }, - ...[ - 'use-webhook:v8n_webhook_key_required', - 'webhook-key-xml-datafeed:v8n_required', - 'webhook-key:v8n_required', - ].map(code => ({ webhook_key: v, use_webhook: on }: Partial) => { + ({ webhook_key: v, use_webhook: on }: Partial) => { const parsedV = parseWebhookKey(v ?? ''); + const code = 'use-webhook:v8n_webhook_key_required'; return !on || !!(parsedV ? parsedV.xml_datafeed : v) || code; - }), + }, - ...[ - 'use-cart-validation:v8n_webhook_key_required', - 'webhook-key-cart-signing:v8n_required', - 'webhook-key:v8n_required', - ].map(code => ({ webhook_key: v, use_cart_validation: on }: Partial) => { + ({ webhook_key: v, use_cart_validation: on }: Partial) => { const parsedV = parseWebhookKey(v ?? ''); + const code = 'use-cart-validation:v8n_webhook_key_required'; return !on || !!(parsedV ? parsedV.cart_signing : v) || code; - }), + }, + + ({ webhook_key: v, use_single_sign_on: on }: Partial) => { + const parsedV = parseWebhookKey(v ?? ''); + const code = 'use-single-sign-on:v8n_webhook_key_required'; + return !on || !!(parsedV ? parsedV.sso : v) || code; + }, - ...(['xml_datafeed', 'cart_signing', 'api_legacy', 'sso'] as const).map( - prop => + ...(['xml_datafeed', 'cart_signing', 'api_legacy', 'sso'] as const) + .map(prop => [ + ({ webhook_key: v }: Partial) => { + const parsedV = parseWebhookKey(v ?? ''); + const code = `webhook-key-${prop.replace(/_/g, '-')}:v8n_required`; + return !parsedV || !!parsedV[prop] || code; + }, ({ webhook_key: v }: Partial) => { const parsedV = parseWebhookKey(v ?? ''); const code = `webhook-key-${prop.replace(/_/g, '-')}:v8n_too_long`; return !parsedV || parsedV[prop].length <= 100 || code; - } - ), + }, + ]) + .flat(), ({ single_sign_on_url: v, use_single_sign_on: on }) => { return !on || !!v || 'single-sign-on-url:v8n_required'; @@ -167,6 +174,9 @@ export class StoreForm extends Base { /** URL of the `fx:shipping_address_types` property helper resource. */ shippingAddressTypes: string | null = null; + /** URL of the Store Secrets settings page if you are using this form on multiple pages. */ + storeSecretsPageUrl: string | null = null; + /** hCaptcha site key for signup verification. If provided, requires users to complete a captcha before creating a store. */ hCaptchaSiteKey: string | null = null; @@ -479,6 +489,12 @@ export class StoreForm extends Base { const displayIdExamples = this.__displayIdExamples; const journalIdExamples = this.__journalIdExamples; + const rawWebhookKey = this.data?.webhook_key ?? ''; + const parsedWebhookKey = parseWebhookKey(rawWebhookKey); + const cartSigningKey = parsedWebhookKey?.cart_signing ?? rawWebhookKey; + const xmlDatafeedKey = parsedWebhookKey?.xml_datafeed ?? rawWebhookKey; + const ssoKey = parsedWebhookKey?.sso ?? rawWebhookKey; + return html` ${this.renderHeader()} @@ -565,7 +581,7 @@ export class StoreForm extends Base { - + { + + ${cartSigningKey && this.form.use_cart_validation + ? this.__renderReadonlyWebhookKey('webhook-key-cart-signing', cartSigningKey) + : ''} @@ -776,6 +796,7 @@ export class StoreForm extends Base { ? html` + ${ssoKey ? this.__renderReadonlyWebhookKey('webhook-key-sso', ssoKey) : ''} ` : ''} @@ -964,6 +985,9 @@ export class StoreForm extends Base { ? html` + ${xmlDatafeedKey + ? this.__renderReadonlyWebhookKey('webhook-key-xml-datafeed', xmlDatafeedKey) + : ''} ` : ''} @@ -1205,4 +1229,33 @@ export class StoreForm extends Base { `, }; } + + private __renderReadonlyWebhookKey(scope: string, key: string) { + return html` + + `; + } } diff --git a/src/elements/public/StoreForm/index.ts b/src/elements/public/StoreForm/index.ts index 32a90b78..141b3acc 100644 --- a/src/elements/public/StoreForm/index.ts +++ b/src/elements/public/StoreForm/index.ts @@ -10,6 +10,7 @@ import '../../internal/InternalSelectControl/index'; import '../../internal/InternalTextControl/index'; import '../../internal/InternalForm/index'; +import '../CopyToClipboard/index'; import '../NucleonElement/index'; import '../I18n/index'; diff --git a/src/server/hapi/createDataset.ts b/src/server/hapi/createDataset.ts index b295a0bc..8ba6824a 100644 --- a/src/server/hapi/createDataset.ts +++ b/src/server/hapi/createDataset.ts @@ -618,7 +618,7 @@ export const createDataset: () => Dataset = () => ({ checkout_type: 'default_account', use_webhook: false, webhook_url: '', - webhook_key: '', + webhook_key: 'A'.repeat(32), use_cart_validation: false, use_single_sign_on: false, single_sign_on_url: '', diff --git a/src/static/translations/store-form/en.json b/src/static/translations/store-form/en.json index d8a65db0..6d85f604 100644 --- a/src/static/translations/store-form/en.json +++ b/src/static/translations/store-form/en.json @@ -114,32 +114,34 @@ "placeholder": "None", "helper_text": "", "v8n_required": "Please create a universal store secret.", - "v8n_too_long": "Please shorten this value to 500 characters or less." + "v8n_too_long": "Please shorten this value to 100 characters or less." }, "webhook-key-api-legacy": { "label": "Legacy API key", "placeholder": "None", "helper_text": "", + "v8n_required": "Please create a legacy API key.", "v8n_too_long": "Please shorten this value to 100 characters or less." }, "webhook-key-xml-datafeed": { "label": "Legacy XML datafeed encryption key", "placeholder": "None", "helper_text": "", - "v8n_required": "This key is required because the legacy XML datafeed is enabled.", + "v8n_required": "Please create a legacy XML datafeed encryption key.", "v8n_too_long": "Please shorten this value to 100 characters or less." }, "webhook-key-sso": { "label": "SSO secret", "placeholder": "None", "helper_text": "", + "v8n_required": "Please create an SSO secret.", "v8n_too_long": "Please shorten this value to 100 characters or less." }, "webhook-key-cart-signing": { "label": "Cart signing key", "placeholder": "None", "helper_text": "", - "v8n_required": "This key is required because cart signing is enabled.", + "v8n_required": "Please create a cart signing key.", "v8n_too_long": "Please shorten this value to 100 characters or less." } }, @@ -243,6 +245,17 @@ "helper_text": "All products added to the cart for your store will need to contain the expires property to ensure stale products can't be purchased.", "checked": "Yes", "unchecked": "No" + }, + "webhook-key-cart-signing": { + "label": "Cart signing key", + "helper_text": "You can edit this key in ", + "link_text": "Store Secrets settings", + "copy-to-clipboard": { + "failed_to_copy": "Failed to copy", + "click_to_copy": "Copy", + "copying": "Copying...", + "done": "Copied" + } } }, "checkout": { @@ -269,7 +282,8 @@ "label": "Enable SSO", "helper_text": "When enabled, Foxy will redirect customers to your SSO endpoint prior to hitting the checkout page. You can use this to validate items or to log customers in via your own auth provider.", "checked": "Yes", - "unchecked": "No" + "unchecked": "No", + "v8n_webhook_key_required": "Please create an SSO secret or a universal store secret to enable this feature." }, "single-sign-on-url": { "label": "SSO endpoint", @@ -277,6 +291,17 @@ "helper_text": "", "v8n_required": "Please enter your SSO endpoint URL", "v8n_too_long": "Please shorten this URL to 300 characters or less" + }, + "webhook-key-sso": { + "label": "SSO secret", + "helper_text": "You can edit this secret in ", + "link_text": "Store Secrets settings", + "copy-to-clipboard": { + "failed_to_copy": "Failed to copy", + "click_to_copy": "Copy", + "copying": "Copying...", + "done": "Copied" + } } }, "receipt": { @@ -378,6 +403,17 @@ "helper_text": "", "v8n_too_long": "Please shorten this URL to 300 characters or less.", "v8n_required": "Please enter a URL." + }, + "webhook-key-xml-datafeed": { + "label": "Encryption key", + "helper_text": "You can edit this key in ", + "link_text": "Store Secrets settings", + "copy-to-clipboard": { + "failed_to_copy": "Failed to copy", + "click_to_copy": "Copy", + "copying": "Copying...", + "done": "Copied" + } } }, "hcaptcha": { From 8699ba1ce3ad77b23521c0983639615e25125731 Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Fri, 14 Feb 2025 14:17:07 -0300 Subject: [PATCH 21/22] fix(foxy-store-form): adjust secret generator options --- src/elements/public/StoreForm/StoreForm.test.ts | 4 ++-- src/elements/public/StoreForm/StoreForm.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/elements/public/StoreForm/StoreForm.test.ts b/src/elements/public/StoreForm/StoreForm.test.ts index 537d3e5f..18d64dbe 100644 --- a/src/elements/public/StoreForm/StoreForm.test.ts +++ b/src/elements/public/StoreForm/StoreForm.test.ts @@ -1049,7 +1049,7 @@ describe('StoreForm', () => { expect(control).to.exist; expect(control).to.have.attribute('layout', 'summary-item'); expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 128, separator: '' }); + expect(control).to.have.deep.property('generatorOptions', { length: 90, separator: '' }); }); ['cart_signing', 'xml_datafeed', 'api_legacy', 'sso'].forEach(key => { @@ -1075,7 +1075,7 @@ describe('StoreForm', () => { expect(control).to.exist; expect(control).to.have.attribute('layout', 'summary-item'); expect(control).to.have.attribute('show-generator'); - expect(control).to.have.deep.property('generatorOptions', { length: 64, separator: '' }); + expect(control).to.have.deep.property('generatorOptions', { length: 90, separator: '' }); expect(control).to.have.attribute('property', 'webhook_key'); expect(control).to.have.attribute('json-path', key); }); diff --git a/src/elements/public/StoreForm/StoreForm.ts b/src/elements/public/StoreForm/StoreForm.ts index 128d0bc5..d6dbfe3f 100644 --- a/src/elements/public/StoreForm/StoreForm.ts +++ b/src/elements/public/StoreForm/StoreForm.ts @@ -396,9 +396,9 @@ export class StoreForm extends Base { { label: 'option_none', value: '' }, ]; - private readonly __singleWebhookKeyGeneratorOptions = { length: 128, separator: '' }; + private readonly __singleWebhookKeyGeneratorOptions = { length: 90, separator: '' }; - private readonly __jsonWebhookKeyGeneratorOptions = { length: 64, separator: '' }; + private readonly __jsonWebhookKeyGeneratorOptions = { length: 90, separator: '' }; private readonly __useSingleWebhookKeyGetValue = () => { try { From 7cced3184e5c2a810e4081e8d01564baae5a0d5f Mon Sep 17 00:00:00 2001 From: Daniil Bratukhin Date: Fri, 14 Feb 2025 14:19:23 -0300 Subject: [PATCH 22/22] chore: regenerate custom-elements.json --- custom-elements.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/custom-elements.json b/custom-elements.json index aeba3d16..3372776b 100644 --- a/custom-elements.json +++ b/custom-elements.json @@ -16844,6 +16844,10 @@ "name": "locale-codes", "type": "string" }, + { + "name": "settings", + "type": "object" + }, { "name": "mode", "type": "string", @@ -16931,6 +16935,11 @@ "attribute": "locale-codes", "type": "string" }, + { + "name": "settings", + "attribute": "settings", + "type": "object" + }, { "name": "templates", "default": "{}" @@ -25474,6 +25483,10 @@ "name": "shipping-address-types", "description": "URL of the `fx:shipping_address_types` property helper resource." }, + { + "name": "store-secrets-page-url", + "description": "URL of the Store Secrets settings page if you are using this form on multiple pages." + }, { "name": "h-captcha-site-key", "description": "hCaptcha site key for signup verification. If provided, requires users to complete a captcha before creating a store." @@ -25612,6 +25625,11 @@ "attribute": "shipping-address-types", "description": "URL of the `fx:shipping_address_types` property helper resource." }, + { + "name": "storeSecretsPageUrl", + "attribute": "store-secrets-page-url", + "description": "URL of the Store Secrets settings page if you are using this form on multiple pages." + }, { "name": "hCaptchaSiteKey", "attribute": "h-captcha-site-key", @@ -26180,6 +26198,10 @@ "path": "./src/elements/public/SubscriptionCard/index.ts", "description": "Card element displaying subscription summary.", "attributes": [ + { + "name": "settings", + "type": "object" + }, { "name": "mode", "type": "string", @@ -26262,6 +26284,11 @@ } ], "properties": [ + { + "name": "settings", + "attribute": "settings", + "type": "object" + }, { "name": "templates", "default": "{}"