@allbluecn/web-app 0.5.0 → 0.6.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/package.json +239 -30
- package/src/components/iteration/auto-schedule-dialog.tsx +150 -0
- package/src/components/iteration/burndown-chart.tsx +63 -0
- package/src/components/iteration/constants.ts +28 -0
- package/src/components/iteration/create-iteration-dialog.tsx +140 -0
- package/src/components/iteration/iteration-card.tsx +60 -0
- package/src/components/iteration/iteration-editor.tsx +116 -0
- package/src/components/iteration/iteration-progress-bar.tsx +44 -0
- package/src/components/iteration/iteration-status-badge.tsx +33 -0
- package/src/components/knowledge/dialog/knowledge-form-dialog.tsx +21 -30
- package/src/components/knowledge/knowledge-toolbar.tsx +124 -1
- package/src/components/layout/sidebar-03/__tests__/nav-workspace.test.tsx +2 -2
- package/src/components/layout/sidebar-03/nav-workspace.tsx +2 -2
- package/src/components/project/create-project-dialog.tsx +44 -57
- package/src/components/shared/__tests__/lucide-curated-icons.test.ts +83 -0
- package/src/components/shared/__tests__/lucide-icon-data.test.ts +131 -0
- package/src/components/shared/__tests__/lucide-icon-picker.test.tsx +197 -0
- package/src/components/shared/lucide-icon-picker/curated-icons.ts +478 -0
- package/src/components/shared/lucide-icon-picker/icon-data.ts +109 -0
- package/src/components/shared/lucide-icon-picker/index.tsx +82 -0
- package/src/components/shared/lucide-icon-picker/lucide-icon-by-name.tsx +78 -0
- package/src/components/shared/lucide-icon-picker/panel.tsx +163 -0
- package/src/components/story/__tests__/constants.test.ts +255 -0
- package/src/components/story/ai/story-ai-panel.tsx +23 -15
- package/src/components/story/ai/story-ai-preview-list.tsx +19 -0
- package/src/components/story/constants.ts +43 -1
- package/src/components/story/create-story-dialog.tsx +42 -16
- package/src/components/story/detail/__tests__/associated-attachments-panel.test.tsx +114 -0
- package/src/components/story/detail/__tests__/categories.test.tsx +62 -0
- package/src/components/story/detail/__tests__/dependencies-button.test.tsx +49 -0
- package/src/components/story/detail/activity-timeline.tsx +26 -4
- package/src/components/story/detail/story-detail-body.tsx +90 -38
- package/src/components/story/detail/story-detail-toolbar/associated-attachments-panel.tsx +857 -0
- package/src/components/story/detail/story-detail-toolbar/categories.tsx +23 -18
- package/src/components/story/detail/story-detail-toolbar/children.tsx +9 -4
- package/src/components/story/detail/story-detail-toolbar/dependency-panel.tsx +95 -27
- package/src/components/story/detail/story-detail-toolbar.tsx +159 -8
- package/src/components/story/detail/story-properties.tsx +21 -4
- package/src/components/story/display/__tests__/group-fields.test.ts +107 -0
- package/src/components/story/display/group-resolver.tsx +2 -2
- package/src/components/story/inline-editors/__tests__/dependency-type-select.test.tsx +155 -0
- package/src/components/story/inline-editors/__tests__/labels-editor.test.tsx +155 -0
- package/src/components/story/inline-editors/__tests__/priority-editor.test.tsx +173 -0
- package/src/components/story/inline-editors/__tests__/state-editor.test.tsx +174 -0
- package/src/components/story/inline-editors/dependency-type-select.tsx +180 -0
- package/src/components/story/inline-editors/index.ts +2 -1
- package/src/components/story/inline-editors/labels-editor.tsx +159 -3
- package/src/components/story/inline-editors/story-select-dialog.tsx +41 -63
- package/src/components/story/peek-panel.tsx +121 -21
- package/src/components/story/relations/__tests__/attachment-manage-dialog.test.tsx +171 -0
- package/src/components/story/relations/__tests__/knowledge-select-dialog.test.tsx +174 -0
- package/src/components/story/relations/__tests__/link-manage-dialog.test.tsx +93 -0
- package/src/components/story/relations/attachment-manage-dialog.tsx +490 -0
- package/src/components/story/relations/file-preview.tsx +173 -0
- package/src/components/story/relations/format.ts +120 -0
- package/src/components/story/relations/general-groups.ts +32 -0
- package/src/components/story/relations/knowledge-select-dialog.tsx +403 -0
- package/src/components/story/relations/link-manage-dialog.tsx +192 -0
- package/src/components/story/relations/story-ref-row.tsx +17 -27
- package/src/components/story/story-panel-header.tsx +25 -19
- package/src/components/story/story-toolbar.tsx +3 -3
- package/src/components/story/transfer-story-popover.tsx +2 -2
- package/src/components/story/types.ts +14 -0
- package/src/components/story/views/create-view-dialog.tsx +3 -3
- package/src/components/story/views/story-list/__tests__/group-header.test.tsx +219 -0
- package/src/components/story/views/story-list/group.tsx +1 -1
- package/src/components/story/views/story-list/inline-story-creator.tsx +2 -2
- package/src/components/story/views/story-list/row.tsx +1 -1
- package/src/components/workspace/create-workspace-dialog.tsx +41 -49
- package/src/lib/__tests__/project-display-id.test.ts +8 -5
- package/src/lib/changelog/sdk-versions.ts +20 -20
- package/src/lib/iteration/__tests__/status.test.ts +41 -0
- package/src/lib/iteration/status.ts +28 -0
- package/src/lib/project-display-id.ts +14 -5
- package/src/lib/project-module-meta.ts +77 -0
- package/src/lib/story/__tests__/video-embed.test.ts +77 -0
- package/src/lib/story/video-embed.ts +59 -0
- package/src/lib/utils.d.ts +1 -1
- package/src/plugins/.gen-manifest.json +13 -0
- package/src/plugins/modules.gen.ts +20 -0
- package/src/plugins/plugins.gen.ts +20 -0
- package/src/plugins/ui.gen.ts +8 -0
- package/src/providers/index.tsx +6 -0
- package/src/routeTree.gen.ts +96 -0
- package/src/routes/__root.tsx +0 -8
- package/src/routes/_nav/inspiration/route.tsx +8 -0
- package/src/routes/_nav/knowledge/index.lazy.tsx +2 -2
- package/src/routes/_nav/prd/$id/route.tsx +9 -0
- package/src/routes/_nav/prd/index.tsx +9 -0
- package/src/routes/_nav/prd/route.tsx +8 -0
- package/src/routes/_nav/projects/$projectId/$storyId/route.lazy.tsx +52 -25
- package/src/routes/_nav/projects/$projectId/$storyId/route.tsx +6 -3
- package/src/routes/_nav/projects/$projectId/index.lazy.tsx +32 -15
- package/src/routes/_nav/projects/$projectId/iterations/$iterationId/route.lazy.tsx +289 -0
- package/src/routes/_nav/projects/$projectId/iterations/$iterationId/route.tsx +27 -0
- package/src/routes/_nav/projects/$projectId/iterations/index.lazy.tsx +111 -0
- package/src/routes/_nav/projects/$projectId/iterations/index.tsx +24 -0
- package/src/routes/_nav/projects/$projectId/route.tsx +4 -2
- package/src/routes/_nav/projects/$projectId/settings/route.lazy.tsx +78 -7
- package/src/routes/_nav/projects/$projectId/settings/route.tsx +6 -2
- package/src/routes/_nav/stories/$storyId/route.lazy.tsx +5 -1
- package/src/routes/_nav/stories/$storyId/route.tsx +4 -0
- package/src/routes/_nav/tags/$id/route.tsx +8 -0
- package/src/routes/_nav/tags/index.tsx +8 -0
- package/src/routes/_nav/tags/route.tsx +8 -0
- package/src/routes/_nav/tags/settings/route.tsx +9 -0
- package/src/routes/_nav/workspaces/$workspaceId/route.lazy.tsx +3 -3
- package/src/routes/_nav/workspaces/$workspaceId/settings/route.lazy.tsx +4 -4
- package/src/routes/_nav/workspaces/index.lazy.tsx +3 -3
- package/src/routes/api/attachments/$id/content.ts +60 -0
- package/src/routes/api/attachments/upload.ts +148 -0
- package/src/routes/share/prd/$prdId/route.tsx +10 -0
- package/src/server/serverFns/__tests__/project-kb.test.ts +147 -0
- package/src/server/serverFns/iteration/__tests__/auto-schedule-core.test.ts +62 -0
- package/src/server/serverFns/iteration/__tests__/burndown-core.test.ts +90 -0
- package/src/server/serverFns/iteration/__tests__/iteration-crud.test.ts +211 -0
- package/src/server/serverFns/iteration/__tests__/iteration-stories.test.ts +155 -0
- package/src/server/serverFns/iteration/__tests__/iteration-transfer.test.ts +136 -0
- package/src/server/serverFns/iteration/auto-schedule-core.ts +54 -0
- package/src/server/serverFns/iteration/auto-schedule-internal.ts +88 -0
- package/src/server/serverFns/iteration/burndown-core.ts +60 -0
- package/src/server/serverFns/iteration/index.ts +22 -0
- package/src/server/serverFns/iteration/iteration-auto-schedule.ts +66 -0
- package/src/server/serverFns/iteration/iteration-burndown.ts +70 -0
- package/src/server/serverFns/iteration/iteration-crud.ts +208 -0
- package/src/server/serverFns/iteration/iteration-stories.ts +111 -0
- package/src/server/serverFns/iteration/iteration-transfer.ts +42 -0
- package/src/server/serverFns/iteration/schemas.ts +58 -0
- package/src/server/serverFns/iteration/transfer-internal.ts +62 -0
- package/src/server/serverFns/knowledge.ts +50 -4
- package/src/server/serverFns/project/module-overview.ts +109 -0
- package/src/server/serverFns/project.ts +45 -2
- package/src/server/serverFns/story/__tests__/kb-scope.test.ts +56 -0
- package/src/server/serverFns/story/__tests__/label-suggest-fn.test.ts +100 -0
- package/src/server/serverFns/story/__tests__/labels.test.ts +67 -0
- package/src/server/serverFns/story/__tests__/story-assoc.test.ts +222 -0
- package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +132 -2
- package/src/server/serverFns/story/index.ts +9 -4
- package/src/server/serverFns/story/kb-general.ts +39 -0
- package/src/server/serverFns/story/kb-scope.ts +52 -0
- package/src/server/serverFns/story/link-preview.ts +115 -0
- package/src/server/serverFns/story/story-assoc.ts +372 -51
- package/src/server/serverFns/story/story-attachments.ts +32 -45
- package/src/{components/project/project-icon.tsx → server/serverFns/story/story-crud/label-palette.ts} +16 -19
- package/src/server/serverFns/story/story-crud/label-suggest-core.ts +88 -0
- package/src/server/serverFns/story/story-crud/label-suggest.ts +38 -0
- package/src/{components/knowledge/knowledge-icon.tsx → server/serverFns/story/story-crud/label-upsert.ts} +13 -19
- package/src/server/serverFns/story/story-crud/labels.ts +3 -5
- package/src/server/serverFns/story/story-crud.ts +53 -6
- package/src/server/serverFns/story/story-dependencies.ts +158 -5
- package/src/server/serverFns/story/story-links.ts +43 -7
- package/src/server/serverFns/story/story-transfer.ts +5 -4
- package/src/server/serverFns/story/story-tree.ts +28 -1
- package/src/server/serverFns/story/types.ts +38 -0
- package/src/styles/globals.css +25 -0
- package/src/types/project.ts +5 -5
- package/vite.shared.ts +2 -0
- package/src/components/project/project-animated-icon.tsx +0 -73
- package/src/components/shared/icon-packs/index.ts +0 -1
- package/src/components/shared/icon-packs/knowledge.ts +0 -1
- package/src/components/shared/icon-packs/prd.ts +0 -1
- package/src/components/shared/icon-packs/project.ts +0 -1
- package/src/components/shared/icon-picker.tsx +0 -1
- package/src/components/story/detail/story-detail-toolbar/attachments.tsx +0 -73
- package/src/components/story/detail/story-detail-toolbar/knowledge.tsx +0 -73
- package/src/components/story/detail/story-detail-toolbar/links.tsx +0 -73
- package/src/components/story/relations/attachments-panel.tsx +0 -179
- package/src/components/story/relations/knowledge-panel.tsx +0 -284
- package/src/components/story/relations/links-panel.tsx +0 -240
- package/src/lib/project-mock.ts +0 -156
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allbluecn/web-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,12 +12,238 @@
|
|
|
12
12
|
"./vite.shared": {
|
|
13
13
|
"types": "./vite.shared.ts",
|
|
14
14
|
"default": "./vite.shared.ts"
|
|
15
|
+
},
|
|
16
|
+
"./lucide-icon-picker": {
|
|
17
|
+
"types": "./src/components/shared/lucide-icon-picker/index.tsx",
|
|
18
|
+
"default": "./src/components/shared/lucide-icon-picker/index.tsx"
|
|
19
|
+
},
|
|
20
|
+
"./lucide-icon-picker/panel": {
|
|
21
|
+
"types": "./src/components/shared/lucide-icon-picker/panel.tsx",
|
|
22
|
+
"default": "./src/components/shared/lucide-icon-picker/panel.tsx"
|
|
23
|
+
},
|
|
24
|
+
"./lucide-icon-picker/icon-data": {
|
|
25
|
+
"types": "./src/components/shared/lucide-icon-picker/icon-data.ts",
|
|
26
|
+
"default": "./src/components/shared/lucide-icon-picker/icon-data.ts"
|
|
27
|
+
},
|
|
28
|
+
"./lucide-icon-picker/curated-icons": {
|
|
29
|
+
"types": "./src/components/shared/lucide-icon-picker/curated-icons.ts",
|
|
30
|
+
"default": "./src/components/shared/lucide-icon-picker/curated-icons.ts"
|
|
31
|
+
},
|
|
32
|
+
"./lucide-icon-picker/lucide-icon-by-name": {
|
|
33
|
+
"types": "./src/components/shared/lucide-icon-picker/lucide-icon-by-name.tsx",
|
|
34
|
+
"default": "./src/components/shared/lucide-icon-picker/lucide-icon-by-name.tsx"
|
|
35
|
+
},
|
|
36
|
+
"./ui/safari": {
|
|
37
|
+
"types": "./src/components/ui/safari.tsx",
|
|
38
|
+
"default": "./src/components/ui/safari.tsx"
|
|
39
|
+
},
|
|
40
|
+
"./ui/alert-dialog": {
|
|
41
|
+
"types": "./src/components/ui/alert-dialog.tsx",
|
|
42
|
+
"default": "./src/components/ui/alert-dialog.tsx"
|
|
43
|
+
},
|
|
44
|
+
"./ui/tabs": {
|
|
45
|
+
"types": "./src/components/ui/tabs.tsx",
|
|
46
|
+
"default": "./src/components/ui/tabs.tsx"
|
|
47
|
+
},
|
|
48
|
+
"./ui/button-group": {
|
|
49
|
+
"types": "./src/components/ui/button-group.tsx",
|
|
50
|
+
"default": "./src/components/ui/button-group.tsx"
|
|
51
|
+
},
|
|
52
|
+
"./ui/card": {
|
|
53
|
+
"types": "./src/components/ui/card.tsx",
|
|
54
|
+
"default": "./src/components/ui/card.tsx"
|
|
55
|
+
},
|
|
56
|
+
"./ui/input-group": {
|
|
57
|
+
"types": "./src/components/ui/input-group.tsx",
|
|
58
|
+
"default": "./src/components/ui/input-group.tsx"
|
|
59
|
+
},
|
|
60
|
+
"./ui/popover": {
|
|
61
|
+
"types": "./src/components/ui/popover.tsx",
|
|
62
|
+
"default": "./src/components/ui/popover.tsx"
|
|
63
|
+
},
|
|
64
|
+
"./ui/progress": {
|
|
65
|
+
"types": "./src/components/ui/progress.tsx",
|
|
66
|
+
"default": "./src/components/ui/progress.tsx"
|
|
67
|
+
},
|
|
68
|
+
"./ui/hover-card": {
|
|
69
|
+
"types": "./src/components/ui/hover-card.tsx",
|
|
70
|
+
"default": "./src/components/ui/hover-card.tsx"
|
|
71
|
+
},
|
|
72
|
+
"./ui/sheet": {
|
|
73
|
+
"types": "./src/components/ui/sheet.tsx",
|
|
74
|
+
"default": "./src/components/ui/sheet.tsx"
|
|
75
|
+
},
|
|
76
|
+
"./ui/field": {
|
|
77
|
+
"types": "./src/components/ui/field.tsx",
|
|
78
|
+
"default": "./src/components/ui/field.tsx"
|
|
79
|
+
},
|
|
80
|
+
"./ui/scroll-area": {
|
|
81
|
+
"types": "./src/components/ui/scroll-area.tsx",
|
|
82
|
+
"default": "./src/components/ui/scroll-area.tsx"
|
|
83
|
+
},
|
|
84
|
+
"./ui/resizable": {
|
|
85
|
+
"types": "./src/components/ui/resizable.tsx",
|
|
86
|
+
"default": "./src/components/ui/resizable.tsx"
|
|
87
|
+
},
|
|
88
|
+
"./ui/label": {
|
|
89
|
+
"types": "./src/components/ui/label.tsx",
|
|
90
|
+
"default": "./src/components/ui/label.tsx"
|
|
91
|
+
},
|
|
92
|
+
"./ui/sonner": {
|
|
93
|
+
"types": "./src/components/ui/sonner.tsx",
|
|
94
|
+
"default": "./src/components/ui/sonner.tsx"
|
|
95
|
+
},
|
|
96
|
+
"./ui/navigation-menu": {
|
|
97
|
+
"types": "./src/components/ui/navigation-menu.tsx",
|
|
98
|
+
"default": "./src/components/ui/navigation-menu.tsx"
|
|
99
|
+
},
|
|
100
|
+
"./ui/accordion": {
|
|
101
|
+
"types": "./src/components/ui/accordion.tsx",
|
|
102
|
+
"default": "./src/components/ui/accordion.tsx"
|
|
103
|
+
},
|
|
104
|
+
"./ui/empty": {
|
|
105
|
+
"types": "./src/components/ui/empty.tsx",
|
|
106
|
+
"default": "./src/components/ui/empty.tsx"
|
|
107
|
+
},
|
|
108
|
+
"./ui/tooltip": {
|
|
109
|
+
"types": "./src/components/ui/tooltip.tsx",
|
|
110
|
+
"default": "./src/components/ui/tooltip.tsx"
|
|
111
|
+
},
|
|
112
|
+
"./ui/alert": {
|
|
113
|
+
"types": "./src/components/ui/alert.tsx",
|
|
114
|
+
"default": "./src/components/ui/alert.tsx"
|
|
115
|
+
},
|
|
116
|
+
"./ui/switch": {
|
|
117
|
+
"types": "./src/components/ui/switch.tsx",
|
|
118
|
+
"default": "./src/components/ui/switch.tsx"
|
|
119
|
+
},
|
|
120
|
+
"./ui/calendar": {
|
|
121
|
+
"types": "./src/components/ui/calendar.tsx",
|
|
122
|
+
"default": "./src/components/ui/calendar.tsx"
|
|
123
|
+
},
|
|
124
|
+
"./ui/breadcrumb": {
|
|
125
|
+
"types": "./src/components/ui/breadcrumb.tsx",
|
|
126
|
+
"default": "./src/components/ui/breadcrumb.tsx"
|
|
127
|
+
},
|
|
128
|
+
"./ui/radio-group": {
|
|
129
|
+
"types": "./src/components/ui/radio-group.tsx",
|
|
130
|
+
"default": "./src/components/ui/radio-group.tsx"
|
|
131
|
+
},
|
|
132
|
+
"./ui/command": {
|
|
133
|
+
"types": "./src/components/ui/command.tsx",
|
|
134
|
+
"default": "./src/components/ui/command.tsx"
|
|
135
|
+
},
|
|
136
|
+
"./ui/item": {
|
|
137
|
+
"types": "./src/components/ui/item.tsx",
|
|
138
|
+
"default": "./src/components/ui/item.tsx"
|
|
139
|
+
},
|
|
140
|
+
"./ui/avatar": {
|
|
141
|
+
"types": "./src/components/ui/avatar.tsx",
|
|
142
|
+
"default": "./src/components/ui/avatar.tsx"
|
|
143
|
+
},
|
|
144
|
+
"./ui/kbd": {
|
|
145
|
+
"types": "./src/components/ui/kbd.tsx",
|
|
146
|
+
"default": "./src/components/ui/kbd.tsx"
|
|
147
|
+
},
|
|
148
|
+
"./ui/dialog": {
|
|
149
|
+
"types": "./src/components/ui/dialog.tsx",
|
|
150
|
+
"default": "./src/components/ui/dialog.tsx"
|
|
151
|
+
},
|
|
152
|
+
"./ui/badge": {
|
|
153
|
+
"types": "./src/components/ui/badge.tsx",
|
|
154
|
+
"default": "./src/components/ui/badge.tsx"
|
|
155
|
+
},
|
|
156
|
+
"./ui/sidebar": {
|
|
157
|
+
"types": "./src/components/ui/sidebar.tsx",
|
|
158
|
+
"default": "./src/components/ui/sidebar.tsx"
|
|
159
|
+
},
|
|
160
|
+
"./ui/table": {
|
|
161
|
+
"types": "./src/components/ui/table.tsx",
|
|
162
|
+
"default": "./src/components/ui/table.tsx"
|
|
163
|
+
},
|
|
164
|
+
"./ui/separator": {
|
|
165
|
+
"types": "./src/components/ui/separator.tsx",
|
|
166
|
+
"default": "./src/components/ui/separator.tsx"
|
|
167
|
+
},
|
|
168
|
+
"./ui/button": {
|
|
169
|
+
"types": "./src/components/ui/button.tsx",
|
|
170
|
+
"default": "./src/components/ui/button.tsx"
|
|
171
|
+
},
|
|
172
|
+
"./ui/toggle": {
|
|
173
|
+
"types": "./src/components/ui/toggle.tsx",
|
|
174
|
+
"default": "./src/components/ui/toggle.tsx"
|
|
175
|
+
},
|
|
176
|
+
"./ui/checkbox": {
|
|
177
|
+
"types": "./src/components/ui/checkbox.tsx",
|
|
178
|
+
"default": "./src/components/ui/checkbox.tsx"
|
|
179
|
+
},
|
|
180
|
+
"./ui/spinner": {
|
|
181
|
+
"types": "./src/components/ui/spinner.tsx",
|
|
182
|
+
"default": "./src/components/ui/spinner.tsx"
|
|
183
|
+
},
|
|
184
|
+
"./ui/collapsible": {
|
|
185
|
+
"types": "./src/components/ui/collapsible.tsx",
|
|
186
|
+
"default": "./src/components/ui/collapsible.tsx"
|
|
187
|
+
},
|
|
188
|
+
"./ui/dropdown-menu": {
|
|
189
|
+
"types": "./src/components/ui/dropdown-menu.tsx",
|
|
190
|
+
"default": "./src/components/ui/dropdown-menu.tsx"
|
|
191
|
+
},
|
|
192
|
+
"./ui/select": {
|
|
193
|
+
"types": "./src/components/ui/select.tsx",
|
|
194
|
+
"default": "./src/components/ui/select.tsx"
|
|
195
|
+
},
|
|
196
|
+
"./ui/textarea": {
|
|
197
|
+
"types": "./src/components/ui/textarea.tsx",
|
|
198
|
+
"default": "./src/components/ui/textarea.tsx"
|
|
199
|
+
},
|
|
200
|
+
"./ui/input": {
|
|
201
|
+
"types": "./src/components/ui/input.tsx",
|
|
202
|
+
"default": "./src/components/ui/input.tsx"
|
|
203
|
+
},
|
|
204
|
+
"./ui/skeleton": {
|
|
205
|
+
"types": "./src/components/ui/skeleton.tsx",
|
|
206
|
+
"default": "./src/components/ui/skeleton.tsx"
|
|
207
|
+
},
|
|
208
|
+
"./ui/context-menu": {
|
|
209
|
+
"types": "./src/components/ui/context-menu.tsx",
|
|
210
|
+
"default": "./src/components/ui/context-menu.tsx"
|
|
211
|
+
},
|
|
212
|
+
"./user-avatar": {
|
|
213
|
+
"types": "./src/components/ui/avatar.tsx",
|
|
214
|
+
"default": "./src/components/ui/avatar.tsx"
|
|
15
215
|
}
|
|
16
216
|
},
|
|
17
217
|
"publishConfig": {
|
|
18
218
|
"access": "public"
|
|
19
219
|
},
|
|
220
|
+
"packageManager": "pnpm@11.20.0",
|
|
221
|
+
"scripts": {
|
|
222
|
+
"dev": "vite --port 3000",
|
|
223
|
+
"build": "vite build",
|
|
224
|
+
"start": "vite preview",
|
|
225
|
+
"lint": "eslint",
|
|
226
|
+
"test": "vitest",
|
|
227
|
+
"test:ui": "vitest --ui",
|
|
228
|
+
"test:run": "vitest run",
|
|
229
|
+
"setup": "pnpm --filter @allbluecn/database generate && pnpm --filter @allbluecn/database migrate:dev",
|
|
230
|
+
"check:features": "tsx scripts/check-feature-keys.ts",
|
|
231
|
+
"assemble": "pnpm -w exec tsx packages/kernel/src/bin.ts --profile oss --assemble --app-dir apps/web",
|
|
232
|
+
"predev": "pnpm assemble && node scripts/check-sdk-versions.mjs",
|
|
233
|
+
"prebuild": "pnpm assemble && node scripts/check-sdk-versions.mjs",
|
|
234
|
+
"pretest": "pnpm assemble",
|
|
235
|
+
"pretest:run": "pnpm assemble",
|
|
236
|
+
"prepublishOnly": "node scripts/check-sdk-versions.mjs"
|
|
237
|
+
},
|
|
20
238
|
"dependencies": {
|
|
239
|
+
"@allbluecn/ai-gateway": "workspace:*",
|
|
240
|
+
"@allbluecn/database": "workspace:*",
|
|
241
|
+
"@allbluecn/kernel": "workspace:*",
|
|
242
|
+
"@allbluecn/plugins-core": "workspace:*",
|
|
243
|
+
"@allbluecn/prototype": "workspace:*",
|
|
244
|
+
"@allbluecn/shared": "workspace:*",
|
|
245
|
+
"@allbluecn/tiptap": "workspace:*",
|
|
246
|
+
"@allbluecn/ui": "workspace:*",
|
|
21
247
|
"@ariakit/react": "^0.4.28",
|
|
22
248
|
"@auth/core": "^0.41.2",
|
|
23
249
|
"@auth/prisma-adapter": "^2.11.2",
|
|
@@ -28,6 +254,8 @@
|
|
|
28
254
|
"@fontsource-variable/geist-mono": "^5.3.0",
|
|
29
255
|
"@iconify/react": "^6.0.2",
|
|
30
256
|
"@lobehub/icons": "^5.16.0",
|
|
257
|
+
"@open-file-viewer/core": "^0.1.43",
|
|
258
|
+
"@open-file-viewer/react": "^0.1.43",
|
|
31
259
|
"@prisma/client": "^7.8.0",
|
|
32
260
|
"@radix-ui/react-dialog": "^1.1.23",
|
|
33
261
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
@@ -101,13 +329,18 @@
|
|
|
101
329
|
"is-hotkey": "^0.2.0",
|
|
102
330
|
"isomorphic-dompurify": "^3.22.0",
|
|
103
331
|
"lowlight": "^3.3.0",
|
|
104
|
-
"lucide
|
|
332
|
+
"lucide": "^1.38.0",
|
|
333
|
+
"lucide-react": "^1.27.0",
|
|
105
334
|
"mind-elixir": "^5.12.2",
|
|
335
|
+
"morphicons": "^1.7.1",
|
|
106
336
|
"motion": "^12.42.2",
|
|
107
337
|
"nanoid": "^5.1.11",
|
|
108
338
|
"next-themes": "^0.4.6",
|
|
109
339
|
"nitro": "3.0.260603-beta",
|
|
110
340
|
"ogl": "^1.0.11",
|
|
341
|
+
"open-file-viewer-workspace": "github:xushanpei/open-file-viewer",
|
|
342
|
+
"pdfjs-dist": "^6.3.289",
|
|
343
|
+
"pinyin-pro": "^3.29.3",
|
|
111
344
|
"prisma": "^7.8.0",
|
|
112
345
|
"radix-ui": "^1.4.3",
|
|
113
346
|
"react": "19.2.4",
|
|
@@ -126,17 +359,10 @@
|
|
|
126
359
|
"tailwind-merge": "^3.5.0",
|
|
127
360
|
"three": "^0.180.0",
|
|
128
361
|
"tw-animate-css": "^1.4.0",
|
|
129
|
-
"zod": "^4.4.3"
|
|
130
|
-
"@allbluecn/database": "0.4.15",
|
|
131
|
-
"@allbluecn/kernel": "0.3.1",
|
|
132
|
-
"@allbluecn/plugins-core": "0.4.15",
|
|
133
|
-
"@allbluecn/prototype": "0.1.1",
|
|
134
|
-
"@allbluecn/ai-gateway": "0.4.16",
|
|
135
|
-
"@allbluecn/shared": "0.4.16",
|
|
136
|
-
"@allbluecn/tiptap": "0.4.16",
|
|
137
|
-
"@allbluecn/ui": "0.4.16"
|
|
362
|
+
"zod": "^4.4.3"
|
|
138
363
|
},
|
|
139
364
|
"devDependencies": {
|
|
365
|
+
"@allblue/devtools": "workspace:*",
|
|
140
366
|
"@babel/parser": "^8.0.4",
|
|
141
367
|
"@babel/traverse": "^8.0.4",
|
|
142
368
|
"@cloudflare/vite-plugin": "^1.40.1",
|
|
@@ -168,8 +394,7 @@
|
|
|
168
394
|
"typescript": "^7",
|
|
169
395
|
"vite": "^8.1.5",
|
|
170
396
|
"vitest": "^4.1.5",
|
|
171
|
-
"wrangler": "^4.99.0"
|
|
172
|
-
"@allblue/devtools": "0.0.1"
|
|
397
|
+
"wrangler": "^4.99.0"
|
|
173
398
|
},
|
|
174
399
|
"prisma": {
|
|
175
400
|
"version": "7.8.0",
|
|
@@ -177,21 +402,5 @@
|
|
|
177
402
|
},
|
|
178
403
|
"optionalDependencies": {
|
|
179
404
|
"@tauri-apps/api": "^2.11.1"
|
|
180
|
-
},
|
|
181
|
-
"scripts": {
|
|
182
|
-
"dev": "vite --port 3000",
|
|
183
|
-
"build": "vite build",
|
|
184
|
-
"start": "vite preview",
|
|
185
|
-
"lint": "eslint",
|
|
186
|
-
"test": "vitest",
|
|
187
|
-
"test:ui": "vitest --ui",
|
|
188
|
-
"test:run": "vitest run",
|
|
189
|
-
"setup": "pnpm --filter @allbluecn/database generate && pnpm --filter @allbluecn/database migrate:dev",
|
|
190
|
-
"check:features": "tsx scripts/check-feature-keys.ts",
|
|
191
|
-
"assemble": "pnpm -w exec tsx packages/kernel/src/bin.ts --profile oss --assemble --app-dir apps/web",
|
|
192
|
-
"predev": "pnpm assemble && node scripts/check-sdk-versions.mjs",
|
|
193
|
-
"prebuild": "pnpm assemble && node scripts/check-sdk-versions.mjs",
|
|
194
|
-
"pretest": "pnpm assemble",
|
|
195
|
-
"pretest:run": "pnpm assemble"
|
|
196
405
|
}
|
|
197
|
-
}
|
|
406
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// AllBlue - 理想之海
|
|
3
|
+
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
+
//
|
|
5
|
+
// This program is free software: you can redistribute it and/or modify
|
|
6
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
// (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU Affero General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
import { useState, useEffect } from "react";
|
|
19
|
+
import { useTranslation } from "react-i18next";
|
|
20
|
+
import { Button } from "@/components/ui/button";
|
|
21
|
+
import { Input } from "@/components/ui/input";
|
|
22
|
+
import { Switch } from "@/components/ui/switch";
|
|
23
|
+
import {
|
|
24
|
+
Dialog,
|
|
25
|
+
DialogContent,
|
|
26
|
+
DialogFooter,
|
|
27
|
+
DialogHeader,
|
|
28
|
+
DialogTitle,
|
|
29
|
+
} from "@/components/ui/dialog";
|
|
30
|
+
import { getAutoScheduleFn, updateAutoScheduleFn } from "@/server/serverFns/iteration";
|
|
31
|
+
import { toast } from "@/components/ui/sonner";
|
|
32
|
+
import { useQuery } from "@tanstack/react-query";
|
|
33
|
+
|
|
34
|
+
interface AutoScheduleDialogProps {
|
|
35
|
+
open: boolean;
|
|
36
|
+
onOpenChange: (open: boolean) => void;
|
|
37
|
+
projectId: string;
|
|
38
|
+
onSaved?: () => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function AutoScheduleDialog({ open, onOpenChange, projectId, onSaved }: AutoScheduleDialogProps) {
|
|
42
|
+
const { t } = useTranslation("iterations");
|
|
43
|
+
const [enabled, setEnabled] = useState(false);
|
|
44
|
+
const [title, setTitle] = useState("迭代");
|
|
45
|
+
const [durationDays, setDurationDays] = useState(14);
|
|
46
|
+
const [cooldownDays, setCooldownDays] = useState(0);
|
|
47
|
+
const [startsOn, setStartsOn] = useState("");
|
|
48
|
+
const [futureCount, setFutureCount] = useState(2);
|
|
49
|
+
const [autoRollover, setAutoRollover] = useState(false);
|
|
50
|
+
const [loading, setLoading] = useState(false);
|
|
51
|
+
|
|
52
|
+
const { data } = useQuery({
|
|
53
|
+
queryKey: ["auto-schedule", projectId],
|
|
54
|
+
queryFn: () => getAutoScheduleFn({ data: { projectId } }),
|
|
55
|
+
enabled: open,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (open && data?.config) {
|
|
60
|
+
setEnabled(data.config.enabled);
|
|
61
|
+
setTitle(data.config.title);
|
|
62
|
+
setDurationDays(data.config.durationDays);
|
|
63
|
+
setCooldownDays(data.config.cooldownDays);
|
|
64
|
+
setStartsOn(data.config.startsOn);
|
|
65
|
+
setFutureCount(data.config.futureCount);
|
|
66
|
+
setAutoRollover(data.config.autoRollover);
|
|
67
|
+
} else if (open) {
|
|
68
|
+
setEnabled(false);
|
|
69
|
+
setTitle("迭代");
|
|
70
|
+
setDurationDays(14);
|
|
71
|
+
setCooldownDays(0);
|
|
72
|
+
setStartsOn(new Date().toISOString().slice(0, 10));
|
|
73
|
+
setFutureCount(2);
|
|
74
|
+
setAutoRollover(false);
|
|
75
|
+
}
|
|
76
|
+
}, [open, data]);
|
|
77
|
+
|
|
78
|
+
async function handleSave() {
|
|
79
|
+
setLoading(true);
|
|
80
|
+
try {
|
|
81
|
+
await updateAutoScheduleFn({
|
|
82
|
+
data: {
|
|
83
|
+
projectId,
|
|
84
|
+
enabled,
|
|
85
|
+
title,
|
|
86
|
+
durationDays,
|
|
87
|
+
cooldownDays,
|
|
88
|
+
startsOn,
|
|
89
|
+
futureCount,
|
|
90
|
+
autoRollover,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
toast.success(t("autoSchedule.saved"));
|
|
94
|
+
onSaved?.();
|
|
95
|
+
onOpenChange(false);
|
|
96
|
+
} catch (e) {
|
|
97
|
+
toast.error(e instanceof Error ? e.message : "保存失败");
|
|
98
|
+
} finally {
|
|
99
|
+
setLoading(false);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
105
|
+
<DialogContent className="sm:max-w-md">
|
|
106
|
+
<DialogHeader>
|
|
107
|
+
<DialogTitle>{t("autoSchedule.title")}</DialogTitle>
|
|
108
|
+
</DialogHeader>
|
|
109
|
+
<div className="space-y-4 py-4">
|
|
110
|
+
<div className="flex items-center justify-between">
|
|
111
|
+
<label className="text-sm font-medium">{t("autoSchedule.enabled")}</label>
|
|
112
|
+
<Switch checked={enabled} onCheckedChange={setEnabled} />
|
|
113
|
+
</div>
|
|
114
|
+
{enabled && (
|
|
115
|
+
<>
|
|
116
|
+
<div className="space-y-2">
|
|
117
|
+
<label className="text-sm font-medium">{t("autoSchedule.baseTitle")}</label>
|
|
118
|
+
<Input value={title} onChange={(e) => setTitle(e.target.value)} />
|
|
119
|
+
</div>
|
|
120
|
+
<div className="space-y-2">
|
|
121
|
+
<label className="text-sm font-medium">{t("autoSchedule.durationDays")}</label>
|
|
122
|
+
<Input type="number" min={1} max={90} value={durationDays} onChange={(e) => setDurationDays(Number(e.target.value))} />
|
|
123
|
+
</div>
|
|
124
|
+
<div className="space-y-2">
|
|
125
|
+
<label className="text-sm font-medium">{t("autoSchedule.cooldownDays")}</label>
|
|
126
|
+
<Input type="number" min={0} max={30} value={cooldownDays} onChange={(e) => setCooldownDays(Number(e.target.value))} />
|
|
127
|
+
</div>
|
|
128
|
+
<div className="space-y-2">
|
|
129
|
+
<label className="text-sm font-medium">{t("autoSchedule.startsOn")}</label>
|
|
130
|
+
<Input type="date" value={startsOn} onChange={(e) => setStartsOn(e.target.value)} />
|
|
131
|
+
</div>
|
|
132
|
+
<div className="space-y-2">
|
|
133
|
+
<label className="text-sm font-medium">{t("autoSchedule.futureCount")}</label>
|
|
134
|
+
<Input type="number" min={1} max={10} value={futureCount} onChange={(e) => setFutureCount(Number(e.target.value))} />
|
|
135
|
+
</div>
|
|
136
|
+
<div className="flex items-center justify-between">
|
|
137
|
+
<label className="text-sm font-medium">{t("autoSchedule.autoRollover")}</label>
|
|
138
|
+
<Switch checked={autoRollover} onCheckedChange={setAutoRollover} />
|
|
139
|
+
</div>
|
|
140
|
+
</>
|
|
141
|
+
)}
|
|
142
|
+
</div>
|
|
143
|
+
<DialogFooter>
|
|
144
|
+
<Button variant="outline" onClick={() => onOpenChange(false)}>{t("actions.cancel")}</Button>
|
|
145
|
+
<Button onClick={() => void handleSave()} disabled={loading || !enabled}>{loading ? "保存中..." : t("actions.save")}</Button>
|
|
146
|
+
</DialogFooter>
|
|
147
|
+
</DialogContent>
|
|
148
|
+
</Dialog>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// AllBlue - 理想之海
|
|
3
|
+
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
+
//
|
|
5
|
+
// This program is free software: you can redistribute it and/or modify
|
|
6
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
// (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU Affero General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
import { useTranslation } from "react-i18next";
|
|
19
|
+
import type { BurndownResult } from "@/server/serverFns/iteration/burndown-core";
|
|
20
|
+
|
|
21
|
+
export function BurndownChart({ data }: { data: BurndownResult & { timezone: string } }) {
|
|
22
|
+
const { t } = useTranslation("iterations");
|
|
23
|
+
if (data.points.length === 0) {
|
|
24
|
+
return <div className="flex h-48 items-center justify-center text-xs text-muted-foreground">{t("burndown.noData")}</div>;
|
|
25
|
+
}
|
|
26
|
+
const W = 640, H = 200, PAD = 28;
|
|
27
|
+
const maxVal = Math.max(1, ...data.points.map((p) => Math.max(p.scope, p.pending, p.ideal)));
|
|
28
|
+
const x = (i: number) => PAD + (i * (W - PAD * 2)) / Math.max(1, data.points.length - 1);
|
|
29
|
+
const y = (v: number) => H - PAD - (v * (H - PAD * 2)) / maxVal;
|
|
30
|
+
const line = (key: "pending" | "ideal") => data.points.map((p, i) => `${i === 0 ? "M" : "L"}${x(i)},${y(p[key])}`).join(" ");
|
|
31
|
+
const fill = data.points.map((p, i) => `${i === 0 ? "M" : "L"}${x(i)},${y(p.pending)}`).join(" ")
|
|
32
|
+
+ " " + [...data.points].reverse().map((p, i) => `L${x(data.points.length - 1 - i)},${y(p.ideal)}`).join(" ");
|
|
33
|
+
const leading = data.status === "leading";
|
|
34
|
+
return (
|
|
35
|
+
<div className="space-y-2">
|
|
36
|
+
<div className="flex items-center justify-between text-xs">
|
|
37
|
+
<span className="font-medium">{t("burndown.title")}</span>
|
|
38
|
+
<span className={leading ? "text-green-600 dark:text-green-400" : data.status === "trailing" ? "text-red-600 dark:text-red-400" : "text-muted-foreground"}>
|
|
39
|
+
{t(leading ? "burndown.leading" : data.status === "trailing" ? "burndown.trailing" : "burndown.pending")}
|
|
40
|
+
</span>
|
|
41
|
+
</div>
|
|
42
|
+
<svg viewBox={`0 0 ${W} ${H}`} className="w-full" role="img">
|
|
43
|
+
{[0, 0.25, 0.5, 0.75, 1].map((r) => (
|
|
44
|
+
<line key={r} x1={PAD} x2={W - PAD} y1={y(maxVal * r)} y2={y(maxVal * r)} className="stroke-border" strokeWidth={1} />
|
|
45
|
+
))}
|
|
46
|
+
<path d={fill} className={leading ? "fill-green-500/15" : "fill-red-500/15"} />
|
|
47
|
+
<path d={line("ideal")} className="stroke-muted-foreground" strokeWidth={1.5} strokeDasharray="4 3" fill="none" />
|
|
48
|
+
<path d={line("pending")} className="stroke-primary" strokeWidth={2} fill="none" />
|
|
49
|
+
{data.points.map((p, i) => (
|
|
50
|
+
<circle key={p.date} cx={x(i)} cy={y(p.pending)} r={2.5} className="fill-primary">
|
|
51
|
+
<title>{`${p.date}: ${p.pending}`}</title>
|
|
52
|
+
</circle>
|
|
53
|
+
))}
|
|
54
|
+
<text x={PAD} y={H - 8} className="fill-muted-foreground text-[10px]">{data.points[0].date}</text>
|
|
55
|
+
<text x={W - PAD} y={H - 8} textAnchor="end" className="fill-muted-foreground text-[10px]">{data.points.at(-1)!.date}</text>
|
|
56
|
+
</svg>
|
|
57
|
+
<div className="flex gap-4 text-xs text-muted-foreground">
|
|
58
|
+
<span className="flex items-center gap-1"><span className="inline-block h-0.5 w-4 bg-primary" />{t("burndown.pending")}</span>
|
|
59
|
+
<span className="flex items-center gap-1"><span className="inline-block h-0.5 w-4 bg-muted-foreground" style={{ backgroundImage: "linear-gradient(90deg, currentColor 50%, transparent 50%)", backgroundSize: "4px 2px" }} />{t("burndown.ideal")}</span>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// AllBlue - 理想之海
|
|
3
|
+
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
+
//
|
|
5
|
+
// This program is free software: you can redistribute it and/or modify
|
|
6
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
// (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU Affero General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
import { Circle, CircleDot, CircleCheckBig } from "lucide-react";
|
|
19
|
+
import type { LucideIcon } from "lucide-react";
|
|
20
|
+
import type { IterationStatus } from "@/lib/iteration/status";
|
|
21
|
+
|
|
22
|
+
export const ITERATION_STATUS_META: Record<IterationStatus, {
|
|
23
|
+
labelKey: string; icon: LucideIcon; className: string;
|
|
24
|
+
}> = {
|
|
25
|
+
upcoming: { labelKey: "status.upcoming", icon: Circle, className: "bg-blue-500/15 text-blue-600 dark:text-blue-400" },
|
|
26
|
+
active: { labelKey: "status.active", icon: CircleDot, className: "bg-amber-500/15 text-amber-600 dark:text-amber-400" },
|
|
27
|
+
completed: { labelKey: "status.completed", icon: CircleCheckBig, className: "bg-green-500/15 text-green-600 dark:text-green-400" },
|
|
28
|
+
};
|