Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/every-terms-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

Updated @saleor/app-sdk and added support for `popupClose` action. Since this release, app will be able to close the popup via code
2 changes: 0 additions & 2 deletions .github/workflows/publish-containers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ jobs:
type=pep440,pattern={{major}}.{{minor}}
context: git


build-push:
needs: prepare-variables
uses: saleor/saleor-internal-actions/.github/workflows/build-push-image-multi-platform.yaml@92c29aa0e4545de579b892b2ef9f2d6366c29c11 # v1.5.2
Expand All @@ -65,7 +64,6 @@ jobs:
COMMIT_ID=${{ github.sha }}
PROJECT_VERSION=${{ needs.prepare-variables.outputs.version }}


summary:
needs: [prepare-variables, build-push]
runs-on: ubuntu-22.04
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
"@graphql-eslint/eslint-plugin": "^4.4.0",
"@playwright/test": "1.56.1",
"@saleor/app-sdk": "1.5.0",
"@saleor/app-sdk": "1.7.0",
"@sentry/cli": "^2.58.2",
"@storybook/react-vite": "9.0.18",
"@swc/jest": "^0.2.39",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

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

2 changes: 2 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
blockExoticSubdeps: true

minimumReleaseAge: 720 # 12h
minimumReleaseAgeExclude:
- "@saleor/app-sdk"
Comment on lines 3 to +5
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimumReleaseAgeExclude for @saleor/app-sdk weakens the workspace’s supply-chain safeguard (allows installing very newly published versions). If this is intended as a temporary workaround for the SDK release, consider documenting the rationale (e.g., comment in the file / PR description) and/or scoping a plan to remove the exclusion once the release has aged.

Copilot uses AI. Check for mistakes.

trustPolicy: no-downgrade

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ jest.mock("../ExternalAppContext/ExternalAppContext");

const mockNotify = jest.fn();
const mockCloseExternalApp = jest.fn();
const mockDeactivate = jest.fn();

jest.mock(
"@dashboard/extensions/components/AppExtensionContext/AppExtensionContextProvider",
() => ({
useActiveAppExtension: () => ({
active: null,
activate: jest.fn(),
deactivate: mockDeactivate,
attachFormState: jest.fn(),
attachFormResponseFrame: jest.fn(),
framesByFormType: {},
}),
}),
);

jest.mock("@dashboard/hooks/useNotifier", () => ({
useNotifier: () => mockNotify,
Expand Down Expand Up @@ -314,6 +329,34 @@ describe("AppActionsHandler", function () {
});
});
});
describe("useHandlePopupCloseAction", () => {
it("Calls deactivate and returns ok response", () => {
// Arrange
const {
result: {
current: { handle },
},
} = renderHook(() => AppActionsHandler.useHandlePopupCloseAction());

// Act
const response = handle({
type: "popupClose",
payload: {
actionId: "test-popup-close",
},
});

// Assert
expect(mockDeactivate).toHaveBeenCalledTimes(1);
expect(response).toEqual({
type: "response",
payload: {
actionId: "test-popup-close",
ok: true,
},
});
});
});
describe("useHandlePermissionRequest", () => {
it("Redirects to a dedicated page with params from action", () => {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
FormPayloadUpdate,
NotificationAction,
NotifyReady,
PopupClose,
RedirectAction,
RequestPermissions,
UpdateRouting,
Expand Down Expand Up @@ -267,6 +268,21 @@ const useHandleAppFormUpdate = () => {
};
};

const useHandlePopupCloseAction = () => {
const { deactivate } = useActiveAppExtension();

return {
handle: (action: PopupClose) => {
const { actionId } = action.payload;

debug(`Handling PopupClose action with ID: %s`, actionId);
deactivate();

return createResponseStatus(actionId, true);
},
};
};

export const AppActionsHandler = {
useHandleNotificationAction,
useHandleUpdateRoutingAction,
Expand All @@ -275,4 +291,5 @@ export const AppActionsHandler = {
createResponseStatus,
useHandlePermissionRequest,
useHandleAppFormUpdate,
useHandlePopupCloseAction,
};
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jest.mock("./appActionsHandler", () => ({
useNotifyReadyAction: jest.fn(),
useHandlePermissionRequest: jest.fn(),
useHandleAppFormUpdate: jest.fn(),
useHandlePopupCloseAction: jest.fn(),
},
}));

Expand All @@ -51,6 +52,7 @@ describe("useAppActions", () => {
const mockHandleNotifyReady = jest.fn();
const mockHandlePermissionRequest = jest.fn();
const mockHandleAppFormUpdate = jest.fn();
const mockHandlePopupClose = jest.fn();

beforeEach(() => {
jest.clearAllMocks();
Expand All @@ -76,6 +78,9 @@ describe("useAppActions", () => {
(AppActionsHandler.useHandleAppFormUpdate as jest.Mock).mockReturnValue({
handle: mockHandleAppFormUpdate,
});
(AppActionsHandler.useHandlePopupCloseAction as jest.Mock).mockReturnValue({
handle: mockHandlePopupClose,
});

// Reset capture message mock to return a proper scope
mockCaptureMessage.mockImplementation((_message, callback) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const useAppActions = (
);
const { handle: handlePermissionRequest } = AppActionsHandler.useHandlePermissionRequest(appId);
const { handle: handleAppFormUpdate } = AppActionsHandler.useHandleAppFormUpdate();
const { handle: handlePopupClose } = AppActionsHandler.useHandlePopupCloseAction();
/**
* Store if app has performed a handshake with Dashboard, to avoid sending events before that
*/
Expand Down Expand Up @@ -61,6 +62,9 @@ export const useAppActions = (
case "formPayloadUpdate": {
return handleAppFormUpdate(action);
}
case "popupClose": {
return handlePopupClose(action);
}
default: {
// @ts-expect-error this is for runtime checking
const actionType = action?.type as string | undefined;
Expand Down
Loading