@burdenoff/microfe-planmagnet 2026.927.2 → 2026.927.3

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 (51) hide show
  1. package/dist/planmagnet/admin/PlanMagnetAdminRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/admin/PlanMagnetAdminRoot.js +128 -124
  3. package/dist/planmagnet/admin/PlanMagnetAdminRoot.js.map +1 -1
  4. package/dist/planmagnet/controls/ConfirmButton.d.ts +25 -0
  5. package/dist/planmagnet/controls/ConfirmButton.d.ts.map +1 -0
  6. package/dist/planmagnet/controls/ConfirmButton.js +30 -0
  7. package/dist/planmagnet/controls/ConfirmButton.js.map +1 -0
  8. package/dist/planmagnet/controls/ProjectControls.d.ts +13 -0
  9. package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -0
  10. package/dist/planmagnet/controls/ProjectControls.js +104 -0
  11. package/dist/planmagnet/controls/ProjectControls.js.map +1 -0
  12. package/dist/planmagnet/controls/WorkItemControls.d.ts +52 -0
  13. package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -0
  14. package/dist/planmagnet/controls/WorkItemControls.js +198 -0
  15. package/dist/planmagnet/controls/WorkItemControls.js.map +1 -0
  16. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +4 -4
  17. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  18. package/dist/planmagnet/pages/DocsDocsPagePage.js +4 -4
  19. package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
  20. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +97 -90
  21. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
  22. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
  23. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +150 -111
  24. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
  25. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  26. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +114 -91
  27. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  28. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  29. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +134 -132
  30. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  31. package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
  32. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +6 -5
  33. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
  34. package/dist/planmagnet/pages/TasksCreateTaskPagePage.d.ts.map +1 -1
  35. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +167 -111
  36. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +1 -1
  37. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  38. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +147 -147
  39. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  40. package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
  41. package/dist/planmagnet/pages/TeamTeamPagePage.js +1 -1
  42. package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
  43. package/dist/planmagnet/people/People.js +1 -1
  44. package/dist/planmagnet/roadmaps/RoadmapControls.d.ts +34 -0
  45. package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -0
  46. package/dist/planmagnet/roadmaps/RoadmapControls.js +301 -0
  47. package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -0
  48. package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
  49. package/dist/planmagnet/sprints/SprintControls.js +194 -215
  50. package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
  51. package/package.json +1 -1
@@ -1,12 +1,13 @@
1
1
  import { PersonName as e } from "../people/People.js";
2
2
  import { useEntityId as t } from "../hooks/useEntityId.js";
3
- import { Calendar as n, CheckSquare as r, FolderKanban as i, Users as a, Zap as o } from "lucide-react";
4
- import { gql as s } from "@apollo/client";
5
- import { useQuery as c } from "@apollo/client/react";
6
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
- import { Badge as d, Card as f, CardContent as p, CardHeader as m, CardTitle as h } from "@burdenoff/fe-libs/ui";
3
+ import { ProjectHeaderActions as n } from "../controls/ProjectControls.js";
4
+ import { Calendar as r, CheckSquare as i, FolderKanban as a, Users as o, Zap as s } from "lucide-react";
5
+ import { gql as c } from "@apollo/client";
6
+ import { useQuery as l } from "@apollo/client/react";
7
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
8
+ import { Badge as f, Card as p, CardContent as m, CardHeader as h, CardTitle as g } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/planmagnet/pages/ProjectsProjectDetailPagePage.tsx
9
- var g = s`
10
+ var _ = c`
10
11
  query GetProjectDetail($id: ID!) {
11
12
  planmagnetProject(id: $id) {
12
13
  id
@@ -56,7 +57,7 @@ var g = s`
56
57
  }
57
58
  }
58
59
  }
59
- `, _ = {
60
+ `, v = {
60
61
  ACTIVE: "bg-green-100 text-green-800",
61
62
  ON_HOLD: "bg-orange-100 text-orange-800",
62
63
  CANCELLED: "bg-red-100 text-red-800",
@@ -64,292 +65,293 @@ var g = s`
64
65
  PLANNING: "bg-gray-100 text-gray-800",
65
66
  ARCHIVED: "bg-gray-100 text-gray-800"
66
67
  };
67
- function v() {
68
- let s = t("projectId"), { data: v, loading: y, error: b } = c(g, {
69
- variables: { id: s },
70
- skip: !s
68
+ function y() {
69
+ let c = t("projectId"), { data: y, loading: b, error: x } = l(_, {
70
+ variables: { id: c },
71
+ skip: !c
71
72
  });
72
- if (!s) return /* @__PURE__ */ l("div", {
73
+ if (!c) return /* @__PURE__ */ u("div", {
73
74
  className: "p-6 text-muted-foreground",
74
75
  children: "No project selected. Open one from the list."
75
76
  });
76
- if (y && !v) return /* @__PURE__ */ l("div", {
77
+ if (b && !y) return /* @__PURE__ */ u("div", {
77
78
  className: "flex items-center justify-center p-12",
78
- children: /* @__PURE__ */ l("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
79
+ children: /* @__PURE__ */ u("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
79
80
  });
80
- if (b) return /* @__PURE__ */ u("div", {
81
+ if (x) return /* @__PURE__ */ d("div", {
81
82
  className: "p-6 text-red-500",
82
- children: ["Error loading project: ", b.message]
83
+ children: ["Error loading project: ", x.message]
83
84
  });
84
- let x = v?.planmagnetProject;
85
- if (!x) return /* @__PURE__ */ l("div", {
85
+ let S = y?.planmagnetProject;
86
+ if (!S) return /* @__PURE__ */ u("div", {
86
87
  className: "p-6 text-muted-foreground",
87
88
  children: "Project not found."
88
89
  });
89
- let S = x.workItems ?? [], C = x.sprints ?? [], w = x.milestones ?? [], T = C.find((e) => e.status === "ACTIVE"), E = S.length, D = S.filter((e) => e.status === "DONE").length;
90
- return /* @__PURE__ */ u("div", {
90
+ let C = S.workItems ?? [], w = S.sprints ?? [], T = S.milestones ?? [], E = w.find((e) => e.status === "ACTIVE"), D = w.filter((e) => e.status === "COMPLETED" && e.velocity != null).sort((e, t) => (t.endDate ?? "").localeCompare(e.endDate ?? ""))[0], O = C.length, k = C.filter((e) => e.status === "DONE").length;
91
+ return /* @__PURE__ */ d("div", {
91
92
  className: "space-y-6 p-6",
92
93
  children: [
93
- /* @__PURE__ */ u("div", {
94
+ /* @__PURE__ */ d("div", {
94
95
  className: "flex items-center justify-between",
95
- children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ u("div", {
96
+ children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("div", {
96
97
  className: "flex items-center gap-2",
97
98
  children: [
98
- /* @__PURE__ */ l(i, { className: "h-5 w-5 text-primary" }),
99
- /* @__PURE__ */ l("h1", {
99
+ /* @__PURE__ */ u(a, { className: "h-5 w-5 text-primary" }),
100
+ /* @__PURE__ */ u("h1", {
100
101
  className: "text-2xl font-semibold",
101
- children: x.name
102
+ children: S.name
102
103
  }),
103
- /* @__PURE__ */ l("span", {
104
- className: `text-xs px-2 py-0.5 rounded-full capitalize ${_[x.status] ?? "bg-gray-100"}`,
105
- children: x.status.toLowerCase().replace("_", " ")
104
+ /* @__PURE__ */ u("span", {
105
+ className: `text-xs px-2 py-0.5 rounded-full capitalize ${v[S.status] ?? "bg-gray-100"}`,
106
+ children: S.status.toLowerCase().replace("_", " ")
106
107
  })
107
108
  ]
108
- }), /* @__PURE__ */ l("p", {
109
+ }), /* @__PURE__ */ u("p", {
109
110
  className: "text-sm text-muted-foreground mt-1",
110
- children: x.description ?? "No description"
111
- })] }), /* @__PURE__ */ u("div", {
112
- className: "flex gap-2",
113
- children: [/* @__PURE__ */ l(d, {
114
- className: "capitalize",
115
- children: x.status.toLowerCase().replace("_", " ")
116
- }), /* @__PURE__ */ l(d, {
111
+ children: S.description ?? "No description"
112
+ })] }), /* @__PURE__ */ d("div", {
113
+ className: "flex flex-col items-end gap-2",
114
+ children: [/* @__PURE__ */ u(n, {
115
+ projectId: S.id,
116
+ name: S.name,
117
+ status: S.status
118
+ }), /* @__PURE__ */ u(f, {
117
119
  variant: "outline",
118
120
  className: "capitalize",
119
- children: x.methodology.toLowerCase()
121
+ children: S.methodology.toLowerCase()
120
122
  })]
121
123
  })]
122
124
  }),
123
- /* @__PURE__ */ u("div", {
125
+ /* @__PURE__ */ d("div", {
124
126
  className: "grid grid-cols-2 md:grid-cols-4 gap-4",
125
127
  children: [
126
- /* @__PURE__ */ l(f, { children: /* @__PURE__ */ u(p, {
128
+ /* @__PURE__ */ u(p, { children: /* @__PURE__ */ d(m, {
127
129
  className: "pt-4",
128
- children: [/* @__PURE__ */ u("div", {
130
+ children: [/* @__PURE__ */ d("div", {
129
131
  className: "flex items-center gap-2 text-muted-foreground text-xs",
130
- children: [/* @__PURE__ */ l(r, { className: "h-4 w-4" }), "Work Items"]
131
- }), /* @__PURE__ */ u("p", {
132
+ children: [/* @__PURE__ */ u(i, { className: "h-4 w-4" }), "Work Items"]
133
+ }), /* @__PURE__ */ d("p", {
132
134
  className: "text-xl font-bold mt-1",
133
135
  children: [
134
- D,
136
+ k,
135
137
  "/",
136
- E
138
+ O
137
139
  ]
138
140
  })]
139
141
  }) }),
140
- /* @__PURE__ */ l(f, { children: /* @__PURE__ */ u(p, {
142
+ /* @__PURE__ */ u(p, { children: /* @__PURE__ */ d(m, {
141
143
  className: "pt-4",
142
- children: [/* @__PURE__ */ u("div", {
144
+ children: [/* @__PURE__ */ d("div", {
143
145
  className: "flex items-center gap-2 text-muted-foreground text-xs",
144
- children: [/* @__PURE__ */ l(o, { className: "h-4 w-4" }), "Sprints"]
145
- }), /* @__PURE__ */ l("p", {
146
+ children: [/* @__PURE__ */ u(s, { className: "h-4 w-4" }), "Sprints"]
147
+ }), /* @__PURE__ */ u("p", {
146
148
  className: "text-xl font-bold mt-1",
147
- children: C.length
149
+ children: w.length
148
150
  })]
149
151
  }) }),
150
- /* @__PURE__ */ l(f, { children: /* @__PURE__ */ u(p, {
152
+ /* @__PURE__ */ u(p, { children: /* @__PURE__ */ d(m, {
151
153
  className: "pt-4",
152
- children: [/* @__PURE__ */ u("div", {
154
+ children: [/* @__PURE__ */ d("div", {
153
155
  className: "flex items-center gap-2 text-muted-foreground text-xs",
154
- children: [/* @__PURE__ */ l(n, { className: "h-4 w-4" }), "Milestones"]
155
- }), /* @__PURE__ */ l("p", {
156
+ children: [/* @__PURE__ */ u(r, { className: "h-4 w-4" }), "Milestones"]
157
+ }), /* @__PURE__ */ u("p", {
156
158
  className: "text-xl font-bold mt-1",
157
- children: w.length
159
+ children: T.length
158
160
  })]
159
161
  }) }),
160
- /* @__PURE__ */ l(f, { children: /* @__PURE__ */ u(p, {
162
+ /* @__PURE__ */ u(p, { children: /* @__PURE__ */ d(m, {
161
163
  className: "pt-4",
162
- children: [/* @__PURE__ */ u("div", {
164
+ children: [/* @__PURE__ */ d("div", {
163
165
  className: "flex items-center gap-2 text-muted-foreground text-xs",
164
- children: [/* @__PURE__ */ l(a, { className: "h-4 w-4" }), "Owner"]
165
- }), /* @__PURE__ */ l("p", {
166
+ children: [/* @__PURE__ */ u(o, { className: "h-4 w-4" }), "Owner"]
167
+ }), /* @__PURE__ */ u("p", {
166
168
  className: "text-sm font-bold mt-1 truncate",
167
- children: /* @__PURE__ */ l(e, { id: x.ownerId })
169
+ children: /* @__PURE__ */ u(e, { id: S.ownerId })
168
170
  })]
169
171
  }) })
170
172
  ]
171
173
  }),
172
- /* @__PURE__ */ u("div", {
174
+ /* @__PURE__ */ d("div", {
173
175
  className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
174
- children: [/* @__PURE__ */ u("div", {
176
+ children: [/* @__PURE__ */ d("div", {
175
177
  className: "lg:col-span-2 space-y-6",
176
178
  children: [
177
- /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(m, { children: /* @__PURE__ */ l(h, { children: "Timeline" }) }), /* @__PURE__ */ u(p, { children: [
178
- /* @__PURE__ */ u("div", {
179
+ /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Timeline" }) }), /* @__PURE__ */ d(m, { children: [
180
+ /* @__PURE__ */ d("div", {
179
181
  className: "flex justify-between text-sm mb-2",
180
- children: [/* @__PURE__ */ l("span", {
182
+ children: [/* @__PURE__ */ u("span", {
181
183
  className: "text-muted-foreground",
182
184
  children: "Duration"
183
- }), /* @__PURE__ */ l("span", {
185
+ }), /* @__PURE__ */ u("span", {
184
186
  className: "font-medium",
185
- children: E > 0 ? `${Math.round(D / E * 100)}% tasks done` : "No tasks yet"
187
+ children: O > 0 ? `${Math.round(k / O * 100)}% tasks done` : "No tasks yet"
186
188
  })]
187
189
  }),
188
- /* @__PURE__ */ l("div", {
190
+ /* @__PURE__ */ u("div", {
189
191
  className: "w-full h-4 rounded-full bg-muted overflow-hidden",
190
- children: /* @__PURE__ */ l("div", {
192
+ children: /* @__PURE__ */ u("div", {
191
193
  className: "h-full bg-primary rounded-full",
192
- style: { width: `${E > 0 ? Math.round(D / E * 100) : 0}%` }
194
+ style: { width: `${O > 0 ? Math.round(k / O * 100) : 0}%` }
193
195
  })
194
196
  }),
195
- /* @__PURE__ */ u("div", {
197
+ /* @__PURE__ */ d("div", {
196
198
  className: "flex justify-between text-xs text-muted-foreground mt-2",
197
- children: [/* @__PURE__ */ l("span", { children: x.startDate ? new Date(x.startDate).toLocaleDateString() : "Not set" }), /* @__PURE__ */ l("span", { children: x.endDate ? new Date(x.endDate).toLocaleDateString() : "Not set" })]
199
+ children: [/* @__PURE__ */ u("span", { children: S.startDate ? new Date(S.startDate).toLocaleDateString() : "Not set" }), /* @__PURE__ */ u("span", { children: S.endDate ? new Date(S.endDate).toLocaleDateString() : "Not set" })]
198
200
  })
199
201
  ] })] }),
200
- T && /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(m, { children: /* @__PURE__ */ u(h, {
202
+ E && /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ d(g, {
201
203
  className: "flex items-center gap-2",
202
- children: [/* @__PURE__ */ l(o, { className: "h-4 w-4 text-primary" }), "Active Sprint"]
203
- }) }), /* @__PURE__ */ u(p, {
204
+ children: [/* @__PURE__ */ u(s, { className: "h-4 w-4 text-primary" }), "Active Sprint"]
205
+ }) }), /* @__PURE__ */ d(m, {
204
206
  className: "space-y-3",
205
207
  children: [
206
- /* @__PURE__ */ u("div", {
208
+ /* @__PURE__ */ d("div", {
207
209
  className: "flex justify-between",
208
- children: [/* @__PURE__ */ l("span", {
210
+ children: [/* @__PURE__ */ u("span", {
209
211
  className: "font-medium",
210
- children: T.name
211
- }), /* @__PURE__ */ l(d, { children: "Active" })]
212
+ children: E.name
213
+ }), /* @__PURE__ */ u(f, { children: "Active" })]
212
214
  }),
213
- T.goal && /* @__PURE__ */ l("p", {
215
+ E.goal && /* @__PURE__ */ u("p", {
214
216
  className: "text-sm text-muted-foreground",
215
- children: T.goal
217
+ children: E.goal
216
218
  }),
217
- /* @__PURE__ */ u("div", {
219
+ /* @__PURE__ */ d("div", {
218
220
  className: "grid grid-cols-3 gap-4 text-center",
219
221
  children: [
220
- /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ u("p", {
222
+ /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("p", {
221
223
  className: "text-lg font-semibold",
222
224
  children: [
223
- T.workItems?.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0),
225
+ E.workItems?.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0),
224
226
  "/",
225
- T.workItems?.reduce((e, t) => e + (t.storyPoints ?? 0), 0) ?? 0
227
+ E.workItems?.reduce((e, t) => e + (t.storyPoints ?? 0), 0) ?? 0
226
228
  ]
227
- }), /* @__PURE__ */ l("p", {
229
+ }), /* @__PURE__ */ u("p", {
228
230
  className: "text-xs text-muted-foreground",
229
231
  children: "Points"
230
232
  })] }),
231
- /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ u("p", {
233
+ /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("p", {
232
234
  className: "text-lg font-semibold",
233
235
  children: [
234
- T.workItems?.filter((e) => e.status === "DONE").length ?? 0,
236
+ E.workItems?.filter((e) => e.status === "DONE").length ?? 0,
235
237
  "/",
236
- T.workItems?.length ?? 0
238
+ E.workItems?.length ?? 0
237
239
  ]
238
- }), /* @__PURE__ */ l("p", {
240
+ }), /* @__PURE__ */ u("p", {
239
241
  className: "text-xs text-muted-foreground",
240
242
  children: "Tasks"
241
243
  })] }),
242
- /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
244
+ /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
243
245
  className: "text-lg font-semibold",
244
- children: T.velocity ?? 0
245
- }), /* @__PURE__ */ l("p", {
246
+ children: D ? `${D.velocity} pts` : "—"
247
+ }), /* @__PURE__ */ u("p", {
246
248
  className: "text-xs text-muted-foreground",
247
- children: "Velocity"
249
+ children: "Velocity of the last sprint"
248
250
  })] })
249
251
  ]
250
252
  })
251
253
  ]
252
254
  })] }),
253
- /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(m, { children: /* @__PURE__ */ u(h, { children: [
255
+ /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ d(g, { children: [
254
256
  "Recent Work Items (",
255
- S.length,
257
+ C.length,
256
258
  ")"
257
- ] }) }), /* @__PURE__ */ u(p, {
259
+ ] }) }), /* @__PURE__ */ d(m, {
258
260
  className: "space-y-2",
259
- children: [S.slice(0, 5).map((e) => /* @__PURE__ */ u("div", {
261
+ children: [C.slice(0, 5).map((e) => /* @__PURE__ */ d("div", {
260
262
  className: "flex items-center justify-between border rounded-md p-2.5",
261
- children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
263
+ children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
262
264
  className: "text-sm font-medium",
263
265
  children: e.key
264
- }), /* @__PURE__ */ l("div", {
266
+ }), /* @__PURE__ */ u("div", {
265
267
  className: "flex gap-1 mt-1",
266
- children: e.labels.map((e) => /* @__PURE__ */ l("span", {
268
+ children: e.labels.map((e) => /* @__PURE__ */ u("span", {
267
269
  className: "text-[10px] px-1.5 py-0.5 rounded bg-muted",
268
270
  children: e
269
271
  }, e))
270
- })] }), /* @__PURE__ */ u("div", {
272
+ })] }), /* @__PURE__ */ d("div", {
271
273
  className: "flex items-center gap-2",
272
- children: [/* @__PURE__ */ u("span", {
274
+ children: [/* @__PURE__ */ d("span", {
273
275
  className: "text-xs text-muted-foreground",
274
276
  children: [e.storyPoints ?? 0, " pts"]
275
- }), /* @__PURE__ */ l(d, {
277
+ }), /* @__PURE__ */ u(f, {
276
278
  variant: "secondary",
277
279
  className: "capitalize text-xs",
278
280
  children: e.status.toLowerCase().replace("_", " ")
279
281
  })]
280
282
  })]
281
- }, e.id)), S.length === 0 && /* @__PURE__ */ l("p", {
283
+ }, e.id)), C.length === 0 && /* @__PURE__ */ u("p", {
282
284
  className: "text-sm text-muted-foreground text-center py-4",
283
285
  children: "No work items yet."
284
286
  })]
285
287
  })] })
286
288
  ]
287
- }), /* @__PURE__ */ u("div", {
289
+ }), /* @__PURE__ */ d("div", {
288
290
  className: "space-y-6",
289
- children: [/* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(m, { children: /* @__PURE__ */ u(h, { children: [
291
+ children: [/* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ d(g, { children: [
290
292
  "Milestones (",
291
- w.length,
293
+ T.length,
292
294
  ")"
293
- ] }) }), /* @__PURE__ */ u(p, {
295
+ ] }) }), /* @__PURE__ */ d(m, {
294
296
  className: "space-y-3",
295
- children: [w.map((e) => /* @__PURE__ */ u("div", {
297
+ children: [T.map((e) => /* @__PURE__ */ d("div", {
296
298
  className: "border-b pb-2 last:border-0",
297
- children: [/* @__PURE__ */ u("div", {
299
+ children: [/* @__PURE__ */ d("div", {
298
300
  className: "flex justify-between",
299
- children: [/* @__PURE__ */ l("span", {
301
+ children: [/* @__PURE__ */ u("span", {
300
302
  className: "text-sm font-medium",
301
303
  children: e.name
302
- }), /* @__PURE__ */ l(d, {
304
+ }), /* @__PURE__ */ u(f, {
303
305
  variant: "outline",
304
306
  className: "text-xs capitalize",
305
307
  children: e.status.toLowerCase().replace("_", " ")
306
308
  })]
307
- }), /* @__PURE__ */ u("div", {
309
+ }), /* @__PURE__ */ d("div", {
308
310
  className: "flex items-center gap-1 text-xs text-muted-foreground mt-1",
309
- children: [/* @__PURE__ */ l(n, { className: "h-3 w-3" }), e.dueDate ? new Date(e.dueDate).toLocaleDateString() : "No due date"]
311
+ children: [/* @__PURE__ */ u(r, { className: "h-3 w-3" }), e.dueDate ? new Date(e.dueDate).toLocaleDateString() : "No due date"]
310
312
  })]
311
- }, e.id)), w.length === 0 && /* @__PURE__ */ l("p", {
313
+ }, e.id)), T.length === 0 && /* @__PURE__ */ u("p", {
312
314
  className: "text-sm text-muted-foreground text-center py-2",
313
315
  children: "No milestones."
314
316
  })]
315
- })] }), /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(m, { children: /* @__PURE__ */ l(h, { children: "Details" }) }), /* @__PURE__ */ u(p, {
317
+ })] }), /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Details" }) }), /* @__PURE__ */ d(m, {
316
318
  className: "space-y-2 text-sm",
317
319
  children: [
318
- /* @__PURE__ */ u("div", {
320
+ /* @__PURE__ */ d("div", {
319
321
  className: "flex justify-between",
320
- children: [/* @__PURE__ */ l("span", {
322
+ children: [/* @__PURE__ */ u("span", {
321
323
  className: "text-muted-foreground",
322
324
  children: "Owner"
323
- }), /* @__PURE__ */ l("span", { children: /* @__PURE__ */ l(e, { id: x.ownerId }) })]
325
+ }), /* @__PURE__ */ u("span", { children: /* @__PURE__ */ u(e, { id: S.ownerId }) })]
324
326
  }),
325
- /* @__PURE__ */ u("div", {
327
+ /* @__PURE__ */ d("div", {
326
328
  className: "flex justify-between",
327
- children: [/* @__PURE__ */ l("span", {
329
+ children: [/* @__PURE__ */ u("span", {
328
330
  className: "text-muted-foreground",
329
331
  children: "Key"
330
- }), /* @__PURE__ */ l("span", {
332
+ }), /* @__PURE__ */ u("span", {
331
333
  className: "font-mono",
332
- children: x.key
334
+ children: S.key
333
335
  })]
334
336
  }),
335
- /* @__PURE__ */ u("div", {
337
+ /* @__PURE__ */ d("div", {
336
338
  className: "flex justify-between",
337
- children: [/* @__PURE__ */ l("span", {
339
+ children: [/* @__PURE__ */ u("span", {
338
340
  className: "text-muted-foreground",
339
341
  children: "Methodology"
340
- }), /* @__PURE__ */ l("span", {
342
+ }), /* @__PURE__ */ u("span", {
341
343
  className: "capitalize",
342
- children: x.methodology.toLowerCase()
344
+ children: S.methodology.toLowerCase()
343
345
  })]
344
346
  }),
345
- x.tags.length > 0 && /* @__PURE__ */ u("div", {
347
+ S.tags.length > 0 && /* @__PURE__ */ d("div", {
346
348
  className: "flex justify-between items-start",
347
- children: [/* @__PURE__ */ l("span", {
349
+ children: [/* @__PURE__ */ u("span", {
348
350
  className: "text-muted-foreground",
349
351
  children: "Tags"
350
- }), /* @__PURE__ */ l("div", {
352
+ }), /* @__PURE__ */ u("div", {
351
353
  className: "flex gap-1 flex-wrap justify-end",
352
- children: x.tags.map((e) => /* @__PURE__ */ l(d, {
354
+ children: S.tags.map((e) => /* @__PURE__ */ u(f, {
353
355
  variant: "outline",
354
356
  className: "text-xs",
355
357
  children: e
@@ -364,6 +366,6 @@ function v() {
364
366
  });
365
367
  }
366
368
  //#endregion
367
- export { v as ProjectsProjectDetailPagePage };
369
+ export { y as ProjectsProjectDetailPagePage };
368
370
 
369
371
  //# sourceMappingURL=ProjectsProjectDetailPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsProjectDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsProjectDetailPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { FolderKanban, CheckSquare, Users, Zap, Calendar } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { PersonName } from '../people/People';\n\nconst GET_PROJECT_DETAIL = gql`\n query GetProjectDetail($id: ID!) {\n planmagnetProject(id: $id) {\n id\n name\n key\n description\n status\n methodology\n ownerId\n startDate\n endDate\n tags\n createdAt\n sprints {\n id\n name\n status\n goal\n capacity\n velocity\n startDate\n endDate\n workItems {\n id\n status\n storyPoints\n }\n }\n milestones {\n id\n name\n description\n status\n dueDate\n ownerId\n }\n workItems {\n id\n key\n description\n status\n priority\n storyPoints\n assigneeId\n labels\n createdAt\n }\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n ACTIVE: 'bg-green-100 text-green-800',\n ON_HOLD: 'bg-orange-100 text-orange-800',\n CANCELLED: 'bg-red-100 text-red-800',\n COMPLETED: 'bg-blue-100 text-blue-800',\n PLANNING: 'bg-gray-100 text-gray-800',\n ARCHIVED: 'bg-gray-100 text-gray-800',\n};\n\nexport function ProjectsProjectDetailPagePage() {\n const projectId = useEntityId('projectId');\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_PROJECT_DETAIL, {\n variables: { id: projectId },\n skip: !projectId,\n });\n\n if (!projectId)\n return (\n <div className=\"p-6 text-muted-foreground\">No project selected. Open one from the list.</div>\n );\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\n if (loading && !data)\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n if (error) return <div className=\"p-6 text-red-500\">Error loading project: {error.message}</div>;\n\n const project = data?.planmagnetProject;\n if (!project) return <div className=\"p-6 text-muted-foreground\">Project not found.</div>;\n\n const projectWorkItems = project.workItems ?? [];\n const projectSprints = project.sprints ?? [];\n const projectMilestones = project.milestones ?? [];\n const activeSprint = projectSprints.find((s: { status: string }) => s.status === 'ACTIVE');\n const totalTasks = projectWorkItems.length;\n const completedTasks = projectWorkItems.filter(\n (wi: { status: string }) => wi.status === 'DONE'\n ).length;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"flex items-center gap-2\">\n <FolderKanban className=\"h-5 w-5 text-primary\" />\n <h1 className=\"text-2xl font-semibold\">{project.name}</h1>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[project.status] ?? 'bg-gray-100'}`}\n >\n {project.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {project.description ?? 'No description'}\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Badge className=\"capitalize\">{project.status.toLowerCase().replace('_', ' ')}</Badge>\n <Badge variant=\"outline\" className=\"capitalize\">\n {project.methodology.toLowerCase()}\n </Badge>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <CheckSquare className=\"h-4 w-4\" />\n Work Items\n </div>\n <p className=\"text-xl font-bold mt-1\">\n {completedTasks}/{totalTasks}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Zap className=\"h-4 w-4\" />\n Sprints\n </div>\n <p className=\"text-xl font-bold mt-1\">{projectSprints.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Calendar className=\"h-4 w-4\" />\n Milestones\n </div>\n <p className=\"text-xl font-bold mt-1\">{projectMilestones.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Users className=\"h-4 w-4\" />\n Owner\n </div>\n <p className=\"text-sm font-bold mt-1 truncate\">\n <PersonName id={project.ownerId} />\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Timeline</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex justify-between text-sm mb-2\">\n <span className=\"text-muted-foreground\">Duration</span>\n <span className=\"font-medium\">\n {totalTasks > 0\n ? `${Math.round((completedTasks / totalTasks) * 100)}% tasks done`\n : 'No tasks yet'}\n </span>\n </div>\n <div className=\"w-full h-4 rounded-full bg-muted overflow-hidden\">\n <div\n className=\"h-full bg-primary rounded-full\"\n style={{\n width: `${totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0}%`,\n }}\n />\n </div>\n <div className=\"flex justify-between text-xs text-muted-foreground mt-2\">\n <span>\n {project.startDate ? new Date(project.startDate).toLocaleDateString() : 'Not set'}\n </span>\n <span>\n {project.endDate ? new Date(project.endDate).toLocaleDateString() : 'Not set'}\n </span>\n </div>\n </CardContent>\n </Card>\n\n {activeSprint && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Zap className=\"h-4 w-4 text-primary\" />\n Active Sprint\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"flex justify-between\">\n <span className=\"font-medium\">{activeSprint.name}</span>\n <Badge>Active</Badge>\n </div>\n {activeSprint.goal && (\n <p className=\"text-sm text-muted-foreground\">{activeSprint.goal}</p>\n )}\n <div className=\"grid grid-cols-3 gap-4 text-center\">\n <div>\n <p className=\"text-lg font-semibold\">\n {activeSprint.workItems\n ?.filter((wi: { status: string }) => wi.status === 'DONE')\n .reduce(\n (s: number, wi: { storyPoints: number | null }) =>\n s + (wi.storyPoints ?? 0),\n 0\n )}\n /\n {activeSprint.workItems?.reduce(\n (s: number, wi: { storyPoints: number | null }) =>\n s + (wi.storyPoints ?? 0),\n 0\n ) ?? 0}\n </p>\n <p className=\"text-xs text-muted-foreground\">Points</p>\n </div>\n <div>\n <p className=\"text-lg font-semibold\">\n {activeSprint.workItems?.filter(\n (wi: { status: string }) => wi.status === 'DONE'\n ).length ?? 0}\n /{activeSprint.workItems?.length ?? 0}\n </p>\n <p className=\"text-xs text-muted-foreground\">Tasks</p>\n </div>\n <div>\n <p className=\"text-lg font-semibold\">{activeSprint.velocity ?? 0}</p>\n <p className=\"text-xs text-muted-foreground\">Velocity</p>\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Work Items ({projectWorkItems.length})</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {projectWorkItems\n .slice(0, 5)\n .map(\n (task: {\n id: string;\n key: string;\n description: string | null;\n status: string;\n storyPoints: number | null;\n labels: string[];\n }) => (\n <div\n key={task.id}\n className=\"flex items-center justify-between border rounded-md p-2.5\"\n >\n <div>\n <p className=\"text-sm font-medium\">{task.key}</p>\n <div className=\"flex gap-1 mt-1\">\n {task.labels.map((l: string) => (\n <span key={l} className=\"text-[10px] px-1.5 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {task.storyPoints ?? 0} pts\n </span>\n <Badge variant=\"secondary\" className=\"capitalize text-xs\">\n {task.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n </div>\n )\n )}\n {projectWorkItems.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">No work items yet.</p>\n )}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Milestones ({projectMilestones.length})</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {projectMilestones.map(\n (ms: { id: string; name: string; status: string; dueDate: string | null }) => (\n <div key={ms.id} className=\"border-b pb-2 last:border-0\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium\">{ms.name}</span>\n <Badge variant=\"outline\" className=\"text-xs capitalize\">\n {ms.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground mt-1\">\n <Calendar className=\"h-3 w-3\" />\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : 'No due date'}\n </div>\n </div>\n )\n )}\n {projectMilestones.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-2\">No milestones.</p>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Owner</span>\n <span>\n <PersonName id={project.ownerId} />\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Key</span>\n <span className=\"font-mono\">{project.key}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Methodology</span>\n <span className=\"capitalize\">{project.methodology.toLowerCase()}</span>\n </div>\n {project.tags.length > 0 && (\n <div className=\"flex justify-between items-start\">\n <span className=\"text-muted-foreground\">Tags</span>\n <div className=\"flex gap-1 flex-wrap justify-end\">\n {project.tags.map((tag: string) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectsProjectDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsProjectDetailPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { FolderKanban, CheckSquare, Users, Zap, Calendar } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { PersonName } from '../people/People';\nimport { ProjectHeaderActions } from '../controls/ProjectControls';\n\nconst GET_PROJECT_DETAIL = gql`\n query GetProjectDetail($id: ID!) {\n planmagnetProject(id: $id) {\n id\n name\n key\n description\n status\n methodology\n ownerId\n startDate\n endDate\n tags\n createdAt\n sprints {\n id\n name\n status\n goal\n capacity\n velocity\n startDate\n endDate\n workItems {\n id\n status\n storyPoints\n }\n }\n milestones {\n id\n name\n description\n status\n dueDate\n ownerId\n }\n workItems {\n id\n key\n description\n status\n priority\n storyPoints\n assigneeId\n labels\n createdAt\n }\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n ACTIVE: 'bg-green-100 text-green-800',\n ON_HOLD: 'bg-orange-100 text-orange-800',\n CANCELLED: 'bg-red-100 text-red-800',\n COMPLETED: 'bg-blue-100 text-blue-800',\n PLANNING: 'bg-gray-100 text-gray-800',\n ARCHIVED: 'bg-gray-100 text-gray-800',\n};\n\nexport function ProjectsProjectDetailPagePage() {\n const projectId = useEntityId('projectId');\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_PROJECT_DETAIL, {\n variables: { id: projectId },\n skip: !projectId,\n });\n\n if (!projectId)\n return (\n <div className=\"p-6 text-muted-foreground\">No project selected. Open one from the list.</div>\n );\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\n if (loading && !data)\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n if (error) return <div className=\"p-6 text-red-500\">Error loading project: {error.message}</div>;\n\n const project = data?.planmagnetProject;\n if (!project) return <div className=\"p-6 text-muted-foreground\">Project not found.</div>;\n\n const projectWorkItems = project.workItems ?? [];\n const projectSprints = project.sprints ?? [];\n const projectMilestones = project.milestones ?? [];\n const activeSprint = projectSprints.find((s: { status: string }) => s.status === 'ACTIVE');\n // Velocity exists only for a COMPLETED sprint (BOFF-7944: this tile read the running sprint's velocity, which is\n // never set, so it always showed 0). Show the latest completed sprint's instead.\n const lastCompleted = projectSprints\n .filter(\n (s: { status: string; velocity: number | null }) =>\n s.status === 'COMPLETED' && s.velocity != null\n )\n .sort((a: { endDate: string | null }, b: { endDate: string | null }) =>\n (b.endDate ?? '').localeCompare(a.endDate ?? '')\n )[0];\n const totalTasks = projectWorkItems.length;\n const completedTasks = projectWorkItems.filter(\n (wi: { status: string }) => wi.status === 'DONE'\n ).length;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"flex items-center gap-2\">\n <FolderKanban className=\"h-5 w-5 text-primary\" />\n <h1 className=\"text-2xl font-semibold\">{project.name}</h1>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[project.status] ?? 'bg-gray-100'}`}\n >\n {project.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {project.description ?? 'No description'}\n </p>\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n {/* Status, Edit and Delete (BOFF-7940): a project could never leave PLANNING from the UI. */}\n <ProjectHeaderActions\n projectId={project.id}\n name={project.name}\n status={project.status}\n />\n <Badge variant=\"outline\" className=\"capitalize\">\n {project.methodology.toLowerCase()}\n </Badge>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <CheckSquare className=\"h-4 w-4\" />\n Work Items\n </div>\n <p className=\"text-xl font-bold mt-1\">\n {completedTasks}/{totalTasks}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Zap className=\"h-4 w-4\" />\n Sprints\n </div>\n <p className=\"text-xl font-bold mt-1\">{projectSprints.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Calendar className=\"h-4 w-4\" />\n Milestones\n </div>\n <p className=\"text-xl font-bold mt-1\">{projectMilestones.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Users className=\"h-4 w-4\" />\n Owner\n </div>\n <p className=\"text-sm font-bold mt-1 truncate\">\n <PersonName id={project.ownerId} />\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Timeline</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex justify-between text-sm mb-2\">\n <span className=\"text-muted-foreground\">Duration</span>\n <span className=\"font-medium\">\n {totalTasks > 0\n ? `${Math.round((completedTasks / totalTasks) * 100)}% tasks done`\n : 'No tasks yet'}\n </span>\n </div>\n <div className=\"w-full h-4 rounded-full bg-muted overflow-hidden\">\n <div\n className=\"h-full bg-primary rounded-full\"\n style={{\n width: `${totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0}%`,\n }}\n />\n </div>\n <div className=\"flex justify-between text-xs text-muted-foreground mt-2\">\n <span>\n {project.startDate ? new Date(project.startDate).toLocaleDateString() : 'Not set'}\n </span>\n <span>\n {project.endDate ? new Date(project.endDate).toLocaleDateString() : 'Not set'}\n </span>\n </div>\n </CardContent>\n </Card>\n\n {activeSprint && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Zap className=\"h-4 w-4 text-primary\" />\n Active Sprint\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"flex justify-between\">\n <span className=\"font-medium\">{activeSprint.name}</span>\n <Badge>Active</Badge>\n </div>\n {activeSprint.goal && (\n <p className=\"text-sm text-muted-foreground\">{activeSprint.goal}</p>\n )}\n <div className=\"grid grid-cols-3 gap-4 text-center\">\n <div>\n <p className=\"text-lg font-semibold\">\n {activeSprint.workItems\n ?.filter((wi: { status: string }) => wi.status === 'DONE')\n .reduce(\n (s: number, wi: { storyPoints: number | null }) =>\n s + (wi.storyPoints ?? 0),\n 0\n )}\n /\n {activeSprint.workItems?.reduce(\n (s: number, wi: { storyPoints: number | null }) =>\n s + (wi.storyPoints ?? 0),\n 0\n ) ?? 0}\n </p>\n <p className=\"text-xs text-muted-foreground\">Points</p>\n </div>\n <div>\n <p className=\"text-lg font-semibold\">\n {activeSprint.workItems?.filter(\n (wi: { status: string }) => wi.status === 'DONE'\n ).length ?? 0}\n /{activeSprint.workItems?.length ?? 0}\n </p>\n <p className=\"text-xs text-muted-foreground\">Tasks</p>\n </div>\n <div>\n <p className=\"text-lg font-semibold\">\n {lastCompleted ? `${lastCompleted.velocity} pts` : '—'}\n </p>\n <p className=\"text-xs text-muted-foreground\">Velocity of the last sprint</p>\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Work Items ({projectWorkItems.length})</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {projectWorkItems\n .slice(0, 5)\n .map(\n (task: {\n id: string;\n key: string;\n description: string | null;\n status: string;\n storyPoints: number | null;\n labels: string[];\n }) => (\n <div\n key={task.id}\n className=\"flex items-center justify-between border rounded-md p-2.5\"\n >\n <div>\n <p className=\"text-sm font-medium\">{task.key}</p>\n <div className=\"flex gap-1 mt-1\">\n {task.labels.map((l: string) => (\n <span key={l} className=\"text-[10px] px-1.5 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {task.storyPoints ?? 0} pts\n </span>\n <Badge variant=\"secondary\" className=\"capitalize text-xs\">\n {task.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n </div>\n )\n )}\n {projectWorkItems.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">No work items yet.</p>\n )}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Milestones ({projectMilestones.length})</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {projectMilestones.map(\n (ms: { id: string; name: string; status: string; dueDate: string | null }) => (\n <div key={ms.id} className=\"border-b pb-2 last:border-0\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium\">{ms.name}</span>\n <Badge variant=\"outline\" className=\"text-xs capitalize\">\n {ms.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground mt-1\">\n <Calendar className=\"h-3 w-3\" />\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : 'No due date'}\n </div>\n </div>\n )\n )}\n {projectMilestones.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-2\">No milestones.</p>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Owner</span>\n <span>\n <PersonName id={project.ownerId} />\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Key</span>\n <span className=\"font-mono\">{project.key}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Methodology</span>\n <span className=\"capitalize\">{project.methodology.toLowerCase()}</span>\n </div>\n {project.tags.length > 0 && (\n <div className=\"flex justify-between items-start\">\n <span className=\"text-muted-foreground\">Tags</span>\n <div className=\"flex gap-1 flex-wrap justify-end\">\n {project.tags.map((tag: string) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SprintsStartSprintPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/SprintsStartSprintPagePage.tsx"],"names":[],"mappings":"AAoGA,wBAAgB,0BAA0B,4CA2PzC"}
1
+ {"version":3,"file":"SprintsStartSprintPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/SprintsStartSprintPagePage.tsx"],"names":[],"mappings":"AAsGA,wBAAgB,0BAA0B,4CAkQzC"}
@@ -49,14 +49,14 @@ var v = l`
49
49
  }
50
50
  `;
51
51
  function y(e) {
52
- let t = e.workItems ?? [], n = t.reduce((e, t) => e + (t.storyPoints ?? 0), 0), r = t.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0);
52
+ let t = e.workItems ?? [];
53
53
  return {
54
- totalPoints: n,
55
- completedPoints: r,
54
+ totalPoints: t.reduce((e, t) => e + (t.storyPoints ?? 0), 0),
55
+ completedPoints: t.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0),
56
56
  tasksTotal: t.length,
57
57
  tasksCompleted: t.filter((e) => e.status === "DONE").length,
58
58
  teamMemberIds: Array.from(new Set(t.map((e) => e.assigneeId).filter((e) => !!e))),
59
- velocity: e.velocity ?? r
59
+ velocity: e.velocity
60
60
  };
61
61
  }
62
62
  function b() {
@@ -173,9 +173,10 @@ function b() {
173
173
  className: "p-3 bg-muted rounded-md",
174
174
  children: [/* @__PURE__ */ d("p", {
175
175
  className: "text-lg font-bold",
176
- children: t.velocity
176
+ children: t.velocity == null ? "—" : t.velocity
177
177
  }), /* @__PURE__ */ d("p", {
178
178
  className: "text-xs text-muted-foreground",
179
+ title: "Story points done when the sprint was completed",
179
180
  children: "Velocity"
180
181
  })]
181
182
  })