From 85cd9ce61e746b06363d2a7d26a2db9d1278c0d5 Mon Sep 17 00:00:00 2001
From: Daniil Bratukhin
Date: Thu, 23 Oct 2025 13:53:04 -0300
Subject: [PATCH 1/9] fix(foxy-payments-api-payment-method-form): update
gateway alphabetical ordering to use the gateway name
---
.../PaymentsApiPaymentMethodForm.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/elements/public/PaymentsApiPaymentMethodForm/PaymentsApiPaymentMethodForm.ts b/src/elements/public/PaymentsApiPaymentMethodForm/PaymentsApiPaymentMethodForm.ts
index b7a6ca54..a722f3d8 100644
--- a/src/elements/public/PaymentsApiPaymentMethodForm/PaymentsApiPaymentMethodForm.ts
+++ b/src/elements/public/PaymentsApiPaymentMethodForm/PaymentsApiPaymentMethodForm.ts
@@ -249,11 +249,11 @@ export class PaymentsApiPaymentMethodForm extends Base {
: allMethods;
return filteredMethods
- .sort((a, b) => a[0].localeCompare(b[0], 'en'))
+ .sort((a, b) => a[1].name.localeCompare(b[1].name, 'en'))
.reduce((groups, [type, helper]) => {
if (helper.is_deprecated) return groups;
- const firstChar = type.charAt(0).toUpperCase();
+ const firstChar = helper.name.charAt(0).toUpperCase();
const isSpecialCharacter = !/\w/.test(firstChar);
const name = isSpecialCharacter ? '#' : firstChar;
const group = groups.find(group => group.name === name);
From 05be8238c2524d2a3bfd5fec3d874eb7285fd9ea Mon Sep 17 00:00:00 2001
From: Daniil Bratukhin
Date: Thu, 23 Oct 2025 14:39:06 -0300
Subject: [PATCH 2/9] fix(foxy-admin-subscription-form): account for future
dated subscriptions in cancellation modal
---
...inSubscriptionFormStatusActionForm.test.ts | 79 +++++++++++++++++++
...alAdminSubscriptionFormStatusActionForm.ts | 39 +++++++--
.../admin-subscription-form/en.json | 4 +
3 files changed, 114 insertions(+), 8 deletions(-)
diff --git a/src/elements/public/AdminSubscriptionForm/internal/InternalAdminSubscriptionFormStatusActionForm/InternalAdminSubscriptionFormStatusActionForm.test.ts b/src/elements/public/AdminSubscriptionForm/internal/InternalAdminSubscriptionFormStatusActionForm/InternalAdminSubscriptionFormStatusActionForm.test.ts
index 3209b493..9cada296 100644
--- a/src/elements/public/AdminSubscriptionForm/internal/InternalAdminSubscriptionFormStatusActionForm/InternalAdminSubscriptionFormStatusActionForm.test.ts
+++ b/src/elements/public/AdminSubscriptionForm/internal/InternalAdminSubscriptionFormStatusActionForm/InternalAdminSubscriptionFormStatusActionForm.test.ts
@@ -102,6 +102,37 @@ describe('AdminSubscriptionForm', () => {
expect($('foxy-i18n[infer=""][key="cancel_how_to_reactivate_text"]')).to.exist;
});
+ it('renders text content for the Cancel state for future subscriptions', async () => {
+ const $ = (selector: string) => form.renderRoot.querySelector(selector);
+ const router = createRouter();
+ const form = await fixture
`;
}
+ private get __refundableAmount(): number {
+ const data = this.nucleon?.data as Data | undefined;
+ const originalTotal = data?.total_order ?? 0;
+ // @ts-expect-error SDK types do not include amount on fx:refund
+ return parseFloat(data?._links['fx:refund']?.amount ?? originalTotal);
+ }
+
private get __storeHref() {
return this.nucleon?.data?._links['fx:store']?.href as string | undefined;
}
diff --git a/src/static/translations/admin-subscription-form/en.json b/src/static/translations/admin-subscription-form/en.json
index b8a5a582..818a8318 100644
--- a/src/static/translations/admin-subscription-form/en.json
+++ b/src/static/translations/admin-subscription-form/en.json
@@ -1287,6 +1287,8 @@
"total_tax": "Tax",
"subtotal": "Subtotal",
"total": "Total",
+ "refundable_amount": "Refundable",
+ "refundable_amount_note": "The amount that can be refunded is different from the order total above because this transaction has been modified",
"price": "{{amount, price}}",
"status_capturing": "Capturing",
"status_captured": "Captured",
@@ -2107,7 +2109,7 @@
"button": "Void"
},
"refund": {
- "message_idle": "This action will attempt to refund the full amount of this transaction. Would you like to proceed?",
+ "message_idle": "This action will attempt to refund {{ amount, price }} to the payment method used in this transaction. Would you like to proceed?",
"message_fail": "Failed to refund this transaction. If you'd like to retry, close this dialog and click the refund button again.",
"message_done": "Transaction was refunded successfully. You can close this dialog now.",
"button_close": "Close",
diff --git a/src/static/translations/transaction/en.json b/src/static/translations/transaction/en.json
index b37ec859..2f471734 100644
--- a/src/static/translations/transaction/en.json
+++ b/src/static/translations/transaction/en.json
@@ -920,6 +920,8 @@
"total_tax": "Tax",
"subtotal": "Subtotal",
"total": "Total",
+ "refundable_amount": "Refundable",
+ "refundable_amount_note": "The amount that can be refunded is different from the order total above because this transaction has been modified",
"price": "{{amount, price}}",
"status_capturing": "Capturing",
"status_captured": "Captured",
@@ -1740,7 +1742,7 @@
"button": "Void"
},
"refund": {
- "message_idle": "This action will attempt to refund the full amount of this transaction. Would you like to proceed?",
+ "message_idle": "This action will attempt to refund {{ amount, price }} to the payment method used in this transaction. Would you like to proceed?",
"message_fail": "Failed to refund this transaction. If you'd like to retry, close this dialog and click the refund button again.",
"message_done": "Transaction was refunded successfully. You can close this dialog now.",
"button_close": "Close",
From b2e6ad0a199400f13c1f74c323c17e57b3e7e4de Mon Sep 17 00:00:00 2001
From: Daniil Bratukhin
Date: Mon, 27 Oct 2025 13:35:18 -0300
Subject: [PATCH 8/9] feat(foxy-webhook-form): add support for the `changelog`
webhook
---
src/elements/public/WebhookForm/WebhookForm.test.ts | 1 +
src/elements/public/WebhookForm/WebhookForm.ts | 1 +
src/static/translations/webhook-form/en.json | 4 +++-
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/elements/public/WebhookForm/WebhookForm.test.ts b/src/elements/public/WebhookForm/WebhookForm.test.ts
index f9236080..aeef84ab 100644
--- a/src/elements/public/WebhookForm/WebhookForm.test.ts
+++ b/src/elements/public/WebhookForm/WebhookForm.test.ts
@@ -153,6 +153,7 @@ describe('WebhookForm', () => {
{ value: 'transaction', label: 'event_resource_transaction' },
{ value: 'transaction_log', label: 'event_resource_transaction_log' },
{ value: 'customer', label: 'event_resource_customer' },
+ { value: 'changelog', label: 'event_resource_changelog' },
];
expect(control).to.exist;
diff --git a/src/elements/public/WebhookForm/WebhookForm.ts b/src/elements/public/WebhookForm/WebhookForm.ts
index d2300436..90349342 100644
--- a/src/elements/public/WebhookForm/WebhookForm.ts
+++ b/src/elements/public/WebhookForm/WebhookForm.ts
@@ -55,6 +55,7 @@ export class WebhookForm extends TranslatableMixin(InternalForm, 'webhook-form')
{ value: 'transaction', label: 'event_resource_transaction' },
{ value: 'transaction_log', label: 'event_resource_transaction_log' },
{ value: 'customer', label: 'event_resource_customer' },
+ { value: 'changelog', label: 'event_resource_changelog' },
];
get hiddenSelector(): BooleanSelector {
diff --git a/src/static/translations/webhook-form/en.json b/src/static/translations/webhook-form/en.json
index 4034e6da..f7852047 100644
--- a/src/static/translations/webhook-form/en.json
+++ b/src/static/translations/webhook-form/en.json
@@ -9,6 +9,7 @@
"subtitle_transaction_log": "Transaction log webhook",
"subtitle_subscription": "Subscription webhook",
"subtitle_customer": "Customer webhook",
+ "subtitle_changelog": "Changelog webhook",
"copy-id": {
"failed_to_copy": "Failed to copy",
"click_to_copy": "Copy ID",
@@ -50,7 +51,8 @@
"event_resource_transaction_log": "Transaction log",
"event_resource_subscription": "Subscription",
"event_resource_transaction": "Transaction",
- "event_resource_customer": "Customer"
+ "event_resource_customer": "Customer",
+ "event_resource_changelog": "Changelog"
},
"url": {
"label": "Endpoint",
From 5831e33c116f24bc785588a39b06aba5fc8ad7bb Mon Sep 17 00:00:00 2001
From: Daniil Bratukhin
Date: Mon, 27 Oct 2025 16:34:01 -0300
Subject: [PATCH 9/9] feat(foxy-user-invitation-form): better handling for when
a user removes themselves from the store
---
.../InternalPostActionControl.ts | 1 +
.../UserInvitationForm.test.ts | 39 ++++++++++++++++++-
.../UserInvitationForm/UserInvitationForm.ts | 37 ++++++++++++++----
.../public/UserInvitationForm/index.ts | 1 +
.../translations/user-invitation-form/en.json | 11 +++++-
5 files changed, 79 insertions(+), 10 deletions(-)
diff --git a/src/elements/internal/InternalPostActionControl/InternalPostActionControl.ts b/src/elements/internal/InternalPostActionControl/InternalPostActionControl.ts
index e119d254..6b3d84da 100644
--- a/src/elements/internal/InternalPostActionControl/InternalPostActionControl.ts
+++ b/src/elements/internal/InternalPostActionControl/InternalPostActionControl.ts
@@ -37,6 +37,7 @@ export class InternalPostActionControl extends InternalControl {
{
const button = evt.currentTarget as ButtonElement;
diff --git a/src/elements/public/UserInvitationForm/UserInvitationForm.test.ts b/src/elements/public/UserInvitationForm/UserInvitationForm.test.ts
index dbe30fd3..8629e893 100644
--- a/src/elements/public/UserInvitationForm/UserInvitationForm.test.ts
+++ b/src/elements/public/UserInvitationForm/UserInvitationForm.test.ts
@@ -4,7 +4,7 @@ import type { Data } from './types';
import './index';
-import { expect, fixture, html, waitUntil } from '@open-wc/testing';
+import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { UserInvitationForm as Form } from './UserInvitationForm';
import { InternalForm } from '../../internal/InternalForm';
import { createRouter } from '../../../server';
@@ -54,6 +54,13 @@ describe('UserInvitationForm', () => {
});
});
+ it('has a reactive property "currentUser"', () => {
+ expect(new Form()).to.have.property('currentUser', null);
+ expect(Form).to.have.deep.nested.property('properties.currentUser', {
+ attribute: 'current-user',
+ });
+ });
+
it('has a reactive property "layout"', () => {
expect(new Form()).to.have.property('layout', null);
expect(Form).to.have.deep.nested.property('properties.layout', {});
@@ -403,6 +410,36 @@ describe('UserInvitationForm', () => {
expect(action).to.have.attribute('theme', 'error');
});
+ it("renders a special async action for revoking current user's access in snapshot admin layout", async () => {
+ const router = createRouter();
+ const form = await fixture