mirror of
https://github.com/suitenumerique/drive.git
synced 2026-08-17 20:15:40 +02:00
✨(frontend) open the messages widget from the help menu
Some instances use the messages widget for support instead of a plain mailto link. A new supportMessagesWidget flag in the help menu config lets the "Contact us" entry open the widget, taking precedence over the support email when both are configured.
This commit is contained in:
@@ -222,6 +222,7 @@ export type ApiConfig = {
|
||||
legalNoticeUrl?: string;
|
||||
};
|
||||
supportEmail?: string;
|
||||
supportMessagesWidget?: boolean;
|
||||
};
|
||||
FRONTEND_THEME?: string;
|
||||
FRONTEND_HIDE_GAUFRE?: boolean;
|
||||
|
||||
+12
-5
@@ -43,6 +43,7 @@ import i18n from "@/features/i18n/initI18n";
|
||||
import { useMemo } from "react";
|
||||
import { UserProfile } from "@/features/ui/components/user/UserProfile";
|
||||
import { Gaufre } from "@/features/ui/components/gaufre/Gaufre";
|
||||
import { useMessagesWidget } from "@/features/feedback/useMessagesWidget";
|
||||
|
||||
export const getGlobalExplorerLayout = (page: React.ReactElement) => {
|
||||
return <GlobalExplorerLayout>{page}</GlobalExplorerLayout>;
|
||||
@@ -199,20 +200,26 @@ const HelpMenuButton = () => {
|
||||
const helpMenuConfig = config?.FRONTEND_HELP_MENU_CONFIG;
|
||||
const hasHelpMenu =
|
||||
!!helpMenuConfig && Object.keys(helpMenuConfig).length > 0;
|
||||
const { showWidget } = useMessagesWidget();
|
||||
|
||||
if (!hasHelpMenu) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const getOnContactUs = () => {
|
||||
if (helpMenuConfig.supportMessagesWidget) {
|
||||
return () => showWidget();
|
||||
}
|
||||
return helpMenuConfig.supportEmail
|
||||
? () => window.open(helpMenuConfig.supportEmail)
|
||||
: undefined;
|
||||
};
|
||||
|
||||
return (
|
||||
<HelpMenu
|
||||
documentationUrl={helpMenuConfig.documentationUrl}
|
||||
legal={helpMenuConfig.legal}
|
||||
onContactUs={
|
||||
helpMenuConfig.supportEmail
|
||||
? () => window.open(helpMenuConfig.supportEmail)
|
||||
: undefined
|
||||
}
|
||||
onContactUs={getOnContactUs()}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ const HELP_MENU_CONFIG = {
|
||||
const overrideHelpMenuConfig = async (
|
||||
page: import("@playwright/test").Page,
|
||||
helpMenuConfig: unknown,
|
||||
extraConfig: Record<string, unknown> = {},
|
||||
) => {
|
||||
await page.route("**/api/v1.0/config/", async (route) => {
|
||||
const response = await route.fetch();
|
||||
@@ -21,10 +22,25 @@ const overrideHelpMenuConfig = async (
|
||||
} else {
|
||||
json.FRONTEND_HELP_MENU_CONFIG = helpMenuConfig;
|
||||
}
|
||||
Object.assign(json, extraConfig);
|
||||
await route.fulfill({ response, json });
|
||||
});
|
||||
};
|
||||
|
||||
// Records window.open calls so that mailto links can be asserted without
|
||||
// relying on the browser actually opening them.
|
||||
const spyOnWindowOpen = async (page: import("@playwright/test").Page) => {
|
||||
await page.addInitScript(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any).__openedUrls = [];
|
||||
window.open = (url?: string | URL) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any).__openedUrls.push(String(url));
|
||||
return null;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
test.describe("Help menu", () => {
|
||||
test("renders the help menu with the configured options", async ({
|
||||
page,
|
||||
@@ -60,6 +76,69 @@ test.describe("Help menu", () => {
|
||||
).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("opens the support email when clicking on contact us", async ({
|
||||
page,
|
||||
}) => {
|
||||
await overrideHelpMenuConfig(page, HELP_MENU_CONFIG);
|
||||
await spyOnWindowOpen(page);
|
||||
await login(page, "drive@example.com");
|
||||
await page.goto("/");
|
||||
|
||||
const footer = page.locator(".c__left-panel__footer__drive");
|
||||
await footer.getByRole("button", { name: "Help" }).click();
|
||||
await page.getByRole("menuitem", { name: "Contact us" }).click();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const openedUrls = await page.evaluate(() => (window as any).__openedUrls);
|
||||
expect(openedUrls).toEqual([HELP_MENU_CONFIG.supportEmail]);
|
||||
});
|
||||
|
||||
test("opens the messages widget when clicking on contact us", async ({
|
||||
page,
|
||||
}) => {
|
||||
const widgetPath = "https://widget.example.com/";
|
||||
await overrideHelpMenuConfig(
|
||||
page,
|
||||
{
|
||||
...HELP_MENU_CONFIG,
|
||||
supportMessagesWidget: true,
|
||||
},
|
||||
{
|
||||
FRONTEND_FEEDBACK_MESSAGES_WIDGET_API_URL: "https://widget.example.com/api/",
|
||||
FRONTEND_FEEDBACK_MESSAGES_WIDGET_PATH: widgetPath,
|
||||
FRONTEND_FEEDBACK_MESSAGES_WIDGET_CHANNEL: "drive",
|
||||
},
|
||||
);
|
||||
// Serve an empty widget script so the injected loader does not hit the
|
||||
// network for real.
|
||||
await page.route(`${widgetPath}feedback.js`, (route) =>
|
||||
route.fulfill({ contentType: "application/javascript", body: "" }),
|
||||
);
|
||||
await spyOnWindowOpen(page);
|
||||
await login(page, "drive@example.com");
|
||||
await page.goto("/");
|
||||
|
||||
const footer = page.locator(".c__left-panel__footer__drive");
|
||||
await footer.getByRole("button", { name: "Help" }).click();
|
||||
await page.getByRole("menuitem", { name: "Contact us" }).click();
|
||||
|
||||
// The widget queues an init call and injects its loader script.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const widgetCalls = await page.evaluate(() => (window as any)._stmsg_widget);
|
||||
expect(widgetCalls).toHaveLength(1);
|
||||
expect(widgetCalls[0][0]).toBe("feedback");
|
||||
expect(widgetCalls[0][1]).toBe("init");
|
||||
expect(widgetCalls[0][2].channel).toBe("drive");
|
||||
await expect(
|
||||
page.locator(`script[src="${widgetPath}feedback.js"]`),
|
||||
).toHaveCount(1);
|
||||
|
||||
// The widget takes precedence over the support email.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const openedUrls = await page.evaluate(() => (window as any).__openedUrls);
|
||||
expect(openedUrls).toEqual([]);
|
||||
});
|
||||
|
||||
test("does not render the help menu when the config is empty", async ({
|
||||
page,
|
||||
}) => {
|
||||
|
||||
Reference in New Issue
Block a user