Add Storybook stories for issue monitor UI surfaces

Captures both IssueMonitorActivityCard variants (external service, generic
wait, no monitor) and the IssueProperties Monitor row in scheduled and
not-scheduled states so future UX reviews can render the surface.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-05-01 20:58:29 -05:00
1 parent 710b11de9e
commit 7e80b7af22
1 file changed
+142
@@ -0,0 +1,142 @@
import type { Meta, StoryObj } from "@storybook/react-vite";
import type { Issue } from "@paperclipai/shared";
import { IssueMonitorActivityCard } from "@/components/IssueMonitorActivityCard";
import { IssueProperties } from "@/components/IssueProperties";
import {
storybookExecutionWorkspaces,
storybookIssueDocuments,
storybookIssues,
} from "../fixtures/paperclipData";
const issueDocumentSummaries = storybookIssueDocuments.map(({ body: _body, ...summary }) => summary);
const baseIssue: Issue = {
...storybookIssues[0]!,
planDocument: storybookIssueDocuments.find((document) => document.key === "plan") ?? null,
documentSummaries: issueDocumentSummaries,
currentExecutionWorkspace: storybookExecutionWorkspaces[0]!,
};
const inFiveMinutes = () => new Date(Date.now() + 5 * 60_000);
const inTwoHours = () => new Date(Date.now() + 2 * 60 * 60_000);
const monitoredIssue: Issue = {
...baseIssue,
monitorNextCheckAt: inFiveMinutes(),
monitorNotes: "Polling Greptile for completed analysis.",
monitorAttemptCount: 2,
executionPolicy: {
...(baseIssue.executionPolicy ?? { mode: "normal", commentRequired: true, stages: [] }),
monitor: {
nextCheckAt: inFiveMinutes().toISOString(),
notes: "Polling Greptile for completed analysis.",
kind: "external_service",
scheduledBy: "assignee",
serviceName: "Greptile",
externalRef: "https://app.greptile.com/runs/abc123",
},
},
};
const longerWaitIssue: Issue = {
...baseIssue,
monitorNextCheckAt: inTwoHours(),
monitorNotes: null,
monitorAttemptCount: 0,
executionPolicy: {
...(baseIssue.executionPolicy ?? { mode: "normal", commentRequired: true, stages: [] }),
monitor: {
nextCheckAt: inTwoHours().toISOString(),
notes: null,
kind: null,
scheduledBy: "assignee",
serviceName: null,
externalRef: null,
},
},
};
function MonitorSurfaceStories() {
return (
<div className="space-y-8 p-6">
<section className="space-y-2">
<div className="text-xs uppercase tracking-wide text-muted-foreground">
IssueMonitorActivityCard - external service (Greptile)
</div>
<IssueMonitorActivityCard
issue={monitoredIssue}
onCheckNow={() => undefined}
checkingNow={false}
/>
</section>
<section className="space-y-2">
<div className="text-xs uppercase tracking-wide text-muted-foreground">
IssueMonitorActivityCard - generic 2h wait, no service metadata
</div>
<IssueMonitorActivityCard
issue={longerWaitIssue}
onCheckNow={() => undefined}
checkingNow={false}
/>
</section>
<section className="space-y-2">
<div className="text-xs uppercase tracking-wide text-muted-foreground">
IssueMonitorActivityCard - returns null when no monitor is set
</div>
<div className="rounded-lg border border-dashed border-border px-3 py-2 text-xs text-muted-foreground">
(intentionally renders nothing for issues without a scheduled monitor)
</div>
<IssueMonitorActivityCard issue={baseIssue} onCheckNow={() => undefined} />
</section>
<div className="grid gap-6 lg:grid-cols-2">
<section className="space-y-2">
<div className="text-xs uppercase tracking-wide text-muted-foreground">
IssueProperties Monitor row - Not scheduled (default state)
</div>
<div className="rounded-lg border border-border bg-background/70 p-4">
<IssueProperties
issue={baseIssue}
onUpdate={() => undefined}
inline
/>
</div>
</section>
<section className="space-y-2">
<div className="text-xs uppercase tracking-wide text-muted-foreground">
IssueProperties Monitor row - Scheduled (Greptile, in 5m)
</div>
<div className="rounded-lg border border-border bg-background/70 p-4">
<IssueProperties
issue={monitoredIssue}
onUpdate={() => undefined}
inline
/>
</div>
</section>
</div>
</div>
);
}
const meta = {
title: "Product/Issue Monitor surfaces",
component: MonitorSurfaceStories,
parameters: {
docs: {
description: {
component:
"Surfaces the IssueMonitorActivityCard and IssueProperties Monitor row in scheduled / not-scheduled / external-service variants for UX review.",
},
},
},
} satisfies Meta<typeof MonitorSurfaceStories>;
export default meta;
type Story = StoryObj<typeof meta>;
export const MonitorSurfaces: Story = {};