@canmingir/link 1.2.66 → 1.2.67

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.
@@ -0,0 +1,336 @@
1
+ import Box from "@mui/material/Box";
2
+ import CssBaseline from "@mui/material/CssBaseline";
3
+ import DevTool from "../lib/DevTool/DevTool";
4
+ import { Iconify } from "@canmingir/link/platform/components";
5
+ import React from "react";
6
+ import SidebarChat from "../lib/SidebarChat/SidebarChat";
7
+
8
+ import { ThemeProvider, createTheme } from "@mui/material/styles";
9
+
10
+ const lightTheme = createTheme({
11
+ palette: { mode: "light", primary: { main: "#1976d2" } },
12
+ });
13
+
14
+ const now = Date.now();
15
+
16
+ const makeMessages = (n) =>
17
+ Array.from({ length: n }, (_, i) => ({
18
+ id: `m-${i}`,
19
+ role: i % 2 === 0 ? "user" : "assistant",
20
+ content:
21
+ i % 2 === 0
22
+ ? `Question number ${i / 2 + 1}?`
23
+ : `Answer number ${Math.ceil(i / 2)}. Lorem ipsum dolor sit amet.`,
24
+ }));
25
+
26
+ const storedSessions = [
27
+ {
28
+ sessionId: "sess-1",
29
+ messages: makeMessages(6),
30
+ lastUpdated: now - 1000 * 60 * 20,
31
+ agentName: "Planner",
32
+ },
33
+ {
34
+ sessionId: "sess-2",
35
+ messages: makeMessages(3),
36
+ lastUpdated: now - 1000 * 60 * 5,
37
+ agentIcon: "solar:rocket-bold-duotone",
38
+ agentName: "Builder",
39
+ },
40
+ {
41
+ sessionId: "sess-3",
42
+ messages: makeMessages(11),
43
+ lastUpdated: now - 1000 * 60,
44
+ agentName: "Reviewer",
45
+ },
46
+ ];
47
+
48
+ const noop = () => {};
49
+
50
+ const Frame = ({ children, theme = lightTheme }) => (
51
+ <ThemeProvider theme={theme}>
52
+ <CssBaseline />
53
+ <Box
54
+ sx={{
55
+ position: "relative",
56
+ width: "100%",
57
+ minWidth: 640,
58
+ minHeight: 520,
59
+ border: "1px dashed",
60
+ borderColor: "divider",
61
+ borderRadius: 2,
62
+ bgcolor: "background.default",
63
+ overflow: "hidden",
64
+ }}
65
+ >
66
+ <Box sx={{ p: 3, color: "text.secondary", fontSize: 13 }}>
67
+ App content — the DevTool docks to the right edge.
68
+ </Box>
69
+ {children}
70
+ </Box>
71
+ </ThemeProvider>
72
+ );
73
+
74
+ export default {
75
+ title: "Lib/DevTool",
76
+ parameters: {
77
+ layout: "fullscreen",
78
+ docs: {
79
+ description: {
80
+ component: `
81
+ \`DevTool\` is the top-level right-side shell. It has **two modes in one component**:
82
+
83
+ - **Slot mode** (no \`children\`, or \`children\` is a node) — a plain glass box with
84
+ \`header\` / \`content\` / \`footer\` slots. Used internally by \`SidebarSessionList\`
85
+ to draw the rail.
86
+ - **Shell mode** (\`children\` is a **function**) — renders the collapsed session
87
+ rail + session popover and hosts the chat surface as the wide drawer.
88
+
89
+ In shell mode \`children\` is a **render prop**: DevTool owns the session state and
90
+ passes it to the function, which returns the chat element (typically
91
+ \`<SidebarChat />\`):
92
+
93
+ \`\`\`jsx
94
+ <DevTool open={open} sessionId={id} history={history} storedSessions={...}>
95
+ {({ open, handleToggle, selectedConversationId, sessionId, history, onNewSession }) => (
96
+ <SidebarChat
97
+ title="Assistant"
98
+ open={open}
99
+ handleToggle={handleToggle}
100
+ selectedConversationId={selectedConversationId}
101
+ sessionId={sessionId}
102
+ history={history}
103
+ onNewSession={onNewSession}
104
+ handleNewUserMessage={send}
105
+ />
106
+ )}
107
+ </DevTool>
108
+ \`\`\`
109
+
110
+ Pass \`open\` to toggle between the collapsed rail and the open chat drawer.
111
+ `,
112
+ },
113
+ },
114
+ },
115
+ };
116
+
117
+ const renderChat =
118
+ (extra = {}) =>
119
+ (ctx) =>
120
+ (
121
+ <SidebarChat
122
+ title="Assistant"
123
+ handleNewUserMessage={noop}
124
+ open={ctx.open}
125
+ handleToggle={ctx.handleToggle}
126
+ selectedConversationId={ctx.selectedConversationId}
127
+ sessionId={ctx.sessionId}
128
+ history={ctx.history}
129
+ onNewSession={ctx.onNewSession}
130
+ {...extra}
131
+ />
132
+ );
133
+
134
+ export const SlotMode = {
135
+ name: "Slot mode — header / content / footer",
136
+ render: () => (
137
+ <Frame>
138
+ <DevTool
139
+ open
140
+ width={62}
141
+ height={280}
142
+ header={<Box sx={{ fontSize: 11, fontWeight: 700, py: 0.5 }}>TOP</Box>}
143
+ content={
144
+ <Box sx={{ display: "flex", flexDirection: "column", gap: 1, py: 1 }}>
145
+ {["A", "B", "C", "D"].map((x) => (
146
+ <Box
147
+ key={x}
148
+ sx={{
149
+ width: 32,
150
+ height: 32,
151
+ borderRadius: "10px",
152
+ display: "flex",
153
+ alignItems: "center",
154
+ justifyContent: "center",
155
+ bgcolor: "action.hover",
156
+ fontSize: 12,
157
+ fontWeight: 700,
158
+ }}
159
+ >
160
+ {x}
161
+ </Box>
162
+ ))}
163
+ </Box>
164
+ }
165
+ footer={
166
+ <Iconify icon="solar:trash-bin-2-bold" width={18} height={18} />
167
+ }
168
+ />
169
+ </Frame>
170
+ ),
171
+ };
172
+
173
+ export const SlotModeClosed = {
174
+ name: "Slot mode — open={false} renders nothing",
175
+ render: () => (
176
+ <Frame>
177
+ <DevTool open={false} content={<Box>you should not see this</Box>} />
178
+ <Box sx={{ position: "absolute", bottom: 12, left: 12, fontSize: 12 }}>
179
+ DevTool returned null — canvas is empty on the right.
180
+ </Box>
181
+ </Frame>
182
+ ),
183
+ };
184
+
185
+ const shellProps = {
186
+ handleToggle: noop,
187
+ selectedConversationId: "sess-3",
188
+ sessionId: "sess-3",
189
+ history: makeMessages(11),
190
+ storedSessions,
191
+ refreshSessions: noop,
192
+ clearAllSessions: noop,
193
+ onSessionSelect: noop,
194
+ onNewSession: noop,
195
+ };
196
+
197
+ export const ShellCollapsed = {
198
+ name: "Shell — collapsed rail (open={false})",
199
+ render: () => (
200
+ <Frame>
201
+ <DevTool {...shellProps} open={false}>
202
+ {renderChat()}
203
+ </DevTool>
204
+ </Frame>
205
+ ),
206
+ };
207
+
208
+ export const ShellCollapsedBeta = {
209
+ name: "Shell — collapsed rail, beta (no Swagger button)",
210
+ render: () => (
211
+ <Frame>
212
+ <DevTool {...shellProps} open={false} beta>
213
+ {renderChat()}
214
+ </DevTool>
215
+ </Frame>
216
+ ),
217
+ };
218
+
219
+ export const ShellCollapsedWithTopAction = {
220
+ name: "Shell — collapsed rail + topAction button",
221
+ render: () => (
222
+ <Frame>
223
+ <DevTool
224
+ {...shellProps}
225
+ open={false}
226
+ topAction={{
227
+ icon: "solar:folder-with-files-bold-duotone",
228
+ label: "Context",
229
+ tooltip: "Open context panel",
230
+ onClick: noop,
231
+ }}
232
+ >
233
+ {renderChat()}
234
+ </DevTool>
235
+ </Frame>
236
+ ),
237
+ };
238
+
239
+ export const ShellCollapsedNoSessions = {
240
+ name: "Shell — collapsed rail, no sessions",
241
+ render: () => (
242
+ <Frame>
243
+ <DevTool
244
+ {...shellProps}
245
+ open={false}
246
+ storedSessions={[]}
247
+ selectedConversationId={undefined}
248
+ sessionId={undefined}
249
+ history={[]}
250
+ >
251
+ {renderChat()}
252
+ </DevTool>
253
+ </Frame>
254
+ ),
255
+ };
256
+
257
+ export const ShellOpen = {
258
+ name: "Shell — open chat drawer",
259
+ render: () => (
260
+ <Frame>
261
+ <DevTool {...shellProps} open>
262
+ {renderChat()}
263
+ </DevTool>
264
+ </Frame>
265
+ ),
266
+ };
267
+
268
+ export const ShellOpenReadOnly = {
269
+ name: "Shell — open chat drawer, read-only",
270
+ render: () => (
271
+ <Frame>
272
+ <DevTool {...shellProps} open>
273
+ {renderChat({ readOnly: true, title: "Assistant (history)" })}
274
+ </DevTool>
275
+ </Frame>
276
+ ),
277
+ };
278
+
279
+ export const ShellOpenEmpty = {
280
+ name: "Shell — open chat drawer, empty conversation",
281
+ render: () => (
282
+ <Frame>
283
+ <DevTool
284
+ {...shellProps}
285
+ open
286
+ history={[]}
287
+ storedSessions={[]}
288
+ selectedConversationId={undefined}
289
+ sessionId={undefined}
290
+ >
291
+ {renderChat()}
292
+ </DevTool>
293
+ </Frame>
294
+ ),
295
+ };
296
+
297
+ export const ShellInteractive = {
298
+ name: "Shell — interactive (toggle + send)",
299
+ render: () => {
300
+ const [open, setOpen] = React.useState(false);
301
+ const [history, setHistory] = React.useState(makeMessages(4));
302
+
303
+ const toggle = () => setOpen((o) => !o);
304
+ const send = (msg) =>
305
+ setHistory((h) => [
306
+ ...h,
307
+ { id: `u-${h.length}`, role: "user", content: msg },
308
+ ]);
309
+ const reset = () => setHistory([]);
310
+
311
+ return (
312
+ <Frame>
313
+ <DevTool
314
+ {...shellProps}
315
+ open={open}
316
+ handleToggle={toggle}
317
+ history={history}
318
+ onNewSession={reset}
319
+ >
320
+ {(ctx) => (
321
+ <SidebarChat
322
+ title="Assistant"
323
+ open={ctx.open}
324
+ handleToggle={ctx.handleToggle}
325
+ selectedConversationId={ctx.selectedConversationId}
326
+ sessionId={ctx.sessionId}
327
+ history={ctx.history}
328
+ onNewSession={ctx.onNewSession}
329
+ handleNewUserMessage={send}
330
+ />
331
+ )}
332
+ </DevTool>
333
+ </Frame>
334
+ );
335
+ },
336
+ };