@startsimpli/ui 0.4.21 → 0.4.23
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/package.json +2 -2
- package/src/components/workflows/WorkflowEmptyState.tsx +256 -0
- package/src/components/workflows/WorkflowListComposer.tsx +644 -0
- package/src/components/workflows/WorkflowSettingsCard.tsx +208 -0
- package/src/components/workflows/WorkflowStatsOverview.tsx +175 -0
- package/src/components/workflows/WorkflowTemplateGallery.tsx +608 -0
- package/src/components/workflows/WorkflowVersionHistory.tsx +151 -0
- package/src/components/workflows/index.ts +33 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@startsimpli/ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.23",
|
|
4
4
|
"description": "Shared UI components package for StartSimpli applications",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
33
33
|
"react": "^18.0.0 || ^19.0.0",
|
|
34
34
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
35
|
-
"@startsimpli/auth": "0.4.
|
|
35
|
+
"@startsimpli/auth": "0.4.20"
|
|
36
36
|
},
|
|
37
37
|
"peerDependenciesMeta": {
|
|
38
38
|
"@startsimpli/auth": {
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
import { Button } from '../ui/button';
|
|
5
|
+
import {
|
|
6
|
+
Card,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
CardDescription,
|
|
10
|
+
CardContent,
|
|
11
|
+
} from '../ui/card';
|
|
12
|
+
import { Checkbox } from '../ui/checkbox';
|
|
13
|
+
import { Label } from '../ui/label';
|
|
14
|
+
import { Sparkles, PlayCircle, HelpCircle, X } from 'lucide-react';
|
|
15
|
+
|
|
16
|
+
const STORAGE_KEY = 'workflow_guidance_dismissed';
|
|
17
|
+
|
|
18
|
+
export interface WorkflowEmptyStateProps {
|
|
19
|
+
onOpenTemplateGallery: () => void;
|
|
20
|
+
onStartFromScratch: () => void;
|
|
21
|
+
onOpenHelp?: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Empty State Component for Workflow Canvas
|
|
26
|
+
*
|
|
27
|
+
* Provides first-time user guidance with two paths:
|
|
28
|
+
* 1. Template Gallery - Pre-built workflows to learn from
|
|
29
|
+
* 2. Start From Scratch - Opens node palette with guidance
|
|
30
|
+
*
|
|
31
|
+
* Features:
|
|
32
|
+
* - localStorage-based dismissal (respects user preference)
|
|
33
|
+
* - Non-intrusive inline design (not a modal)
|
|
34
|
+
* - Action-oriented messaging (not "Welcome!")
|
|
35
|
+
* - Re-accessible via help button
|
|
36
|
+
*/
|
|
37
|
+
export function WorkflowEmptyState({
|
|
38
|
+
onOpenTemplateGallery,
|
|
39
|
+
onStartFromScratch,
|
|
40
|
+
onOpenHelp,
|
|
41
|
+
}: WorkflowEmptyStateProps) {
|
|
42
|
+
const [isDismissed, setIsDismissed] = useState(true);
|
|
43
|
+
const [dontShowAgain, setDontShowAgain] = useState(false);
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
// Check if user has dismissed guidance
|
|
47
|
+
const dismissed = localStorage.getItem(STORAGE_KEY) === 'true';
|
|
48
|
+
setIsDismissed(dismissed);
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
const handleTemplateGalleryClick = () => {
|
|
52
|
+
if (dontShowAgain) {
|
|
53
|
+
localStorage.setItem(STORAGE_KEY, 'true');
|
|
54
|
+
}
|
|
55
|
+
setIsDismissed(true);
|
|
56
|
+
onOpenTemplateGallery();
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const handleStartFromScratchClick = () => {
|
|
60
|
+
if (dontShowAgain) {
|
|
61
|
+
localStorage.setItem(STORAGE_KEY, 'true');
|
|
62
|
+
}
|
|
63
|
+
setIsDismissed(true);
|
|
64
|
+
onStartFromScratch();
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleDismiss = () => {
|
|
68
|
+
if (dontShowAgain) {
|
|
69
|
+
localStorage.setItem(STORAGE_KEY, 'true');
|
|
70
|
+
}
|
|
71
|
+
setIsDismissed(true);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
if (isDismissed) {
|
|
75
|
+
// Show persistent help button for returning users
|
|
76
|
+
return (
|
|
77
|
+
<div className="absolute bottom-6 right-6 z-10">
|
|
78
|
+
<Button
|
|
79
|
+
variant="outline"
|
|
80
|
+
size="icon"
|
|
81
|
+
onClick={onOpenHelp}
|
|
82
|
+
className="h-12 w-12 rounded-full shadow-lg hover:shadow-xl transition-all"
|
|
83
|
+
title="Need help? View templates and guidance"
|
|
84
|
+
>
|
|
85
|
+
<HelpCircle className="h-5 w-5" />
|
|
86
|
+
</Button>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div
|
|
93
|
+
className="flex items-center justify-center z-10"
|
|
94
|
+
role="dialog"
|
|
95
|
+
aria-labelledby="welcome-title"
|
|
96
|
+
aria-describedby="welcome-description"
|
|
97
|
+
aria-modal="false"
|
|
98
|
+
>
|
|
99
|
+
<Card className="w-full max-w-[720px] pointer-events-auto animate-in fade-in-0 zoom-in-95 duration-300 relative">
|
|
100
|
+
{/* Close button */}
|
|
101
|
+
<button
|
|
102
|
+
onClick={handleDismiss}
|
|
103
|
+
aria-label="Close welcome panel"
|
|
104
|
+
aria-keyshortcuts="Escape"
|
|
105
|
+
className="absolute right-4 top-4 rounded-full p-2 text-muted-foreground hover:bg-muted hover:text-foreground transition-colors"
|
|
106
|
+
>
|
|
107
|
+
<X className="w-5 h-5" aria-hidden="true" />
|
|
108
|
+
</button>
|
|
109
|
+
|
|
110
|
+
<CardHeader className="text-center pb-4 pt-10 px-10">
|
|
111
|
+
<CardTitle id="welcome-title" className="text-2xl font-semibold">
|
|
112
|
+
Welcome to Workflow Builder
|
|
113
|
+
</CardTitle>
|
|
114
|
+
<CardDescription
|
|
115
|
+
id="welcome-description"
|
|
116
|
+
className="text-sm text-muted-foreground leading-relaxed mt-2"
|
|
117
|
+
>
|
|
118
|
+
Create automated workflows with browser actions, logic, and AI
|
|
119
|
+
</CardDescription>
|
|
120
|
+
</CardHeader>
|
|
121
|
+
|
|
122
|
+
<CardContent className="flex flex-col gap-6 px-10 pb-10">
|
|
123
|
+
{/* Option 1: Template Gallery */}
|
|
124
|
+
<button
|
|
125
|
+
onClick={handleTemplateGalleryClick}
|
|
126
|
+
className="block w-full group text-left"
|
|
127
|
+
aria-label="Browse template gallery"
|
|
128
|
+
aria-describedby="template-gallery-desc"
|
|
129
|
+
>
|
|
130
|
+
<Card className="cursor-pointer transition-all duration-150 hover:shadow-md hover:border-primary/50 hover:scale-[1.02]">
|
|
131
|
+
<CardContent className="pt-6 pb-6">
|
|
132
|
+
<div className="flex items-start gap-4">
|
|
133
|
+
<div className="flex-shrink-0">
|
|
134
|
+
<div className="h-12 w-12 rounded-lg bg-primary/5 flex items-center justify-center group-hover:bg-primary/10 transition-colors">
|
|
135
|
+
<Sparkles className="h-6 w-6 text-primary/60" />
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
<div className="flex-1 text-left">
|
|
139
|
+
<h3 className="font-medium text-base mb-1">
|
|
140
|
+
Browse Template Gallery
|
|
141
|
+
</h3>
|
|
142
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
143
|
+
Start with a pre-built workflow and customize it to your
|
|
144
|
+
needs. Perfect for learning common patterns.
|
|
145
|
+
</p>
|
|
146
|
+
<div className="mt-2 flex items-center gap-2 text-xs text-muted-foreground">
|
|
147
|
+
<span className="inline-flex items-center gap-1">
|
|
148
|
+
⭐⭐⭐⭐⭐ Popular choice
|
|
149
|
+
</span>
|
|
150
|
+
<span>•</span>
|
|
151
|
+
<span>5 templates available</span>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</CardContent>
|
|
156
|
+
</Card>
|
|
157
|
+
<span id="template-gallery-desc" className="sr-only">
|
|
158
|
+
Choose from 5 pre-built workflow templates including login flows,
|
|
159
|
+
data extraction, API integration, multi-page navigation, and form
|
|
160
|
+
submission.
|
|
161
|
+
</span>
|
|
162
|
+
</button>
|
|
163
|
+
|
|
164
|
+
{/* Option 2: Start From Scratch */}
|
|
165
|
+
<button
|
|
166
|
+
onClick={handleStartFromScratchClick}
|
|
167
|
+
className="block w-full group text-left"
|
|
168
|
+
aria-label="Start from scratch"
|
|
169
|
+
aria-describedby="start-scratch-desc"
|
|
170
|
+
>
|
|
171
|
+
<Card className="cursor-pointer transition-all duration-150 hover:shadow-md hover:border-primary/50 hover:scale-[1.02]">
|
|
172
|
+
<CardContent className="pt-6 pb-6">
|
|
173
|
+
<div className="flex items-start gap-4">
|
|
174
|
+
<div className="flex-shrink-0">
|
|
175
|
+
<div className="h-12 w-12 rounded-lg bg-primary/5 flex items-center justify-center group-hover:bg-primary/10 transition-colors">
|
|
176
|
+
<PlayCircle className="h-6 w-6 text-primary/60" />
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
<div className="flex-1 text-left">
|
|
180
|
+
<h3 className="font-medium text-base mb-1">
|
|
181
|
+
Start From Scratch
|
|
182
|
+
</h3>
|
|
183
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
184
|
+
Build your workflow from the ground up. We'll
|
|
185
|
+
highlight the node palette and show you how to get started.
|
|
186
|
+
</p>
|
|
187
|
+
<div className="mt-2 text-xs text-muted-foreground">
|
|
188
|
+
For experienced users
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</CardContent>
|
|
193
|
+
</Card>
|
|
194
|
+
<span id="start-scratch-desc" className="sr-only">
|
|
195
|
+
Create a custom workflow by adding nodes from the node palette.
|
|
196
|
+
Ideal for users familiar with workflow automation.
|
|
197
|
+
</span>
|
|
198
|
+
</button>
|
|
199
|
+
|
|
200
|
+
{/* Don't show again checkbox */}
|
|
201
|
+
<div className="flex items-center justify-between pt-4 border-t">
|
|
202
|
+
<div className="flex items-center space-x-2">
|
|
203
|
+
<Checkbox
|
|
204
|
+
id="dontShowAgain"
|
|
205
|
+
checked={dontShowAgain}
|
|
206
|
+
onCheckedChange={(checked) => setDontShowAgain(checked === true)}
|
|
207
|
+
/>
|
|
208
|
+
<Label
|
|
209
|
+
htmlFor="dontShowAgain"
|
|
210
|
+
className="text-sm text-muted-foreground cursor-pointer"
|
|
211
|
+
>
|
|
212
|
+
Don't show this again
|
|
213
|
+
</Label>
|
|
214
|
+
</div>
|
|
215
|
+
<Button
|
|
216
|
+
variant="ghost"
|
|
217
|
+
size="sm"
|
|
218
|
+
onClick={handleDismiss}
|
|
219
|
+
className="text-muted-foreground hover:text-foreground"
|
|
220
|
+
>
|
|
221
|
+
Close
|
|
222
|
+
</Button>
|
|
223
|
+
</div>
|
|
224
|
+
</CardContent>
|
|
225
|
+
</Card>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Hook to manage empty state visibility and reset.
|
|
232
|
+
*/
|
|
233
|
+
export function useWorkflowEmptyState() {
|
|
234
|
+
const [isGuidanceDismissed, setIsGuidanceDismissed] = useState(true);
|
|
235
|
+
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
const dismissed = localStorage.getItem(STORAGE_KEY) === 'true';
|
|
238
|
+
setIsGuidanceDismissed(dismissed);
|
|
239
|
+
}, []);
|
|
240
|
+
|
|
241
|
+
const resetGuidance = () => {
|
|
242
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
243
|
+
setIsGuidanceDismissed(false);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const dismissGuidance = () => {
|
|
247
|
+
localStorage.setItem(STORAGE_KEY, 'true');
|
|
248
|
+
setIsGuidanceDismissed(true);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
isGuidanceDismissed,
|
|
253
|
+
resetGuidance,
|
|
254
|
+
dismissGuidance,
|
|
255
|
+
};
|
|
256
|
+
}
|