import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import type {
DocumentRevision,
ExecutionWorkspaceCloseReadiness,
Goal,
IssueAttachment,
} from "@paperclipai/shared";
import { useQueryClient } from "@tanstack/react-query";
import { Badge } from "@/components/ui/badge";
import { DocumentDiffModal } from "@/components/DocumentDiffModal";
import { ExecutionWorkspaceCloseDialog } from "@/components/ExecutionWorkspaceCloseDialog";
import { ImageGalleryModal } from "@/components/ImageGalleryModal";
import { NewAgentDialog } from "@/components/NewAgentDialog";
import { NewGoalDialog } from "@/components/NewGoalDialog";
import { NewIssueDialog } from "@/components/NewIssueDialog";
import { NewProjectDialog } from "@/components/NewProjectDialog";
import { PathInstructionsModal } from "@/components/PathInstructionsModal";
import { useCompany } from "@/context/CompanyContext";
import { useDialog } from "@/context/DialogContext";
import { queryKeys } from "@/lib/queryKeys";
import {
storybookAgents,
storybookAuthSession,
storybookCompanies,
storybookExecutionWorkspaces,
storybookIssueDocuments,
storybookIssueLabels,
storybookIssues,
storybookProjects,
} from "../fixtures/paperclipData";
const COMPANY_ID = "company-storybook";
const SELECTED_COMPANY_STORAGE_KEY = "paperclip.selectedCompanyId";
const ISSUE_DRAFT_STORAGE_KEY = "paperclip:issue-draft";
const storybookGoals: Goal[] = [
{
id: "goal-company",
companyId: COMPANY_ID,
title: "Build Paperclip",
description: "Make autonomous companies easier to run and govern.",
level: "company",
status: "active",
parentId: null,
ownerAgentId: "agent-cto",
createdAt: new Date("2026-04-01T09:00:00.000Z"),
updatedAt: new Date("2026-04-20T11:00:00.000Z"),
},
{
id: "goal-storybook",
companyId: COMPANY_ID,
title: "Complete Storybook coverage",
description: "Expose dense board UI states for review before release.",
level: "team",
status: "active",
parentId: "goal-company",
ownerAgentId: "agent-codex",
createdAt: new Date("2026-04-17T09:00:00.000Z"),
updatedAt: new Date("2026-04-20T11:10:00.000Z"),
},
{
id: "goal-governance",
companyId: COMPANY_ID,
title: "Tighten governance review",
description: "Make review and approval gates visible in every operator flow.",
level: "team",
status: "planned",
parentId: "goal-company",
ownerAgentId: "agent-cto",
createdAt: new Date("2026-04-18T09:00:00.000Z"),
updatedAt: new Date("2026-04-20T11:15:00.000Z"),
},
];
const documentRevisions: DocumentRevision[] = [
{
id: "revision-plan-1",
companyId: COMPANY_ID,
documentId: "document-plan-storybook",
issueId: "issue-storybook-1",
key: "plan",
revisionNumber: 1,
title: "Plan",
format: "markdown",
body: [
"# Plan",
"",
"- Add overview stories for the dashboard.",
"- Create issue list stories for filters and grouping.",
"- Ask QA to review the final Storybook build.",
].join("\n"),
changeSummary: "Initial plan",
createdByAgentId: "agent-codex",
createdByUserId: null,
createdAt: new Date("2026-04-20T08:00:00.000Z"),
},
{
id: "revision-plan-2",
companyId: COMPANY_ID,
documentId: "document-plan-storybook",
issueId: "issue-storybook-1",
key: "plan",
revisionNumber: 2,
title: "Plan",
format: "markdown",
body: [
"# Plan",
"",
"- Add overview stories for the dashboard.",
"- Create issue list stories for filters, grouping, and workspace state.",
"- Add dialog stories for issue, goal, project, and workspace workflows.",
"- Ask QA to review the final Storybook build.",
].join("\n"),
changeSummary: "Expanded component coverage",
createdByAgentId: "agent-codex",
createdByUserId: null,
createdAt: new Date("2026-04-20T10:00:00.000Z"),
},
{
id: "revision-plan-3",
companyId: COMPANY_ID,
documentId: "document-plan-storybook",
issueId: "issue-storybook-1",
key: "plan",
revisionNumber: 3,
title: "Plan",
format: "markdown",
body: storybookIssueDocuments[0]?.body ?? "",
changeSummary: "Aligned with current issue scope",
createdByAgentId: "agent-codex",
createdByUserId: null,
createdAt: new Date("2026-04-20T11:30:00.000Z"),
},
];
const closeReadinessReady: ExecutionWorkspaceCloseReadiness = {
workspaceId: "execution-workspace-storybook",
state: "ready_with_warnings",
blockingReasons: [],
warnings: [
"The branch is still two commits ahead of master.",
"One shared runtime service will be stopped during cleanup.",
],
linkedIssues: [
{
id: "issue-storybook-1",
identifier: "PAP-1641",
title: "Create super-detailed storybooks for the project",
status: "done",
isTerminal: true,
},
{
id: "issue-storybook-6",
identifier: "PAP-1670",
title: "Publish static Storybook preview",
status: "todo",
isTerminal: false,
},
],
plannedActions: [
{
kind: "stop_runtime_services",
label: "Stop Storybook preview",
description: "Stops the managed Storybook preview service before archiving the workspace record.",
command: "pnpm dev:stop",
},
{
kind: "git_worktree_remove",
label: "Remove git worktree",
description: "Removes the issue worktree from the local worktree parent directory.",
command: "git worktree remove .paperclip/worktrees/PAP-1641-create-super-detailed-storybooks-for-our-project",
},
{
kind: "archive_record",
label: "Archive workspace record",
description: "Keeps audit history while removing the workspace from active workspace views.",
command: null,
},
],
isDestructiveCloseAllowed: true,
isSharedWorkspace: false,
isProjectPrimaryWorkspace: false,
git: {
repoRoot: "/Users/dotta/paperclip",
workspacePath: "/Users/dotta/paperclip/.paperclip/worktrees/PAP-1641-create-super-detailed-storybooks-for-our-project",
branchName: "PAP-1641-create-super-detailed-storybooks-for-our-project",
baseRef: "master",
hasDirtyTrackedFiles: true,
hasUntrackedFiles: false,
dirtyEntryCount: 3,
untrackedEntryCount: 0,
aheadCount: 2,
behindCount: 0,
isMergedIntoBase: false,
createdByRuntime: true,
},
runtimeServices: storybookExecutionWorkspaces[0]?.runtimeServices ?? [],
};
const closeReadinessBlocked: ExecutionWorkspaceCloseReadiness = {
...closeReadinessReady,
state: "blocked",
blockingReasons: [
"PAP-1670 is still open and references this execution workspace.",
"The worktree has dirty tracked files that have not been committed.",
],
warnings: [],
plannedActions: closeReadinessReady.plannedActions.slice(0, 1),
};
const galleryImages: IssueAttachment[] = [
{
id: "attachment-storybook-dashboard",
companyId: COMPANY_ID,
issueId: "issue-storybook-1",
issueCommentId: null,
assetId: "asset-dashboard",
provider: "storybook",
objectKey: "storybook/dashboard-preview.svg",
contentType: "image/svg+xml",
byteSize: 1480,
sha256: "storybook-dashboard-preview",
originalFilename: "dashboard-preview.png",
createdByAgentId: "agent-codex",
createdByUserId: null,
createdAt: new Date("2026-04-20T10:30:00.000Z"),
updatedAt: new Date("2026-04-20T10:30:00.000Z"),
contentPath:
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1400' height='900' viewBox='0 0 1400 900'%3E%3Crect width='1400' height='900' fill='%230f172a'/%3E%3Crect x='88' y='96' width='1224' height='708' rx='28' fill='%23111827' stroke='%23334155' stroke-width='4'/%3E%3Crect x='136' y='148' width='264' height='604' rx='18' fill='%231e293b'/%3E%3Crect x='444' y='148' width='380' height='190' rx='18' fill='%230f766e'/%3E%3Crect x='860' y='148' width='348' height='190' rx='18' fill='%232563eb'/%3E%3Crect x='444' y='382' width='764' height='104' rx='18' fill='%23334155'/%3E%3Crect x='444' y='526' width='764' height='104' rx='18' fill='%23334155'/%3E%3Crect x='444' y='670' width='520' height='82' rx='18' fill='%23334155'/%3E%3Ccircle cx='236' cy='236' r='58' fill='%2314b8a6'/%3E%3Crect x='188' y='334' width='164' height='18' rx='9' fill='%2394a3b8'/%3E%3Crect x='188' y='386' width='128' height='18' rx='9' fill='%2364748b'/%3E%3Crect x='188' y='438' width='176' height='18' rx='9' fill='%2364748b'/%3E%3C/svg%3E",
},
{
id: "attachment-storybook-diff",
companyId: COMPANY_ID,
issueId: "issue-storybook-1",
issueCommentId: null,
assetId: "asset-diff",
provider: "storybook",
objectKey: "storybook/diff-preview.svg",
contentType: "image/svg+xml",
byteSize: 1320,
sha256: "storybook-diff-preview",
originalFilename: "document-diff-preview.png",
createdByAgentId: "agent-qa",
createdByUserId: null,
createdAt: new Date("2026-04-20T10:40:00.000Z"),
updatedAt: new Date("2026-04-20T10:40:00.000Z"),
contentPath:
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1400' height='900' viewBox='0 0 1400 900'%3E%3Crect width='1400' height='900' fill='%23171717'/%3E%3Crect x='110' y='104' width='1180' height='692' rx='24' fill='%230a0a0a' stroke='%23333333' stroke-width='4'/%3E%3Crect x='160' y='164' width='1080' height='48' rx='12' fill='%23262626'/%3E%3Crect x='160' y='260' width='1080' height='52' fill='%2315221a'/%3E%3Crect x='160' y='312' width='1080' height='52' fill='%23231818'/%3E%3Crect x='160' y='364' width='1080' height='52' fill='%2315221a'/%3E%3Crect x='160' y='468' width='1080' height='52' fill='%23231818'/%3E%3Crect x='160' y='520' width='1080' height='52' fill='%2315221a'/%3E%3Crect x='220' y='276' width='720' height='18' rx='9' fill='%2374c69d'/%3E%3Crect x='220' y='328' width='540' height='18' rx='9' fill='%23fca5a5'/%3E%3Crect x='220' y='380' width='820' height='18' rx='9' fill='%2374c69d'/%3E%3Crect x='220' y='484' width='480' height='18' rx='9' fill='%23fca5a5'/%3E%3Crect x='220' y='536' width='760' height='18' rx='9' fill='%2374c69d'/%3E%3C/svg%3E",
},
];
function Section({
eyebrow,
title,
description,
children,
}: {
eyebrow: string;
title: string;
description?: string;
children: ReactNode;
}) {
return (
{description}{title}
{description ? (