@shipfox/client-onboarding 23.0.0 → 25.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +28 -0
- package/README.md +26 -7
- package/dist/components/setup-checklist-body.d.ts +3 -0
- package/dist/components/setup-checklist-body.d.ts.map +1 -0
- package/dist/components/setup-checklist-body.js +25 -0
- package/dist/components/setup-checklist-body.js.map +1 -0
- package/dist/components/setup-checklist-completion.d.ts +6 -0
- package/dist/components/setup-checklist-completion.d.ts.map +1 -0
- package/dist/components/setup-checklist-completion.js +156 -0
- package/dist/components/setup-checklist-completion.js.map +1 -0
- package/dist/components/setup-checklist-confetti.d.ts +13 -0
- package/dist/components/setup-checklist-confetti.d.ts.map +1 -0
- package/dist/components/setup-checklist-confetti.js +24 -0
- package/dist/components/setup-checklist-confetti.js.map +1 -0
- package/dist/components/setup-checklist-host-primitives.d.ts +11 -0
- package/dist/components/setup-checklist-host-primitives.d.ts.map +1 -0
- package/dist/components/setup-checklist-host-primitives.js +71 -0
- package/dist/components/setup-checklist-host-primitives.js.map +1 -0
- package/dist/components/setup-checklist-row.d.ts +7 -0
- package/dist/components/setup-checklist-row.d.ts.map +1 -0
- package/dist/components/setup-checklist-row.js +177 -0
- package/dist/components/setup-checklist-row.js.map +1 -0
- package/dist/components/setup-checklist-types.d.ts +19 -0
- package/dist/components/setup-checklist-types.d.ts.map +1 -0
- package/dist/components/setup-checklist-types.js +3 -0
- package/dist/components/setup-checklist-types.js.map +1 -0
- package/dist/components/setup-checklist.d.ts +5 -0
- package/dist/components/setup-checklist.d.ts.map +1 -0
- package/dist/components/setup-checklist.js +5 -0
- package/dist/components/setup-checklist.js.map +1 -0
- package/dist/components/setup-checklist.stories.d.ts +19 -0
- package/dist/components/setup-checklist.stories.d.ts.map +1 -0
- package/dist/components/setup-checklist.stories.js +305 -0
- package/dist/components/setup-checklist.stories.js.map +1 -0
- package/dist/components/workspace-setup-checklist.d.ts +3 -0
- package/dist/components/workspace-setup-checklist.d.ts.map +1 -0
- package/dist/components/workspace-setup-checklist.js +80 -0
- package/dist/components/workspace-setup-checklist.js.map +1 -0
- package/dist/components/workspace-setup-indicator.d.ts +3 -0
- package/dist/components/workspace-setup-indicator.d.ts.map +1 -0
- package/dist/components/workspace-setup-indicator.js +133 -0
- package/dist/components/workspace-setup-indicator.js.map +1 -0
- package/dist/core/setup-checklist.d.ts +2 -0
- package/dist/core/setup-checklist.d.ts.map +1 -1
- package/dist/core/setup-checklist.js +11 -6
- package/dist/core/setup-checklist.js.map +1 -1
- package/dist/feature.d.ts +6 -0
- package/dist/feature.d.ts.map +1 -0
- package/dist/feature.js +19 -0
- package/dist/feature.js.map +1 -0
- package/dist/hooks/api/setup-checklist.d.ts +13 -0
- package/dist/hooks/api/setup-checklist.d.ts.map +1 -0
- package/dist/hooks/api/setup-checklist.js +103 -0
- package/dist/hooks/api/setup-checklist.js.map +1 -0
- package/dist/hooks/use-checklist-analytics.d.ts +6 -0
- package/dist/hooks/use-checklist-analytics.d.ts.map +1 -0
- package/dist/hooks/use-checklist-analytics.js +51 -0
- package/dist/hooks/use-checklist-analytics.js.map +1 -0
- package/dist/hooks/use-checklist-dismissal.d.ts +5 -0
- package/dist/hooks/use-checklist-dismissal.d.ts.map +1 -0
- package/dist/hooks/use-checklist-dismissal.js +31 -0
- package/dist/hooks/use-checklist-dismissal.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +12 -5
- package/src/components/setup-checklist-body.tsx +35 -0
- package/src/components/setup-checklist-completion.test.tsx +124 -0
- package/src/components/setup-checklist-completion.tsx +165 -0
- package/src/components/setup-checklist-confetti.test.ts +19 -0
- package/src/components/setup-checklist-confetti.ts +39 -0
- package/src/components/setup-checklist-host-primitives.tsx +65 -0
- package/src/components/setup-checklist-row.tsx +189 -0
- package/src/components/setup-checklist-types.ts +21 -0
- package/src/components/setup-checklist.stories.tsx +281 -0
- package/src/components/setup-checklist.test.tsx +564 -0
- package/src/components/setup-checklist.tsx +8 -0
- package/src/components/workspace-setup-checklist.tsx +91 -0
- package/src/components/workspace-setup-indicator.tsx +126 -0
- package/src/core/setup-checklist.test.ts +2 -2
- package/src/core/setup-checklist.ts +19 -10
- package/src/feature.ts +16 -0
- package/src/hooks/api/setup-checklist.ts +144 -0
- package/src/hooks/use-checklist-analytics.ts +60 -0
- package/src/hooks/use-checklist-dismissal.ts +30 -0
- package/src/index.ts +8 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/vitest.config.ts +2 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ButtonLink } from '@shipfox/react-ui/button';
|
|
3
|
+
import { Icon } from '@shipfox/react-ui/icon';
|
|
4
|
+
import { Text } from '@shipfox/react-ui/typography';
|
|
5
|
+
import { cn } from '@shipfox/react-ui/utils';
|
|
6
|
+
import { Link } from '@tanstack/react-router';
|
|
7
|
+
const GETTING_STARTED_URL = 'https://www.shipfox.io/docs/getting-started';
|
|
8
|
+
export function ChecklistRow({ item, workspaceSlug, onAction }) {
|
|
9
|
+
const pointer = !item.tracked;
|
|
10
|
+
const showDetails = pointer || item.status === 'open';
|
|
11
|
+
const statusLabel = item.status === 'done' ? 'done' : pointer ? 'next step' : item.attention ? 'needs attention' : 'to do';
|
|
12
|
+
return /*#__PURE__*/ _jsxs("li", {
|
|
13
|
+
className: "flex min-w-0 items-start gap-group border-b border-border-neutral-base px-row py-row last:border-b-0",
|
|
14
|
+
children: [
|
|
15
|
+
/*#__PURE__*/ _jsx(ChecklistStatus, {
|
|
16
|
+
item: item,
|
|
17
|
+
pointer: pointer,
|
|
18
|
+
label: statusLabel
|
|
19
|
+
}),
|
|
20
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
21
|
+
className: "min-w-0 flex-1",
|
|
22
|
+
children: [
|
|
23
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
24
|
+
as: "span",
|
|
25
|
+
size: "sm",
|
|
26
|
+
className: cn('block', item.status === 'done' && !pointer ? 'text-foreground-neutral-muted' : 'text-foreground-neutral-base'),
|
|
27
|
+
children: item.title
|
|
28
|
+
}),
|
|
29
|
+
showDetails && item.purpose ? /*#__PURE__*/ _jsx(Text, {
|
|
30
|
+
as: "span",
|
|
31
|
+
size: "xs",
|
|
32
|
+
className: "mt-tight block text-foreground-neutral-muted",
|
|
33
|
+
children: item.purpose
|
|
34
|
+
}) : null,
|
|
35
|
+
showDetails && item.action ? /*#__PURE__*/ _jsx("div", {
|
|
36
|
+
className: "mt-inline",
|
|
37
|
+
children: /*#__PURE__*/ _jsx(ChecklistActionLink, {
|
|
38
|
+
item: item,
|
|
39
|
+
action: item.action,
|
|
40
|
+
pointer: pointer,
|
|
41
|
+
workspaceSlug: workspaceSlug,
|
|
42
|
+
onAction: onAction
|
|
43
|
+
})
|
|
44
|
+
}) : null
|
|
45
|
+
]
|
|
46
|
+
})
|
|
47
|
+
]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function ChecklistStatus({ item, pointer, label }) {
|
|
51
|
+
if (pointer) {
|
|
52
|
+
return /*#__PURE__*/ _jsxs("span", {
|
|
53
|
+
className: "mt-1 shrink-0",
|
|
54
|
+
children: [
|
|
55
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
56
|
+
name: item.status === 'done' ? 'checkCircleSolid' : 'circleDottedLine',
|
|
57
|
+
className: cn('size-16', item.status === 'done' ? 'text-foreground-highlight-interactive' : 'text-foreground-neutral-subtle'),
|
|
58
|
+
"aria-hidden": "true"
|
|
59
|
+
}),
|
|
60
|
+
/*#__PURE__*/ _jsx("span", {
|
|
61
|
+
className: "sr-only",
|
|
62
|
+
children: label
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (item.status === 'done') {
|
|
68
|
+
return /*#__PURE__*/ _jsxs("span", {
|
|
69
|
+
className: "mt-1 shrink-0",
|
|
70
|
+
children: [
|
|
71
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
72
|
+
name: "checkCircleSolid",
|
|
73
|
+
className: "size-16 text-foreground-highlight-interactive",
|
|
74
|
+
"aria-hidden": "true"
|
|
75
|
+
}),
|
|
76
|
+
/*#__PURE__*/ _jsx("span", {
|
|
77
|
+
className: "sr-only",
|
|
78
|
+
children: label
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return /*#__PURE__*/ _jsxs("span", {
|
|
84
|
+
className: "mt-1 shrink-0",
|
|
85
|
+
children: [
|
|
86
|
+
/*#__PURE__*/ _jsx("span", {
|
|
87
|
+
"aria-hidden": "true",
|
|
88
|
+
className: "block size-16 rounded-full border-2 border-foreground-neutral-subtle"
|
|
89
|
+
}),
|
|
90
|
+
/*#__PURE__*/ _jsx("span", {
|
|
91
|
+
className: "sr-only",
|
|
92
|
+
children: label
|
|
93
|
+
})
|
|
94
|
+
]
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function ChecklistActionLink({ item, action, pointer, workspaceSlug, onAction }) {
|
|
98
|
+
const handleClick = ()=>onAction?.(item);
|
|
99
|
+
const variant = pointer ? 'muted' : 'interactive';
|
|
100
|
+
if (action.href === '/docs/getting-started') {
|
|
101
|
+
return /*#__PURE__*/ _jsx(ButtonLink, {
|
|
102
|
+
asChild: true,
|
|
103
|
+
variant: variant,
|
|
104
|
+
underline: true,
|
|
105
|
+
iconRight: "chevronRight",
|
|
106
|
+
children: /*#__PURE__*/ _jsx("a", {
|
|
107
|
+
href: GETTING_STARTED_URL,
|
|
108
|
+
onClick: handleClick,
|
|
109
|
+
children: action.label
|
|
110
|
+
})
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (action.href === '/settings/integrations') {
|
|
114
|
+
return /*#__PURE__*/ _jsx(ButtonLink, {
|
|
115
|
+
asChild: true,
|
|
116
|
+
variant: variant,
|
|
117
|
+
underline: true,
|
|
118
|
+
iconRight: "chevronRight",
|
|
119
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
120
|
+
to: "/w/$workspaceSlug/settings/integrations",
|
|
121
|
+
params: {
|
|
122
|
+
workspaceSlug
|
|
123
|
+
},
|
|
124
|
+
onClick: handleClick,
|
|
125
|
+
children: action.label
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (action.href === '/settings/runners') {
|
|
130
|
+
return /*#__PURE__*/ _jsx(ButtonLink, {
|
|
131
|
+
asChild: true,
|
|
132
|
+
variant: variant,
|
|
133
|
+
underline: true,
|
|
134
|
+
iconRight: "chevronRight",
|
|
135
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
136
|
+
to: "/w/$workspaceSlug/settings/runners",
|
|
137
|
+
params: {
|
|
138
|
+
workspaceSlug
|
|
139
|
+
},
|
|
140
|
+
onClick: handleClick,
|
|
141
|
+
children: action.label
|
|
142
|
+
})
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (action.href === '/settings/agents') {
|
|
146
|
+
return /*#__PURE__*/ _jsx(ButtonLink, {
|
|
147
|
+
asChild: true,
|
|
148
|
+
variant: variant,
|
|
149
|
+
underline: true,
|
|
150
|
+
iconRight: "chevronRight",
|
|
151
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
152
|
+
to: "/w/$workspaceSlug/settings/agents",
|
|
153
|
+
params: {
|
|
154
|
+
workspaceSlug
|
|
155
|
+
},
|
|
156
|
+
onClick: handleClick,
|
|
157
|
+
children: action.label
|
|
158
|
+
})
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return /*#__PURE__*/ _jsx(ButtonLink, {
|
|
162
|
+
asChild: true,
|
|
163
|
+
variant: variant,
|
|
164
|
+
underline: true,
|
|
165
|
+
iconRight: "chevronRight",
|
|
166
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
167
|
+
to: "/w/$workspaceSlug/settings/members",
|
|
168
|
+
params: {
|
|
169
|
+
workspaceSlug
|
|
170
|
+
},
|
|
171
|
+
onClick: handleClick,
|
|
172
|
+
children: action.label
|
|
173
|
+
})
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
//# sourceMappingURL=setup-checklist-row.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/setup-checklist-row.tsx"],"sourcesContent":["import {ButtonLink} from '@shipfox/react-ui/button';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {Link} from '@tanstack/react-router';\nimport type {SetupChecklistItem} from '#core/setup-checklist.js';\n\nconst GETTING_STARTED_URL = 'https://www.shipfox.io/docs/getting-started';\n\nexport function ChecklistRow({\n item,\n workspaceSlug,\n onAction,\n}: {\n item: SetupChecklistItem;\n workspaceSlug: string;\n onAction?: ((item: SetupChecklistItem) => void) | undefined;\n}) {\n const pointer = !item.tracked;\n const showDetails = pointer || item.status === 'open';\n const statusLabel =\n item.status === 'done'\n ? 'done'\n : pointer\n ? 'next step'\n : item.attention\n ? 'needs attention'\n : 'to do';\n\n return (\n <li className=\"flex min-w-0 items-start gap-group border-b border-border-neutral-base px-row py-row last:border-b-0\">\n <ChecklistStatus item={item} pointer={pointer} label={statusLabel} />\n <div className=\"min-w-0 flex-1\">\n <Text\n as=\"span\"\n size=\"sm\"\n className={cn(\n 'block',\n item.status === 'done' && !pointer\n ? 'text-foreground-neutral-muted'\n : 'text-foreground-neutral-base',\n )}\n >\n {item.title}\n </Text>\n {showDetails && item.purpose ? (\n <Text as=\"span\" size=\"xs\" className=\"mt-tight block text-foreground-neutral-muted\">\n {item.purpose}\n </Text>\n ) : null}\n {showDetails && item.action ? (\n <div className=\"mt-inline\">\n <ChecklistActionLink\n item={item}\n action={item.action}\n pointer={pointer}\n workspaceSlug={workspaceSlug}\n onAction={onAction}\n />\n </div>\n ) : null}\n </div>\n </li>\n );\n}\n\nfunction ChecklistStatus({\n item,\n pointer,\n label,\n}: {\n item: SetupChecklistItem;\n pointer: boolean;\n label: string;\n}) {\n if (pointer) {\n return (\n <span className=\"mt-1 shrink-0\">\n <Icon\n name={item.status === 'done' ? 'checkCircleSolid' : 'circleDottedLine'}\n className={cn(\n 'size-16',\n item.status === 'done'\n ? 'text-foreground-highlight-interactive'\n : 'text-foreground-neutral-subtle',\n )}\n aria-hidden=\"true\"\n />\n <span className=\"sr-only\">{label}</span>\n </span>\n );\n }\n\n if (item.status === 'done') {\n return (\n <span className=\"mt-1 shrink-0\">\n <Icon\n name=\"checkCircleSolid\"\n className=\"size-16 text-foreground-highlight-interactive\"\n aria-hidden=\"true\"\n />\n <span className=\"sr-only\">{label}</span>\n </span>\n );\n }\n\n return (\n <span className=\"mt-1 shrink-0\">\n <span\n aria-hidden=\"true\"\n className=\"block size-16 rounded-full border-2 border-foreground-neutral-subtle\"\n />\n <span className=\"sr-only\">{label}</span>\n </span>\n );\n}\n\nfunction ChecklistActionLink({\n item,\n action,\n pointer,\n workspaceSlug,\n onAction,\n}: {\n item: SetupChecklistItem;\n action: NonNullable<SetupChecklistItem['action']>;\n pointer: boolean;\n workspaceSlug: string;\n onAction?: ((item: SetupChecklistItem) => void) | undefined;\n}) {\n const handleClick = () => onAction?.(item);\n const variant = pointer ? 'muted' : 'interactive';\n\n if (action.href === '/docs/getting-started') {\n return (\n <ButtonLink asChild variant={variant} underline iconRight=\"chevronRight\">\n <a href={GETTING_STARTED_URL} onClick={handleClick}>\n {action.label}\n </a>\n </ButtonLink>\n );\n }\n\n if (action.href === '/settings/integrations') {\n return (\n <ButtonLink asChild variant={variant} underline iconRight=\"chevronRight\">\n <Link\n to=\"/w/$workspaceSlug/settings/integrations\"\n params={{workspaceSlug}}\n onClick={handleClick}\n >\n {action.label}\n </Link>\n </ButtonLink>\n );\n }\n\n if (action.href === '/settings/runners') {\n return (\n <ButtonLink asChild variant={variant} underline iconRight=\"chevronRight\">\n <Link\n to=\"/w/$workspaceSlug/settings/runners\"\n params={{workspaceSlug}}\n onClick={handleClick}\n >\n {action.label}\n </Link>\n </ButtonLink>\n );\n }\n\n if (action.href === '/settings/agents') {\n return (\n <ButtonLink asChild variant={variant} underline iconRight=\"chevronRight\">\n <Link to=\"/w/$workspaceSlug/settings/agents\" params={{workspaceSlug}} onClick={handleClick}>\n {action.label}\n </Link>\n </ButtonLink>\n );\n }\n\n return (\n <ButtonLink asChild variant={variant} underline iconRight=\"chevronRight\">\n <Link to=\"/w/$workspaceSlug/settings/members\" params={{workspaceSlug}} onClick={handleClick}>\n {action.label}\n </Link>\n </ButtonLink>\n );\n}\n"],"names":["ButtonLink","Icon","Text","cn","Link","GETTING_STARTED_URL","ChecklistRow","item","workspaceSlug","onAction","pointer","tracked","showDetails","status","statusLabel","attention","li","className","ChecklistStatus","label","div","as","size","title","purpose","action","ChecklistActionLink","span","name","aria-hidden","handleClick","variant","href","asChild","underline","iconRight","a","onClick","to","params"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SetupChecklist, SetupChecklistItem } from '#core/setup-checklist.js';
|
|
2
|
+
export interface WorkspaceReference {
|
|
3
|
+
id: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WorkspaceSetupHostProps {
|
|
7
|
+
/** A stable workspace makes the hosts easy to compose in isolated surfaces and stories. */
|
|
8
|
+
workspace?: WorkspaceReference;
|
|
9
|
+
}
|
|
10
|
+
export interface SetupChecklistBodyProps {
|
|
11
|
+
checklist: SetupChecklist;
|
|
12
|
+
workspaceSlug: string;
|
|
13
|
+
completion?: boolean;
|
|
14
|
+
showBurst?: boolean;
|
|
15
|
+
onBurstComplete?: () => void;
|
|
16
|
+
onAction?: ((item: SetupChecklistItem) => void) | undefined;
|
|
17
|
+
onDone?: () => void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=setup-checklist-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-checklist-types.d.ts","sourceRoot":"","sources":["../../src/components/setup-checklist-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,2FAA2F;IAC3F,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,cAAc,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/setup-checklist-types.ts"],"sourcesContent":["import type {SetupChecklist, SetupChecklistItem} from '#core/setup-checklist.js';\n\nexport interface WorkspaceReference {\n id: string;\n slug: string;\n}\n\nexport interface WorkspaceSetupHostProps {\n /** A stable workspace makes the hosts easy to compose in isolated surfaces and stories. */\n workspace?: WorkspaceReference;\n}\n\nexport interface SetupChecklistBodyProps {\n checklist: SetupChecklist;\n workspaceSlug: string;\n completion?: boolean;\n showBurst?: boolean;\n onBurstComplete?: () => void;\n onAction?: ((item: SetupChecklistItem) => void) | undefined;\n onDone?: () => void;\n}\n"],"names":[],"mappings":"AAYA,WAQC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SetupChecklistBody } from './setup-checklist-body.js';
|
|
2
|
+
export type { SetupChecklistBodyProps, WorkspaceReference, WorkspaceSetupHostProps, } from './setup-checklist-types.js';
|
|
3
|
+
export { WorkspaceSetupChecklist } from './workspace-setup-checklist.js';
|
|
4
|
+
export { WorkspaceSetupIndicator } from './workspace-setup-indicator.js';
|
|
5
|
+
//# sourceMappingURL=setup-checklist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-checklist.d.ts","sourceRoot":"","sources":["../../src/components/setup-checklist.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,2BAA2B,CAAC;AAC7D,YAAY,EACV,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,uBAAuB,EAAC,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAC,uBAAuB,EAAC,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/setup-checklist.tsx"],"sourcesContent":["export {SetupChecklistBody} from './setup-checklist-body.js';\nexport type {\n SetupChecklistBodyProps,\n WorkspaceReference,\n WorkspaceSetupHostProps,\n} from './setup-checklist-types.js';\nexport {WorkspaceSetupChecklist} from './workspace-setup-checklist.js';\nexport {WorkspaceSetupIndicator} from './workspace-setup-indicator.js';\n"],"names":["SetupChecklistBody","WorkspaceSetupChecklist","WorkspaceSetupIndicator"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,4BAA4B;AAM7D,SAAQC,uBAAuB,QAAO,iCAAiC;AACvE,SAAQC,uBAAuB,QAAO,iCAAiC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react';
|
|
2
|
+
declare const meta: {
|
|
3
|
+
title: string;
|
|
4
|
+
parameters: {
|
|
5
|
+
layout: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
type Story = StoryObj<typeof meta>;
|
|
10
|
+
export declare const CloudPanel: Story;
|
|
11
|
+
export declare const CloudIndicator: Story;
|
|
12
|
+
export declare const SelfHostedPanel: Story;
|
|
13
|
+
export declare const SelfHostedIndicator: Story;
|
|
14
|
+
export declare const NeedsAttentionPanel: Story;
|
|
15
|
+
export declare const NeedsAttentionIndicator: Story;
|
|
16
|
+
export declare const Dismissed: Story;
|
|
17
|
+
export declare const CompletedWithBurst: Story;
|
|
18
|
+
export declare const CompletedWithoutBurst: Story;
|
|
19
|
+
//# sourceMappingURL=setup-checklist.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-checklist.stories.d.ts","sourceRoot":"","sources":["../../src/components/setup-checklist.stories.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AA0FrD,QAAA,MAAM,IAAI;;;QAGN,MAAM;;CAEM,CAAC;eAEF,IAAI;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAE7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAEjC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAEjC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAErC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAEhC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAEnC,CAAC"}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { modelProviderQueryKeys } from '@shipfox/client-agent';
|
|
3
|
+
import { integrationConnectionsQueryOptions, integrationProvidersQueryOptions } from '@shipfox/client-integrations';
|
|
4
|
+
import { provisionerTokenQueryKeys } from '@shipfox/client-runners';
|
|
5
|
+
import { clearWorkspaceSetupChecklistDismissal, dismissWorkspaceSetupChecklist } from '@shipfox/client-shell/runtime';
|
|
6
|
+
import { listInvitationsQueryKey, listMembersQueryKey } from '@shipfox/client-workspace-settings';
|
|
7
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
8
|
+
import { createMemoryHistory, createRootRoute, createRoute, createRouter, Outlet, RouterProvider } from '@tanstack/react-router';
|
|
9
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
10
|
+
import { deriveSetupChecklist } from '#core/setup-checklist.js';
|
|
11
|
+
import { SetupChecklistBody, WorkspaceSetupChecklist, WorkspaceSetupIndicator } from './setup-checklist.js';
|
|
12
|
+
const WORKSPACE = {
|
|
13
|
+
id: 'story-workspace',
|
|
14
|
+
slug: 'acme'
|
|
15
|
+
};
|
|
16
|
+
const DISMISSED_WORKSPACE = {
|
|
17
|
+
id: 'dismissed-story-workspace',
|
|
18
|
+
slug: WORKSPACE.slug
|
|
19
|
+
};
|
|
20
|
+
const now = new Date().toISOString();
|
|
21
|
+
const githubProvider = {
|
|
22
|
+
provider: 'github',
|
|
23
|
+
displayName: 'GitHub',
|
|
24
|
+
capabilities: [
|
|
25
|
+
'source_control'
|
|
26
|
+
]
|
|
27
|
+
};
|
|
28
|
+
const linearProvider = {
|
|
29
|
+
provider: 'linear',
|
|
30
|
+
displayName: 'Linear',
|
|
31
|
+
capabilities: [
|
|
32
|
+
'agent_tools'
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
const githubConnection = {
|
|
36
|
+
id: 'github-connection',
|
|
37
|
+
workspaceId: WORKSPACE.id,
|
|
38
|
+
provider: 'github',
|
|
39
|
+
externalAccountId: 'github-account',
|
|
40
|
+
slug: 'github-account',
|
|
41
|
+
displayName: 'GitHub',
|
|
42
|
+
lifecycleStatus: 'active',
|
|
43
|
+
capabilities: [
|
|
44
|
+
'source_control'
|
|
45
|
+
],
|
|
46
|
+
createdAt: now,
|
|
47
|
+
updatedAt: now
|
|
48
|
+
};
|
|
49
|
+
const disabledLinearConnection = {
|
|
50
|
+
id: 'linear-connection',
|
|
51
|
+
workspaceId: WORKSPACE.id,
|
|
52
|
+
provider: 'linear',
|
|
53
|
+
externalAccountId: 'linear-account',
|
|
54
|
+
slug: 'linear-account',
|
|
55
|
+
displayName: 'Linear',
|
|
56
|
+
lifecycleStatus: 'error',
|
|
57
|
+
capabilities: [
|
|
58
|
+
'agent_tools'
|
|
59
|
+
],
|
|
60
|
+
createdAt: now,
|
|
61
|
+
updatedAt: now
|
|
62
|
+
};
|
|
63
|
+
const completeChecklist = deriveSetupChecklist({
|
|
64
|
+
readiness: {
|
|
65
|
+
providers: [
|
|
66
|
+
{
|
|
67
|
+
provider: 'github',
|
|
68
|
+
displayName: 'GitHub',
|
|
69
|
+
capabilities: [
|
|
70
|
+
'source_control'
|
|
71
|
+
],
|
|
72
|
+
connected: true,
|
|
73
|
+
attention: false
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
provider: 'linear',
|
|
77
|
+
displayName: 'Linear',
|
|
78
|
+
capabilities: [
|
|
79
|
+
'agent_tools'
|
|
80
|
+
],
|
|
81
|
+
connected: true,
|
|
82
|
+
attention: false
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
attentionProviders: [],
|
|
86
|
+
hasSourceControl: true,
|
|
87
|
+
hasToolIntegration: true
|
|
88
|
+
},
|
|
89
|
+
installationRunners: 'managed',
|
|
90
|
+
workspaceRunnerCapacity: false,
|
|
91
|
+
modelProvider: {
|
|
92
|
+
installationProvided: true,
|
|
93
|
+
configured: false
|
|
94
|
+
},
|
|
95
|
+
membership: {
|
|
96
|
+
memberCount: 2,
|
|
97
|
+
pendingInvitationCount: 0
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
const meta = {
|
|
101
|
+
title: 'Client onboarding/Setup checklist',
|
|
102
|
+
parameters: {
|
|
103
|
+
layout: 'fullscreen'
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
export default meta;
|
|
107
|
+
export const CloudPanel = {
|
|
108
|
+
render: ()=>/*#__PURE__*/ _jsx(HostStory, {
|
|
109
|
+
scenario: "cloud",
|
|
110
|
+
host: "panel"
|
|
111
|
+
})
|
|
112
|
+
};
|
|
113
|
+
export const CloudIndicator = {
|
|
114
|
+
render: ()=>/*#__PURE__*/ _jsx(HostStory, {
|
|
115
|
+
scenario: "cloud",
|
|
116
|
+
host: "indicator"
|
|
117
|
+
})
|
|
118
|
+
};
|
|
119
|
+
export const SelfHostedPanel = {
|
|
120
|
+
render: ()=>/*#__PURE__*/ _jsx(HostStory, {
|
|
121
|
+
scenario: "self-hosted",
|
|
122
|
+
host: "panel"
|
|
123
|
+
})
|
|
124
|
+
};
|
|
125
|
+
export const SelfHostedIndicator = {
|
|
126
|
+
render: ()=>/*#__PURE__*/ _jsx(HostStory, {
|
|
127
|
+
scenario: "self-hosted",
|
|
128
|
+
host: "indicator"
|
|
129
|
+
})
|
|
130
|
+
};
|
|
131
|
+
export const NeedsAttentionPanel = {
|
|
132
|
+
render: ()=>/*#__PURE__*/ _jsx(HostStory, {
|
|
133
|
+
scenario: "attention",
|
|
134
|
+
host: "panel"
|
|
135
|
+
})
|
|
136
|
+
};
|
|
137
|
+
export const NeedsAttentionIndicator = {
|
|
138
|
+
render: ()=>/*#__PURE__*/ _jsx(HostStory, {
|
|
139
|
+
scenario: "attention",
|
|
140
|
+
host: "indicator"
|
|
141
|
+
})
|
|
142
|
+
};
|
|
143
|
+
export const Dismissed = {
|
|
144
|
+
render: ()=>/*#__PURE__*/ _jsx(DismissedStory, {})
|
|
145
|
+
};
|
|
146
|
+
export const CompletedWithBurst = {
|
|
147
|
+
render: ()=>/*#__PURE__*/ _jsx(CompletedStory, {
|
|
148
|
+
showBurst: true
|
|
149
|
+
})
|
|
150
|
+
};
|
|
151
|
+
export const CompletedWithoutBurst = {
|
|
152
|
+
render: ()=>/*#__PURE__*/ _jsx(CompletedStory, {})
|
|
153
|
+
};
|
|
154
|
+
function HostStory({ scenario, host }) {
|
|
155
|
+
return /*#__PURE__*/ _jsx(StoryProviders, {
|
|
156
|
+
scenario: scenario,
|
|
157
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
158
|
+
className: "min-h-[240px] bg-background-subtle-base p-frame",
|
|
159
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
160
|
+
className: "mx-auto flex w-full max-w-[480px] flex-col gap-group",
|
|
161
|
+
children: host === 'panel' ? /*#__PURE__*/ _jsx(WorkspaceSetupChecklist, {
|
|
162
|
+
workspace: WORKSPACE
|
|
163
|
+
}) : /*#__PURE__*/ _jsx("div", {
|
|
164
|
+
className: "flex justify-end border-b border-border-neutral-base bg-background-neutral-base p-row",
|
|
165
|
+
children: /*#__PURE__*/ _jsx(WorkspaceSetupIndicator, {
|
|
166
|
+
workspace: WORKSPACE
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function CompletedStory({ showBurst = false }) {
|
|
174
|
+
return /*#__PURE__*/ _jsx(StoryProviders, {
|
|
175
|
+
scenario: "complete",
|
|
176
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
177
|
+
className: "min-h-[240px] bg-background-subtle-base p-frame",
|
|
178
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
179
|
+
className: "mx-auto w-full max-w-[480px]",
|
|
180
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
181
|
+
className: "overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base",
|
|
182
|
+
children: /*#__PURE__*/ _jsx(SetupChecklistBody, {
|
|
183
|
+
checklist: completeChecklist,
|
|
184
|
+
workspaceSlug: WORKSPACE.slug,
|
|
185
|
+
completion: true,
|
|
186
|
+
showBurst: showBurst
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function DismissedStory() {
|
|
194
|
+
const [initialized, setInitialized] = useState(false);
|
|
195
|
+
useEffect(()=>{
|
|
196
|
+
dismissWorkspaceSetupChecklist(DISMISSED_WORKSPACE.id);
|
|
197
|
+
setInitialized(true);
|
|
198
|
+
return ()=>clearWorkspaceSetupChecklistDismissal(DISMISSED_WORKSPACE.id);
|
|
199
|
+
}, []);
|
|
200
|
+
return /*#__PURE__*/ _jsx(StoryProviders, {
|
|
201
|
+
scenario: "cloud",
|
|
202
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
203
|
+
className: "min-h-[240px] bg-background-subtle-base p-frame",
|
|
204
|
+
children: initialized ? /*#__PURE__*/ _jsx(WorkspaceSetupChecklist, {
|
|
205
|
+
workspace: DISMISSED_WORKSPACE
|
|
206
|
+
}) : null
|
|
207
|
+
})
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function StoryProviders({ scenario, children }) {
|
|
211
|
+
const queryClient = useMemo(()=>createScenarioQueryClient(scenario), [
|
|
212
|
+
scenario
|
|
213
|
+
]);
|
|
214
|
+
const router = useMemo(()=>createStoryRouter(children), [
|
|
215
|
+
children
|
|
216
|
+
]);
|
|
217
|
+
return /*#__PURE__*/ _jsx(QueryClientProvider, {
|
|
218
|
+
client: queryClient,
|
|
219
|
+
children: /*#__PURE__*/ _jsx(RouterProvider, {
|
|
220
|
+
router: router
|
|
221
|
+
})
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
function createScenarioQueryClient(scenario) {
|
|
225
|
+
const queryClient = new QueryClient({
|
|
226
|
+
defaultOptions: {
|
|
227
|
+
queries: {
|
|
228
|
+
retry: false
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
const cloud = scenario === 'cloud' || scenario === 'complete';
|
|
233
|
+
const attention = scenario === 'attention';
|
|
234
|
+
const providers = attention ? [
|
|
235
|
+
githubProvider,
|
|
236
|
+
linearProvider
|
|
237
|
+
] : [
|
|
238
|
+
githubProvider
|
|
239
|
+
];
|
|
240
|
+
const connections = attention ? [
|
|
241
|
+
githubConnection,
|
|
242
|
+
disabledLinearConnection
|
|
243
|
+
] : [
|
|
244
|
+
githubConnection
|
|
245
|
+
];
|
|
246
|
+
const runnerResponse = {
|
|
247
|
+
provisioners: [],
|
|
248
|
+
installationRunners: cloud ? 'managed' : 'none'
|
|
249
|
+
};
|
|
250
|
+
const catalog = {
|
|
251
|
+
providers: [],
|
|
252
|
+
workspaceProviders: 'enabled',
|
|
253
|
+
managedProviderId: cloud ? 'managed-default' : null,
|
|
254
|
+
instanceDefaultProviderId: null
|
|
255
|
+
};
|
|
256
|
+
queryClient.setQueryData(integrationProvidersQueryOptions().queryKey, providers);
|
|
257
|
+
queryClient.setQueryData(integrationConnectionsQueryOptions(WORKSPACE.id).queryKey, connections);
|
|
258
|
+
queryClient.setQueryData(provisionerTokenQueryKeys.active(WORKSPACE.id), runnerResponse);
|
|
259
|
+
queryClient.setQueryData(modelProviderQueryKeys.catalog(), catalog);
|
|
260
|
+
queryClient.setQueryData(modelProviderQueryKeys.configs(WORKSPACE.id), {
|
|
261
|
+
configs: [],
|
|
262
|
+
defaultHarnessId: null,
|
|
263
|
+
defaultProviderId: null
|
|
264
|
+
});
|
|
265
|
+
queryClient.setQueryData(listMembersQueryKey(WORKSPACE.id), [
|
|
266
|
+
{
|
|
267
|
+
id: 'member-1',
|
|
268
|
+
userId: 'user-1',
|
|
269
|
+
workspaceId: WORKSPACE.id,
|
|
270
|
+
email: 'you@example.com',
|
|
271
|
+
name: 'You',
|
|
272
|
+
role: 'admin',
|
|
273
|
+
joinedAt: now,
|
|
274
|
+
updatedAt: now
|
|
275
|
+
}
|
|
276
|
+
]);
|
|
277
|
+
queryClient.setQueryData(listInvitationsQueryKey(WORKSPACE.id), []);
|
|
278
|
+
return queryClient;
|
|
279
|
+
}
|
|
280
|
+
function createStoryRouter(children) {
|
|
281
|
+
const rootRoute = createRootRoute({
|
|
282
|
+
component: Outlet
|
|
283
|
+
});
|
|
284
|
+
const routes = [
|
|
285
|
+
'/w/$workspaceSlug',
|
|
286
|
+
'/w/$workspaceSlug/settings/integrations',
|
|
287
|
+
'/w/$workspaceSlug/settings/runners',
|
|
288
|
+
'/w/$workspaceSlug/settings/agents',
|
|
289
|
+
'/w/$workspaceSlug/settings/members'
|
|
290
|
+
].map((path)=>createRoute({
|
|
291
|
+
getParentRoute: ()=>rootRoute,
|
|
292
|
+
path,
|
|
293
|
+
component: ()=>children
|
|
294
|
+
}));
|
|
295
|
+
return createRouter({
|
|
296
|
+
routeTree: rootRoute.addChildren(routes),
|
|
297
|
+
history: createMemoryHistory({
|
|
298
|
+
initialEntries: [
|
|
299
|
+
'/w/acme'
|
|
300
|
+
]
|
|
301
|
+
})
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
//# sourceMappingURL=setup-checklist.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/setup-checklist.stories.tsx"],"sourcesContent":["import {modelProviderQueryKeys} from '@shipfox/client-agent';\nimport {\n type IntegrationConnection,\n type IntegrationProvider,\n integrationConnectionsQueryOptions,\n integrationProvidersQueryOptions,\n} from '@shipfox/client-integrations';\nimport {provisionerTokenQueryKeys} from '@shipfox/client-runners';\nimport {\n clearWorkspaceSetupChecklistDismissal,\n dismissWorkspaceSetupChecklist,\n} from '@shipfox/client-shell/runtime';\nimport {listInvitationsQueryKey, listMembersQueryKey} from '@shipfox/client-workspace-settings';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {\n createMemoryHistory,\n createRootRoute,\n createRoute,\n createRouter,\n Outlet,\n RouterProvider,\n} from '@tanstack/react-router';\nimport type {ReactNode} from 'react';\nimport {useEffect, useMemo, useState} from 'react';\nimport {deriveSetupChecklist} from '#core/setup-checklist.js';\nimport {\n SetupChecklistBody,\n type WorkspaceReference,\n WorkspaceSetupChecklist,\n WorkspaceSetupIndicator,\n} from './setup-checklist.js';\n\nconst WORKSPACE: WorkspaceReference = {id: 'story-workspace', slug: 'acme'};\nconst DISMISSED_WORKSPACE: WorkspaceReference = {\n id: 'dismissed-story-workspace',\n slug: WORKSPACE.slug,\n};\nconst now = new Date().toISOString();\n\nconst githubProvider: IntegrationProvider = {\n provider: 'github',\n displayName: 'GitHub',\n capabilities: ['source_control'],\n};\nconst linearProvider: IntegrationProvider = {\n provider: 'linear',\n displayName: 'Linear',\n capabilities: ['agent_tools'],\n};\nconst githubConnection: IntegrationConnection = {\n id: 'github-connection',\n workspaceId: WORKSPACE.id,\n provider: 'github',\n externalAccountId: 'github-account',\n slug: 'github-account',\n displayName: 'GitHub',\n lifecycleStatus: 'active',\n capabilities: ['source_control'],\n createdAt: now,\n updatedAt: now,\n};\nconst disabledLinearConnection: IntegrationConnection = {\n id: 'linear-connection',\n workspaceId: WORKSPACE.id,\n provider: 'linear',\n externalAccountId: 'linear-account',\n slug: 'linear-account',\n displayName: 'Linear',\n lifecycleStatus: 'error',\n capabilities: ['agent_tools'],\n createdAt: now,\n updatedAt: now,\n};\n\nconst completeChecklist = deriveSetupChecklist({\n readiness: {\n providers: [\n {\n provider: 'github',\n displayName: 'GitHub',\n capabilities: ['source_control'],\n connected: true,\n attention: false,\n },\n {\n provider: 'linear',\n displayName: 'Linear',\n capabilities: ['agent_tools'],\n connected: true,\n attention: false,\n },\n ],\n attentionProviders: [],\n hasSourceControl: true,\n hasToolIntegration: true,\n },\n installationRunners: 'managed',\n workspaceRunnerCapacity: false,\n modelProvider: {installationProvided: true, configured: false},\n membership: {memberCount: 2, pendingInvitationCount: 0},\n});\n\nconst meta = {\n title: 'Client onboarding/Setup checklist',\n parameters: {\n layout: 'fullscreen',\n },\n} satisfies Meta;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const CloudPanel: Story = {\n render: () => <HostStory scenario=\"cloud\" host=\"panel\" />,\n};\n\nexport const CloudIndicator: Story = {\n render: () => <HostStory scenario=\"cloud\" host=\"indicator\" />,\n};\n\nexport const SelfHostedPanel: Story = {\n render: () => <HostStory scenario=\"self-hosted\" host=\"panel\" />,\n};\n\nexport const SelfHostedIndicator: Story = {\n render: () => <HostStory scenario=\"self-hosted\" host=\"indicator\" />,\n};\n\nexport const NeedsAttentionPanel: Story = {\n render: () => <HostStory scenario=\"attention\" host=\"panel\" />,\n};\n\nexport const NeedsAttentionIndicator: Story = {\n render: () => <HostStory scenario=\"attention\" host=\"indicator\" />,\n};\n\nexport const Dismissed: Story = {\n render: () => <DismissedStory />,\n};\n\nexport const CompletedWithBurst: Story = {\n render: () => <CompletedStory showBurst />,\n};\n\nexport const CompletedWithoutBurst: Story = {\n render: () => <CompletedStory />,\n};\n\nfunction HostStory({scenario, host}: {scenario: Scenario; host: 'panel' | 'indicator'}) {\n return (\n <StoryProviders scenario={scenario}>\n <div className=\"min-h-[240px] bg-background-subtle-base p-frame\">\n <div className=\"mx-auto flex w-full max-w-[480px] flex-col gap-group\">\n {host === 'panel' ? (\n <WorkspaceSetupChecklist workspace={WORKSPACE} />\n ) : (\n <div className=\"flex justify-end border-b border-border-neutral-base bg-background-neutral-base p-row\">\n <WorkspaceSetupIndicator workspace={WORKSPACE} />\n </div>\n )}\n </div>\n </div>\n </StoryProviders>\n );\n}\n\nfunction CompletedStory({showBurst = false}: {showBurst?: boolean}) {\n return (\n <StoryProviders scenario=\"complete\">\n <div className=\"min-h-[240px] bg-background-subtle-base p-frame\">\n <div className=\"mx-auto w-full max-w-[480px]\">\n <div className=\"overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base\">\n <SetupChecklistBody\n checklist={completeChecklist}\n workspaceSlug={WORKSPACE.slug}\n completion\n showBurst={showBurst}\n />\n </div>\n </div>\n </div>\n </StoryProviders>\n );\n}\n\nfunction DismissedStory() {\n const [initialized, setInitialized] = useState(false);\n\n useEffect(() => {\n dismissWorkspaceSetupChecklist(DISMISSED_WORKSPACE.id);\n setInitialized(true);\n return () => clearWorkspaceSetupChecklistDismissal(DISMISSED_WORKSPACE.id);\n }, []);\n\n return (\n <StoryProviders scenario=\"cloud\">\n <div className=\"min-h-[240px] bg-background-subtle-base p-frame\">\n {initialized ? <WorkspaceSetupChecklist workspace={DISMISSED_WORKSPACE} /> : null}\n </div>\n </StoryProviders>\n );\n}\n\ntype Scenario = 'attention' | 'cloud' | 'complete' | 'self-hosted';\n\nfunction StoryProviders({scenario, children}: {scenario: Scenario; children: ReactNode}) {\n const queryClient = useMemo(() => createScenarioQueryClient(scenario), [scenario]);\n const router = useMemo(() => createStoryRouter(children), [children]);\n\n return (\n <QueryClientProvider client={queryClient}>\n <RouterProvider router={router} />\n </QueryClientProvider>\n );\n}\n\nfunction createScenarioQueryClient(scenario: Scenario) {\n const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}});\n const cloud = scenario === 'cloud' || scenario === 'complete';\n const attention = scenario === 'attention';\n const providers = attention ? [githubProvider, linearProvider] : [githubProvider];\n const connections = attention ? [githubConnection, disabledLinearConnection] : [githubConnection];\n const runnerResponse = {\n provisioners: [],\n installationRunners: cloud ? ('managed' as const) : ('none' as const),\n };\n const catalog = {\n providers: [],\n workspaceProviders: 'enabled' as const,\n managedProviderId: cloud ? 'managed-default' : null,\n instanceDefaultProviderId: null,\n };\n\n queryClient.setQueryData(integrationProvidersQueryOptions().queryKey, providers);\n queryClient.setQueryData(integrationConnectionsQueryOptions(WORKSPACE.id).queryKey, connections);\n queryClient.setQueryData(provisionerTokenQueryKeys.active(WORKSPACE.id), runnerResponse);\n queryClient.setQueryData(modelProviderQueryKeys.catalog(), catalog);\n queryClient.setQueryData(modelProviderQueryKeys.configs(WORKSPACE.id), {\n configs: [],\n defaultHarnessId: null,\n defaultProviderId: null,\n });\n queryClient.setQueryData(listMembersQueryKey(WORKSPACE.id), [\n {\n id: 'member-1',\n userId: 'user-1',\n workspaceId: WORKSPACE.id,\n email: 'you@example.com',\n name: 'You',\n role: 'admin' as const,\n joinedAt: now,\n updatedAt: now,\n },\n ]);\n queryClient.setQueryData(listInvitationsQueryKey(WORKSPACE.id), []);\n\n return queryClient;\n}\n\nfunction createStoryRouter(children: ReactNode) {\n const rootRoute = createRootRoute({component: Outlet});\n const routes = [\n '/w/$workspaceSlug',\n '/w/$workspaceSlug/settings/integrations',\n '/w/$workspaceSlug/settings/runners',\n '/w/$workspaceSlug/settings/agents',\n '/w/$workspaceSlug/settings/members',\n ].map((path) =>\n createRoute({\n getParentRoute: () => rootRoute,\n path,\n component: () => children,\n }),\n );\n\n return createRouter({\n routeTree: rootRoute.addChildren(routes),\n history: createMemoryHistory({initialEntries: ['/w/acme']}),\n });\n}\n"],"names":["modelProviderQueryKeys","integrationConnectionsQueryOptions","integrationProvidersQueryOptions","provisionerTokenQueryKeys","clearWorkspaceSetupChecklistDismissal","dismissWorkspaceSetupChecklist","listInvitationsQueryKey","listMembersQueryKey","QueryClient","QueryClientProvider","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","useEffect","useMemo","useState","deriveSetupChecklist","SetupChecklistBody","WorkspaceSetupChecklist","WorkspaceSetupIndicator","WORKSPACE","id","slug","DISMISSED_WORKSPACE","now","Date","toISOString","githubProvider","provider","displayName","capabilities","linearProvider","githubConnection","workspaceId","externalAccountId","lifecycleStatus","createdAt","updatedAt","disabledLinearConnection","completeChecklist","readiness","providers","connected","attention","attentionProviders","hasSourceControl","hasToolIntegration","installationRunners","workspaceRunnerCapacity","modelProvider","installationProvided","configured","membership","memberCount","pendingInvitationCount","meta","title","parameters","layout","CloudPanel","render","HostStory","scenario","host","CloudIndicator","SelfHostedPanel","SelfHostedIndicator","NeedsAttentionPanel","NeedsAttentionIndicator","Dismissed","DismissedStory","CompletedWithBurst","CompletedStory","showBurst","CompletedWithoutBurst","StoryProviders","div","className","workspace","checklist","workspaceSlug","completion","initialized","setInitialized","children","queryClient","createScenarioQueryClient","router","createStoryRouter","client","defaultOptions","queries","retry","cloud","connections","runnerResponse","provisioners","catalog","workspaceProviders","managedProviderId","instanceDefaultProviderId","setQueryData","queryKey","active","configs","defaultHarnessId","defaultProviderId","userId","email","name","role","joinedAt","rootRoute","component","routes","map","path","getParentRoute","routeTree","addChildren","history","initialEntries"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-setup-checklist.d.ts","sourceRoot":"","sources":["../../src/components/workspace-setup-checklist.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAqB,uBAAuB,EAAC,MAAM,4BAA4B,CAAC;AAE5F,wBAAgB,uBAAuB,CAAC,KAAK,GAAE,uBAA4B,+BAQ1E"}
|