@burdenoff/microfe-planmagnet 2026.925.18 → 2026.926.1

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 (47) hide show
  1. package/dist/generated/wspace-types.d.ts +61 -2
  2. package/dist/generated/wspace-types.d.ts.map +1 -1
  3. package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
  4. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +1 -1
  5. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  6. package/dist/planmagnet/pages/ProductsCreateProductPagePage.d.ts.map +1 -1
  7. package/dist/planmagnet/pages/ProductsCreateProductPagePage.js +93 -98
  8. package/dist/planmagnet/pages/ProductsCreateProductPagePage.js.map +1 -1
  9. package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.d.ts.map +1 -1
  10. package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.js +72 -79
  11. package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.js.map +1 -1
  12. package/dist/planmagnet/pages/ProductsEditProductPagePage.d.ts.map +1 -1
  13. package/dist/planmagnet/pages/ProductsEditProductPagePage.js +112 -123
  14. package/dist/planmagnet/pages/ProductsEditProductPagePage.js.map +1 -1
  15. package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
  16. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +92 -98
  17. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
  18. package/dist/planmagnet/pages/ProductsProductsPagePage.d.ts.map +1 -1
  19. package/dist/planmagnet/pages/ProductsProductsPagePage.js +88 -96
  20. package/dist/planmagnet/pages/ProductsProductsPagePage.js.map +1 -1
  21. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.d.ts.map +1 -1
  22. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js +116 -114
  23. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js.map +1 -1
  24. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
  25. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +82 -88
  26. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
  27. package/dist/planmagnet/pages/ProductsRoadmapsPagePage.d.ts.map +1 -1
  28. package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js +79 -79
  29. package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js.map +1 -1
  30. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
  31. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +150 -154
  32. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
  33. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.d.ts.map +1 -1
  34. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +120 -109
  35. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js.map +1 -1
  36. package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
  37. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +75 -31
  38. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
  39. package/dist/planmagnet/roadmaps/planningFocus.d.ts +23 -0
  40. package/dist/planmagnet/roadmaps/planningFocus.d.ts.map +1 -0
  41. package/dist/planmagnet/roadmaps/planningFocus.js +76 -0
  42. package/dist/planmagnet/roadmaps/planningFocus.js.map +1 -0
  43. package/dist/planmagnet/sprints/SprintDates.d.ts +37 -0
  44. package/dist/planmagnet/sprints/SprintDates.d.ts.map +1 -0
  45. package/dist/planmagnet/sprints/SprintDates.js +114 -0
  46. package/dist/planmagnet/sprints/SprintDates.js.map +1 -0
  47. package/package.json +1 -1
@@ -1,14 +1,15 @@
1
1
  import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
2
- import { useEntityId as t } from "../hooks/useEntityId.js";
3
- import { SprintLifecycleActions as n } from "../sprints/SprintControls.js";
4
- import { useMemo as r, useState as i } from "react";
5
- import { ArrowLeft as a, Save as o } from "lucide-react";
6
- import { gql as s } from "@apollo/client";
7
- import { useMutation as c, useQuery as l } from "@apollo/client/react";
8
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
- import { Button as f, Card as p, CardContent as m, CardHeader as h, CardTitle as g, Input as _ } from "@burdenoff/fe-libs/ui";
2
+ import { throwOnError as t } from "../utils/mutationResult.js";
3
+ import { useEntityId as n } from "../hooks/useEntityId.js";
4
+ import { SprintLifecycleActions as r } from "../sprints/SprintControls.js";
5
+ import { useMemo as i, useState as a } from "react";
6
+ import { ArrowLeft as o, Save as s } from "lucide-react";
7
+ import { gql as c } from "@apollo/client";
8
+ import { useMutation as l, useQuery as u } from "@apollo/client/react";
9
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
10
+ import { Button as p, Card as m, CardContent as h, CardHeader as g, CardTitle as _, Input as v } from "@burdenoff/fe-libs/ui";
10
11
  //#region src/planmagnet/pages/ProjectsPlanningEditPagePage.tsx
11
- var v = s`
12
+ var y = c`
12
13
  query GetSprintForEdit($id: ID!, $workspaceId: ID!) {
13
14
  planmagnetSprint(id: $id) {
14
15
  id
@@ -27,7 +28,7 @@ var v = s`
27
28
  }
28
29
  }
29
30
  }
30
- `, y = s`
31
+ `, b = c`
31
32
  mutation UpdateSprint($id: ID!, $input: PlanmagnetUpdateSprintInput!) {
32
33
  planmagnetUpdateSprint(id: $id, input: $input) {
33
34
  id
@@ -40,166 +41,176 @@ var v = s`
40
41
  }
41
42
  }
42
43
  `;
43
- function b() {
44
- let { workspaceId: s } = e(), b = t("sprintId"), { data: x, loading: S, error: C } = l(v, {
44
+ function x() {
45
+ let { workspaceId: c } = e(), x = n("sprintId"), { data: S, loading: C, error: w } = u(y, {
45
46
  variables: {
46
- id: b,
47
- workspaceId: s ?? "default"
47
+ id: x,
48
+ workspaceId: c ?? "default"
48
49
  },
49
- skip: !b
50
- }), [w, T] = i(null), E = x?.planmagnetSprint, D = x?.planmagnetProjects?.items ?? [], O = r(() => ({
51
- name: E?.name ?? "",
52
- startDate: E?.startDate ? E.startDate.split("T")[0] : "",
53
- endDate: E?.endDate ? E.endDate.split("T")[0] : "",
54
- goal: E?.goal ?? "",
55
- capacity: E?.capacity?.toString() ?? ""
56
- }), [E]), [k, A] = i({}), j = {
57
- ...O,
58
- ...k
59
- }, M = (e) => A(e), [N, { loading: P, error: F }] = c(y, {
60
- refetchQueries: [
61
- "GetSprints",
62
- "GetSprintDetail",
63
- "GetSprintForEdit",
64
- "GetDashboardData"
65
- ],
66
- onCompleted: () => {
67
- T("Sprint updated successfully.");
68
- }
69
- });
70
- return b ? S && !x ? /* @__PURE__ */ u("div", {
50
+ skip: !x
51
+ }), [T, E] = a(null), D = S?.planmagnetSprint, O = S?.planmagnetProjects?.items ?? [], k = i(() => ({
52
+ name: D?.name ?? "",
53
+ startDate: D?.startDate ? D.startDate.split("T")[0] : "",
54
+ endDate: D?.endDate ? D.endDate.split("T")[0] : "",
55
+ goal: D?.goal ?? "",
56
+ capacity: D?.capacity?.toString() ?? ""
57
+ }), [D]), [A, j] = a({}), M = {
58
+ ...k,
59
+ ...A
60
+ }, N = (e) => j((t) => {
61
+ let n = { ...t };
62
+ for (let [t, r] of Object.entries(e)) r !== M[t] && (n[t] = r);
63
+ return n;
64
+ }), [P, F] = a(null), [I, { loading: L }] = l(b, { refetchQueries: [
65
+ "GetSprints",
66
+ "GetSprintDetail",
67
+ "GetSprintForEdit",
68
+ "GetDashboardData"
69
+ ] });
70
+ return x ? C && !S ? /* @__PURE__ */ d("div", {
71
71
  className: "flex items-center justify-center p-12",
72
- children: /* @__PURE__ */ u("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
73
- }) : C ? /* @__PURE__ */ d("div", {
72
+ children: /* @__PURE__ */ d("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
73
+ }) : w ? /* @__PURE__ */ f("div", {
74
74
  className: "p-6 text-red-500",
75
- children: ["Error loading sprint: ", C.message]
76
- }) : E ? /* @__PURE__ */ d("div", {
75
+ children: ["Error loading sprint: ", w.message]
76
+ }) : D ? /* @__PURE__ */ f("div", {
77
77
  className: "space-y-6 p-6 max-w-4xl",
78
78
  children: [
79
- /* @__PURE__ */ d("div", {
79
+ /* @__PURE__ */ f("div", {
80
80
  className: "flex items-center justify-between",
81
- children: [/* @__PURE__ */ d("div", {
81
+ children: [/* @__PURE__ */ f("div", {
82
82
  className: "flex items-center gap-3",
83
- children: [/* @__PURE__ */ u(f, {
83
+ children: [/* @__PURE__ */ d(p, {
84
84
  variant: "ghost",
85
85
  size: "sm",
86
- children: /* @__PURE__ */ u(a, { className: "h-4 w-4" })
87
- }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
86
+ children: /* @__PURE__ */ d(o, { className: "h-4 w-4" })
87
+ }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
88
88
  className: "text-2xl font-semibold",
89
89
  children: "Edit Planning Session"
90
- }), /* @__PURE__ */ u("p", {
90
+ }), /* @__PURE__ */ d("p", {
91
91
  className: "text-sm text-muted-foreground",
92
- children: E.name
92
+ children: D.name
93
93
  })] })]
94
- }), /* @__PURE__ */ d(f, {
94
+ }), /* @__PURE__ */ f(p, {
95
95
  size: "sm",
96
- onClick: () => {
97
- E && N({ variables: {
98
- id: E.id,
99
- input: {
100
- name: j.name || void 0,
101
- startDate: j.startDate || void 0,
102
- endDate: j.endDate || void 0,
103
- goal: j.goal || void 0,
104
- capacity: j.capacity ? parseInt(j.capacity, 10) : void 0
105
- }
106
- } });
96
+ onClick: async () => {
97
+ if (!D) return;
98
+ F(null), E(null);
99
+ let e = {
100
+ ...M.startDate !== k.startDate && M.startDate ? { startDate: M.startDate } : {},
101
+ ...M.endDate !== k.endDate && M.endDate ? { endDate: M.endDate } : {}
102
+ };
103
+ try {
104
+ await t(I({ variables: {
105
+ id: D.id,
106
+ input: {
107
+ name: M.name || void 0,
108
+ ...e,
109
+ goal: M.goal || void 0,
110
+ capacity: M.capacity ? parseInt(M.capacity, 10) : void 0
111
+ }
112
+ } })), E("Sprint updated successfully."), j({});
113
+ } catch (e) {
114
+ F(e instanceof Error ? e.message : "The sprint could not be saved.");
115
+ }
107
116
  },
108
- disabled: P,
109
- children: [/* @__PURE__ */ u(o, { className: "mr-1 h-4 w-4" }), P ? "Saving..." : "Save Changes"]
117
+ disabled: L,
118
+ children: [/* @__PURE__ */ d(s, { className: "mr-1 h-4 w-4" }), L ? "Saving..." : "Save Changes"]
110
119
  })]
111
120
  }),
112
- w && /* @__PURE__ */ u("div", {
113
- className: "p-3 bg-green-50 text-green-800 rounded-md text-sm",
114
- children: w
121
+ T && /* @__PURE__ */ d("div", {
122
+ role: "status",
123
+ className: "p-3 rounded-md text-sm bg-muted text-status-success-text",
124
+ children: T
115
125
  }),
116
- F && /* @__PURE__ */ d("div", {
117
- className: "p-3 bg-red-50 text-red-800 rounded-md text-sm",
118
- children: ["Error: ", F.message]
126
+ P && /* @__PURE__ */ f("div", {
127
+ role: "alert",
128
+ className: "p-3 rounded-md text-sm bg-destructive/10 text-destructive",
129
+ children: ["Error: ", P]
119
130
  }),
120
- /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Session Details" }) }), /* @__PURE__ */ d(m, {
131
+ /* @__PURE__ */ f(m, { children: [/* @__PURE__ */ d(g, { children: /* @__PURE__ */ d(_, { children: "Session Details" }) }), /* @__PURE__ */ f(h, {
121
132
  className: "space-y-4",
122
133
  children: [
123
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
134
+ /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
124
135
  className: "text-sm font-medium",
125
136
  children: "Name"
126
- }), /* @__PURE__ */ u(_, {
127
- value: j.name,
128
- onChange: (e) => M({
129
- ...j,
137
+ }), /* @__PURE__ */ d(v, {
138
+ value: M.name,
139
+ onChange: (e) => N({
140
+ ...M,
130
141
  name: e.target.value
131
142
  }),
132
143
  className: "mt-1"
133
144
  })] }),
134
- /* @__PURE__ */ d("div", {
145
+ /* @__PURE__ */ f("div", {
135
146
  className: "grid grid-cols-2 gap-4",
136
- children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
147
+ children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
137
148
  className: "text-sm font-medium",
138
149
  children: "Project"
139
- }), /* @__PURE__ */ u("div", {
150
+ }), /* @__PURE__ */ d("div", {
140
151
  className: "mt-1 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground",
141
- children: D.find((e) => e.id === E.projectId)?.name ?? E.projectId
142
- })] }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
152
+ children: O.find((e) => e.id === D.projectId)?.name ?? D.projectId
153
+ })] }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
143
154
  className: "text-sm font-medium",
144
155
  children: "Status"
145
- }), /* @__PURE__ */ d("div", {
156
+ }), /* @__PURE__ */ f("div", {
146
157
  className: "mt-1 flex items-start justify-between gap-2",
147
- children: [/* @__PURE__ */ u("span", {
158
+ children: [/* @__PURE__ */ d("span", {
148
159
  className: "rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground capitalize",
149
- children: E.status.toLowerCase().replace(/_/g, " ")
150
- }), /* @__PURE__ */ u(n, {
151
- sprintId: E.id,
152
- sprintName: E.name,
153
- status: E.status
160
+ children: D.status.toLowerCase().replace(/_/g, " ")
161
+ }), /* @__PURE__ */ d(r, {
162
+ sprintId: D.id,
163
+ sprintName: D.name,
164
+ status: D.status
154
165
  })]
155
166
  })] })]
156
167
  }),
157
- /* @__PURE__ */ d("div", {
168
+ /* @__PURE__ */ f("div", {
158
169
  className: "grid grid-cols-2 gap-4",
159
- children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
170
+ children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
160
171
  className: "text-sm font-medium",
161
172
  children: "Start Date"
162
- }), /* @__PURE__ */ u(_, {
173
+ }), /* @__PURE__ */ d(v, {
163
174
  type: "date",
164
- value: j.startDate,
165
- onChange: (e) => M({
166
- ...j,
175
+ value: M.startDate,
176
+ onChange: (e) => N({
177
+ ...M,
167
178
  startDate: e.target.value
168
179
  }),
169
180
  className: "mt-1"
170
- })] }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
181
+ })] }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
171
182
  className: "text-sm font-medium",
172
183
  children: "End Date"
173
- }), /* @__PURE__ */ u(_, {
184
+ }), /* @__PURE__ */ d(v, {
174
185
  type: "date",
175
- value: j.endDate,
176
- onChange: (e) => M({
177
- ...j,
186
+ value: M.endDate,
187
+ onChange: (e) => N({
188
+ ...M,
178
189
  endDate: e.target.value
179
190
  }),
180
191
  className: "mt-1"
181
192
  })] })]
182
193
  }),
183
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
194
+ /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
184
195
  className: "text-sm font-medium",
185
196
  children: "Goal"
186
- }), /* @__PURE__ */ u("textarea", {
197
+ }), /* @__PURE__ */ d("textarea", {
187
198
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]",
188
- value: j.goal,
189
- onChange: (e) => M({
190
- ...j,
199
+ value: M.goal,
200
+ onChange: (e) => N({
201
+ ...M,
191
202
  goal: e.target.value
192
203
  }),
193
204
  placeholder: "Sprint goal..."
194
205
  })] }),
195
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
206
+ /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
196
207
  className: "text-sm font-medium",
197
208
  children: "Capacity (story points)"
198
- }), /* @__PURE__ */ u(_, {
209
+ }), /* @__PURE__ */ d(v, {
199
210
  type: "number",
200
- value: j.capacity,
201
- onChange: (e) => M({
202
- ...j,
211
+ value: M.capacity,
212
+ onChange: (e) => N({
213
+ ...M,
203
214
  capacity: e.target.value
204
215
  }),
205
216
  className: "mt-1",
@@ -208,15 +219,15 @@ function b() {
208
219
  ]
209
220
  })] })
210
221
  ]
211
- }) : /* @__PURE__ */ u("div", {
222
+ }) : /* @__PURE__ */ d("div", {
212
223
  className: "p-6 text-muted-foreground",
213
224
  children: "Planning session not found."
214
- }) : /* @__PURE__ */ u("div", {
225
+ }) : /* @__PURE__ */ d("div", {
215
226
  className: "p-6 text-muted-foreground",
216
227
  children: "No planning session selected. Open one from the list."
217
228
  });
218
229
  }
219
230
  //#endregion
220
- export { b as ProjectsPlanningEditPagePage };
231
+ export { x as ProjectsPlanningEditPagePage };
221
232
 
222
233
  //# sourceMappingURL=ProjectsPlanningEditPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsPlanningEditPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsPlanningEditPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery, useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft } from 'lucide-react';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { SprintLifecycleActions } from '../sprints/SprintControls';\n\nconst GET_SPRINT_FOR_EDIT = gql`\n query GetSprintForEdit($id: ID!, $workspaceId: ID!) {\n planmagnetSprint(id: $id) {\n id\n name\n projectId\n status\n startDate\n endDate\n goal\n capacity\n }\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst UPDATE_SPRINT = gql`\n mutation UpdateSprint($id: ID!, $input: PlanmagnetUpdateSprintInput!) {\n planmagnetUpdateSprint(id: $id, input: $input) {\n id\n name\n status\n startDate\n endDate\n goal\n capacity\n }\n }\n`;\n\nexport function ProjectsPlanningEditPagePage() {\n const { workspaceId } = usePlanMagnet();\n const sprintId = useEntityId('sprintId');\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_SPRINT_FOR_EDIT, {\n variables: { id: sprintId, workspaceId: workspaceId ?? 'default' },\n skip: !sprintId,\n });\n\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const sprint = data?.planmagnetSprint;\n const projects = data?.planmagnetProjects?.items ?? [];\n\n const defaultForm = useMemo(\n () => ({\n name: sprint?.name ?? '',\n startDate: sprint?.startDate ? sprint.startDate.split('T')[0] : '',\n endDate: sprint?.endDate ? sprint.endDate.split('T')[0] : '',\n goal: sprint?.goal ?? '',\n capacity: sprint?.capacity?.toString() ?? '',\n }),\n [sprint]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (updates: Record<string, string>) => setFormOverrides(updates);\n\n const [updateSprint, { loading: saving, error: saveError }] = useMutation(UPDATE_SPRINT, {\n refetchQueries: ['GetSprints', 'GetSprintDetail', 'GetSprintForEdit', 'GetDashboardData'],\n onCompleted: () => {\n setSuccessMessage('Sprint updated successfully.');\n },\n });\n\n const handleSave = () => {\n if (!sprint) return;\n updateSprint({\n variables: {\n id: sprint.id,\n input: {\n name: form.name || undefined,\n startDate: form.startDate || undefined,\n endDate: form.endDate || undefined,\n goal: form.goal || undefined,\n capacity: form.capacity ? parseInt(form.capacity, 10) : undefined,\n },\n },\n });\n };\n\n if (!sprintId)\n return (\n <div className=\"p-6 text-muted-foreground\">\n No planning session selected. Open one from the list.\n </div>\n );\n // Only before the first load: a refetch after a sprint action must not blank\n // the page (it unmounted the controls mid-action).\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 sprint: {error.message}</div>;\n if (!sprint) return <div className=\"p-6 text-muted-foreground\">Planning session not found.</div>;\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"sm\">\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Planning Session</h1>\n <p className=\"text-sm text-muted-foreground\">{sprint.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\n\n {successMessage && (\n <div className=\"p-3 bg-green-50 text-green-800 rounded-md text-sm\">{successMessage}</div>\n )}\n {saveError && (\n <div className=\"p-3 bg-red-50 text-red-800 rounded-md text-sm\">\n Error: {saveError.message}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Session Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Project</label>\n <div className=\"mt-1 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground\">\n {projects.find((p: { id: string; name: string }) => p.id === sprint.projectId)\n ?.name ?? sprint.projectId}\n </div>\n </div>\n <div>\n {/* Status is not an editable field: planmagnetUpdateSprint does not\n accept it, and sending it failed EVERY save on this page. It\n changes only through the guarded lifecycle actions. */}\n <label className=\"text-sm font-medium\">Status</label>\n <div className=\"mt-1 flex items-start justify-between gap-2\">\n <span className=\"rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground capitalize\">\n {sprint.status.toLowerCase().replace(/_/g, ' ')}\n </span>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Start Date</label>\n <Input\n type=\"date\"\n value={form.startDate}\n onChange={(e) => setForm({ ...form, startDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">End Date</label>\n <Input\n type=\"date\"\n value={form.endDate}\n onChange={(e) => setForm({ ...form, endDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Goal</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]\"\n value={form.goal}\n onChange={(e) => setForm({ ...form, goal: e.target.value })}\n placeholder=\"Sprint goal...\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Capacity (story points)</label>\n <Input\n type=\"number\"\n value={form.capacity}\n onChange={(e) => setForm({ ...form, capacity: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. 40\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectsPlanningEditPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsPlanningEditPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery, useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft } from 'lucide-react';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { SprintLifecycleActions } from '../sprints/SprintControls';\nimport { throwOnError } from '../utils/mutationResult';\n\nconst GET_SPRINT_FOR_EDIT = gql`\n query GetSprintForEdit($id: ID!, $workspaceId: ID!) {\n planmagnetSprint(id: $id) {\n id\n name\n projectId\n status\n startDate\n endDate\n goal\n capacity\n }\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst UPDATE_SPRINT = gql`\n mutation UpdateSprint($id: ID!, $input: PlanmagnetUpdateSprintInput!) {\n planmagnetUpdateSprint(id: $id, input: $input) {\n id\n name\n status\n startDate\n endDate\n goal\n capacity\n }\n }\n`;\n\nexport function ProjectsPlanningEditPagePage() {\n const { workspaceId } = usePlanMagnet();\n const sprintId = useEntityId('sprintId');\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_SPRINT_FOR_EDIT, {\n variables: { id: sprintId, workspaceId: workspaceId ?? 'default' },\n skip: !sprintId,\n });\n\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const sprint = data?.planmagnetSprint;\n const projects = data?.planmagnetProjects?.items ?? [];\n\n const defaultForm = useMemo(\n () => ({\n name: sprint?.name ?? '',\n startDate: sprint?.startDate ? sprint.startDate.split('T')[0] : '',\n endDate: sprint?.endDate ? sprint.endDate.split('T')[0] : '',\n goal: sprint?.goal ?? '',\n capacity: sprint?.capacity?.toString() ?? '',\n }),\n [sprint]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n // Keep ONLY the fields the user actually edited. Callers pass the whole form\n // ({ ...form, field }); copying every field made untouched dates stale\n // snapshots, so after a refetch (e.g. a CONFLICT) a retry re-sent the old\n // dates and silently reverted a teammate's replan (BOFF-7918 review).\n const setForm = (updates: Record<string, string>) =>\n setFormOverrides((prev) => {\n const next = { ...prev };\n for (const [key, value] of Object.entries(updates)) {\n if (value !== form[key as keyof typeof form]) next[key] = value;\n }\n return next;\n });\n\n const [saveError, setSaveError] = useState<string | null>(null);\n const [updateSprint, { loading: saving }] = useMutation(UPDATE_SPRINT, {\n refetchQueries: ['GetSprints', 'GetSprintDetail', 'GetSprintForEdit', 'GetDashboardData'],\n });\n\n const handleSave = async () => {\n if (!sprint) return;\n setSaveError(null);\n setSuccessMessage(null);\n // Send the planned dates only when the user changed them (BOFF-7918).\n // Every change to a planned date is recorded in the sprint's plan history,\n // so re-sending unchanged dates on a rename must not look like a replan.\n const dateChanges = {\n ...(form.startDate !== defaultForm.startDate && form.startDate\n ? { startDate: form.startDate }\n : {}),\n ...(form.endDate !== defaultForm.endDate && form.endDate ? { endDate: form.endDate } : {}),\n };\n try {\n await throwOnError(\n updateSprint({\n variables: {\n id: sprint.id,\n input: {\n name: form.name || undefined,\n ...dateChanges,\n goal: form.goal || undefined,\n capacity: form.capacity ? parseInt(form.capacity, 10) : undefined,\n },\n },\n })\n );\n // Only after the service ACCEPTED it: under fe-libs' errorPolicy 'all' a\n // refused save resolves, and onCompleted reported success for it.\n setSuccessMessage('Sprint updated successfully.');\n setFormOverrides({});\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The sprint could not be saved.');\n }\n };\n\n if (!sprintId)\n return (\n <div className=\"p-6 text-muted-foreground\">\n No planning session selected. Open one from the list.\n </div>\n );\n // Only before the first load: a refetch after a sprint action must not blank\n // the page (it unmounted the controls mid-action).\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 sprint: {error.message}</div>;\n if (!sprint) return <div className=\"p-6 text-muted-foreground\">Planning session not found.</div>;\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"sm\">\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Planning Session</h1>\n <p className=\"text-sm text-muted-foreground\">{sprint.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\n\n {successMessage && (\n <div role=\"status\" className=\"p-3 rounded-md text-sm bg-muted text-status-success-text\">\n {successMessage}\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md text-sm bg-destructive/10 text-destructive\">\n Error: {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Session Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Project</label>\n <div className=\"mt-1 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground\">\n {projects.find((p: { id: string; name: string }) => p.id === sprint.projectId)\n ?.name ?? sprint.projectId}\n </div>\n </div>\n <div>\n {/* Status is not an editable field: planmagnetUpdateSprint does not\n accept it, and sending it failed EVERY save on this page. It\n changes only through the guarded lifecycle actions. */}\n <label className=\"text-sm font-medium\">Status</label>\n <div className=\"mt-1 flex items-start justify-between gap-2\">\n <span className=\"rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground capitalize\">\n {sprint.status.toLowerCase().replace(/_/g, ' ')}\n </span>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Start Date</label>\n <Input\n type=\"date\"\n value={form.startDate}\n onChange={(e) => setForm({ ...form, startDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">End Date</label>\n <Input\n type=\"date\"\n value={form.endDate}\n onChange={(e) => setForm({ ...form, endDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Goal</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]\"\n value={form.goal}\n onChange={(e) => setForm({ ...form, goal: e.target.value })}\n placeholder=\"Sprint goal...\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Capacity (story points)</label>\n <Input\n type=\"number\"\n value={form.capacity}\n onChange={(e) => setForm({ ...form, capacity: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. 40\"\n />\n </div>\n </CardContent>\n </Card>\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":"AAiFA,wBAAgB,0BAA0B,4CAwNzC"}
1
+ {"version":3,"file":"SprintsStartSprintPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/SprintsStartSprintPagePage.tsx"],"names":[],"mappings":"AAmGA,wBAAgB,0BAA0B,4CA2PzC"}
@@ -1,7 +1,8 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
2
  import { detailPath as n } from "../utils/rowNavigation.js";
3
3
  import { NewSprintDialog as r, SprintLifecycleActions as i } from "../sprints/SprintControls.js";
4
- import { Calendar as a, Users as o, Zap as s } from "lucide-react";
4
+ import { SprintDates as a } from "../sprints/SprintDates.js";
5
+ import { Users as o, Zap as s } from "lucide-react";
5
6
  import { gql as c } from "@apollo/client";
6
7
  import { useQuery as l } from "@apollo/client/react";
7
8
  import { jsx as u, jsxs as d } from "react/jsx-runtime";
@@ -21,6 +22,18 @@ var _ = c`
21
22
  status
22
23
  startDate
23
24
  endDate
25
+ startedAt
26
+ completedAt
27
+ baselineStartDate
28
+ baselineEndDate
29
+ planChanges {
30
+ field
31
+ fromValue
32
+ toValue
33
+ sprintStatus
34
+ changedBy
35
+ changedAt
36
+ }
24
37
  velocity
25
38
  workItems {
26
39
  id
@@ -52,7 +65,7 @@ function y() {
52
65
  pagination: { first: 50 }
53
66
  },
54
67
  skip: !c
55
- }), S = y?.planmagnetSprints?.items ?? [], C = S.filter((e) => e.status === "ACTIVE" || e.status === "REVIEW"), w = S.filter((e) => e.status === "PLANNING"), T = t(), E = (e) => T(n("/projects/planning-detail-page", e));
68
+ }), S = y?.planmagnetSprints?.items ?? [], C = S.filter((e) => e.status === "ACTIVE" || e.status === "REVIEW"), w = S.filter((e) => e.status === "PLANNING"), T = S.filter((e) => e.status === "COMPLETED" || e.status === "CANCELLED"), E = t(), D = (e) => E(n("/projects/planning-detail-page", e));
56
69
  return b && !y ? /* @__PURE__ */ u("div", {
57
70
  className: "flex items-center justify-center p-12",
58
71
  children: /* @__PURE__ */ u("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
@@ -75,7 +88,7 @@ function y() {
75
88
  C.length,
76
89
  " active"
77
90
  ]
78
- })] }), /* @__PURE__ */ u(r, { onCreated: E })]
91
+ })] }), /* @__PURE__ */ u(r, { onCreated: D })]
79
92
  }),
80
93
  C.length > 0 && /* @__PURE__ */ d("div", {
81
94
  className: "space-y-4",
@@ -93,7 +106,7 @@ function y() {
93
106
  children: [/* @__PURE__ */ u(s, { className: "h-4 w-4 text-primary" }), /* @__PURE__ */ u("button", {
94
107
  type: "button",
95
108
  className: "hover:underline text-left",
96
- onClick: () => E(e.id),
109
+ onClick: () => D(e.id),
97
110
  children: e.name
98
111
  })]
99
112
  }), /* @__PURE__ */ d("div", {
@@ -112,24 +125,17 @@ function y() {
112
125
  className: "text-sm text-muted-foreground",
113
126
  children: e.goal ?? ""
114
127
  }),
115
- /* @__PURE__ */ d("div", {
128
+ /* @__PURE__ */ u(a, { sprint: e }),
129
+ /* @__PURE__ */ u("div", {
116
130
  className: "flex gap-4 text-xs text-muted-foreground",
117
- children: [/* @__PURE__ */ d("span", {
118
- className: "flex items-center gap-1",
119
- children: [
120
- /* @__PURE__ */ u(a, { className: "h-3 w-3" }),
121
- e.startDate ?? "?",
122
- " - ",
123
- e.endDate ?? "?"
124
- ]
125
- }), /* @__PURE__ */ d("span", {
131
+ children: /* @__PURE__ */ d("span", {
126
132
  className: "flex items-center gap-1",
127
133
  children: [
128
134
  /* @__PURE__ */ u(o, { className: "h-3 w-3" }),
129
135
  t.teamMemberIds.length,
130
136
  " members"
131
137
  ]
132
- })]
138
+ })
133
139
  }),
134
140
  /* @__PURE__ */ d("div", {
135
141
  className: "grid grid-cols-3 gap-4 text-center",
@@ -241,7 +247,7 @@ function y() {
241
247
  children: /* @__PURE__ */ u("button", {
242
248
  type: "button",
243
249
  className: "hover:underline text-left",
244
- onClick: () => E(e.id),
250
+ onClick: () => D(e.id),
245
251
  children: e.name
246
252
  })
247
253
  }), /* @__PURE__ */ d("div", {
@@ -258,23 +264,61 @@ function y() {
258
264
  })
259
265
  }), /* @__PURE__ */ d(m, {
260
266
  className: "space-y-2",
261
- children: [/* @__PURE__ */ u("p", {
262
- className: "text-sm text-muted-foreground",
263
- children: e.goal ?? ""
264
- }), /* @__PURE__ */ d("div", {
265
- className: "flex gap-4 text-xs text-muted-foreground",
266
- children: [
267
- /* @__PURE__ */ d("span", { children: [
268
- e.startDate ?? "?",
269
- " - ",
270
- e.endDate ?? "?"
271
- ] }),
272
- /* @__PURE__ */ d("span", { children: [t.totalPoints, " points planned"] }),
273
- /* @__PURE__ */ d("span", { children: [t.teamMemberIds.length, " members"] })
274
- ]
275
- })]
267
+ children: [
268
+ /* @__PURE__ */ u("p", {
269
+ className: "text-sm text-muted-foreground",
270
+ children: e.goal ?? ""
271
+ }),
272
+ /* @__PURE__ */ u(a, { sprint: e }),
273
+ /* @__PURE__ */ d("div", {
274
+ className: "flex gap-4 text-xs text-muted-foreground",
275
+ children: [/* @__PURE__ */ d("span", { children: [t.totalPoints, " points planned"] }), /* @__PURE__ */ d("span", { children: [t.teamMemberIds.length, " members"] })]
276
+ })
277
+ ]
276
278
  })] }, e.id);
277
279
  })]
280
+ }),
281
+ T.length > 0 && /* @__PURE__ */ d("div", {
282
+ className: "space-y-4",
283
+ "data-testid": "finished-sprints",
284
+ children: [/* @__PURE__ */ u("h2", {
285
+ className: "text-lg font-medium",
286
+ children: "Finished"
287
+ }), T.map((e) => {
288
+ let t = v(e);
289
+ return /* @__PURE__ */ d(p, {
290
+ "data-testid": "finished-sprint",
291
+ children: [/* @__PURE__ */ u(h, {
292
+ className: "pb-2",
293
+ children: /* @__PURE__ */ d("div", {
294
+ className: "flex items-center justify-between",
295
+ children: [/* @__PURE__ */ u(g, {
296
+ className: "text-base",
297
+ children: /* @__PURE__ */ u("button", {
298
+ type: "button",
299
+ className: "hover:underline text-left",
300
+ onClick: () => D(e.id),
301
+ children: e.name
302
+ })
303
+ }), /* @__PURE__ */ u(f, {
304
+ variant: "outline",
305
+ children: e.status === "COMPLETED" ? "Completed" : "Cancelled"
306
+ })]
307
+ })
308
+ }), /* @__PURE__ */ d(m, {
309
+ className: "space-y-2",
310
+ children: [/* @__PURE__ */ u(a, { sprint: e }), /* @__PURE__ */ d("p", {
311
+ className: "text-xs text-muted-foreground",
312
+ children: [
313
+ t.completedPoints,
314
+ "/",
315
+ t.totalPoints,
316
+ " points done"
317
+ ]
318
+ })]
319
+ })]
320
+ }, e.id);
321
+ })]
278
322
  })
279
323
  ]
280
324
  });