@autobe/ui 0.19.1 → 0.20.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/lib/AutoBeChatUploadSendButton.d.ts +15 -0
- package/lib/AutoBeChatUploadSendButton.js +38 -0
- package/lib/AutoBeChatUploadSendButton.js.map +1 -0
- package/lib/AutoBeFileUploadBox.d.ts +10 -0
- package/lib/AutoBeFileUploadBox.js +68 -0
- package/lib/AutoBeFileUploadBox.js.map +1 -0
- package/lib/AutoBeVoiceRecoderButton.d.ts +11 -0
- package/lib/AutoBeVoiceRecoderButton.js +58 -0
- package/lib/AutoBeVoiceRecoderButton.js.map +1 -0
- package/lib/events/AutoBeCompleteEventMovie.d.ts +7 -0
- package/lib/events/AutoBeCompleteEventMovie.js +210 -0
- package/lib/events/AutoBeCompleteEventMovie.js.map +1 -0
- package/lib/events/AutoBeProgressEventMovie.js +2 -61
- package/lib/events/AutoBeProgressEventMovie.js.map +1 -1
- package/lib/events/AutoBeScenarioEventMovie.js +2 -44
- package/lib/events/AutoBeScenarioEventMovie.js.map +1 -1
- package/lib/events/AutoBeValidateEventMovie.d.ts +6 -0
- package/lib/events/AutoBeValidateEventMovie.js +115 -0
- package/lib/events/AutoBeValidateEventMovie.js.map +1 -0
- package/lib/events/common/CollapsibleEventGroup.d.ts +28 -0
- package/lib/events/common/CollapsibleEventGroup.js +89 -0
- package/lib/events/common/CollapsibleEventGroup.js.map +1 -0
- package/lib/events/common/EventCard.d.ts +13 -0
- package/lib/events/common/EventCard.js +43 -0
- package/lib/events/common/EventCard.js.map +1 -0
- package/lib/events/common/EventContent.d.ts +11 -0
- package/lib/events/common/EventContent.js +14 -0
- package/lib/events/common/EventContent.js.map +1 -0
- package/lib/events/common/EventHeader.d.ts +15 -0
- package/lib/events/common/EventHeader.js +41 -0
- package/lib/events/common/EventHeader.js.map +1 -0
- package/lib/events/common/EventIcon.d.ts +11 -0
- package/lib/events/common/EventIcon.js +50 -0
- package/lib/events/common/EventIcon.js.map +1 -0
- package/lib/events/common/ProgressBar.d.ts +14 -0
- package/lib/events/common/ProgressBar.js +33 -0
- package/lib/events/common/ProgressBar.js.map +1 -0
- package/lib/events/common/index.d.ts +6 -0
- package/lib/events/common/index.js +16 -0
- package/lib/events/common/index.js.map +1 -0
- package/lib/events/groups/ValidateEventGroup.d.ts +12 -0
- package/lib/events/groups/ValidateEventGroup.js +78 -0
- package/lib/events/groups/ValidateEventGroup.js.map +1 -0
- package/lib/events/groups/index.d.ts +1 -0
- package/lib/events/groups/index.js +6 -0
- package/lib/events/groups/index.js.map +1 -0
- package/lib/events/index.d.ts +5 -0
- package/lib/events/index.js +25 -1
- package/lib/events/index.js.map +1 -1
- package/lib/events/utils/eventGrouper.d.ts +20 -0
- package/lib/events/utils/eventGrouper.js +74 -0
- package/lib/events/utils/eventGrouper.js.map +1 -0
- package/lib/events/utils/index.d.ts +1 -0
- package/lib/events/utils/index.js +6 -0
- package/lib/events/utils/index.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +7 -1
- package/lib/index.js.map +1 -1
- package/lib/utils/AutoBeFileUploader.d.ts +28 -0
- package/lib/utils/AutoBeFileUploader.js +237 -0
- package/lib/utils/AutoBeFileUploader.js.map +1 -0
- package/lib/utils/AutoBeVoiceRecorder.d.ts +7 -0
- package/lib/utils/AutoBeVoiceRecorder.js +94 -0
- package/lib/utils/AutoBeVoiceRecorder.js.map +1 -0
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.js +20 -0
- package/lib/utils/index.js.map +1 -0
- package/package.json +17 -2
- package/src/AutoBeChatUploadSendButton.tsx +66 -0
- package/src/AutoBeFileUploadBox.tsx +124 -0
- package/src/AutoBeVoiceRecoderButton.tsx +100 -0
- package/src/events/AutoBeCompleteEventMovie.tsx +402 -0
- package/src/events/AutoBeProgressEventMovie.tsx +12 -125
- package/src/events/AutoBeScenarioEventMovie.tsx +5 -93
- package/src/events/AutoBeValidateEventMovie.tsx +326 -0
- package/src/events/README.md +169 -0
- package/src/events/common/CollapsibleEventGroup.tsx +220 -0
- package/src/events/common/EventCard.tsx +61 -0
- package/src/events/common/EventContent.tsx +31 -0
- package/src/events/common/EventHeader.tsx +85 -0
- package/src/events/common/EventIcon.tsx +82 -0
- package/src/events/common/ProgressBar.tsx +63 -0
- package/src/events/common/index.ts +13 -0
- package/src/events/groups/ValidateEventGroup.tsx +150 -0
- package/src/events/groups/index.ts +4 -0
- package/src/events/index.ts +14 -0
- package/src/events/utils/eventGrouper.tsx +118 -0
- package/src/events/utils/index.ts +1 -0
- package/src/index.ts +6 -0
- package/src/utils/AutoBeFileUploader.ts +279 -0
- package/src/utils/AutoBeVoiceRecorder.ts +95 -0
- package/src/utils/index.ts +3 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AutoBeAnalyzeCompleteEvent,
|
|
3
|
+
AutoBeInterfaceCompleteEvent,
|
|
4
|
+
AutoBePrismaCompleteEvent,
|
|
5
|
+
AutoBeRealizeCompleteEvent,
|
|
6
|
+
AutoBeTestCompleteEvent,
|
|
7
|
+
IAutoBeGetFilesOptions,
|
|
8
|
+
} from "@autobe/interface";
|
|
9
|
+
import StackBlitzSDK from "@stackblitz/sdk";
|
|
10
|
+
import JsZip from "jszip";
|
|
11
|
+
import { useState } from "react";
|
|
12
|
+
import { VariadicSingleton } from "tstl";
|
|
13
|
+
|
|
14
|
+
import { EventCard, EventContent, EventHeader } from "./common";
|
|
15
|
+
|
|
16
|
+
export interface IAutoBeCompleteEventMovieProps {
|
|
17
|
+
getFiles: (
|
|
18
|
+
options?: Partial<IAutoBeGetFilesOptions>,
|
|
19
|
+
) => Promise<Record<string, string>>;
|
|
20
|
+
event:
|
|
21
|
+
| AutoBeAnalyzeCompleteEvent
|
|
22
|
+
| AutoBePrismaCompleteEvent
|
|
23
|
+
| AutoBeInterfaceCompleteEvent
|
|
24
|
+
| AutoBeTestCompleteEvent
|
|
25
|
+
| AutoBeRealizeCompleteEvent;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const AutoBeCompleteEventMovie = (
|
|
29
|
+
props: IAutoBeCompleteEventMovieProps,
|
|
30
|
+
) => {
|
|
31
|
+
const stage = getStage(props.event);
|
|
32
|
+
const [size, setSize] = useState<number | null>(null);
|
|
33
|
+
const [downloading, setDownloading] = useState(false);
|
|
34
|
+
|
|
35
|
+
const getFiles = async (dbms: "postgres" | "sqlite") => {
|
|
36
|
+
setDownloading(true);
|
|
37
|
+
try {
|
|
38
|
+
const result = await props.getFiles({
|
|
39
|
+
dbms,
|
|
40
|
+
stage,
|
|
41
|
+
});
|
|
42
|
+
return result;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
throw error;
|
|
45
|
+
} finally {
|
|
46
|
+
setDownloading(false);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const openStackBlitz = async () => {
|
|
51
|
+
const files: Record<string, string> = Object.fromEntries(
|
|
52
|
+
Object.entries(await getFiles("sqlite")).filter(
|
|
53
|
+
([key, value]) =>
|
|
54
|
+
key.startsWith("autobe/") === false &&
|
|
55
|
+
new TextEncoder().encode(value).length < 512 * 1024, // 512 KB
|
|
56
|
+
),
|
|
57
|
+
);
|
|
58
|
+
const size: number = Object.values(files)
|
|
59
|
+
.map((str) => new TextEncoder().encode(str).length)
|
|
60
|
+
.reduce((a, b) => a + b, 0);
|
|
61
|
+
setSize(size);
|
|
62
|
+
StackBlitzSDK.openProject(
|
|
63
|
+
{
|
|
64
|
+
title: `AutoBE Generated Backend Server (${props.event.type})`,
|
|
65
|
+
template: "node",
|
|
66
|
+
files,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
newWindow: true,
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const download = async (dbms: "postgres" | "sqlite") => {
|
|
75
|
+
const zip: JsZip = new JsZip();
|
|
76
|
+
const directory = new VariadicSingleton((location: string): JsZip => {
|
|
77
|
+
const separated: string[] = location.split("/");
|
|
78
|
+
if (separated.length === 1) return zip.folder(separated[0])!;
|
|
79
|
+
const parent: JsZip = directory.get(separated.slice(0, -1).join("/"));
|
|
80
|
+
return parent.folder(separated.at(-1)!)!;
|
|
81
|
+
});
|
|
82
|
+
for (const [file, content] of Object.entries(await getFiles(dbms))) {
|
|
83
|
+
const separated: string[] = file.split("/");
|
|
84
|
+
if (separated.length === 1) zip.file(file, content);
|
|
85
|
+
else {
|
|
86
|
+
const folder: JsZip = directory.get(separated.slice(0, -1).join("/"));
|
|
87
|
+
folder.file(separated.at(-1)!, content);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const data: Blob = await zip.generateAsync({ type: "blob" });
|
|
91
|
+
|
|
92
|
+
const url: string = URL.createObjectURL(data);
|
|
93
|
+
const a: HTMLAnchorElement = document.createElement("a");
|
|
94
|
+
a.href = url;
|
|
95
|
+
a.download = `AutoBE.${props.event.type}.zip`;
|
|
96
|
+
document.body.appendChild(a);
|
|
97
|
+
a.click();
|
|
98
|
+
document.body.removeChild(a);
|
|
99
|
+
URL.revokeObjectURL(url);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const title: string | null = getTitle(props.event);
|
|
103
|
+
if (title === null) return null;
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<EventCard variant="success">
|
|
107
|
+
<EventHeader
|
|
108
|
+
title={`${title} Completed`}
|
|
109
|
+
timestamp={props.event.created_at}
|
|
110
|
+
iconType="success"
|
|
111
|
+
/>
|
|
112
|
+
<EventContent>
|
|
113
|
+
<div style={{ marginBottom: "1rem" }}>
|
|
114
|
+
<div
|
|
115
|
+
style={{
|
|
116
|
+
display: "inline-flex",
|
|
117
|
+
alignItems: "center",
|
|
118
|
+
padding: "6px 12px",
|
|
119
|
+
border: "1px solid #4caf50",
|
|
120
|
+
borderRadius: "16px",
|
|
121
|
+
backgroundColor: "transparent",
|
|
122
|
+
color: "#4caf50",
|
|
123
|
+
fontSize: "14px",
|
|
124
|
+
fontWeight: 500,
|
|
125
|
+
gap: "6px",
|
|
126
|
+
marginBottom: "1rem",
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
129
|
+
✅ {title} Completed
|
|
130
|
+
</div>
|
|
131
|
+
<br />
|
|
132
|
+
<br />
|
|
133
|
+
{title} has been completed.
|
|
134
|
+
{getMessage(openStackBlitz, props.event)}
|
|
135
|
+
<br />
|
|
136
|
+
<br />
|
|
137
|
+
Please check the result in the file explorer.
|
|
138
|
+
{size !== null && size >= LIMIT && (
|
|
139
|
+
<div
|
|
140
|
+
style={{
|
|
141
|
+
backgroundColor: "#fffbeb",
|
|
142
|
+
border: "1px solid #fed7aa",
|
|
143
|
+
borderRadius: "0.5rem",
|
|
144
|
+
padding: "1rem",
|
|
145
|
+
marginTop: "1rem",
|
|
146
|
+
color: "#92400e",
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
<strong>⚠️ Warning:</strong> This project is too large (
|
|
150
|
+
{(size / 1024 / 1024).toFixed(1)} MB) for StackBlitz.
|
|
151
|
+
<br />
|
|
152
|
+
<br />
|
|
153
|
+
Try downloading it directly instead!
|
|
154
|
+
</div>
|
|
155
|
+
)}
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
{/* Action Buttons */}
|
|
159
|
+
<div
|
|
160
|
+
style={{
|
|
161
|
+
display: "flex",
|
|
162
|
+
gap: "0.75rem",
|
|
163
|
+
justifyContent: "flex-end",
|
|
164
|
+
flexWrap: "wrap",
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
{downloading ? (
|
|
168
|
+
<button
|
|
169
|
+
disabled
|
|
170
|
+
style={{
|
|
171
|
+
display: "flex",
|
|
172
|
+
alignItems: "center",
|
|
173
|
+
gap: "0.5rem",
|
|
174
|
+
padding: "0.75rem 1rem",
|
|
175
|
+
backgroundColor: "#f3f4f6",
|
|
176
|
+
border: "1px solid #d1d5db",
|
|
177
|
+
borderRadius: "0.5rem",
|
|
178
|
+
cursor: "not-allowed",
|
|
179
|
+
fontSize: "0.875rem",
|
|
180
|
+
color: "#6b7280",
|
|
181
|
+
}}
|
|
182
|
+
>
|
|
183
|
+
⏳ Downloading Source Codes...
|
|
184
|
+
</button>
|
|
185
|
+
) : props.event.type === "analyzeComplete" ? (
|
|
186
|
+
<>
|
|
187
|
+
<ActionButton
|
|
188
|
+
icon="📥"
|
|
189
|
+
text="Zip (SQLite)"
|
|
190
|
+
onClick={() => download("sqlite")}
|
|
191
|
+
title={
|
|
192
|
+
stage !== "analyze"
|
|
193
|
+
? "Download SQLite-based backend application (ideal for local development and testing)"
|
|
194
|
+
: "Download requirement analysis report"
|
|
195
|
+
}
|
|
196
|
+
/>
|
|
197
|
+
<ActionButton
|
|
198
|
+
icon="🚀"
|
|
199
|
+
text="StackBlitz"
|
|
200
|
+
onClick={() => openStackBlitz()}
|
|
201
|
+
variant={size !== null && size >= LIMIT ? "warning" : "primary"}
|
|
202
|
+
title="Open project in StackBlitz for instant online development and testing"
|
|
203
|
+
/>
|
|
204
|
+
</>
|
|
205
|
+
) : (
|
|
206
|
+
<>
|
|
207
|
+
<ActionButton
|
|
208
|
+
icon="☁️"
|
|
209
|
+
text="Zip (Postgres)"
|
|
210
|
+
onClick={() => download("postgres")}
|
|
211
|
+
title="Download PostgreSQL-based backend application (optimized for production deployment)"
|
|
212
|
+
/>
|
|
213
|
+
<ActionButton
|
|
214
|
+
icon="📥"
|
|
215
|
+
text="Zip (SQLite)"
|
|
216
|
+
onClick={() => download("sqlite")}
|
|
217
|
+
title="Download SQLite-based backend application (ideal for local development and testing)"
|
|
218
|
+
/>
|
|
219
|
+
<ActionButton
|
|
220
|
+
icon="🚀"
|
|
221
|
+
text="StackBlitz"
|
|
222
|
+
onClick={() => openStackBlitz()}
|
|
223
|
+
variant={size !== null && size >= LIMIT ? "warning" : "primary"}
|
|
224
|
+
title="Open project in StackBlitz for instant online development and testing"
|
|
225
|
+
/>
|
|
226
|
+
</>
|
|
227
|
+
)}
|
|
228
|
+
</div>
|
|
229
|
+
</EventContent>
|
|
230
|
+
</EventCard>
|
|
231
|
+
);
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
interface IActionButtonProps {
|
|
235
|
+
icon: string;
|
|
236
|
+
text: string;
|
|
237
|
+
onClick: () => void;
|
|
238
|
+
title?: string;
|
|
239
|
+
variant?: "primary" | "warning";
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const ActionButton = (props: IActionButtonProps) => {
|
|
243
|
+
const { icon, text, onClick, title, variant = "primary" } = props;
|
|
244
|
+
|
|
245
|
+
const getButtonStyles = () => {
|
|
246
|
+
const baseStyles = {
|
|
247
|
+
display: "flex",
|
|
248
|
+
alignItems: "center",
|
|
249
|
+
gap: "0.5rem",
|
|
250
|
+
padding: "0.75rem 1rem",
|
|
251
|
+
borderRadius: "0.5rem",
|
|
252
|
+
cursor: "pointer",
|
|
253
|
+
fontSize: "0.875rem",
|
|
254
|
+
fontWeight: 500,
|
|
255
|
+
border: "1px solid",
|
|
256
|
+
transition: "all 0.2s ease",
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
if (variant === "warning") {
|
|
260
|
+
return {
|
|
261
|
+
...baseStyles,
|
|
262
|
+
backgroundColor: "#fffbeb",
|
|
263
|
+
borderColor: "#f59e0b",
|
|
264
|
+
color: "#92400e",
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
...baseStyles,
|
|
270
|
+
backgroundColor: "#3b82f6",
|
|
271
|
+
borderColor: "#3b82f6",
|
|
272
|
+
color: "#ffffff",
|
|
273
|
+
};
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
return (
|
|
277
|
+
<button
|
|
278
|
+
onClick={onClick}
|
|
279
|
+
title={title}
|
|
280
|
+
style={getButtonStyles()}
|
|
281
|
+
onMouseEnter={(e) => {
|
|
282
|
+
if (variant === "warning") {
|
|
283
|
+
e.currentTarget.style.backgroundColor = "#fef3c7";
|
|
284
|
+
} else {
|
|
285
|
+
e.currentTarget.style.backgroundColor = "#2563eb";
|
|
286
|
+
}
|
|
287
|
+
}}
|
|
288
|
+
onMouseLeave={(e) => {
|
|
289
|
+
if (variant === "warning") {
|
|
290
|
+
e.currentTarget.style.backgroundColor = "#fffbeb";
|
|
291
|
+
} else {
|
|
292
|
+
e.currentTarget.style.backgroundColor = "#3b82f6";
|
|
293
|
+
}
|
|
294
|
+
}}
|
|
295
|
+
>
|
|
296
|
+
<span>{icon}</span>
|
|
297
|
+
<span>{text}</span>
|
|
298
|
+
</button>
|
|
299
|
+
);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// Helper functions
|
|
303
|
+
|
|
304
|
+
function getTitle(
|
|
305
|
+
event: IAutoBeCompleteEventMovieProps["event"],
|
|
306
|
+
): string | null {
|
|
307
|
+
switch (event.type) {
|
|
308
|
+
case "analyzeComplete":
|
|
309
|
+
return "Analyze";
|
|
310
|
+
case "prismaComplete":
|
|
311
|
+
if (event.compiled.type !== "success") return "Prisma (Error)";
|
|
312
|
+
return "Prisma";
|
|
313
|
+
case "interfaceComplete":
|
|
314
|
+
return "Interface";
|
|
315
|
+
case "testComplete":
|
|
316
|
+
return "Test";
|
|
317
|
+
case "realizeComplete":
|
|
318
|
+
return "Realize";
|
|
319
|
+
default:
|
|
320
|
+
event satisfies never;
|
|
321
|
+
throw new Error("Unknown event type");
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const getMessage = (
|
|
326
|
+
openStackBlitz: () => void,
|
|
327
|
+
event: IAutoBeCompleteEventMovieProps["event"],
|
|
328
|
+
) => {
|
|
329
|
+
if (event.type === "prismaComplete" && event.compiled.type === "failure")
|
|
330
|
+
return (
|
|
331
|
+
<>
|
|
332
|
+
<br />
|
|
333
|
+
<br />
|
|
334
|
+
Succeeded to compose <code>AutoBePrisma.IApplication</code> typed AST
|
|
335
|
+
(Abstract Syntax Tree) data, but failed to generate Prisma schema files
|
|
336
|
+
from it. This is a bug of <code>@autobe</code>. Please{" "}
|
|
337
|
+
<a
|
|
338
|
+
href="https://github.com/wrtnlabs/autobe/issues"
|
|
339
|
+
target="_blank"
|
|
340
|
+
style={{ color: "#3b82f6", textDecoration: "underline" }}
|
|
341
|
+
>
|
|
342
|
+
write a bug report to our repository
|
|
343
|
+
</a>{" "}
|
|
344
|
+
with the{" "}
|
|
345
|
+
<a
|
|
346
|
+
href="#"
|
|
347
|
+
onClick={() => openStackBlitz()}
|
|
348
|
+
style={{ color: "#3b82f6", textDecoration: "underline" }}
|
|
349
|
+
>
|
|
350
|
+
<code>autobe/histories.json</code>
|
|
351
|
+
</a>{" "}
|
|
352
|
+
file.
|
|
353
|
+
</>
|
|
354
|
+
);
|
|
355
|
+
else if (
|
|
356
|
+
(event.type === "testComplete" || event.type === "realizeComplete") &&
|
|
357
|
+
event.compiled.type !== "success"
|
|
358
|
+
)
|
|
359
|
+
return (
|
|
360
|
+
<>
|
|
361
|
+
<br />
|
|
362
|
+
<br />
|
|
363
|
+
Succeeded to compose{" "}
|
|
364
|
+
{event.type === "testComplete" ? "test functions" : "realize functions"}
|
|
365
|
+
, but failed to pass the TypeScript compilation. This is a bug of{" "}
|
|
366
|
+
<code>@autobe</code>. Please{" "}
|
|
367
|
+
<a
|
|
368
|
+
href="https://github.com/wrtnlabs/autobe/issues"
|
|
369
|
+
target="_blank"
|
|
370
|
+
style={{ color: "#3b82f6", textDecoration: "underline" }}
|
|
371
|
+
>
|
|
372
|
+
write a bug report to our repository
|
|
373
|
+
</a>{" "}
|
|
374
|
+
with the{" "}
|
|
375
|
+
<a
|
|
376
|
+
href="#"
|
|
377
|
+
onClick={() => openStackBlitz()}
|
|
378
|
+
style={{ color: "#3b82f6", textDecoration: "underline" }}
|
|
379
|
+
>
|
|
380
|
+
<code>autobe/histories.json</code>
|
|
381
|
+
</a>{" "}
|
|
382
|
+
file.
|
|
383
|
+
</>
|
|
384
|
+
);
|
|
385
|
+
return null;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const getStage = (event: IAutoBeCompleteEventMovieProps["event"]) => {
|
|
389
|
+
if (event.type === "analyzeComplete") return "analyze";
|
|
390
|
+
else if (event.type === "prismaComplete") return "prisma";
|
|
391
|
+
else if (event.type === "interfaceComplete") return "interface";
|
|
392
|
+
else if (event.type === "testComplete") return "test";
|
|
393
|
+
else if (event.type === "realizeComplete") return "realize";
|
|
394
|
+
else {
|
|
395
|
+
event satisfies never;
|
|
396
|
+
return undefined;
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const LIMIT = 3 * 1024 * 1024;
|
|
401
|
+
|
|
402
|
+
export default AutoBeCompleteEventMovie;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AutoBeEvent, AutoBeProgressEventBase } from "@autobe/interface";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { EventCard, EventContent, EventHeader, ProgressBar } from "./common";
|
|
4
4
|
|
|
5
5
|
export function AutoBeProgressEventMovie(
|
|
6
6
|
props: AutoBeProgressEventMovie.IProps,
|
|
@@ -8,130 +8,17 @@ export function AutoBeProgressEventMovie(
|
|
|
8
8
|
const state: IState = getState(props.event);
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<div
|
|
23
|
-
style={{
|
|
24
|
-
display: "flex",
|
|
25
|
-
alignItems: "center",
|
|
26
|
-
justifyContent: "space-between",
|
|
27
|
-
marginBottom: "1rem",
|
|
28
|
-
}}
|
|
29
|
-
>
|
|
30
|
-
<div
|
|
31
|
-
style={{
|
|
32
|
-
display: "flex",
|
|
33
|
-
alignItems: "center",
|
|
34
|
-
gap: "0.75rem",
|
|
35
|
-
}}
|
|
36
|
-
>
|
|
37
|
-
{/* Status Icon */}
|
|
38
|
-
<div
|
|
39
|
-
style={{
|
|
40
|
-
width: "2rem",
|
|
41
|
-
height: "2rem",
|
|
42
|
-
backgroundColor: "#4caf50",
|
|
43
|
-
borderRadius: "50%",
|
|
44
|
-
display: "flex",
|
|
45
|
-
alignItems: "center",
|
|
46
|
-
justifyContent: "center",
|
|
47
|
-
}}
|
|
48
|
-
>
|
|
49
|
-
<svg
|
|
50
|
-
width="16"
|
|
51
|
-
height="16"
|
|
52
|
-
viewBox="0 0 24 24"
|
|
53
|
-
fill="currentColor"
|
|
54
|
-
style={{ color: "#ffffff" }}
|
|
55
|
-
>
|
|
56
|
-
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
|
|
57
|
-
</svg>
|
|
58
|
-
</div>
|
|
59
|
-
|
|
60
|
-
{/* Title */}
|
|
61
|
-
<div>
|
|
62
|
-
<h3
|
|
63
|
-
style={{
|
|
64
|
-
fontSize: "1.125rem",
|
|
65
|
-
fontWeight: "600",
|
|
66
|
-
color: "#1e293b",
|
|
67
|
-
margin: 0,
|
|
68
|
-
marginBottom: "0.25rem",
|
|
69
|
-
}}
|
|
70
|
-
>
|
|
71
|
-
{state.title}
|
|
72
|
-
</h3>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
{/* Timestamp */}
|
|
77
|
-
<div
|
|
78
|
-
style={{
|
|
79
|
-
fontSize: "0.75rem",
|
|
80
|
-
color: "#64748b",
|
|
81
|
-
textAlign: "right",
|
|
82
|
-
}}
|
|
83
|
-
>
|
|
84
|
-
{formatTime(props.event.created_at)}
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
|
|
88
|
-
{/* Content */}
|
|
89
|
-
<div
|
|
90
|
-
style={{
|
|
91
|
-
fontSize: "0.875rem",
|
|
92
|
-
lineHeight: "1.5",
|
|
93
|
-
color: "#475569",
|
|
94
|
-
backgroundColor: "#ffffff",
|
|
95
|
-
padding: "1rem",
|
|
96
|
-
borderRadius: "0.5rem",
|
|
97
|
-
border: "1px solid #e2e8f0",
|
|
98
|
-
}}
|
|
99
|
-
>
|
|
100
|
-
<div style={{ marginBottom: "1rem" }}>{state.description}</div>
|
|
101
|
-
|
|
102
|
-
{/* Progress Bar */}
|
|
103
|
-
<div
|
|
104
|
-
style={{
|
|
105
|
-
width: "100%",
|
|
106
|
-
height: "10px",
|
|
107
|
-
backgroundColor: "#e2e8f0",
|
|
108
|
-
borderRadius: "10px",
|
|
109
|
-
overflow: "hidden",
|
|
110
|
-
marginBottom: "0.5rem",
|
|
111
|
-
}}
|
|
112
|
-
>
|
|
113
|
-
<div
|
|
114
|
-
style={{
|
|
115
|
-
width: `${Math.round((state.completed / state.total) * 100)}%`,
|
|
116
|
-
height: "100%",
|
|
117
|
-
backgroundColor: "#4caf50",
|
|
118
|
-
borderRadius: "10px",
|
|
119
|
-
transition: "width 0.3s ease",
|
|
120
|
-
}}
|
|
121
|
-
/>
|
|
122
|
-
</div>
|
|
123
|
-
|
|
124
|
-
<div
|
|
125
|
-
style={{
|
|
126
|
-
fontSize: "0.75rem",
|
|
127
|
-
color: "#64748b",
|
|
128
|
-
textAlign: "center",
|
|
129
|
-
}}
|
|
130
|
-
>
|
|
131
|
-
{state.completed} / {state.total} completed
|
|
132
|
-
</div>
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
11
|
+
<EventCard>
|
|
12
|
+
<EventHeader
|
|
13
|
+
title={state.title}
|
|
14
|
+
timestamp={props.event.created_at}
|
|
15
|
+
iconType="progress"
|
|
16
|
+
/>
|
|
17
|
+
<EventContent>
|
|
18
|
+
<div style={{ marginBottom: 0 }}>{state.description}</div>
|
|
19
|
+
<ProgressBar current={state.completed} total={state.total} />
|
|
20
|
+
</EventContent>
|
|
21
|
+
</EventCard>
|
|
135
22
|
);
|
|
136
23
|
}
|
|
137
24
|
type ExtractType<T, U> = T extends U ? T : never;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "@autobe/interface";
|
|
7
7
|
import { JSX } from "react";
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { EventCard, EventContent, EventHeader } from "./common";
|
|
10
10
|
|
|
11
11
|
export interface IAutoBeScenarioEventMovieProps {
|
|
12
12
|
event:
|
|
@@ -22,98 +22,10 @@ export const AutoBeScenarioEventMovie = (
|
|
|
22
22
|
const { title, description } = getState(event);
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
borderRadius: "0.75rem",
|
|
30
|
-
padding: "1.5rem",
|
|
31
|
-
marginBottom: "1rem",
|
|
32
|
-
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
|
|
33
|
-
}}
|
|
34
|
-
>
|
|
35
|
-
{/* Header */}
|
|
36
|
-
<div
|
|
37
|
-
style={{
|
|
38
|
-
display: "flex",
|
|
39
|
-
alignItems: "center",
|
|
40
|
-
justifyContent: "space-between",
|
|
41
|
-
marginBottom: "1rem",
|
|
42
|
-
}}
|
|
43
|
-
>
|
|
44
|
-
<div
|
|
45
|
-
style={{
|
|
46
|
-
display: "flex",
|
|
47
|
-
alignItems: "center",
|
|
48
|
-
gap: "0.75rem",
|
|
49
|
-
}}
|
|
50
|
-
>
|
|
51
|
-
{/* Status Icon */}
|
|
52
|
-
<div
|
|
53
|
-
style={{
|
|
54
|
-
width: "2rem",
|
|
55
|
-
height: "2rem",
|
|
56
|
-
backgroundColor: "#3b82f6",
|
|
57
|
-
borderRadius: "50%",
|
|
58
|
-
display: "flex",
|
|
59
|
-
alignItems: "center",
|
|
60
|
-
justifyContent: "center",
|
|
61
|
-
}}
|
|
62
|
-
>
|
|
63
|
-
<svg
|
|
64
|
-
width="16"
|
|
65
|
-
height="16"
|
|
66
|
-
viewBox="0 0 24 24"
|
|
67
|
-
fill="currentColor"
|
|
68
|
-
style={{ color: "#ffffff" }}
|
|
69
|
-
>
|
|
70
|
-
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
|
|
71
|
-
</svg>
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
{/* Title and Step */}
|
|
75
|
-
<div>
|
|
76
|
-
<h3
|
|
77
|
-
style={{
|
|
78
|
-
fontSize: "1.125rem",
|
|
79
|
-
fontWeight: "600",
|
|
80
|
-
color: "#1e293b",
|
|
81
|
-
margin: 0,
|
|
82
|
-
marginBottom: "0.25rem",
|
|
83
|
-
}}
|
|
84
|
-
>
|
|
85
|
-
{title}
|
|
86
|
-
</h3>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
|
|
90
|
-
{/* Timestamp */}
|
|
91
|
-
<div
|
|
92
|
-
style={{
|
|
93
|
-
fontSize: "0.75rem",
|
|
94
|
-
color: "#64748b",
|
|
95
|
-
textAlign: "right",
|
|
96
|
-
}}
|
|
97
|
-
>
|
|
98
|
-
{formatTime(event.created_at)}
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
{/* Description */}
|
|
103
|
-
<div
|
|
104
|
-
style={{
|
|
105
|
-
fontSize: "0.875rem",
|
|
106
|
-
lineHeight: "1.5",
|
|
107
|
-
color: "#475569",
|
|
108
|
-
backgroundColor: "#ffffff",
|
|
109
|
-
padding: "1rem",
|
|
110
|
-
borderRadius: "0.5rem",
|
|
111
|
-
border: "1px solid #e2e8f0",
|
|
112
|
-
}}
|
|
113
|
-
>
|
|
114
|
-
{description}
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
25
|
+
<EventCard>
|
|
26
|
+
<EventHeader title={title} timestamp={event.created_at} iconType="info" />
|
|
27
|
+
<EventContent>{description}</EventContent>
|
|
28
|
+
</EventCard>
|
|
117
29
|
);
|
|
118
30
|
};
|
|
119
31
|
export default AutoBeScenarioEventMovie;
|