@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.
Files changed (194) hide show
  1. package/dist/blocks/dashboard/index.d.ts +4 -1
  2. package/dist/blocks/empty-states/index.d.ts +4 -1
  3. package/dist/blocks/error-pages/index.d.ts +4 -1
  4. package/dist/blocks/index.d.ts +1 -1
  5. package/dist/blocks/landing/index.d.ts +4 -1
  6. package/dist/blocks/pricing/index.d.ts +5 -1
  7. package/dist/blocks/sidebar/index.d.ts +5 -1
  8. package/dist/index.cjs.js +130 -130
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.es.js +7905 -7856
  11. package/dist/stories/Button.d.ts +14 -0
  12. package/dist/stories/Button.stories.d.ts +8 -0
  13. package/dist/stories/Header.d.ts +11 -0
  14. package/dist/stories/Header.stories.d.ts +6 -0
  15. package/dist/stories/Page.d.ts +2 -0
  16. package/dist/stories/Page.stories.d.ts +6 -0
  17. package/dist/types/index.d.ts +1 -0
  18. package/dist/types/link.d.ts +23 -0
  19. package/package.json +11 -3
  20. package/src/blocks/activity-timeline/ActivityTimeline.stories.tsx +460 -0
  21. package/src/blocks/apm-overview/APMOverview.stories.tsx +435 -0
  22. package/src/blocks/auth-2fa/Auth2FA.stories.tsx +308 -0
  23. package/src/blocks/calendar-view/CalendarView.stories.tsx +398 -0
  24. package/src/blocks/chat/Chat.stories.tsx +466 -0
  25. package/src/blocks/chat-interface/ChatInterface.stories.tsx +412 -0
  26. package/src/blocks/checkout-flow/CheckoutFlow.stories.tsx +408 -0
  27. package/src/blocks/cicd-builder/CICDBuilder.stories.tsx +499 -0
  28. package/src/blocks/cloud-cost-dashboard/CloudCostDashboard.stories.tsx +356 -0
  29. package/src/blocks/container-orchestrator/ContainerOrchestrator.stories.tsx +461 -0
  30. package/src/blocks/dashboard/Dashboard.stories.tsx +559 -0
  31. package/src/blocks/dashboard/index.tsx +68 -27
  32. package/src/blocks/dashboard-kpi/DashboardKPI.stories.tsx +422 -0
  33. package/src/blocks/database-admin/DatabaseAdmin.stories.tsx +393 -0
  34. package/src/blocks/deployment-dashboard/DeploymentDashboard.stories.tsx +457 -0
  35. package/src/blocks/empty-states/EmptyStates.stories.tsx +467 -0
  36. package/src/blocks/empty-states/index.tsx +26 -8
  37. package/src/blocks/error-pages/ErrorPages.stories.tsx +401 -0
  38. package/src/blocks/error-pages/index.tsx +26 -8
  39. package/src/blocks/faq/FAQ.stories.tsx +416 -0
  40. package/src/blocks/file-manager/FileManager.stories.tsx +413 -0
  41. package/src/blocks/footer/Footer.stories.tsx +328 -0
  42. package/src/blocks/gitops-sync-status/GitOpsSyncStatus.stories.tsx +529 -0
  43. package/src/blocks/header/WakaHeader.stories.tsx +455 -0
  44. package/src/blocks/headtab/Headtab.stories.tsx +369 -0
  45. package/src/blocks/i18n-editor/I18nEditor.stories.tsx +451 -0
  46. package/src/blocks/incident-manager/IncidentManager.stories.tsx +464 -0
  47. package/src/blocks/index.ts +1 -1
  48. package/src/blocks/infrastructure-map/InfrastructureMap.stories.tsx +533 -0
  49. package/src/blocks/kanban-board/KanbanBoard.stories.tsx +494 -0
  50. package/src/blocks/landing/WakaLanding.stories.tsx +449 -0
  51. package/src/blocks/landing/index.tsx +125 -66
  52. package/src/blocks/language-selector/LanguageSelector.stories.tsx +345 -0
  53. package/src/blocks/layout/Layout.stories.tsx +373 -0
  54. package/src/blocks/login/Login.stories.tsx +443 -0
  55. package/src/blocks/on-call-schedule/OnCallSchedule.stories.tsx +381 -0
  56. package/src/blocks/player-profile/PlayerProfile.stories.tsx +316 -0
  57. package/src/blocks/pricing/WakaPricing.stories.tsx +530 -0
  58. package/src/blocks/pricing/index.tsx +38 -4
  59. package/src/blocks/profile/Profile.stories.tsx +371 -0
  60. package/src/blocks/release-notes/ReleaseNotes.stories.tsx +431 -0
  61. package/src/blocks/settings/Settings.stories.tsx +520 -0
  62. package/src/blocks/sidebar/WakaSidebar.stories.tsx +513 -0
  63. package/src/blocks/sidebar/index.tsx +49 -20
  64. package/src/blocks/theme-creator-block/ThemeCreatorBlock.stories.tsx +370 -0
  65. package/src/blocks/user-management/UserManagement.stories.tsx +411 -0
  66. package/src/blocks/wizard/Wizard.stories.tsx +683 -0
  67. package/src/components/accordion/Accordion.stories.tsx +93 -0
  68. package/src/components/alert/Alert.stories.tsx +95 -0
  69. package/src/components/alert-dialog/AlertDialog.stories.tsx +126 -0
  70. package/src/components/aspect-ratio/AspectRatio.stories.tsx +118 -0
  71. package/src/components/avatar/Avatar.stories.tsx +104 -0
  72. package/src/components/button/Button.stories.tsx +12 -1
  73. package/src/components/calendar/Calendar.stories.tsx +102 -0
  74. package/src/components/card/Card.stories.tsx +125 -0
  75. package/src/components/checkbox/Checkbox.stories.tsx +100 -0
  76. package/src/components/code/Code.stories.tsx +402 -0
  77. package/src/components/collapsible/Collapsible.stories.tsx +123 -0
  78. package/src/components/command/Command.stories.tsx +207 -0
  79. package/src/components/context-menu/ContextMenu.stories.tsx +220 -0
  80. package/src/components/dialog/Dialog.stories.tsx +157 -0
  81. package/src/components/dropdown-menu/DropdownMenu.stories.tsx +225 -0
  82. package/src/components/form/Form.stories.tsx +413 -0
  83. package/src/components/hover-card/HoverCard.stories.tsx +148 -0
  84. package/src/components/input-otp/InputOTP.stories.tsx +255 -0
  85. package/src/components/label/Label.stories.tsx +68 -0
  86. package/src/components/menubar/Menubar.stories.tsx +278 -0
  87. package/src/components/navigation-menu/NavigationMenu.stories.tsx +202 -0
  88. package/src/components/popover/Popover.stories.tsx +199 -0
  89. package/src/components/progress/Progress.stories.tsx +104 -0
  90. package/src/components/radio-group/RadioGroup.stories.tsx +138 -0
  91. package/src/components/scroll-area/ScrollArea.stories.tsx +153 -0
  92. package/src/components/select/Select.stories.tsx +146 -0
  93. package/src/components/separator/Separator.stories.tsx +117 -0
  94. package/src/components/sheet/Sheet.stories.tsx +195 -0
  95. package/src/components/skeleton/Skeleton.stories.tsx +114 -0
  96. package/src/components/slider/Slider.stories.tsx +157 -0
  97. package/src/components/switch/Switch.stories.tsx +114 -0
  98. package/src/components/table/Table.stories.tsx +153 -0
  99. package/src/components/tabs/Tabs.stories.tsx +155 -0
  100. package/src/components/textarea/Textarea.stories.tsx +116 -0
  101. package/src/components/toast/Toast.stories.tsx +160 -0
  102. package/src/components/toggle/Toggle.stories.tsx +125 -0
  103. package/src/components/tooltip/Tooltip.stories.tsx +133 -0
  104. package/src/components/typography/Typography.stories.tsx +207 -0
  105. package/src/components/waka-3d-pie-chart/Waka3DPieChart.stories.tsx +308 -0
  106. package/src/components/waka-achievement-unlock/WakaAchievementUnlock.stories.tsx +353 -0
  107. package/src/components/waka-artifact-list/WakaArtifactList.stories.tsx +258 -0
  108. package/src/components/waka-autocomplete/WakaAutocomplete.stories.tsx +224 -0
  109. package/src/components/waka-badge-showcase/WakaBadgeShowcase.stories.tsx +269 -0
  110. package/src/components/waka-barcode/WakaBarcode.stories.tsx +227 -0
  111. package/src/components/waka-bottom-sheet/WakaBottomSheet.stories.tsx +408 -0
  112. package/src/components/waka-breadcrumb/WakaBreadcrumb.stories.tsx +237 -0
  113. package/src/components/waka-build-matrix/WakaBuildMatrix.stories.tsx +328 -0
  114. package/src/components/waka-carousel/WakaCarousel.stories.tsx +296 -0
  115. package/src/components/waka-charts/WakaCharts.stories.tsx +519 -0
  116. package/src/components/waka-color-picker/WakaColorPicker.stories.tsx +200 -0
  117. package/src/components/waka-combobox/WakaCombobox.stories.tsx +250 -0
  118. package/src/components/waka-container-list/WakaContainerList.stories.tsx +315 -0
  119. package/src/components/waka-contribution-graph/WakaContributionGraph.stories.tsx +354 -0
  120. package/src/components/waka-cost-breakdown/WakaCostBreakdown.stories.tsx +348 -0
  121. package/src/components/waka-daily-reward/WakaDailyReward.stories.tsx +365 -0
  122. package/src/components/waka-database-card/WakaDatabaseCard.stories.tsx +306 -0
  123. package/src/components/waka-date-range-picker/WakaDateRangePicker.stories.tsx +339 -0
  124. package/src/components/waka-datetime-picker/WakaDateTimePicker.stories.tsx +317 -0
  125. package/src/components/waka-deployment-lane/WakaDeploymentLane.stories.tsx +292 -0
  126. package/src/components/waka-dock/WakaDock.stories.tsx +332 -0
  127. package/src/components/waka-drawer/WakaDrawer.stories.tsx +437 -0
  128. package/src/components/waka-env-var-editor/WakaEnvVarEditor.stories.tsx +263 -0
  129. package/src/components/waka-error-shake/WakaErrorShake.stories.tsx +410 -0
  130. package/src/components/waka-file-upload/WakaFileUpload.stories.tsx +239 -0
  131. package/src/components/waka-flow-diagram/WakaFlowDiagram.stories.tsx +365 -0
  132. package/src/components/waka-funnel-chart/WakaFunnelChart.stories.tsx +281 -0
  133. package/src/components/waka-glow-card/WakaGlowCard.stories.tsx +274 -0
  134. package/src/components/waka-haptic-button/WakaHapticButton.stories.tsx +349 -0
  135. package/src/components/waka-health-pulse/WakaHealthPulse.stories.tsx +293 -0
  136. package/src/components/waka-heatmap/WakaHeatmap.stories.tsx +376 -0
  137. package/src/components/waka-image/WakaImage.stories.tsx +255 -0
  138. package/src/components/waka-incident-timeline/WakaIncidentTimeline.stories.tsx +300 -0
  139. package/src/components/waka-kanban/WakaKanban.stories.tsx +399 -0
  140. package/src/components/waka-kubernetes-overview/WakaKubernetesOverview.stories.tsx +281 -0
  141. package/src/components/waka-leaderboard/WakaLeaderboard.stories.tsx +300 -0
  142. package/src/components/waka-level-progress/WakaLevelProgress.stories.tsx +313 -0
  143. package/src/components/waka-loading-orbit/WakaLoadingOrbit.stories.tsx +413 -0
  144. package/src/components/waka-log-viewer/WakaLogViewer.stories.tsx +312 -0
  145. package/src/components/waka-loot-box/WakaLootBox.stories.tsx +374 -0
  146. package/src/components/waka-metric-sparkline/WakaMetricSparkline.stories.tsx +312 -0
  147. package/src/components/waka-migration-list/WakaMigrationList.stories.tsx +289 -0
  148. package/src/components/waka-modal/WakaModal.stories.tsx +434 -0
  149. package/src/components/waka-morph-button/WakaMorphButton.stories.tsx +405 -0
  150. package/src/components/waka-network-topology/WakaNetworkTopology.stories.tsx +364 -0
  151. package/src/components/waka-notifications/WakaNotifications.stories.tsx +290 -0
  152. package/src/components/waka-number-input/WakaNumberInput.stories.tsx +282 -0
  153. package/src/components/waka-pagination/WakaPagination.stories.tsx +328 -0
  154. package/src/components/waka-password-strength/WakaPasswordStrength.stories.tsx +318 -0
  155. package/src/components/waka-pipeline-view/WakaPipelineView.stories.tsx +386 -0
  156. package/src/components/waka-player-card/WakaPlayerCard.stories.tsx +333 -0
  157. package/src/components/waka-pod-card/WakaPodCard.stories.tsx +435 -0
  158. package/src/components/waka-qrcode/WakaQRCode.stories.tsx +232 -0
  159. package/src/components/waka-query-explain/WakaQueryExplain.stories.tsx +407 -0
  160. package/src/components/waka-quest-card/WakaQuestCard.stories.tsx +394 -0
  161. package/src/components/waka-quota-bar/WakaQuotaBar.stories.tsx +435 -0
  162. package/src/components/waka-radar-score/WakaRadarScore.stories.tsx +372 -0
  163. package/src/components/waka-resource-gauge/WakaResourceGauge.stories.tsx +366 -0
  164. package/src/components/waka-rich-text-editor/WakaRichTextEditor.stories.tsx +238 -0
  165. package/src/components/waka-sankey-diagram/WakaSankeyDiagram.stories.tsx +389 -0
  166. package/src/components/waka-scratch-card/WakaScratchCard.stories.tsx +388 -0
  167. package/src/components/waka-secret-card/WakaSecretCard.stories.tsx +314 -0
  168. package/src/components/waka-segmented-control/WakaSegmentedControl.stories.tsx +309 -0
  169. package/src/components/waka-server-rack/WakaServerRack.stories.tsx +382 -0
  170. package/src/components/waka-service-graph/WakaServiceGraph.stories.tsx +262 -0
  171. package/src/components/waka-skeleton-wave/WakaSkeletonWave.stories.tsx +321 -0
  172. package/src/components/waka-skill-tree/WakaSkillTree.stories.tsx +308 -0
  173. package/src/components/waka-spin-wheel/WakaSpinWheel.stories.tsx +368 -0
  174. package/src/components/waka-spinner/WakaSpinner.stories.tsx +156 -0
  175. package/src/components/waka-stat/WakaStat.stories.tsx +334 -0
  176. package/src/components/waka-status-matrix/WakaStatusMatrix.stories.tsx +331 -0
  177. package/src/components/waka-stepper/WakaStepper.stories.tsx +468 -0
  178. package/src/components/waka-streak-counter/WakaStreakCounter.stories.tsx +235 -0
  179. package/src/components/waka-success-explosion/WakaSuccessExplosion.stories.tsx +389 -0
  180. package/src/components/waka-tabs-morph/WakaTabsMorph.stories.tsx +471 -0
  181. package/src/components/waka-terminal-output/WakaTerminalOutput.stories.tsx +351 -0
  182. package/src/components/waka-test-report/WakaTestReport.stories.tsx +322 -0
  183. package/src/components/waka-tilt-card/WakaTiltCard.stories.tsx +300 -0
  184. package/src/components/waka-time-picker/WakaTimePicker.stories.tsx +227 -0
  185. package/src/components/waka-timeline/WakaTimeline.stories.tsx +383 -0
  186. package/src/components/waka-tournament-bracket/WakaTournamentBracket.stories.tsx +375 -0
  187. package/src/components/waka-trace-viewer/WakaTraceViewer.stories.tsx +445 -0
  188. package/src/components/waka-tree/WakaTree.stories.tsx +359 -0
  189. package/src/components/waka-treemap-chart/WakaTreemapChart.stories.tsx +378 -0
  190. package/src/components/waka-typewriter/WakaTypewriter.stories.tsx +366 -0
  191. package/src/components/waka-versus-card/WakaVersusCard.stories.tsx +530 -0
  192. package/src/components/waka-video/WakaVideo.stories.tsx +203 -0
  193. package/src/components/waka-virtual-list/WakaVirtualList.stories.tsx +273 -0
  194. package/src/components/waka-xp-bar/WakaXPBar.stories.tsx +305 -0
@@ -0,0 +1,399 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaKanban, useKanban } from './index'
3
+ import type { KanbanColumn, KanbanCard } from './index'
4
+ import * as React from 'react'
5
+
6
+ const meta: Meta<typeof WakaKanban> = {
7
+ title: 'Components/Display/WakaKanban',
8
+ component: WakaKanban,
9
+ parameters: {
10
+ layout: 'fullscreen',
11
+ docs: {
12
+ description: {
13
+ component: 'A drag-and-drop Kanban board component for task management and workflow visualization.',
14
+ },
15
+ },
16
+ },
17
+ tags: ['autodocs'],
18
+ argTypes: {
19
+ allowAddCard: {
20
+ control: 'boolean',
21
+ description: 'Allow adding new cards',
22
+ },
23
+ allowAddColumn: {
24
+ control: 'boolean',
25
+ description: 'Allow adding new columns',
26
+ },
27
+ allowColumnDrag: {
28
+ control: 'boolean',
29
+ description: 'Allow dragging columns',
30
+ },
31
+ },
32
+ }
33
+
34
+ export default meta
35
+ type Story = StoryObj<typeof WakaKanban>
36
+
37
+ const sampleColumns: KanbanColumn[] = [
38
+ {
39
+ id: 'todo',
40
+ title: 'To Do',
41
+ color: '#6B7280',
42
+ cards: [
43
+ {
44
+ id: 'card-1',
45
+ title: 'Design new landing page',
46
+ description: 'Create wireframes and mockups for the new marketing landing page',
47
+ labels: [
48
+ { id: 'l1', name: 'Design', color: '#8B5CF6' },
49
+ ],
50
+ priority: 'high',
51
+ assignee: { id: 'u1', name: 'John Doe' },
52
+ },
53
+ {
54
+ id: 'card-2',
55
+ title: 'Write API documentation',
56
+ description: 'Document all REST API endpoints',
57
+ labels: [
58
+ { id: 'l2', name: 'Docs', color: '#3B82F6' },
59
+ ],
60
+ priority: 'medium',
61
+ },
62
+ ],
63
+ },
64
+ {
65
+ id: 'in-progress',
66
+ title: 'In Progress',
67
+ color: '#3B82F6',
68
+ limit: 3,
69
+ cards: [
70
+ {
71
+ id: 'card-3',
72
+ title: 'Implement user authentication',
73
+ description: 'Add OAuth2 support for Google and GitHub login',
74
+ labels: [
75
+ { id: 'l3', name: 'Backend', color: '#10B981' },
76
+ { id: 'l4', name: 'Security', color: '#EF4444' },
77
+ ],
78
+ priority: 'urgent',
79
+ assignee: { id: 'u2', name: 'Jane Smith' },
80
+ dueDate: new Date('2024-01-25'),
81
+ },
82
+ ],
83
+ },
84
+ {
85
+ id: 'review',
86
+ title: 'In Review',
87
+ color: '#F59E0B',
88
+ cards: [
89
+ {
90
+ id: 'card-4',
91
+ title: 'Fix responsive issues',
92
+ description: 'Address mobile layout bugs reported by QA',
93
+ labels: [
94
+ { id: 'l5', name: 'Bug', color: '#EF4444' },
95
+ ],
96
+ priority: 'high',
97
+ assignee: { id: 'u1', name: 'John Doe' },
98
+ },
99
+ ],
100
+ },
101
+ {
102
+ id: 'done',
103
+ title: 'Done',
104
+ color: '#10B981',
105
+ cards: [
106
+ {
107
+ id: 'card-5',
108
+ title: 'Setup CI/CD pipeline',
109
+ description: 'Configure GitHub Actions for automated testing and deployment',
110
+ labels: [
111
+ { id: 'l6', name: 'DevOps', color: '#8B5CF6' },
112
+ ],
113
+ priority: 'medium',
114
+ assignee: { id: 'u3', name: 'Mike Johnson' },
115
+ },
116
+ ],
117
+ },
118
+ ]
119
+
120
+ export const Default: Story = {
121
+ args: {},
122
+ render: (args) => {
123
+ const { columns, moveCard, addCard, deleteCard } = useKanban(sampleColumns)
124
+
125
+ return (
126
+ <div className="h-[600px] bg-muted/30">
127
+ <WakaKanban
128
+ {...args}
129
+ columns={columns}
130
+ onCardMove={moveCard}
131
+ onCardAdd={addCard}
132
+ onCardDelete={deleteCard}
133
+ onCardClick={(card) => console.log('Card clicked:', card)}
134
+ />
135
+ </div>
136
+ )
137
+ },
138
+ }
139
+
140
+ export const WithColumnManagement: Story = {
141
+ render: () => {
142
+ const { columns, moveCard, addCard, deleteCard, addColumn, deleteColumn, moveColumn } = useKanban(sampleColumns)
143
+
144
+ return (
145
+ <div className="h-[600px] bg-muted/30">
146
+ <WakaKanban
147
+ columns={columns}
148
+ onCardMove={moveCard}
149
+ onCardAdd={addCard}
150
+ onCardDelete={deleteCard}
151
+ onColumnAdd={addColumn}
152
+ onColumnDelete={deleteColumn}
153
+ onColumnMove={moveColumn}
154
+ allowAddColumn
155
+ allowColumnDrag
156
+ />
157
+ </div>
158
+ )
159
+ },
160
+ }
161
+
162
+ export const ReadOnly: Story = {
163
+ args: {
164
+ columns: sampleColumns,
165
+ allowAddCard: false,
166
+ height: 600,
167
+ },
168
+ }
169
+
170
+ export const CustomCardRenderer: Story = {
171
+ render: () => {
172
+ const { columns, moveCard } = useKanban(sampleColumns)
173
+
174
+ const renderCard = (card: KanbanCard) => (
175
+ <div className="bg-gradient-to-br from-primary/5 to-primary/10 border border-primary/20 rounded-lg p-3">
176
+ <h4 className="font-semibold text-sm">{card.title}</h4>
177
+ {card.description && (
178
+ <p className="text-xs text-muted-foreground mt-1 line-clamp-2">
179
+ {card.description}
180
+ </p>
181
+ )}
182
+ {card.priority && (
183
+ <div className="mt-2">
184
+ <span className={`
185
+ text-[10px] font-medium px-2 py-0.5 rounded-full
186
+ ${card.priority === 'urgent' ? 'bg-red-100 text-red-700' : ''}
187
+ ${card.priority === 'high' ? 'bg-orange-100 text-orange-700' : ''}
188
+ ${card.priority === 'medium' ? 'bg-blue-100 text-blue-700' : ''}
189
+ ${card.priority === 'low' ? 'bg-gray-100 text-gray-700' : ''}
190
+ `}>
191
+ {card.priority}
192
+ </span>
193
+ </div>
194
+ )}
195
+ </div>
196
+ )
197
+
198
+ return (
199
+ <div className="h-[600px] bg-muted/30">
200
+ <WakaKanban
201
+ columns={columns}
202
+ onCardMove={moveCard}
203
+ renderCard={renderCard}
204
+ allowAddCard={false}
205
+ />
206
+ </div>
207
+ )
208
+ },
209
+ }
210
+
211
+ export const WithWIPLimits: Story = {
212
+ render: () => {
213
+ const columnsWithLimits: KanbanColumn[] = [
214
+ {
215
+ id: 'backlog',
216
+ title: 'Backlog',
217
+ cards: sampleColumns[0].cards,
218
+ },
219
+ {
220
+ id: 'in-progress',
221
+ title: 'In Progress',
222
+ color: '#3B82F6',
223
+ limit: 2,
224
+ cards: sampleColumns[1].cards,
225
+ },
226
+ {
227
+ id: 'review',
228
+ title: 'Review',
229
+ color: '#F59E0B',
230
+ limit: 1,
231
+ cards: sampleColumns[2].cards,
232
+ },
233
+ {
234
+ id: 'done',
235
+ title: 'Done',
236
+ color: '#10B981',
237
+ cards: sampleColumns[3].cards,
238
+ },
239
+ ]
240
+
241
+ const { columns, moveCard, addCard } = useKanban(columnsWithLimits)
242
+
243
+ return (
244
+ <div className="h-[600px] bg-muted/30">
245
+ <WakaKanban
246
+ columns={columns}
247
+ onCardMove={moveCard}
248
+ onCardAdd={addCard}
249
+ />
250
+ </div>
251
+ )
252
+ },
253
+ }
254
+
255
+ export const SimpleBoard: Story = {
256
+ render: () => {
257
+ const simpleColumns: KanbanColumn[] = [
258
+ {
259
+ id: 'ideas',
260
+ title: 'Ideas',
261
+ cards: [
262
+ { id: '1', title: 'Mobile app redesign' },
263
+ { id: '2', title: 'Add dark mode' },
264
+ { id: '3', title: 'Performance optimization' },
265
+ ],
266
+ },
267
+ {
268
+ id: 'doing',
269
+ title: 'Doing',
270
+ cards: [
271
+ { id: '4', title: 'API refactoring' },
272
+ ],
273
+ },
274
+ {
275
+ id: 'done',
276
+ title: 'Done',
277
+ cards: [
278
+ { id: '5', title: 'Database migration' },
279
+ { id: '6', title: 'User feedback survey' },
280
+ ],
281
+ },
282
+ ]
283
+
284
+ const { columns, moveCard, addCard } = useKanban(simpleColumns)
285
+
286
+ return (
287
+ <div className="h-[500px] bg-muted/30">
288
+ <WakaKanban
289
+ columns={columns}
290
+ onCardMove={moveCard}
291
+ onCardAdd={addCard}
292
+ />
293
+ </div>
294
+ )
295
+ },
296
+ }
297
+
298
+ export const ProjectManagement: Story = {
299
+ render: () => {
300
+ const projectColumns: KanbanColumn[] = [
301
+ {
302
+ id: 'planning',
303
+ title: 'Planning',
304
+ color: '#6B7280',
305
+ cards: [
306
+ {
307
+ id: 'p1',
308
+ title: 'Q1 Roadmap Review',
309
+ description: 'Review and finalize Q1 product roadmap',
310
+ labels: [{ id: 'pm', name: 'PM', color: '#8B5CF6' }],
311
+ priority: 'high',
312
+ dueDate: new Date('2024-01-20'),
313
+ },
314
+ ],
315
+ },
316
+ {
317
+ id: 'design',
318
+ title: 'Design',
319
+ color: '#EC4899',
320
+ cards: [
321
+ {
322
+ id: 'd1',
323
+ title: 'Dashboard Wireframes',
324
+ description: 'Create wireframes for analytics dashboard',
325
+ labels: [{ id: 'design', name: 'Design', color: '#EC4899' }],
326
+ assignee: { id: 'designer', name: 'Sarah' },
327
+ },
328
+ ],
329
+ },
330
+ {
331
+ id: 'development',
332
+ title: 'Development',
333
+ color: '#3B82F6',
334
+ limit: 4,
335
+ cards: [
336
+ {
337
+ id: 'dev1',
338
+ title: 'User Settings API',
339
+ description: 'Implement user settings CRUD endpoints',
340
+ labels: [
341
+ { id: 'backend', name: 'Backend', color: '#10B981' },
342
+ ],
343
+ priority: 'urgent',
344
+ assignee: { id: 'dev1', name: 'Mike' },
345
+ },
346
+ {
347
+ id: 'dev2',
348
+ title: 'Payment Integration',
349
+ description: 'Integrate Stripe payment gateway',
350
+ labels: [
351
+ { id: 'backend', name: 'Backend', color: '#10B981' },
352
+ { id: 'security', name: 'Security', color: '#EF4444' },
353
+ ],
354
+ priority: 'high',
355
+ assignee: { id: 'dev2', name: 'Jane' },
356
+ },
357
+ ],
358
+ },
359
+ {
360
+ id: 'testing',
361
+ title: 'Testing',
362
+ color: '#F59E0B',
363
+ cards: [
364
+ {
365
+ id: 't1',
366
+ title: 'E2E Test Suite',
367
+ description: 'Write end-to-end tests for checkout flow',
368
+ labels: [{ id: 'qa', name: 'QA', color: '#F59E0B' }],
369
+ assignee: { id: 'qa1', name: 'Tom' },
370
+ },
371
+ ],
372
+ },
373
+ {
374
+ id: 'deployed',
375
+ title: 'Deployed',
376
+ color: '#10B981',
377
+ cards: [],
378
+ },
379
+ ]
380
+
381
+ const { columns, moveCard, addCard, deleteCard } = useKanban(projectColumns)
382
+
383
+ return (
384
+ <div className="h-[700px] bg-muted/30">
385
+ <div className="p-4 border-b bg-background">
386
+ <h2 className="text-xl font-semibold">Project Alpha - Sprint 3</h2>
387
+ <p className="text-sm text-muted-foreground">Jan 15 - Jan 28, 2024</p>
388
+ </div>
389
+ <WakaKanban
390
+ columns={columns}
391
+ onCardMove={moveCard}
392
+ onCardAdd={addCard}
393
+ onCardDelete={deleteCard}
394
+ height="calc(100% - 80px)"
395
+ />
396
+ </div>
397
+ )
398
+ },
399
+ }
@@ -0,0 +1,281 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import {
3
+ WakaKubernetesOverview,
4
+ defaultK8sNodes,
5
+ defaultK8sPods,
6
+ defaultK8sDeployments,
7
+ defaultK8sServices,
8
+ defaultK8sNamespaces,
9
+ } from './index'
10
+ import type { K8sNode, K8sPod, K8sDeployment, K8sService, K8sNamespace } from './index'
11
+ import * as React from 'react'
12
+
13
+ const unhealthyNodes: K8sNode[] = [
14
+ {
15
+ name: 'node-1',
16
+ status: 'Ready',
17
+ roles: ['control-plane'],
18
+ version: '1.28.2',
19
+ cpu: { used: 7.5, total: 8 },
20
+ memory: { used: 14 * 1024 * 1024 * 1024, total: 16 * 1024 * 1024 * 1024 },
21
+ pods: { running: 95, total: 110 },
22
+ },
23
+ {
24
+ name: 'node-2',
25
+ status: 'NotReady',
26
+ roles: ['worker'],
27
+ version: '1.28.2',
28
+ cpu: { used: 0, total: 8 },
29
+ memory: { used: 0, total: 32 * 1024 * 1024 * 1024 },
30
+ pods: { running: 0, total: 110 },
31
+ },
32
+ {
33
+ name: 'node-3',
34
+ status: 'Unknown',
35
+ roles: ['worker'],
36
+ version: '1.28.2',
37
+ cpu: { used: 4, total: 8 },
38
+ memory: { used: 16 * 1024 * 1024 * 1024, total: 32 * 1024 * 1024 * 1024 },
39
+ pods: { running: 20, total: 110 },
40
+ },
41
+ ]
42
+
43
+ const manyPods: K8sPod[] = [
44
+ { name: 'api-server-7d8f9b6c4d-x2k9l', namespace: 'default', phase: 'Running', ready: '2/2', restarts: 0, age: '5d' },
45
+ { name: 'api-server-7d8f9b6c4d-y3l0m', namespace: 'default', phase: 'Running', ready: '2/2', restarts: 0, age: '5d' },
46
+ { name: 'api-server-7d8f9b6c4d-z4m1n', namespace: 'default', phase: 'Running', ready: '2/2', restarts: 1, age: '5d' },
47
+ { name: 'web-frontend-5c8d7e9f1b-a1b2c', namespace: 'default', phase: 'Running', ready: '1/1', restarts: 0, age: '3d' },
48
+ { name: 'web-frontend-5c8d7e9f1b-d3e4f', namespace: 'default', phase: 'Running', ready: '1/1', restarts: 2, age: '3d' },
49
+ { name: 'postgres-0', namespace: 'database', phase: 'Running', ready: '1/1', restarts: 0, age: '14d' },
50
+ { name: 'postgres-1', namespace: 'database', phase: 'Running', ready: '1/1', restarts: 0, age: '14d' },
51
+ { name: 'redis-master-0', namespace: 'cache', phase: 'Running', ready: '1/1', restarts: 0, age: '7d' },
52
+ { name: 'redis-replica-0', namespace: 'cache', phase: 'Running', ready: '1/1', restarts: 0, age: '7d' },
53
+ { name: 'redis-replica-1', namespace: 'cache', phase: 'Running', ready: '1/1', restarts: 0, age: '7d' },
54
+ { name: 'worker-6f7g8h9i0j-p5q6r', namespace: 'default', phase: 'Pending', ready: '0/1', restarts: 0, age: '2m' },
55
+ { name: 'worker-6f7g8h9i0j-s7t8u', namespace: 'default', phase: 'Failed', ready: '0/1', restarts: 5, age: '10m' },
56
+ { name: 'migration-job-abc123', namespace: 'database', phase: 'Succeeded', ready: '0/1', restarts: 0, age: '1h' },
57
+ { name: 'cronjob-cleanup-12345', namespace: 'kube-system', phase: 'Running', ready: '1/1', restarts: 0, age: '5m' },
58
+ ]
59
+
60
+ const largeClusterNodes: K8sNode[] = [
61
+ ...defaultK8sNodes,
62
+ {
63
+ name: 'node-4',
64
+ status: 'Ready',
65
+ roles: ['worker'],
66
+ version: '1.28.2',
67
+ cpu: { used: 6.2, total: 16 },
68
+ memory: { used: 48 * 1024 * 1024 * 1024, total: 64 * 1024 * 1024 * 1024 },
69
+ pods: { running: 85, total: 250 },
70
+ },
71
+ {
72
+ name: 'node-5',
73
+ status: 'Ready',
74
+ roles: ['worker'],
75
+ version: '1.28.2',
76
+ cpu: { used: 4.8, total: 16 },
77
+ memory: { used: 32 * 1024 * 1024 * 1024, total: 64 * 1024 * 1024 * 1024 },
78
+ pods: { running: 62, total: 250 },
79
+ },
80
+ {
81
+ name: 'node-6',
82
+ status: 'Ready',
83
+ roles: ['worker', 'gpu'],
84
+ version: '1.28.2',
85
+ cpu: { used: 12.5, total: 32 },
86
+ memory: { used: 96 * 1024 * 1024 * 1024, total: 128 * 1024 * 1024 * 1024 },
87
+ pods: { running: 12, total: 50 },
88
+ },
89
+ ]
90
+
91
+ const meta: Meta<typeof WakaKubernetesOverview> = {
92
+ title: 'Components/DevOps/WakaKubernetesOverview',
93
+ component: WakaKubernetesOverview,
94
+ parameters: {
95
+ layout: 'centered',
96
+ docs: {
97
+ description: {
98
+ component: 'A Kubernetes cluster overview with nodes, pods, deployments, and services tabs, namespace filtering, and resource metrics.',
99
+ },
100
+ },
101
+ },
102
+ tags: ['autodocs'],
103
+ argTypes: {
104
+ isLoading: {
105
+ control: 'boolean',
106
+ description: 'Loading state',
107
+ },
108
+ },
109
+ }
110
+
111
+ export default meta
112
+ type Story = StoryObj<typeof WakaKubernetesOverview>
113
+
114
+ export const Default: Story = {
115
+ args: {
116
+ clusterName: 'production-cluster',
117
+ nodes: defaultK8sNodes,
118
+ pods: defaultK8sPods,
119
+ deployments: defaultK8sDeployments,
120
+ services: defaultK8sServices,
121
+ namespaces: defaultK8sNamespaces,
122
+ },
123
+ render: (args) => (
124
+ <div className="w-[900px] h-[600px]">
125
+ <WakaKubernetesOverview
126
+ {...args}
127
+ onResourceClick={(type, name, ns) => console.log('Click:', type, name, ns)}
128
+ onRefresh={() => console.log('Refresh')}
129
+ />
130
+ </div>
131
+ ),
132
+ }
133
+
134
+ export const UnhealthyCluster: Story = {
135
+ render: () => (
136
+ <div className="w-[900px] h-[600px]">
137
+ <p className="text-sm text-muted-foreground mb-4">
138
+ Cluster with unhealthy nodes
139
+ </p>
140
+ <WakaKubernetesOverview
141
+ clusterName="staging-cluster"
142
+ nodes={unhealthyNodes}
143
+ pods={manyPods}
144
+ deployments={defaultK8sDeployments}
145
+ services={defaultK8sServices}
146
+ namespaces={defaultK8sNamespaces}
147
+ onResourceClick={(type, name, ns) => console.log('Click:', type, name, ns)}
148
+ />
149
+ </div>
150
+ ),
151
+ }
152
+
153
+ export const LargeCluster: Story = {
154
+ render: () => (
155
+ <div className="w-[900px] h-[600px]">
156
+ <WakaKubernetesOverview
157
+ clusterName="large-production"
158
+ nodes={largeClusterNodes}
159
+ pods={manyPods}
160
+ deployments={[
161
+ ...defaultK8sDeployments,
162
+ { name: 'ml-worker', namespace: 'ml', replicas: { ready: 4, desired: 4 }, status: 'Available', age: '10d' },
163
+ { name: 'inference-api', namespace: 'ml', replicas: { ready: 2, desired: 2 }, status: 'Available', age: '5d' },
164
+ ]}
165
+ services={[
166
+ ...defaultK8sServices,
167
+ { name: 'ml-inference', namespace: 'ml', type: 'LoadBalancer', clusterIP: '10.96.0.50', externalIP: '35.200.100.50', ports: [{ port: 8080, targetPort: 8080, protocol: 'TCP' }], age: '5d' },
168
+ ]}
169
+ namespaces={[
170
+ ...defaultK8sNamespaces,
171
+ { name: 'ml', status: 'Active', age: '30d' },
172
+ { name: 'monitoring', status: 'Active', age: '60d' },
173
+ ]}
174
+ onResourceClick={(type, name, ns) => console.log('Click:', type, name, ns)}
175
+ onRefresh={() => console.log('Refresh')}
176
+ />
177
+ </div>
178
+ ),
179
+ }
180
+
181
+ export const WithNamespaceFilter: Story = {
182
+ render: () => {
183
+ const [namespace, setNamespace] = React.useState<string>('default')
184
+
185
+ return (
186
+ <div className="w-[900px] h-[600px]">
187
+ <p className="text-sm text-muted-foreground mb-4">
188
+ Filtered by namespace: {namespace}
189
+ </p>
190
+ <WakaKubernetesOverview
191
+ clusterName="production-cluster"
192
+ nodes={defaultK8sNodes}
193
+ pods={manyPods}
194
+ deployments={defaultK8sDeployments}
195
+ services={defaultK8sServices}
196
+ namespaces={defaultK8sNamespaces}
197
+ selectedNamespace={namespace}
198
+ onNamespaceChange={setNamespace}
199
+ onResourceClick={(type, name, ns) => console.log('Click:', type, name, ns)}
200
+ />
201
+ </div>
202
+ )
203
+ },
204
+ }
205
+
206
+ export const Loading: Story = {
207
+ render: () => (
208
+ <div className="w-[900px] h-[600px]">
209
+ <WakaKubernetesOverview
210
+ clusterName="production-cluster"
211
+ nodes={defaultK8sNodes}
212
+ pods={defaultK8sPods}
213
+ deployments={defaultK8sDeployments}
214
+ services={defaultK8sServices}
215
+ namespaces={defaultK8sNamespaces}
216
+ isLoading
217
+ onRefresh={() => console.log('Refresh')}
218
+ />
219
+ </div>
220
+ ),
221
+ }
222
+
223
+ export const SingleNode: Story = {
224
+ render: () => (
225
+ <div className="w-[900px] h-[500px]">
226
+ <WakaKubernetesOverview
227
+ clusterName="minikube"
228
+ nodes={[defaultK8sNodes[0]]}
229
+ pods={defaultK8sPods.slice(0, 3)}
230
+ deployments={defaultK8sDeployments.slice(0, 2)}
231
+ services={defaultK8sServices.slice(0, 2)}
232
+ namespaces={[defaultK8sNamespaces[0]]}
233
+ />
234
+ </div>
235
+ ),
236
+ }
237
+
238
+ export const EmptyCluster: Story = {
239
+ render: () => (
240
+ <div className="w-[900px] h-[500px]">
241
+ <WakaKubernetesOverview
242
+ clusterName="new-cluster"
243
+ nodes={defaultK8sNodes}
244
+ pods={[]}
245
+ deployments={[]}
246
+ services={[]}
247
+ namespaces={[{ name: 'default', status: 'Active', age: '1m' }]}
248
+ />
249
+ </div>
250
+ ),
251
+ }
252
+
253
+ export const K8sDashboard: Story = {
254
+ render: () => (
255
+ <div className="p-6 rounded-xl border bg-card">
256
+ <div className="flex items-center justify-between mb-6">
257
+ <div>
258
+ <h2 className="text-xl font-bold">Kubernetes Dashboard</h2>
259
+ <p className="text-sm text-muted-foreground">Cluster: production-east-1</p>
260
+ </div>
261
+ <div className="flex items-center gap-2">
262
+ <div className="w-2 h-2 rounded-full bg-green-500" />
263
+ <span className="text-sm text-green-500 font-medium">All systems healthy</span>
264
+ </div>
265
+ </div>
266
+
267
+ <div className="w-[850px]">
268
+ <WakaKubernetesOverview
269
+ clusterName="production-east-1"
270
+ nodes={defaultK8sNodes}
271
+ pods={manyPods}
272
+ deployments={defaultK8sDeployments}
273
+ services={defaultK8sServices}
274
+ namespaces={defaultK8sNamespaces}
275
+ onResourceClick={(type, name, ns) => console.log('Click:', type, name, ns)}
276
+ onRefresh={() => console.log('Refresh')}
277
+ />
278
+ </div>
279
+ </div>
280
+ ),
281
+ }