Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: release 1.36.0 #195

Merged
merged 18 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d8a3a92
build: bump node version for cdn upload action
pheekus Dec 20, 2024
54dc196
feat(foxy-native-integration-form): enable custom tax endpoint config
pheekus Dec 20, 2024
602b9b4
refactor(foxy-internal-form): update non-idle styles
pheekus Jan 3, 2025
f0ac53d
feat(foxy-native-integration-form): update ui with new controls
pheekus Jan 3, 2025
ef00aa7
test(foxy-native-integration-card): fix tests
pheekus Jan 7, 2025
e0a9304
fix(foxy-tax-card): fix subtitle text for custom tax endpoint
pheekus Jan 7, 2025
363df6a
feat(foxy-tax-form): rebuild with updated base class and controls
pheekus Jan 7, 2025
9c88266
chore: regenerate custom-elements.json
pheekus Jan 7, 2025
ebcfc69
feat(foxy-payments-api-payment-method-form): add a switch for `use_au…
pheekus Jan 8, 2025
89731d4
fix(foxy-payments-api-payment-method-form): use password controls for…
pheekus Jan 8, 2025
2e7542c
fix(foxy-nucleon): fix default content type
pheekus Jan 8, 2025
6f83652
fix(foxy-admin-subscription-form): use yyyy-mm-dd format for start/en…
pheekus Jan 9, 2025
f21b5f1
feat(foxy-payments-api): update virtual property helper for google re…
pheekus Jan 9, 2025
e8522fe
fix(foxy-customer-portal): support `0000-00-00` date format in `end_d…
pheekus Jan 13, 2025
58ba0d4
chore: update foxy sdk
pheekus Jan 14, 2025
5b3292d
feat(foxy-customer-portal): show Update Password form when logged in …
pheekus Jan 14, 2025
c7da0de
test(foxy-subscription-settings-form): fix tests
pheekus Jan 14, 2025
d86716a
test(foxy-user-invitation-form): fix tests
pheekus Jan 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- name: Install dependencies
run: npm ci
- name: Build
Expand Down
440 changes: 406 additions & 34 deletions custom-elements.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"prepack": "npm run lint && rimraf dist && node ./.build/compile-for-npm.js && rollup -c"
},
"dependencies": {
"@foxy.io/sdk": "^1.12.0",
"@foxy.io/sdk": "^1.13.0",
"@open-wc/lit-helpers": "^0.3.12",
"@open-wc/scoped-elements": "^1.2.1",
"@polymer/iron-icons": "^3.0.1",
Expand All @@ -38,6 +38,7 @@
"cookie-storage": "^6.1.0",
"dedent": "^1.5.3",
"email-validator": "^2.0.4",
"highlight.js": "^10.7.3",
"html-entities": "^2.4.0",
"i18next": "^19.7.0",
"i18next-http-backend": "^1.0.18",
Expand All @@ -49,7 +50,6 @@
"uainfer": "^0.5.0",
"vanilla-hcaptcha": "^1.0.2",
"webcomponent-qr-code": "^1.0.5",
"highlight.js": "^10.7.3",
"xstate": "^4.16.0"
},
"devDependencies": {
Expand Down Expand Up @@ -160,4 +160,4 @@
"publishConfig": {
"access": "public"
}
}
}
4 changes: 2 additions & 2 deletions src/elements/internal/InternalForm/InternalForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ export class InternalForm<TData extends HALJSONResource> extends Base<TData> {
<div
class=${classMap({
'space-y-m': true,
'transition-opacity': true,
'opacity-0 pointer-events-none': isSpinnerVisible,
'transition-all filter': true,
'opacity-30 blur-sm pointer-events-none': isSpinnerVisible,
})}
>
${this.__generalErrors.map(err => this.__renderGeneralError(err))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ describe('AdminSubscriptionForm', () => {

expect(control?.localName).to.equal('foxy-internal-date-control');
expect(control).to.have.attribute('layout', 'summary-item');
expect(control).to.have.attribute('format', 'iso-long');
});

it('renders frequency control inside of the general summary control', async () => {
Expand Down Expand Up @@ -233,7 +232,6 @@ describe('AdminSubscriptionForm', () => {

expect(control?.localName).to.equal('foxy-internal-date-control');
expect(control).to.have.attribute('layout', 'summary-item');
expect(control).to.have.attribute('format', 'iso-long');
});

it('renders date control for end date inside of the general summary control', async () => {
Expand All @@ -253,7 +251,6 @@ describe('AdminSubscriptionForm', () => {

expect(control?.localName).to.equal('foxy-internal-date-control');
expect(control).to.have.attribute('layout', 'summary-item');
expect(control).to.have.attribute('format', 'iso-long');
});

it('renders summary control with overdue information', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,17 @@ export class AdminSubscriptionForm extends Base<Data> {
</foxy-internal-admin-subscription-form-error>

<foxy-internal-summary-control infer="general">
<foxy-internal-date-control layout="summary-item" format="iso-long" infer="start-date">
<foxy-internal-date-control layout="summary-item" infer="start-date">
</foxy-internal-date-control>
<foxy-internal-frequency-control
layout="summary-item"
infer="frequency"
allow-twice-a-month
>
</foxy-internal-frequency-control>
<foxy-internal-date-control
layout="summary-item"
format="iso-long"
infer="next-transaction-date"
>
<foxy-internal-date-control layout="summary-item" infer="next-transaction-date">
</foxy-internal-date-control>
<foxy-internal-date-control layout="summary-item" format="iso-long" infer="end-date">
<foxy-internal-date-control layout="summary-item" infer="end-date">
</foxy-internal-date-control>
</foxy-internal-summary-control>

Expand Down
11 changes: 1 addition & 10 deletions src/elements/public/CartForm/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import type { Resource } from '@foxy.io/sdk/core';
import type { Rels } from '@foxy.io/sdk/backend';

// TODO remove this once SDK is fixed
type OriginalData = Resource<Rels.Cart, { zoom: ['discounts'] }>;
type FixedData = Omit<OriginalData, 'billing_region' | 'shipping_region'> & {
/** Corresponds to the `region` field in `fx:customer_address`. API quirk. */
billing_state: string;
/** Corresponds to the `region` field in `fx:customer_address`. API quirk. */
shipping_state: string;
};

export type Data = FixedData;
export type Data = Resource<Rels.Cart, { zoom: ['discounts'] }>;
2 changes: 0 additions & 2 deletions src/elements/public/CustomerForm/CustomerForm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,6 @@ describe('CustomerForm', () => {
form.data = { ...data, first_name: '', last_name: '' };
expect(form.headerTitleOptions).to.have.property('context', 'no_name');

// TODO: remove this when SDK types are fixed
// @ts-expect-error SDK types are incomplete
form.data = { ...data, first_name: null, last_name: null };
expect(form.headerTitleOptions).to.have.property('context', 'no_name');
});
Expand Down
66 changes: 65 additions & 1 deletion src/elements/public/CustomerPortal/CustomerPortal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,42 @@ import { CustomerPortal } from './CustomerPortal';
import { TransactionsTable } from '../TransactionsTable/TransactionsTable';
import { InternalCustomerPortalLoggedInView } from './InternalCustomerPortalLoggedInView';
import { InternalCustomerPortalLoggedOutView } from './InternalCustomerPortalLoggedOutView';
import { InternalCustomerPortalPasswordResetView } from './InternalCustomerPortalPasswordResetView';

describe('CustomerPortal', () => {
before(() => localStorage.clear());

it('extends CustomerApi', () => {
expect(new CustomerPortal()).to.be.instanceOf(CustomerApi);
});

it('imports and defines dependencies', () => {
expect(customElements.get('iron-icon')).to.exist;
expect(customElements.get('vaadin-button')).to.exist;
expect(customElements.get('foxy-internal-password-control')).to.exist;
expect(customElements.get('foxy-internal-sandbox')).to.exist;
expect(customElements.get('foxy-internal-form')).to.exist;
expect(customElements.get('foxy-access-recovery-form')).to.exist;
expect(customElements.get('foxy-payment-method-card')).to.exist;
expect(customElements.get('foxy-transactions-table')).to.exist;
expect(customElements.get('foxy-subscription-card')).to.exist;
expect(customElements.get('foxy-subscription-form')).to.exist;
expect(customElements.get('foxy-collection-pages')).to.exist;
expect(customElements.get('foxy-collection-page')).to.exist;
expect(customElements.get('foxy-customer-form')).to.exist;
expect(customElements.get('foxy-sign-in-form')).to.exist;
expect(customElements.get('foxy-form-dialog')).to.exist;
expect(customElements.get('foxy-spinner')).to.exist;
expect(customElements.get('foxy-i18n')).to.exist;
expect(customElements.get('foxy-customer')).to.exist;
expect(customElements.get('foxy-internal-customer-portal-logged-in-view')).to.exist;
expect(customElements.get('foxy-internal-customer-portal-logged-out-view')).to.exist;
expect(customElements.get('foxy-internal-customer-portal-password-reset-view')).to.exist;
expect(customElements.get('foxy-internal-customer-portal-subscriptions')).to.exist;
expect(customElements.get('foxy-internal-customer-portal-transactions')).to.exist;
expect(customElements.get('foxy-internal-customer-portal-link')).to.exist;
});

it('registers as foxy-customer-portal', () => {
expect(customElements.get('foxy-customer-portal')).to.equal(CustomerPortal);
});
Expand Down Expand Up @@ -84,7 +114,15 @@ describe('CustomerPortal', () => {
});

it('renders foxy-internal-customer-portal-logged-in-view when logged in', async () => {
localStorage.setItem(API.SESSION, 'session-stub');
localStorage.setItem(
API.SESSION,
JSON.stringify({
force_password_reset: false,
session_token: `dasjhf348tuhrgskjfhw48ourowi4rshajdhf`,
expires_in: 2419200,
jwt: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.Et9HFtf9R3GEMA0IICOfFMVXY7kkTX1wr4qCyhIf58U',
})
);

const transactionsTableColumns = [TransactionsTable.idColumn];

Expand All @@ -110,4 +148,30 @@ describe('CustomerPortal', () => {

localStorage.clear();
});

it('renders foxy-internal-customer-portal-password-reset-view when logged in with temporary password', async () => {
localStorage.setItem(
API.SESSION,
JSON.stringify({
force_password_reset: true,
session_token: `dasjhf348tuhrgskjfhw48ourowi4rshajdhf`,
expires_in: 2419200,
jwt: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.Et9HFtf9R3GEMA0IICOfFMVXY7kkTX1wr4qCyhIf58U',
})
);

const layout = html`
<foxy-customer-portal base="https://demo.api/portal/"></foxy-customer-portal>
`;

const element = await fixture<CustomerPortal>(layout);
const view = element.renderRoot.firstElementChild as InternalCustomerPortalPasswordResetView;

expect(view).to.be.instanceOf(InternalCustomerPortalPasswordResetView);
expect(view).to.have.property('localName', 'foxy-internal-customer-portal-password-reset-view');
expect(view).to.have.attribute('href', 'https://demo.api/portal/');
expect(view).to.have.attribute('infer', 'password-reset');

localStorage.clear();
});
});
56 changes: 45 additions & 11 deletions src/elements/public/CustomerPortal/CustomerPortal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CustomerApi } from '../CustomerApi/CustomerApi';
import { ThemeableMixin } from '../../../mixins/themeable';
import { TranslatableMixin } from '../../../mixins/translatable';
import { TransactionsTable } from '../TransactionsTable/TransactionsTable';
import { UpdateEvent } from '../NucleonElement/UpdateEvent';
import { ifDefined } from 'lit-html/directives/if-defined';

export class CustomerPortal extends TranslatableMixin(
Expand All @@ -15,6 +16,7 @@ export class CustomerPortal extends TranslatableMixin(
return {
...super.properties,
transactionsTableColumns: { attribute: false },
skipPasswordReset: { type: Boolean, attribute: 'skip-password-reset' },
embedUrl: { attribute: 'embed-url' },
group: { type: String },
};
Expand All @@ -30,6 +32,11 @@ export class CustomerPortal extends TranslatableMixin(
TransactionsTable.receiptColumn,
];

#temporaryPassword: string | null = null;

/** When set to true, portal won't display Password Reset screen if customer logs in with a temporary password. */
skipPasswordReset = false;

/**
* URL of the Payment Card Embed for updating payment method.
* When set, the payment method will be editable. Otherwise, the customers
Expand Down Expand Up @@ -58,24 +65,51 @@ export class CustomerPortal extends TranslatableMixin(
}

return this.api.storage.getItem(API.SESSION)
? html`
<foxy-internal-customer-portal-logged-in-view
embed-url=${ifDefined(this.embedUrl ?? void 0)}
customer=${this.base}
class="h-full"
infer=""
href=${ifDefined(settingsHref?.toString())}
.transactionsTableColumns=${this.transactionsTableColumns}
>
</foxy-internal-customer-portal-logged-in-view>
`
? !this.skipPasswordReset && this.api.usesTemporaryPassword
? html`
<foxy-internal-customer-portal-password-reset-view
password-old=${ifDefined(this.#temporaryPassword ?? void 0)}
infer="password-reset"
href=${this.base}
@update=${(evt: UpdateEvent) => {
if (evt.detail?.result === UpdateEvent.UpdateResult.ResourceUpdated) {
this.api.usesTemporaryPassword = false;
this.#temporaryPassword = null;
this.requestUpdate();
}
}}
>
</foxy-internal-customer-portal-password-reset-view>
`
: html`
<foxy-internal-customer-portal-logged-in-view
embed-url=${ifDefined(this.embedUrl ?? void 0)}
customer=${this.base}
class="h-full"
infer=""
href=${ifDefined(settingsHref?.toString())}
.transactionsTableColumns=${this.transactionsTableColumns}
>
</foxy-internal-customer-portal-logged-in-view>
`
: html`
<foxy-internal-customer-portal-logged-out-view
class="h-full"
infer=""
href=${ifDefined(settingsHref?.toString())}
@password=${(evt: CustomEvent<string | null>) => {
this.#temporaryPassword = evt.detail;
}}
>
</foxy-internal-customer-portal-logged-out-view>
`;
}

updated(changedProperties: Map<keyof this, unknown>): void {
super.updated(changedProperties);
const isLoggedIn = this.api.storage.getItem(API.SESSION) !== null;
if (isLoggedIn && (this.skipPasswordReset || !this.api.usesTemporaryPassword)) {
this.#temporaryPassword = null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,12 @@ export class InternalCustomerPortalLoggedOutView extends Base<Data> {
id="sign-in-form"
ns="${this.ns} ${customElements.get('foxy-sign-in-form')?.defaultNS ?? ''}"
.templates=${this.getNestedTemplates('sign-in:form')}
@update=${() => this.requestUpdate()}
@update=${(evt: CustomEvent) => {
const target = evt.currentTarget as SignInForm;
const password = target.form.credential?.password ?? null;
this.dispatchEvent(new CustomEvent('password', { detail: password }));
this.requestUpdate();
}}
>
</foxy-sign-in-form>

Expand Down
Loading
Loading