@wakastellar/ui 2.3.4 → 2.4.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/dist/blocks/dashboard/index.d.ts +4 -1
- package/dist/blocks/empty-states/index.d.ts +4 -1
- package/dist/blocks/error-pages/index.d.ts +4 -1
- package/dist/blocks/index.d.ts +1 -1
- package/dist/blocks/landing/index.d.ts +4 -1
- package/dist/blocks/pricing/index.d.ts +5 -1
- package/dist/blocks/sidebar/index.d.ts +5 -1
- package/dist/index.cjs.js +130 -130
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +7905 -7856
- package/dist/stories/Button.d.ts +14 -0
- package/dist/stories/Button.stories.d.ts +8 -0
- package/dist/stories/Header.d.ts +11 -0
- package/dist/stories/Header.stories.d.ts +6 -0
- package/dist/stories/Page.d.ts +2 -0
- package/dist/stories/Page.stories.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/link.d.ts +23 -0
- package/package.json +11 -3
- package/src/blocks/activity-timeline/ActivityTimeline.stories.tsx +460 -0
- package/src/blocks/apm-overview/APMOverview.stories.tsx +435 -0
- package/src/blocks/auth-2fa/Auth2FA.stories.tsx +308 -0
- package/src/blocks/calendar-view/CalendarView.stories.tsx +398 -0
- package/src/blocks/chat/Chat.stories.tsx +466 -0
- package/src/blocks/chat-interface/ChatInterface.stories.tsx +412 -0
- package/src/blocks/checkout-flow/CheckoutFlow.stories.tsx +408 -0
- package/src/blocks/cicd-builder/CICDBuilder.stories.tsx +499 -0
- package/src/blocks/cloud-cost-dashboard/CloudCostDashboard.stories.tsx +356 -0
- package/src/blocks/container-orchestrator/ContainerOrchestrator.stories.tsx +461 -0
- package/src/blocks/dashboard/Dashboard.stories.tsx +559 -0
- package/src/blocks/dashboard/index.tsx +68 -27
- package/src/blocks/dashboard-kpi/DashboardKPI.stories.tsx +422 -0
- package/src/blocks/database-admin/DatabaseAdmin.stories.tsx +393 -0
- package/src/blocks/deployment-dashboard/DeploymentDashboard.stories.tsx +457 -0
- package/src/blocks/empty-states/EmptyStates.stories.tsx +467 -0
- package/src/blocks/empty-states/index.tsx +26 -8
- package/src/blocks/error-pages/ErrorPages.stories.tsx +401 -0
- package/src/blocks/error-pages/index.tsx +26 -8
- package/src/blocks/faq/FAQ.stories.tsx +416 -0
- package/src/blocks/file-manager/FileManager.stories.tsx +413 -0
- package/src/blocks/footer/Footer.stories.tsx +328 -0
- package/src/blocks/gitops-sync-status/GitOpsSyncStatus.stories.tsx +529 -0
- package/src/blocks/header/WakaHeader.stories.tsx +455 -0
- package/src/blocks/headtab/Headtab.stories.tsx +369 -0
- package/src/blocks/i18n-editor/I18nEditor.stories.tsx +451 -0
- package/src/blocks/incident-manager/IncidentManager.stories.tsx +464 -0
- package/src/blocks/index.ts +1 -1
- package/src/blocks/infrastructure-map/InfrastructureMap.stories.tsx +533 -0
- package/src/blocks/kanban-board/KanbanBoard.stories.tsx +494 -0
- package/src/blocks/landing/WakaLanding.stories.tsx +449 -0
- package/src/blocks/landing/index.tsx +125 -66
- package/src/blocks/language-selector/LanguageSelector.stories.tsx +345 -0
- package/src/blocks/layout/Layout.stories.tsx +373 -0
- package/src/blocks/login/Login.stories.tsx +443 -0
- package/src/blocks/on-call-schedule/OnCallSchedule.stories.tsx +381 -0
- package/src/blocks/player-profile/PlayerProfile.stories.tsx +316 -0
- package/src/blocks/pricing/WakaPricing.stories.tsx +530 -0
- package/src/blocks/pricing/index.tsx +38 -4
- package/src/blocks/profile/Profile.stories.tsx +371 -0
- package/src/blocks/release-notes/ReleaseNotes.stories.tsx +431 -0
- package/src/blocks/settings/Settings.stories.tsx +520 -0
- package/src/blocks/sidebar/WakaSidebar.stories.tsx +513 -0
- package/src/blocks/sidebar/index.tsx +49 -20
- package/src/blocks/theme-creator-block/ThemeCreatorBlock.stories.tsx +370 -0
- package/src/blocks/user-management/UserManagement.stories.tsx +411 -0
- package/src/blocks/wizard/Wizard.stories.tsx +683 -0
- package/src/components/accordion/Accordion.stories.tsx +93 -0
- package/src/components/alert/Alert.stories.tsx +95 -0
- package/src/components/alert-dialog/AlertDialog.stories.tsx +126 -0
- package/src/components/aspect-ratio/AspectRatio.stories.tsx +118 -0
- package/src/components/avatar/Avatar.stories.tsx +104 -0
- package/src/components/button/Button.stories.tsx +12 -1
- package/src/components/calendar/Calendar.stories.tsx +102 -0
- package/src/components/card/Card.stories.tsx +125 -0
- package/src/components/checkbox/Checkbox.stories.tsx +100 -0
- package/src/components/code/Code.stories.tsx +402 -0
- package/src/components/collapsible/Collapsible.stories.tsx +123 -0
- package/src/components/command/Command.stories.tsx +207 -0
- package/src/components/context-menu/ContextMenu.stories.tsx +220 -0
- package/src/components/dialog/Dialog.stories.tsx +157 -0
- package/src/components/dropdown-menu/DropdownMenu.stories.tsx +225 -0
- package/src/components/form/Form.stories.tsx +413 -0
- package/src/components/hover-card/HoverCard.stories.tsx +148 -0
- package/src/components/input-otp/InputOTP.stories.tsx +255 -0
- package/src/components/label/Label.stories.tsx +68 -0
- package/src/components/menubar/Menubar.stories.tsx +278 -0
- package/src/components/navigation-menu/NavigationMenu.stories.tsx +202 -0
- package/src/components/popover/Popover.stories.tsx +199 -0
- package/src/components/progress/Progress.stories.tsx +104 -0
- package/src/components/radio-group/RadioGroup.stories.tsx +138 -0
- package/src/components/scroll-area/ScrollArea.stories.tsx +153 -0
- package/src/components/select/Select.stories.tsx +146 -0
- package/src/components/separator/Separator.stories.tsx +117 -0
- package/src/components/sheet/Sheet.stories.tsx +195 -0
- package/src/components/skeleton/Skeleton.stories.tsx +114 -0
- package/src/components/slider/Slider.stories.tsx +157 -0
- package/src/components/switch/Switch.stories.tsx +114 -0
- package/src/components/table/Table.stories.tsx +153 -0
- package/src/components/tabs/Tabs.stories.tsx +155 -0
- package/src/components/textarea/Textarea.stories.tsx +116 -0
- package/src/components/toast/Toast.stories.tsx +160 -0
- package/src/components/toggle/Toggle.stories.tsx +125 -0
- package/src/components/tooltip/Tooltip.stories.tsx +133 -0
- package/src/components/typography/Typography.stories.tsx +207 -0
- package/src/components/waka-3d-pie-chart/Waka3DPieChart.stories.tsx +308 -0
- package/src/components/waka-achievement-unlock/WakaAchievementUnlock.stories.tsx +353 -0
- package/src/components/waka-artifact-list/WakaArtifactList.stories.tsx +258 -0
- package/src/components/waka-autocomplete/WakaAutocomplete.stories.tsx +224 -0
- package/src/components/waka-badge-showcase/WakaBadgeShowcase.stories.tsx +269 -0
- package/src/components/waka-barcode/WakaBarcode.stories.tsx +227 -0
- package/src/components/waka-bottom-sheet/WakaBottomSheet.stories.tsx +408 -0
- package/src/components/waka-breadcrumb/WakaBreadcrumb.stories.tsx +237 -0
- package/src/components/waka-build-matrix/WakaBuildMatrix.stories.tsx +328 -0
- package/src/components/waka-carousel/WakaCarousel.stories.tsx +296 -0
- package/src/components/waka-charts/WakaCharts.stories.tsx +519 -0
- package/src/components/waka-color-picker/WakaColorPicker.stories.tsx +200 -0
- package/src/components/waka-combobox/WakaCombobox.stories.tsx +250 -0
- package/src/components/waka-container-list/WakaContainerList.stories.tsx +315 -0
- package/src/components/waka-contribution-graph/WakaContributionGraph.stories.tsx +354 -0
- package/src/components/waka-cost-breakdown/WakaCostBreakdown.stories.tsx +348 -0
- package/src/components/waka-daily-reward/WakaDailyReward.stories.tsx +365 -0
- package/src/components/waka-database-card/WakaDatabaseCard.stories.tsx +306 -0
- package/src/components/waka-date-range-picker/WakaDateRangePicker.stories.tsx +339 -0
- package/src/components/waka-datetime-picker/WakaDateTimePicker.stories.tsx +317 -0
- package/src/components/waka-deployment-lane/WakaDeploymentLane.stories.tsx +292 -0
- package/src/components/waka-dock/WakaDock.stories.tsx +332 -0
- package/src/components/waka-drawer/WakaDrawer.stories.tsx +437 -0
- package/src/components/waka-env-var-editor/WakaEnvVarEditor.stories.tsx +263 -0
- package/src/components/waka-error-shake/WakaErrorShake.stories.tsx +410 -0
- package/src/components/waka-file-upload/WakaFileUpload.stories.tsx +239 -0
- package/src/components/waka-flow-diagram/WakaFlowDiagram.stories.tsx +365 -0
- package/src/components/waka-funnel-chart/WakaFunnelChart.stories.tsx +281 -0
- package/src/components/waka-glow-card/WakaGlowCard.stories.tsx +274 -0
- package/src/components/waka-haptic-button/WakaHapticButton.stories.tsx +349 -0
- package/src/components/waka-health-pulse/WakaHealthPulse.stories.tsx +293 -0
- package/src/components/waka-heatmap/WakaHeatmap.stories.tsx +376 -0
- package/src/components/waka-image/WakaImage.stories.tsx +255 -0
- package/src/components/waka-incident-timeline/WakaIncidentTimeline.stories.tsx +300 -0
- package/src/components/waka-kanban/WakaKanban.stories.tsx +399 -0
- package/src/components/waka-kubernetes-overview/WakaKubernetesOverview.stories.tsx +281 -0
- package/src/components/waka-leaderboard/WakaLeaderboard.stories.tsx +300 -0
- package/src/components/waka-level-progress/WakaLevelProgress.stories.tsx +313 -0
- package/src/components/waka-loading-orbit/WakaLoadingOrbit.stories.tsx +413 -0
- package/src/components/waka-log-viewer/WakaLogViewer.stories.tsx +312 -0
- package/src/components/waka-loot-box/WakaLootBox.stories.tsx +374 -0
- package/src/components/waka-metric-sparkline/WakaMetricSparkline.stories.tsx +312 -0
- package/src/components/waka-migration-list/WakaMigrationList.stories.tsx +289 -0
- package/src/components/waka-modal/WakaModal.stories.tsx +434 -0
- package/src/components/waka-morph-button/WakaMorphButton.stories.tsx +405 -0
- package/src/components/waka-network-topology/WakaNetworkTopology.stories.tsx +364 -0
- package/src/components/waka-notifications/WakaNotifications.stories.tsx +290 -0
- package/src/components/waka-number-input/WakaNumberInput.stories.tsx +282 -0
- package/src/components/waka-pagination/WakaPagination.stories.tsx +328 -0
- package/src/components/waka-password-strength/WakaPasswordStrength.stories.tsx +318 -0
- package/src/components/waka-pipeline-view/WakaPipelineView.stories.tsx +386 -0
- package/src/components/waka-player-card/WakaPlayerCard.stories.tsx +333 -0
- package/src/components/waka-pod-card/WakaPodCard.stories.tsx +435 -0
- package/src/components/waka-qrcode/WakaQRCode.stories.tsx +232 -0
- package/src/components/waka-query-explain/WakaQueryExplain.stories.tsx +407 -0
- package/src/components/waka-quest-card/WakaQuestCard.stories.tsx +394 -0
- package/src/components/waka-quota-bar/WakaQuotaBar.stories.tsx +435 -0
- package/src/components/waka-radar-score/WakaRadarScore.stories.tsx +372 -0
- package/src/components/waka-resource-gauge/WakaResourceGauge.stories.tsx +366 -0
- package/src/components/waka-rich-text-editor/WakaRichTextEditor.stories.tsx +238 -0
- package/src/components/waka-sankey-diagram/WakaSankeyDiagram.stories.tsx +389 -0
- package/src/components/waka-scratch-card/WakaScratchCard.stories.tsx +388 -0
- package/src/components/waka-secret-card/WakaSecretCard.stories.tsx +314 -0
- package/src/components/waka-segmented-control/WakaSegmentedControl.stories.tsx +309 -0
- package/src/components/waka-server-rack/WakaServerRack.stories.tsx +382 -0
- package/src/components/waka-service-graph/WakaServiceGraph.stories.tsx +262 -0
- package/src/components/waka-skeleton-wave/WakaSkeletonWave.stories.tsx +321 -0
- package/src/components/waka-skill-tree/WakaSkillTree.stories.tsx +308 -0
- package/src/components/waka-spin-wheel/WakaSpinWheel.stories.tsx +368 -0
- package/src/components/waka-spinner/WakaSpinner.stories.tsx +156 -0
- package/src/components/waka-stat/WakaStat.stories.tsx +334 -0
- package/src/components/waka-status-matrix/WakaStatusMatrix.stories.tsx +331 -0
- package/src/components/waka-stepper/WakaStepper.stories.tsx +468 -0
- package/src/components/waka-streak-counter/WakaStreakCounter.stories.tsx +235 -0
- package/src/components/waka-success-explosion/WakaSuccessExplosion.stories.tsx +389 -0
- package/src/components/waka-tabs-morph/WakaTabsMorph.stories.tsx +471 -0
- package/src/components/waka-terminal-output/WakaTerminalOutput.stories.tsx +351 -0
- package/src/components/waka-test-report/WakaTestReport.stories.tsx +322 -0
- package/src/components/waka-tilt-card/WakaTiltCard.stories.tsx +300 -0
- package/src/components/waka-time-picker/WakaTimePicker.stories.tsx +227 -0
- package/src/components/waka-timeline/WakaTimeline.stories.tsx +383 -0
- package/src/components/waka-tournament-bracket/WakaTournamentBracket.stories.tsx +375 -0
- package/src/components/waka-trace-viewer/WakaTraceViewer.stories.tsx +445 -0
- package/src/components/waka-tree/WakaTree.stories.tsx +359 -0
- package/src/components/waka-treemap-chart/WakaTreemapChart.stories.tsx +378 -0
- package/src/components/waka-typewriter/WakaTypewriter.stories.tsx +366 -0
- package/src/components/waka-versus-card/WakaVersusCard.stories.tsx +530 -0
- package/src/components/waka-video/WakaVideo.stories.tsx +203 -0
- package/src/components/waka-virtual-list/WakaVirtualList.stories.tsx +273 -0
- package/src/components/waka-xp-bar/WakaXPBar.stories.tsx +305 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { WakaPasswordStrength, WakaPasswordStrengthIndicator } from './index'
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof WakaPasswordStrength> = {
|
|
6
|
+
title: 'Components/Forms/WakaPasswordStrength',
|
|
7
|
+
component: WakaPasswordStrength,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: 'A password strength indicator with animated bar, checklist, and configurable requirements.',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
tags: ['autodocs'],
|
|
17
|
+
argTypes: {
|
|
18
|
+
size: {
|
|
19
|
+
control: 'select',
|
|
20
|
+
options: ['sm', 'default', 'lg'],
|
|
21
|
+
description: 'Size of the component',
|
|
22
|
+
},
|
|
23
|
+
showInput: {
|
|
24
|
+
control: 'boolean',
|
|
25
|
+
description: 'Show password input',
|
|
26
|
+
},
|
|
27
|
+
showStrengthBar: {
|
|
28
|
+
control: 'boolean',
|
|
29
|
+
description: 'Show strength bar',
|
|
30
|
+
},
|
|
31
|
+
showChecklist: {
|
|
32
|
+
control: 'boolean',
|
|
33
|
+
description: 'Show requirements checklist',
|
|
34
|
+
},
|
|
35
|
+
showStrengthLabel: {
|
|
36
|
+
control: 'boolean',
|
|
37
|
+
description: 'Show strength label',
|
|
38
|
+
},
|
|
39
|
+
animated: {
|
|
40
|
+
control: 'boolean',
|
|
41
|
+
description: 'Enable animations',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default meta
|
|
47
|
+
type Story = StoryObj<typeof WakaPasswordStrength>
|
|
48
|
+
|
|
49
|
+
export const Default: Story = {
|
|
50
|
+
render: function PasswordStrengthDemo() {
|
|
51
|
+
const [password, setPassword] = React.useState('')
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div className="w-[350px]">
|
|
55
|
+
<WakaPasswordStrength
|
|
56
|
+
password={password}
|
|
57
|
+
onPasswordChange={setPassword}
|
|
58
|
+
label="Password"
|
|
59
|
+
placeholder="Enter password"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
)
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const WithInitialValue: Story = {
|
|
67
|
+
render: function InitialValueDemo() {
|
|
68
|
+
const [password, setPassword] = React.useState('MyP@ssw0rd!')
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div className="w-[350px]">
|
|
72
|
+
<WakaPasswordStrength
|
|
73
|
+
password={password}
|
|
74
|
+
onPasswordChange={setPassword}
|
|
75
|
+
label="Password"
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
)
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const BarOnly: Story = {
|
|
83
|
+
render: function BarOnlyDemo() {
|
|
84
|
+
const [password, setPassword] = React.useState('')
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className="w-[350px]">
|
|
88
|
+
<WakaPasswordStrength
|
|
89
|
+
password={password}
|
|
90
|
+
onPasswordChange={setPassword}
|
|
91
|
+
label="Password"
|
|
92
|
+
showChecklist={false}
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
)
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const ChecklistOnly: Story = {
|
|
100
|
+
render: function ChecklistOnlyDemo() {
|
|
101
|
+
const [password, setPassword] = React.useState('')
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<div className="w-[350px]">
|
|
105
|
+
<WakaPasswordStrength
|
|
106
|
+
password={password}
|
|
107
|
+
onPasswordChange={setPassword}
|
|
108
|
+
label="Password"
|
|
109
|
+
showStrengthBar={false}
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
)
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const CustomRequirements: Story = {
|
|
117
|
+
render: function CustomRequirementsDemo() {
|
|
118
|
+
const [password, setPassword] = React.useState('')
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<div className="w-[350px]">
|
|
122
|
+
<WakaPasswordStrength
|
|
123
|
+
password={password}
|
|
124
|
+
onPasswordChange={setPassword}
|
|
125
|
+
label="Password"
|
|
126
|
+
minLength={10}
|
|
127
|
+
requireUppercase
|
|
128
|
+
requireLowercase
|
|
129
|
+
requireNumber
|
|
130
|
+
requireSpecialChar={false}
|
|
131
|
+
customRequirements={[
|
|
132
|
+
{
|
|
133
|
+
key: 'noSpaces',
|
|
134
|
+
label: 'No spaces allowed',
|
|
135
|
+
validate: (p) => !p.includes(' '),
|
|
136
|
+
required: true,
|
|
137
|
+
},
|
|
138
|
+
]}
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
)
|
|
142
|
+
},
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const Sizes: Story = {
|
|
146
|
+
render: function SizesDemo() {
|
|
147
|
+
const [password, setPassword] = React.useState('Test123!')
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<div className="space-y-8 w-[350px]">
|
|
151
|
+
<div>
|
|
152
|
+
<p className="text-sm text-muted-foreground mb-2">Small</p>
|
|
153
|
+
<WakaPasswordStrength
|
|
154
|
+
password={password}
|
|
155
|
+
onPasswordChange={setPassword}
|
|
156
|
+
size="sm"
|
|
157
|
+
/>
|
|
158
|
+
</div>
|
|
159
|
+
<div>
|
|
160
|
+
<p className="text-sm text-muted-foreground mb-2">Default</p>
|
|
161
|
+
<WakaPasswordStrength
|
|
162
|
+
password={password}
|
|
163
|
+
onPasswordChange={setPassword}
|
|
164
|
+
size="default"
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
<div>
|
|
168
|
+
<p className="text-sm text-muted-foreground mb-2">Large</p>
|
|
169
|
+
<WakaPasswordStrength
|
|
170
|
+
password={password}
|
|
171
|
+
onPasswordChange={setPassword}
|
|
172
|
+
size="lg"
|
|
173
|
+
/>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
)
|
|
177
|
+
},
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export const WithError: Story = {
|
|
181
|
+
render: function ErrorDemo() {
|
|
182
|
+
const [password, setPassword] = React.useState('weak')
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<div className="w-[350px]">
|
|
186
|
+
<WakaPasswordStrength
|
|
187
|
+
password={password}
|
|
188
|
+
onPasswordChange={setPassword}
|
|
189
|
+
label="Password"
|
|
190
|
+
error="Password does not meet requirements"
|
|
191
|
+
/>
|
|
192
|
+
</div>
|
|
193
|
+
)
|
|
194
|
+
},
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export const Disabled: Story = {
|
|
198
|
+
render: () => (
|
|
199
|
+
<div className="w-[350px]">
|
|
200
|
+
<WakaPasswordStrength
|
|
201
|
+
password="SecureP@ss123"
|
|
202
|
+
label="Password"
|
|
203
|
+
disabled
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
),
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export const NoAnimation: Story = {
|
|
210
|
+
render: function NoAnimationDemo() {
|
|
211
|
+
const [password, setPassword] = React.useState('')
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<div className="w-[350px]">
|
|
215
|
+
<WakaPasswordStrength
|
|
216
|
+
password={password}
|
|
217
|
+
onPasswordChange={setPassword}
|
|
218
|
+
label="Password"
|
|
219
|
+
animated={false}
|
|
220
|
+
/>
|
|
221
|
+
</div>
|
|
222
|
+
)
|
|
223
|
+
},
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export const IndicatorOnly: Story = {
|
|
227
|
+
render: function IndicatorOnlyDemo() {
|
|
228
|
+
const [password, setPassword] = React.useState('')
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<div className="w-[350px] space-y-4">
|
|
232
|
+
<div>
|
|
233
|
+
<label className="text-sm font-medium">Password</label>
|
|
234
|
+
<input
|
|
235
|
+
type="password"
|
|
236
|
+
value={password}
|
|
237
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
238
|
+
className="w-full mt-1 px-3 py-2 border rounded-md"
|
|
239
|
+
placeholder="Enter password"
|
|
240
|
+
/>
|
|
241
|
+
</div>
|
|
242
|
+
<WakaPasswordStrengthIndicator password={password} />
|
|
243
|
+
</div>
|
|
244
|
+
)
|
|
245
|
+
},
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export const StrengthLevels: Story = {
|
|
249
|
+
render: () => (
|
|
250
|
+
<div className="w-[350px] space-y-6">
|
|
251
|
+
<div>
|
|
252
|
+
<p className="text-sm text-muted-foreground mb-2">Weak</p>
|
|
253
|
+
<WakaPasswordStrength password="abc" showInput={false} showChecklist={false} />
|
|
254
|
+
</div>
|
|
255
|
+
<div>
|
|
256
|
+
<p className="text-sm text-muted-foreground mb-2">Fair</p>
|
|
257
|
+
<WakaPasswordStrength password="abc12345" showInput={false} showChecklist={false} />
|
|
258
|
+
</div>
|
|
259
|
+
<div>
|
|
260
|
+
<p className="text-sm text-muted-foreground mb-2">Good</p>
|
|
261
|
+
<WakaPasswordStrength password="Abc12345" showInput={false} showChecklist={false} />
|
|
262
|
+
</div>
|
|
263
|
+
<div>
|
|
264
|
+
<p className="text-sm text-muted-foreground mb-2">Strong</p>
|
|
265
|
+
<WakaPasswordStrength password="Abc12345!" showInput={false} showChecklist={false} />
|
|
266
|
+
</div>
|
|
267
|
+
<div>
|
|
268
|
+
<p className="text-sm text-muted-foreground mb-2">Very Strong</p>
|
|
269
|
+
<WakaPasswordStrength password="Abc12345!@#$XYZ" showInput={false} showChecklist={false} />
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
),
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export const RegistrationForm: Story = {
|
|
276
|
+
render: function RegistrationDemo() {
|
|
277
|
+
const [password, setPassword] = React.useState('')
|
|
278
|
+
const [confirmPassword, setConfirmPassword] = React.useState('')
|
|
279
|
+
const [isValid, setIsValid] = React.useState(false)
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<div className="w-[400px] space-y-6 p-6 border rounded-lg">
|
|
283
|
+
<div>
|
|
284
|
+
<h3 className="font-semibold">Create Account</h3>
|
|
285
|
+
<p className="text-sm text-muted-foreground">Choose a strong password</p>
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
<WakaPasswordStrength
|
|
289
|
+
password={password}
|
|
290
|
+
onPasswordChange={setPassword}
|
|
291
|
+
label="Password"
|
|
292
|
+
onStrengthChange={(result) => setIsValid(result.isValid)}
|
|
293
|
+
/>
|
|
294
|
+
|
|
295
|
+
<div className="space-y-2">
|
|
296
|
+
<label className="text-sm font-medium">Confirm Password</label>
|
|
297
|
+
<input
|
|
298
|
+
type="password"
|
|
299
|
+
value={confirmPassword}
|
|
300
|
+
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
301
|
+
className="w-full px-3 py-2 border rounded-md"
|
|
302
|
+
placeholder="Confirm password"
|
|
303
|
+
/>
|
|
304
|
+
{confirmPassword && password !== confirmPassword && (
|
|
305
|
+
<p className="text-sm text-destructive">Passwords do not match</p>
|
|
306
|
+
)}
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
<button
|
|
310
|
+
className="w-full py-2 px-4 bg-primary text-primary-foreground rounded-md disabled:opacity-50"
|
|
311
|
+
disabled={!isValid || password !== confirmPassword}
|
|
312
|
+
>
|
|
313
|
+
Create Account
|
|
314
|
+
</button>
|
|
315
|
+
</div>
|
|
316
|
+
)
|
|
317
|
+
},
|
|
318
|
+
}
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { WakaPipelineView } from './index'
|
|
3
|
+
import type { PipelineStage, StageStatus } from './index'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
|
|
6
|
+
const completedPipeline: PipelineStage[] = [
|
|
7
|
+
{ id: 'checkout', name: 'Checkout', status: 'success', duration: 3 },
|
|
8
|
+
{ id: 'install', name: 'Install', status: 'success', duration: 45 },
|
|
9
|
+
{ id: 'lint', name: 'Lint', status: 'success', duration: 12 },
|
|
10
|
+
{ id: 'test', name: 'Test', status: 'success', duration: 89 },
|
|
11
|
+
{ id: 'build', name: 'Build', status: 'success', duration: 34 },
|
|
12
|
+
{ id: 'deploy', name: 'Deploy', status: 'success', duration: 28 },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
const runningPipeline: PipelineStage[] = [
|
|
16
|
+
{ id: 'checkout', name: 'Checkout', status: 'success', duration: 3 },
|
|
17
|
+
{ id: 'install', name: 'Install', status: 'success', duration: 45 },
|
|
18
|
+
{ id: 'lint', name: 'Lint', status: 'success', duration: 12 },
|
|
19
|
+
{ id: 'test', name: 'Test', status: 'running', duration: 42 },
|
|
20
|
+
{ id: 'build', name: 'Build', status: 'pending' },
|
|
21
|
+
{ id: 'deploy', name: 'Deploy', status: 'pending' },
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
const failedPipeline: PipelineStage[] = [
|
|
25
|
+
{ id: 'checkout', name: 'Checkout', status: 'success', duration: 3 },
|
|
26
|
+
{ id: 'install', name: 'Install', status: 'success', duration: 45 },
|
|
27
|
+
{ id: 'lint', name: 'Lint', status: 'success', duration: 12 },
|
|
28
|
+
{ id: 'test', name: 'Test', status: 'failed', duration: 156 },
|
|
29
|
+
{ id: 'build', name: 'Build', status: 'skipped' },
|
|
30
|
+
{ id: 'deploy', name: 'Deploy', status: 'skipped' },
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
const pipelineWithJobs: PipelineStage[] = [
|
|
34
|
+
{ id: 'checkout', name: 'Checkout', status: 'success', duration: 3 },
|
|
35
|
+
{
|
|
36
|
+
id: 'test',
|
|
37
|
+
name: 'Test',
|
|
38
|
+
status: 'success',
|
|
39
|
+
duration: 156,
|
|
40
|
+
jobs: [
|
|
41
|
+
{ id: 'unit', name: 'Unit Tests', status: 'success', duration: 45 },
|
|
42
|
+
{ id: 'integration', name: 'Integration Tests', status: 'success', duration: 89 },
|
|
43
|
+
{ id: 'e2e', name: 'E2E Tests', status: 'success', duration: 120 },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'build',
|
|
48
|
+
name: 'Build',
|
|
49
|
+
status: 'running',
|
|
50
|
+
jobs: [
|
|
51
|
+
{ id: 'build-app', name: 'Build App', status: 'success', duration: 23 },
|
|
52
|
+
{ id: 'build-docs', name: 'Build Docs', status: 'running' },
|
|
53
|
+
{ id: 'build-storybook', name: 'Build Storybook', status: 'pending' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'deploy',
|
|
58
|
+
name: 'Deploy',
|
|
59
|
+
status: 'pending',
|
|
60
|
+
jobs: [
|
|
61
|
+
{ id: 'deploy-staging', name: 'Deploy Staging', status: 'pending' },
|
|
62
|
+
{ id: 'deploy-prod', name: 'Deploy Production', status: 'pending' },
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
const meta: Meta<typeof WakaPipelineView> = {
|
|
68
|
+
title: 'Components/DevOps/WakaPipelineView',
|
|
69
|
+
component: WakaPipelineView,
|
|
70
|
+
parameters: {
|
|
71
|
+
layout: 'centered',
|
|
72
|
+
docs: {
|
|
73
|
+
description: {
|
|
74
|
+
component: 'A CI/CD pipeline visualization with stage status, duration, parallel jobs, retry support, and horizontal/vertical layouts.',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
tags: ['autodocs'],
|
|
79
|
+
argTypes: {
|
|
80
|
+
variant: {
|
|
81
|
+
control: 'select',
|
|
82
|
+
options: ['horizontal', 'vertical'],
|
|
83
|
+
description: 'Layout variant',
|
|
84
|
+
},
|
|
85
|
+
size: {
|
|
86
|
+
control: 'select',
|
|
87
|
+
options: ['sm', 'md', 'lg'],
|
|
88
|
+
description: 'Size variant',
|
|
89
|
+
},
|
|
90
|
+
showDuration: {
|
|
91
|
+
control: 'boolean',
|
|
92
|
+
description: 'Show duration for each stage',
|
|
93
|
+
},
|
|
94
|
+
showJobs: {
|
|
95
|
+
control: 'boolean',
|
|
96
|
+
description: 'Show parallel jobs within stages',
|
|
97
|
+
},
|
|
98
|
+
animated: {
|
|
99
|
+
control: 'boolean',
|
|
100
|
+
description: 'Enable animations',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export default meta
|
|
106
|
+
type Story = StoryObj<typeof WakaPipelineView>
|
|
107
|
+
|
|
108
|
+
export const Default: Story = {
|
|
109
|
+
args: {
|
|
110
|
+
stages: completedPipeline,
|
|
111
|
+
variant: 'horizontal',
|
|
112
|
+
size: 'md',
|
|
113
|
+
showDuration: true,
|
|
114
|
+
showJobs: true,
|
|
115
|
+
animated: true,
|
|
116
|
+
},
|
|
117
|
+
render: (args) => <WakaPipelineView {...args} onStageClick={(id) => console.log('Clicked:', id)} />,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const Running: Story = {
|
|
121
|
+
render: () => (
|
|
122
|
+
<WakaPipelineView
|
|
123
|
+
stages={runningPipeline}
|
|
124
|
+
onStageClick={(id) => console.log('Clicked:', id)}
|
|
125
|
+
/>
|
|
126
|
+
),
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export const Failed: Story = {
|
|
130
|
+
render: () => (
|
|
131
|
+
<WakaPipelineView
|
|
132
|
+
stages={failedPipeline}
|
|
133
|
+
onStageClick={(id) => console.log('Clicked:', id)}
|
|
134
|
+
onRetry={(id) => console.log('Retry:', id)}
|
|
135
|
+
/>
|
|
136
|
+
),
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const WithJobs: Story = {
|
|
140
|
+
render: () => (
|
|
141
|
+
<WakaPipelineView
|
|
142
|
+
stages={pipelineWithJobs}
|
|
143
|
+
showJobs
|
|
144
|
+
onStageClick={(id) => console.log('Clicked:', id)}
|
|
145
|
+
/>
|
|
146
|
+
),
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export const Vertical: Story = {
|
|
150
|
+
render: () => (
|
|
151
|
+
<div className="w-[400px]">
|
|
152
|
+
<WakaPipelineView
|
|
153
|
+
stages={runningPipeline}
|
|
154
|
+
variant="vertical"
|
|
155
|
+
onStageClick={(id) => console.log('Clicked:', id)}
|
|
156
|
+
/>
|
|
157
|
+
</div>
|
|
158
|
+
),
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export const VerticalWithJobs: Story = {
|
|
162
|
+
render: () => (
|
|
163
|
+
<div className="w-[400px]">
|
|
164
|
+
<WakaPipelineView
|
|
165
|
+
stages={pipelineWithJobs}
|
|
166
|
+
variant="vertical"
|
|
167
|
+
showJobs
|
|
168
|
+
onStageClick={(id) => console.log('Clicked:', id)}
|
|
169
|
+
/>
|
|
170
|
+
</div>
|
|
171
|
+
),
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export const Sizes: Story = {
|
|
175
|
+
render: () => (
|
|
176
|
+
<div className="space-y-8">
|
|
177
|
+
<div>
|
|
178
|
+
<p className="text-sm text-muted-foreground mb-4">Small</p>
|
|
179
|
+
<WakaPipelineView stages={completedPipeline} size="sm" />
|
|
180
|
+
</div>
|
|
181
|
+
<div>
|
|
182
|
+
<p className="text-sm text-muted-foreground mb-4">Medium (Default)</p>
|
|
183
|
+
<WakaPipelineView stages={completedPipeline} size="md" />
|
|
184
|
+
</div>
|
|
185
|
+
<div>
|
|
186
|
+
<p className="text-sm text-muted-foreground mb-4">Large</p>
|
|
187
|
+
<WakaPipelineView stages={completedPipeline} size="lg" />
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
),
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export const AllStatuses: Story = {
|
|
194
|
+
render: () => {
|
|
195
|
+
const allStatuses: PipelineStage[] = [
|
|
196
|
+
{ id: '1', name: 'Pending', status: 'pending' },
|
|
197
|
+
{ id: '2', name: 'Running', status: 'running' },
|
|
198
|
+
{ id: '3', name: 'Success', status: 'success', duration: 30 },
|
|
199
|
+
{ id: '4', name: 'Failed', status: 'failed', duration: 45 },
|
|
200
|
+
{ id: '5', name: 'Skipped', status: 'skipped' },
|
|
201
|
+
{ id: '6', name: 'Cancelled', status: 'cancelled' },
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<div className="space-y-6">
|
|
206
|
+
<p className="text-sm text-muted-foreground">All possible stage statuses</p>
|
|
207
|
+
<WakaPipelineView stages={allStatuses} />
|
|
208
|
+
</div>
|
|
209
|
+
)
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export const NoDuration: Story = {
|
|
214
|
+
render: () => (
|
|
215
|
+
<WakaPipelineView
|
|
216
|
+
stages={completedPipeline}
|
|
217
|
+
showDuration={false}
|
|
218
|
+
/>
|
|
219
|
+
),
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export const NoAnimations: Story = {
|
|
223
|
+
render: () => (
|
|
224
|
+
<WakaPipelineView
|
|
225
|
+
stages={runningPipeline}
|
|
226
|
+
animated={false}
|
|
227
|
+
/>
|
|
228
|
+
),
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export const Interactive: Story = {
|
|
232
|
+
render: () => {
|
|
233
|
+
const [stages, setStages] = React.useState<PipelineStage[]>([
|
|
234
|
+
{ id: 'checkout', name: 'Checkout', status: 'pending' },
|
|
235
|
+
{ id: 'install', name: 'Install', status: 'pending' },
|
|
236
|
+
{ id: 'lint', name: 'Lint', status: 'pending' },
|
|
237
|
+
{ id: 'test', name: 'Test', status: 'pending' },
|
|
238
|
+
{ id: 'build', name: 'Build', status: 'pending' },
|
|
239
|
+
{ id: 'deploy', name: 'Deploy', status: 'pending' },
|
|
240
|
+
])
|
|
241
|
+
const [currentIndex, setCurrentIndex] = React.useState(-1)
|
|
242
|
+
|
|
243
|
+
const runPipeline = () => {
|
|
244
|
+
setStages(prev => prev.map(s => ({ ...s, status: 'pending' as StageStatus, duration: undefined })))
|
|
245
|
+
setCurrentIndex(0)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
React.useEffect(() => {
|
|
249
|
+
if (currentIndex < 0 || currentIndex >= stages.length) return
|
|
250
|
+
|
|
251
|
+
// Set current stage to running
|
|
252
|
+
setStages(prev => prev.map((s, i) => ({
|
|
253
|
+
...s,
|
|
254
|
+
status: i === currentIndex ? 'running' : i < currentIndex ? 'success' : 'pending',
|
|
255
|
+
})))
|
|
256
|
+
|
|
257
|
+
// Complete after random duration
|
|
258
|
+
const duration = Math.floor(Math.random() * 3000) + 1000
|
|
259
|
+
const timer = setTimeout(() => {
|
|
260
|
+
setStages(prev => prev.map((s, i) => ({
|
|
261
|
+
...s,
|
|
262
|
+
status: i <= currentIndex ? 'success' : 'pending',
|
|
263
|
+
duration: i === currentIndex ? Math.floor(duration / 1000) : s.duration,
|
|
264
|
+
})))
|
|
265
|
+
setCurrentIndex(prev => prev + 1)
|
|
266
|
+
}, duration)
|
|
267
|
+
|
|
268
|
+
return () => clearTimeout(timer)
|
|
269
|
+
}, [currentIndex, stages.length])
|
|
270
|
+
|
|
271
|
+
const isRunning = currentIndex >= 0 && currentIndex < stages.length
|
|
272
|
+
const isComplete = currentIndex >= stages.length
|
|
273
|
+
|
|
274
|
+
return (
|
|
275
|
+
<div className="space-y-6">
|
|
276
|
+
<WakaPipelineView
|
|
277
|
+
stages={stages}
|
|
278
|
+
onStageClick={(id) => console.log('Clicked:', id)}
|
|
279
|
+
/>
|
|
280
|
+
|
|
281
|
+
<div className="flex items-center gap-4">
|
|
282
|
+
<button
|
|
283
|
+
onClick={runPipeline}
|
|
284
|
+
disabled={isRunning}
|
|
285
|
+
className="px-4 py-2 text-sm rounded bg-primary text-primary-foreground disabled:opacity-50"
|
|
286
|
+
>
|
|
287
|
+
{isComplete ? 'Run Again' : isRunning ? 'Running...' : 'Start Pipeline'}
|
|
288
|
+
</button>
|
|
289
|
+
{isComplete && (
|
|
290
|
+
<span className="text-sm text-green-500">Pipeline completed successfully!</span>
|
|
291
|
+
)}
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
)
|
|
295
|
+
},
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export const CICDDashboard: Story = {
|
|
299
|
+
render: () => {
|
|
300
|
+
const pipelines = [
|
|
301
|
+
{
|
|
302
|
+
name: 'main',
|
|
303
|
+
commit: 'fix: resolve memory leak in worker',
|
|
304
|
+
stages: completedPipeline,
|
|
305
|
+
time: '2 hours ago',
|
|
306
|
+
status: 'success' as const,
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: 'feature/auth',
|
|
310
|
+
commit: 'feat: add OAuth2 support',
|
|
311
|
+
stages: runningPipeline,
|
|
312
|
+
time: '5 minutes ago',
|
|
313
|
+
status: 'running' as const,
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: 'fix/api-timeout',
|
|
317
|
+
commit: 'fix: increase API timeout to 30s',
|
|
318
|
+
stages: failedPipeline,
|
|
319
|
+
time: '1 hour ago',
|
|
320
|
+
status: 'failed' as const,
|
|
321
|
+
},
|
|
322
|
+
]
|
|
323
|
+
|
|
324
|
+
return (
|
|
325
|
+
<div className="w-[900px] p-6 rounded-xl border bg-card">
|
|
326
|
+
<h2 className="text-xl font-bold mb-6">CI/CD Pipelines</h2>
|
|
327
|
+
|
|
328
|
+
<div className="space-y-6">
|
|
329
|
+
{pipelines.map((pipeline) => (
|
|
330
|
+
<div key={pipeline.name} className="p-4 rounded-lg border bg-muted/20">
|
|
331
|
+
<div className="flex items-center justify-between mb-4">
|
|
332
|
+
<div className="flex items-center gap-3">
|
|
333
|
+
<div className={`w-2 h-2 rounded-full ${
|
|
334
|
+
pipeline.status === 'success' ? 'bg-green-500' :
|
|
335
|
+
pipeline.status === 'running' ? 'bg-blue-500 animate-pulse' :
|
|
336
|
+
'bg-red-500'
|
|
337
|
+
}`} />
|
|
338
|
+
<span className="font-mono font-medium">{pipeline.name}</span>
|
|
339
|
+
<span className="text-sm text-muted-foreground truncate max-w-[300px]">
|
|
340
|
+
{pipeline.commit}
|
|
341
|
+
</span>
|
|
342
|
+
</div>
|
|
343
|
+
<span className="text-xs text-muted-foreground">{pipeline.time}</span>
|
|
344
|
+
</div>
|
|
345
|
+
|
|
346
|
+
<WakaPipelineView
|
|
347
|
+
stages={pipeline.stages}
|
|
348
|
+
size="sm"
|
|
349
|
+
onRetry={pipeline.status === 'failed' ? (id) => console.log('Retry:', id) : undefined}
|
|
350
|
+
/>
|
|
351
|
+
</div>
|
|
352
|
+
))}
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
)
|
|
356
|
+
},
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export const LongPipeline: Story = {
|
|
360
|
+
render: () => {
|
|
361
|
+
const longPipeline: PipelineStage[] = [
|
|
362
|
+
{ id: '1', name: 'Init', status: 'success', duration: 2 },
|
|
363
|
+
{ id: '2', name: 'Checkout', status: 'success', duration: 5 },
|
|
364
|
+
{ id: '3', name: 'Install', status: 'success', duration: 120 },
|
|
365
|
+
{ id: '4', name: 'Lint', status: 'success', duration: 15 },
|
|
366
|
+
{ id: '5', name: 'Type Check', status: 'success', duration: 25 },
|
|
367
|
+
{ id: '6', name: 'Unit Tests', status: 'success', duration: 90 },
|
|
368
|
+
{ id: '7', name: 'Integration', status: 'running', duration: 45 },
|
|
369
|
+
{ id: '8', name: 'E2E Tests', status: 'pending' },
|
|
370
|
+
{ id: '9', name: 'Build', status: 'pending' },
|
|
371
|
+
{ id: '10', name: 'Docker', status: 'pending' },
|
|
372
|
+
{ id: '11', name: 'Deploy Staging', status: 'pending' },
|
|
373
|
+
{ id: '12', name: 'Smoke Tests', status: 'pending' },
|
|
374
|
+
{ id: '13', name: 'Deploy Prod', status: 'pending' },
|
|
375
|
+
]
|
|
376
|
+
|
|
377
|
+
return (
|
|
378
|
+
<div className="overflow-x-auto pb-4">
|
|
379
|
+
<WakaPipelineView
|
|
380
|
+
stages={longPipeline}
|
|
381
|
+
size="sm"
|
|
382
|
+
/>
|
|
383
|
+
</div>
|
|
384
|
+
)
|
|
385
|
+
},
|
|
386
|
+
}
|