diff --git a/README.md b/README.md index 18ab5de..f7b04fc 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ Self-hosting not your thing? A hosted version of JobOps is coming. - Managed updates - Self-hosted will always be free and open source -👉 Join the waitlist at https://try.jobops.app?utm_source=github&utm_medium=readme&utm_campaign=waitlist +👉 Join the waitlist at [https://try.jobops.app](https://try.jobops.app?utm_source=github&utm_medium=readme&utm_campaign=waitlist) ## Contributing diff --git a/orchestrator/src/client/pages/OrchestratorPage.test.tsx b/orchestrator/src/client/pages/OrchestratorPage.test.tsx index f9ebd4d..6ed10b7 100644 --- a/orchestrator/src/client/pages/OrchestratorPage.test.tsx +++ b/orchestrator/src/client/pages/OrchestratorPage.test.tsx @@ -46,6 +46,7 @@ vi.mock("sonner", () => ({ })); let mockIsPipelineRunning = false; +let mockDemoMode = false; let mockPipelineTerminalEvent: { status: "completed" | "cancelled" | "failed"; errorMessage: string | null; @@ -125,6 +126,17 @@ vi.mock("./orchestrator/useOrchestratorData", () => ({ }), })); +vi.mock("../hooks/useDemoInfo", () => ({ + useDemoInfo: () => ({ + demoMode: mockDemoMode, + resetCadenceHours: 6, + lastResetAt: null, + nextResetAt: null, + baselineVersion: null, + baselineName: null, + }), +})); + vi.mock("./orchestrator/usePipelineSources", () => ({ usePipelineSources: () => ({ pipelineSources: mockPipelineSources, @@ -373,6 +385,7 @@ describe("OrchestratorPage", () => { vi.clearAllMocks(); localStorage.clear(); localStorage.setItem("has-seen-keyboard-shortcuts", "true"); + mockDemoMode = false; mockIsPipelineRunning = false; mockPipelineTerminalEvent = null; mockPipelineSources = ["linkedin"]; @@ -1068,6 +1081,25 @@ describe("OrchestratorPage", () => { }); }); + it("does not auto-open the keyboard shortcut dialog in demo mode", () => { + mockDemoMode = true; + localStorage.removeItem("has-seen-keyboard-shortcuts"); + window.matchMedia = createMatchMedia( + true, + ) as unknown as typeof window.matchMedia; + + render( + + + } /> + } /> + + , + ); + + expect(screen.getByTestId("help-dialog")).toHaveTextContent("closed"); + }); + it("disables other shortcuts while help dialog is open", async () => { window.matchMedia = createMatchMedia( true, diff --git a/orchestrator/src/client/pages/OrchestratorPage.tsx b/orchestrator/src/client/pages/OrchestratorPage.tsx index 8e9f18a..31cd5c7 100644 --- a/orchestrator/src/client/pages/OrchestratorPage.tsx +++ b/orchestrator/src/client/pages/OrchestratorPage.tsx @@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button"; import { Drawer, DrawerClose, DrawerContent } from "@/components/ui/drawer"; import { KeyboardShortcutBar } from "../components/KeyboardShortcutBar"; import { KeyboardShortcutDialog } from "../components/KeyboardShortcutDialog"; +import { useDemoInfo } from "../hooks/useDemoInfo"; import type { FilterTab } from "./orchestrator/constants"; import { FloatingJobActionsBar } from "./orchestrator/FloatingJobActionsBar"; import { JobCommandBar } from "./orchestrator/JobCommandBar"; @@ -107,6 +108,7 @@ export const OrchestratorPage: React.FC = () => { ); const { settings } = useSettings(); + const demoInfo = useDemoInfo(); const { jobs, selectedJob, @@ -305,11 +307,12 @@ export const OrchestratorPage: React.FC = () => { }, [isDesktop, isDetailDrawerOpen]); useEffect(() => { + if (demoInfo?.demoMode) return; const hasSeen = localStorage.getItem("has-seen-keyboard-shortcuts"); if (!hasSeen) { setIsHelpDialogOpen(true); } - }, []); + }, [demoInfo?.demoMode]); const onDrawerOpenChange = (open: boolean) => { setIsDetailDrawerOpen(open);