Skip to content

Commit 0dfc079

Browse files
committed
feat(ui-preview): add footer update confirm preview
1 parent e0d512f commit 0dfc079

4 files changed

Lines changed: 135 additions & 44 deletions

File tree

packages/web/src/ui-preview/catalog.test.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
1+
import { fireEvent, render, screen, waitFor, within } from "@testing-library/react";
22
import { Provider } from "jotai";
33
import { MemoryRouter, Route, Routes } from "react-router-dom";
44
import { afterEach, beforeEach, describe, expect, it } from "vitest";
@@ -129,6 +129,7 @@ describe("UI preview catalog", () => {
129129
"command-palette",
130130
"branch-quick-pick",
131131
"footer-update-rail-review",
132+
"footer-update-rail-confirm-review",
132133
"toast-stack",
133134
"mobile-workspace-drawer",
134135
"mobile-files-sheet",
@@ -358,6 +359,24 @@ describe("UI preview catalog", () => {
358359
expect(document.querySelector(".footer-update-rail-review.mobile-shell")).toBeTruthy();
359360
});
360361

362+
it("renders the footer update confirm review scene with the post-click confirmation dialog", async () => {
363+
renderScene("footer-update-rail-confirm-review");
364+
365+
const dialog = await screen.findByRole("dialog", { name: /confirm update/i });
366+
expect(dialog).toBeInTheDocument();
367+
expect(within(dialog).getByRole("button", { name: /update now/i })).toBeInTheDocument();
368+
expect(screen.getByText(/1 terminals, 2 sessions, and 3 supervisor tasks/)).toBeInTheDocument();
369+
});
370+
371+
it("renders the footer update confirm review scene on mobile with the post-click confirmation dialog", async () => {
372+
renderScene("footer-update-rail-confirm-review", "mobile");
373+
374+
const dialog = await screen.findByRole("dialog", { name: /confirm update/i });
375+
expect(dialog).toBeInTheDocument();
376+
expect(within(dialog).getByRole("button", { name: /update now/i })).toBeInTheDocument();
377+
expect(screen.getByText(/1 terminals, 2 sessions, and 3 supervisor tasks/)).toBeInTheDocument();
378+
});
379+
361380
it("renders the workspace terminal empty review scene", async () => {
362381
renderScene("workspace-terminal-empty-review");
363382

packages/web/src/ui-preview/scene-metadata.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ describe("ui preview scene metadata", () => {
2424
"readme-desktop-review",
2525
"readme-mobile-progress",
2626
"footer-update-rail-review",
27+
"footer-update-rail-confirm-review",
2728
"workspace-topbar-review",
2829
"workspace-sidebar-files-review",
2930
"workspace-sidebar-git-review",

packages/web/src/ui-preview/scene-metadata.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,18 @@ export const UI_PREVIEW_SCENE_METADATA: UiPreviewSceneMetadata[] = [
239239
locales: ["zh", "en"],
240240
capture: { selector: ".footer-update-rail-review" },
241241
},
242+
{
243+
id: "footer-update-rail-confirm-review",
244+
title: "Footer Update Rail Confirm Review",
245+
category: "modal",
246+
source: "showcase",
247+
description:
248+
"Workspace footer review with the confirmation dialog opened after clicking Update Now.",
249+
devices: ["desktop", "mobile"],
250+
themes: allThemeIds(),
251+
locales: ["zh", "en"],
252+
capture: { selector: ".modal-overlay" },
253+
},
242254
{
243255
id: "workspace-icon-review",
244256
title: "Workspace Icon Review",

packages/web/src/ui-preview/scenes/showcase-scenes.tsx

Lines changed: 102 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { GitPanel } from "../../features/workspace/views/shared/git-panel";
2828
import { WorkspaceLaunchModal } from "../../features/workspace/views/shared/workspace-launch-modal";
2929
import { WorkspaceStatusBar } from "../../features/workspace/views/shared/workspace-status-bar";
3030
import { WorktreeManagerSurface } from "../../features/workspace/views/shared/worktree-manager-surface";
31+
import { useTranslation } from "../../lib/i18n";
3132
import type { UiPreviewSceneDefinition } from "../catalog";
3233
import { getUiPreviewSceneMetadata } from "../scene-metadata";
3334

@@ -789,6 +790,88 @@ function scene(
789790
};
790791
}
791792

793+
function FooterUpdateRailPreviewShell({
794+
device,
795+
className,
796+
}: {
797+
device: "desktop" | "mobile";
798+
className: string;
799+
}) {
800+
return device === "mobile" ? (
801+
<div
802+
className={`${className} mobile-shell mobile-shell--stacked mobile-shell--motion-reduced`}
803+
data-testid="mobile-shell"
804+
>
805+
<MobileTopBar
806+
activeWorkspace={workspace}
807+
drawerOpen={false}
808+
onOpenSettings={() => {}}
809+
onToggleDrawer={() => {}}
810+
/>
811+
<main className="mobile-shell__viewport">
812+
<div className="mobile-shell__content" style={{ paddingBottom: "144px" }} />
813+
</main>
814+
<div
815+
className="mobile-shell__bottom-stack"
816+
data-testid="mobile-bottom-stack"
817+
style={{ "--mobile-keyboard-inset": "0px" } as CSSProperties}
818+
>
819+
<div className="mobile-dock-shell">
820+
<MobileDock activeItem="agent" onSelectItem={() => {}} />
821+
</div>
822+
<WorkspaceStatusBar workspaceId={workspace.id} gitState={readmeDesktopGitStatus} />
823+
</div>
824+
</div>
825+
) : (
826+
<div className={className}>
827+
<div className="workspace-page workspace-page--desktop">
828+
<TopBar />
829+
<div className="workspace-body">
830+
<div className="workspace-main-area">
831+
<div className="workspace-main-stage" />
832+
</div>
833+
</div>
834+
<WorkspaceStatusBar
835+
align="start"
836+
workspaceId={workspace.id}
837+
gitState={readmeDesktopGitStatus}
838+
/>
839+
</div>
840+
</div>
841+
);
842+
}
843+
844+
function FooterUpdateRailConfirmPreview({ device }: { device: "desktop" | "mobile" }) {
845+
const t = useTranslation();
846+
847+
return (
848+
<>
849+
<FooterUpdateRailPreviewShell className="footer-update-rail-confirm-review" device={device} />
850+
<ConfirmDialog
851+
open
852+
onOpenChange={() => {}}
853+
title={t("settings.about.confirm_update_title")}
854+
description={
855+
<div className="settings-dialog-copy">
856+
<p>{t("settings.about.confirm_update_message")}</p>
857+
<p>
858+
{t("settings.about.confirm_update_activity", {
859+
terminals: 1,
860+
sessions: 2,
861+
supervisors: 3,
862+
})}
863+
</p>
864+
</div>
865+
}
866+
cancelText={t("action.cancel")}
867+
confirmText={t("settings.about.update_now")}
868+
tone="danger"
869+
onConfirm={() => {}}
870+
/>
871+
</>
872+
);
873+
}
874+
792875
export function createShowcaseScenes(): UiPreviewSceneDefinition[] {
793876
return [
794877
scene("workspace-launch-modal", {
@@ -884,49 +967,25 @@ export function createShowcaseScenes(): UiPreviewSceneDefinition[] {
884967
},
885968
updateState: footerUpdateRailPreviewState,
886969
}),
887-
render: (context) =>
888-
context.device === "mobile" ? (
889-
<div
890-
className="footer-update-rail-review mobile-shell mobile-shell--stacked mobile-shell--motion-reduced"
891-
data-testid="mobile-shell"
892-
>
893-
<MobileTopBar
894-
activeWorkspace={workspace}
895-
drawerOpen={false}
896-
onOpenSettings={() => {}}
897-
onToggleDrawer={() => {}}
898-
/>
899-
<main className="mobile-shell__viewport">
900-
<div className="mobile-shell__content" style={{ paddingBottom: "144px" }} />
901-
</main>
902-
<div
903-
className="mobile-shell__bottom-stack"
904-
data-testid="mobile-bottom-stack"
905-
style={{ "--mobile-keyboard-inset": "0px" } as CSSProperties}
906-
>
907-
<div className="mobile-dock-shell">
908-
<MobileDock activeItem="agent" onSelectItem={() => {}} />
909-
</div>
910-
<WorkspaceStatusBar workspaceId={workspace.id} gitState={readmeDesktopGitStatus} />
911-
</div>
912-
</div>
913-
) : (
914-
<div className="footer-update-rail-review">
915-
<div className="workspace-page workspace-page--desktop">
916-
<TopBar />
917-
<div className="workspace-body">
918-
<div className="workspace-main-area">
919-
<div className="workspace-main-stage" />
920-
</div>
921-
</div>
922-
<WorkspaceStatusBar
923-
align="start"
924-
workspaceId={workspace.id}
925-
gitState={readmeDesktopGitStatus}
926-
/>
927-
</div>
928-
</div>
929-
),
970+
render: (context) => (
971+
<FooterUpdateRailPreviewShell
972+
className="footer-update-rail-review"
973+
device={context.device}
974+
/>
975+
),
976+
}),
977+
scene("footer-update-rail-confirm-review", {
978+
router: () => ({ initialEntries: ["/workspace"], path: "/workspace" }),
979+
seed: (context) => ({
980+
...context,
981+
workspaces: [workspace],
982+
activeWorkspaceId: workspace.id,
983+
gitStateByWorkspaceId: {
984+
[workspace.id]: readmeDesktopGitStatus,
985+
},
986+
updateState: footerUpdateRailPreviewState,
987+
}),
988+
render: (context) => <FooterUpdateRailConfirmPreview device={context.device} />,
930989
}),
931990
scene("workspace-icon-review", {
932991
router: () => ({ initialEntries: ["/workspace"], path: "/workspace" }),

0 commit comments

Comments
 (0)