@burdenoff/microfe-planmagnet 2026.924.5 → 2026.925.2

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.
@@ -1,13 +1,14 @@
1
1
  import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
2
2
  import { useEntityId as t } from "../hooks/useEntityId.js";
3
- import { useMemo as n, useState as r } from "react";
4
- import { ArrowLeft as i, Save as a } from "lucide-react";
5
- import { gql as o } from "@apollo/client";
6
- import { useMutation as s, useQuery as c } from "@apollo/client/react";
7
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
8
- import { Button as d, Card as f, CardContent as p, CardHeader as m, CardTitle as h, Input as g } from "@burdenoff/fe-libs/ui";
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";
9
10
  //#region src/planmagnet/pages/ProjectsPlanningEditPagePage.tsx
10
- var _ = o`
11
+ var v = s`
11
12
  query GetSprintForEdit($id: ID!, $workspaceId: ID!) {
12
13
  planmagnetSprint(id: $id) {
13
14
  id
@@ -26,7 +27,7 @@ var _ = o`
26
27
  }
27
28
  }
28
29
  }
29
- `, v = o`
30
+ `, y = s`
30
31
  mutation UpdateSprint($id: ID!, $input: PlanmagnetUpdateSprintInput!) {
31
32
  planmagnetUpdateSprint(id: $id, input: $input) {
32
33
  id
@@ -39,24 +40,23 @@ var _ = o`
39
40
  }
40
41
  }
41
42
  `;
42
- function y() {
43
- let { workspaceId: o } = e(), y = t("sprintId"), { data: b, loading: x, error: S } = c(_, {
43
+ function b() {
44
+ let { workspaceId: s } = e(), b = t("sprintId"), { data: x, loading: S, error: C } = l(v, {
44
45
  variables: {
45
- id: y,
46
- workspaceId: o ?? "default"
46
+ id: b,
47
+ workspaceId: s ?? "default"
47
48
  },
48
- skip: !y
49
- }), [C, w] = r(null), T = b?.planmagnetSprint, E = b?.planmagnetProjects?.items ?? [], D = n(() => ({
50
- name: T?.name ?? "",
51
- status: T?.status ?? "PLANNING",
52
- startDate: T?.startDate ? T.startDate.split("T")[0] : "",
53
- endDate: T?.endDate ? T.endDate.split("T")[0] : "",
54
- goal: T?.goal ?? "",
55
- capacity: T?.capacity?.toString() ?? ""
56
- }), [T]), [O, k] = r({}), A = {
57
- ...D,
58
- ...O
59
- }, j = (e) => k(e), [M, { loading: N, error: P }] = s(v, {
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
60
  refetchQueries: [
61
61
  "GetSprints",
62
62
  "GetSprintDetail",
@@ -64,150 +64,142 @@ function y() {
64
64
  "GetDashboardData"
65
65
  ],
66
66
  onCompleted: () => {
67
- w("Sprint updated successfully.");
67
+ T("Sprint updated successfully.");
68
68
  }
69
69
  });
70
- return y ? x ? /* @__PURE__ */ l("div", {
70
+ return b ? S ? /* @__PURE__ */ u("div", {
71
71
  className: "flex items-center justify-center p-12",
72
- children: /* @__PURE__ */ l("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
73
- }) : S ? /* @__PURE__ */ u("div", {
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", {
74
74
  className: "p-6 text-red-500",
75
- children: ["Error loading sprint: ", S.message]
76
- }) : T ? /* @__PURE__ */ u("div", {
75
+ children: ["Error loading sprint: ", C.message]
76
+ }) : E ? /* @__PURE__ */ d("div", {
77
77
  className: "space-y-6 p-6 max-w-4xl",
78
78
  children: [
79
- /* @__PURE__ */ u("div", {
79
+ /* @__PURE__ */ d("div", {
80
80
  className: "flex items-center justify-between",
81
- children: [/* @__PURE__ */ u("div", {
81
+ children: [/* @__PURE__ */ d("div", {
82
82
  className: "flex items-center gap-3",
83
- children: [/* @__PURE__ */ l(d, {
83
+ children: [/* @__PURE__ */ u(f, {
84
84
  variant: "ghost",
85
85
  size: "sm",
86
- children: /* @__PURE__ */ l(i, { className: "h-4 w-4" })
87
- }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("h1", {
86
+ children: /* @__PURE__ */ u(a, { className: "h-4 w-4" })
87
+ }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
88
88
  className: "text-2xl font-semibold",
89
89
  children: "Edit Planning Session"
90
- }), /* @__PURE__ */ l("p", {
90
+ }), /* @__PURE__ */ u("p", {
91
91
  className: "text-sm text-muted-foreground",
92
- children: T.name
92
+ children: E.name
93
93
  })] })]
94
- }), /* @__PURE__ */ u(d, {
94
+ }), /* @__PURE__ */ d(f, {
95
95
  size: "sm",
96
96
  onClick: () => {
97
- T && M({ variables: {
98
- id: T.id,
97
+ E && N({ variables: {
98
+ id: E.id,
99
99
  input: {
100
- name: A.name || void 0,
101
- status: A.status || void 0,
102
- startDate: A.startDate || void 0,
103
- endDate: A.endDate || void 0,
104
- goal: A.goal || void 0,
105
- capacity: A.capacity ? parseInt(A.capacity, 10) : void 0
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
106
105
  }
107
106
  } });
108
107
  },
109
- disabled: N,
110
- children: [/* @__PURE__ */ l(a, { className: "mr-1 h-4 w-4" }), N ? "Saving..." : "Save Changes"]
108
+ disabled: P,
109
+ children: [/* @__PURE__ */ u(o, { className: "mr-1 h-4 w-4" }), P ? "Saving..." : "Save Changes"]
111
110
  })]
112
111
  }),
113
- C && /* @__PURE__ */ l("div", {
112
+ w && /* @__PURE__ */ u("div", {
114
113
  className: "p-3 bg-green-50 text-green-800 rounded-md text-sm",
115
- children: C
114
+ children: w
116
115
  }),
117
- P && /* @__PURE__ */ u("div", {
116
+ F && /* @__PURE__ */ d("div", {
118
117
  className: "p-3 bg-red-50 text-red-800 rounded-md text-sm",
119
- children: ["Error: ", P.message]
118
+ children: ["Error: ", F.message]
120
119
  }),
121
- /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(m, { children: /* @__PURE__ */ l(h, { children: "Session Details" }) }), /* @__PURE__ */ u(p, {
120
+ /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Session Details" }) }), /* @__PURE__ */ d(m, {
122
121
  className: "space-y-4",
123
122
  children: [
124
- /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
123
+ /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
125
124
  className: "text-sm font-medium",
126
125
  children: "Name"
127
- }), /* @__PURE__ */ l(g, {
128
- value: A.name,
129
- onChange: (e) => j({
130
- ...A,
126
+ }), /* @__PURE__ */ u(_, {
127
+ value: j.name,
128
+ onChange: (e) => M({
129
+ ...j,
131
130
  name: e.target.value
132
131
  }),
133
132
  className: "mt-1"
134
133
  })] }),
135
- /* @__PURE__ */ u("div", {
134
+ /* @__PURE__ */ d("div", {
136
135
  className: "grid grid-cols-2 gap-4",
137
- children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
136
+ children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
138
137
  className: "text-sm font-medium",
139
138
  children: "Project"
140
- }), /* @__PURE__ */ l("div", {
139
+ }), /* @__PURE__ */ u("div", {
141
140
  className: "mt-1 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground",
142
- children: E.find((e) => e.id === T.projectId)?.name ?? T.projectId
143
- })] }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
141
+ children: D.find((e) => e.id === E.projectId)?.name ?? E.projectId
142
+ })] }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
144
143
  className: "text-sm font-medium",
145
144
  children: "Status"
146
- }), /* @__PURE__ */ l("select", {
147
- className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
148
- value: A.status,
149
- onChange: (e) => j({
150
- ...A,
151
- status: e.target.value
152
- }),
153
- children: [
154
- "PLANNING",
155
- "ACTIVE",
156
- "REVIEW",
157
- "COMPLETED",
158
- "CANCELLED"
159
- ].map((e) => /* @__PURE__ */ l("option", {
160
- value: e,
161
- children: e.toLowerCase().replace(/_/g, " ")
162
- }, e))
145
+ }), /* @__PURE__ */ d("div", {
146
+ className: "mt-1 flex items-start justify-between gap-2",
147
+ children: [/* @__PURE__ */ u("span", {
148
+ 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
154
+ })]
163
155
  })] })]
164
156
  }),
165
- /* @__PURE__ */ u("div", {
157
+ /* @__PURE__ */ d("div", {
166
158
  className: "grid grid-cols-2 gap-4",
167
- children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
159
+ children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
168
160
  className: "text-sm font-medium",
169
161
  children: "Start Date"
170
- }), /* @__PURE__ */ l(g, {
162
+ }), /* @__PURE__ */ u(_, {
171
163
  type: "date",
172
- value: A.startDate,
173
- onChange: (e) => j({
174
- ...A,
164
+ value: j.startDate,
165
+ onChange: (e) => M({
166
+ ...j,
175
167
  startDate: e.target.value
176
168
  }),
177
169
  className: "mt-1"
178
- })] }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
170
+ })] }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
179
171
  className: "text-sm font-medium",
180
172
  children: "End Date"
181
- }), /* @__PURE__ */ l(g, {
173
+ }), /* @__PURE__ */ u(_, {
182
174
  type: "date",
183
- value: A.endDate,
184
- onChange: (e) => j({
185
- ...A,
175
+ value: j.endDate,
176
+ onChange: (e) => M({
177
+ ...j,
186
178
  endDate: e.target.value
187
179
  }),
188
180
  className: "mt-1"
189
181
  })] })]
190
182
  }),
191
- /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
183
+ /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
192
184
  className: "text-sm font-medium",
193
185
  children: "Goal"
194
- }), /* @__PURE__ */ l("textarea", {
186
+ }), /* @__PURE__ */ u("textarea", {
195
187
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]",
196
- value: A.goal,
197
- onChange: (e) => j({
198
- ...A,
188
+ value: j.goal,
189
+ onChange: (e) => M({
190
+ ...j,
199
191
  goal: e.target.value
200
192
  }),
201
193
  placeholder: "Sprint goal..."
202
194
  })] }),
203
- /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
195
+ /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
204
196
  className: "text-sm font-medium",
205
197
  children: "Capacity (story points)"
206
- }), /* @__PURE__ */ l(g, {
198
+ }), /* @__PURE__ */ u(_, {
207
199
  type: "number",
208
- value: A.capacity,
209
- onChange: (e) => j({
210
- ...A,
200
+ value: j.capacity,
201
+ onChange: (e) => M({
202
+ ...j,
211
203
  capacity: e.target.value
212
204
  }),
213
205
  className: "mt-1",
@@ -216,15 +208,15 @@ function y() {
216
208
  ]
217
209
  })] })
218
210
  ]
219
- }) : /* @__PURE__ */ l("div", {
211
+ }) : /* @__PURE__ */ u("div", {
220
212
  className: "p-6 text-muted-foreground",
221
213
  children: "Planning session not found."
222
- }) : /* @__PURE__ */ l("div", {
214
+ }) : /* @__PURE__ */ u("div", {
223
215
  className: "p-6 text-muted-foreground",
224
216
  children: "No planning session selected. Open one from the list."
225
217
  });
226
218
  }
227
219
  //#endregion
228
- export { y as ProjectsPlanningEditPagePage };
220
+ export { b as ProjectsPlanningEditPagePage };
229
221
 
230
222
  //# 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';\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 status: sprint?.status ?? 'PLANNING',\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 statuses = ['PLANNING', 'ACTIVE', 'REVIEW', 'COMPLETED', 'CANCELLED'] as const;\n\n const handleSave = () => {\n if (!sprint) return;\n updateSprint({\n variables: {\n id: sprint.id,\n input: {\n name: form.name || undefined,\n status: form.status || 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 if (loading)\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 <label className=\"text-sm font-medium\">Status</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.status}\n onChange={(e) => setForm({ ...form, status: e.target.value })}\n >\n {statuses.map((s) => (\n <option key={s} value={s}>\n {s.toLowerCase().replace(/_/g, ' ')}\n </option>\n ))}\n </select>\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';\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 if (loading)\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 +1 @@
1
- {"version":3,"file":"ProjectsPlanningPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsPlanningPagePage.tsx"],"names":[],"mappings":"AAyCA,wBAAgB,wBAAwB,4CA8HvC"}
1
+ {"version":3,"file":"ProjectsPlanningPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsPlanningPagePage.tsx"],"names":[],"mappings":"AA8CA,wBAAgB,wBAAwB,4CAoIvC"}
@@ -1,18 +1,23 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
2
  import { detailPath as n, rowLinkProps as r } from "../utils/rowNavigation.js";
3
- import { CalendarClock as i, FolderKanban as a } from "lucide-react";
4
- import { gql as o } from "@apollo/client";
5
- import { useQuery as s } from "@apollo/client/react";
6
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
- import { Badge as u, Card as d, CardContent as f, CardHeader as p, CardTitle as m } from "@burdenoff/fe-libs/ui";
3
+ import { NewSprintDialog as i } from "../sprints/SprintControls.js";
4
+ import { CalendarClock as a, FolderKanban as o } from "lucide-react";
5
+ import { gql as s } from "@apollo/client";
6
+ import { useQuery as c } from "@apollo/client/react";
7
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
8
+ import { Badge as d, Card as f, CardContent as p, CardHeader as m, CardTitle as h } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/planmagnet/pages/ProjectsPlanningPagePage.tsx
9
- var h = o`
10
+ var g = s`
10
11
  query GetSprints($workspaceId: ID!) {
11
12
  planmagnetSprints(workspaceId: $workspaceId, pagination: { first: 100 }) {
12
13
  items {
13
14
  id
14
15
  name
15
16
  projectId
17
+ project {
18
+ id
19
+ name
20
+ }
16
21
  status
17
22
  startDate
18
23
  endDate
@@ -28,102 +33,105 @@ var h = o`
28
33
  totalCount
29
34
  }
30
35
  }
31
- `, g = {
36
+ `, _ = {
32
37
  PLANNING: "bg-blue-100 text-blue-800",
33
38
  ACTIVE: "bg-green-100 text-green-800",
34
39
  REVIEW: "bg-purple-100 text-purple-800",
35
40
  COMPLETED: "bg-gray-100 text-gray-800",
36
41
  CANCELLED: "bg-red-100 text-red-800"
37
42
  };
38
- function _() {
39
- let { workspaceId: o } = e(), _ = t(), { data: v, loading: y, error: b } = s(h, { variables: { workspaceId: o ?? "default" } });
40
- if (y) return /* @__PURE__ */ c("div", {
43
+ function v() {
44
+ let { workspaceId: s } = e(), v = t(), { data: y, loading: b, error: x } = c(g, { variables: { workspaceId: s ?? "default" } });
45
+ if (b) return /* @__PURE__ */ l("div", {
41
46
  className: "flex items-center justify-center p-12",
42
- children: /* @__PURE__ */ c("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
47
+ children: /* @__PURE__ */ l("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
43
48
  });
44
- if (b) return /* @__PURE__ */ l("div", {
49
+ if (x) return /* @__PURE__ */ u("div", {
45
50
  className: "p-6 text-red-500",
46
- children: ["Error loading planning sessions: ", b.message]
51
+ children: ["Error loading planning sessions: ", x.message]
47
52
  });
48
- let x = v?.planmagnetSprints?.items ?? [];
49
- return /* @__PURE__ */ l("div", {
53
+ let S = y?.planmagnetSprints?.items ?? [];
54
+ return /* @__PURE__ */ u("div", {
50
55
  className: "space-y-6 p-6",
51
56
  children: [
52
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
53
- className: "text-2xl font-semibold",
54
- children: "Planning Sessions"
55
- }), /* @__PURE__ */ l("p", {
56
- className: "text-sm text-muted-foreground",
57
- children: [x.length, " sprints across all projects"]
58
- })] }),
59
- /* @__PURE__ */ c("div", {
57
+ /* @__PURE__ */ u("div", {
58
+ className: "flex items-center justify-between",
59
+ children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("h1", {
60
+ className: "text-2xl font-semibold",
61
+ children: "Planning Sessions"
62
+ }), /* @__PURE__ */ u("p", {
63
+ className: "text-sm text-muted-foreground",
64
+ children: [S.length, " sprints across all projects"]
65
+ })] }), /* @__PURE__ */ l(i, { onCreated: (e) => v(n("/projects/planning-detail-page", e)) })]
66
+ }),
67
+ /* @__PURE__ */ l("div", {
60
68
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
61
- children: x.map((e) => {
62
- let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), o = e.capacity ?? 0, s = o > 0 ? Math.round(t / o * 100) : 0;
63
- return /* @__PURE__ */ l(d, {
64
- ...r(() => _(n("/projects/planning-detail-page", e.id)), e.name),
65
- children: [/* @__PURE__ */ c(p, {
69
+ children: S.map((e) => {
70
+ let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), i = e.capacity ?? 0, s = i > 0 ? Math.round(t / i * 100) : 0;
71
+ return /* @__PURE__ */ u(f, {
72
+ ...r(() => v(n("/projects/planning-detail-page", e.id)), e.name),
73
+ children: [/* @__PURE__ */ l(m, {
66
74
  className: "pb-2",
67
- children: /* @__PURE__ */ l("div", {
75
+ children: /* @__PURE__ */ u("div", {
68
76
  className: "flex items-center justify-between",
69
- children: [/* @__PURE__ */ l(m, {
77
+ children: [/* @__PURE__ */ u(h, {
70
78
  className: "text-base flex items-center gap-2",
71
- children: [/* @__PURE__ */ c(i, { className: "h-4 w-4 text-primary" }), e.name]
72
- }), /* @__PURE__ */ c(u, {
79
+ children: [/* @__PURE__ */ l(a, { className: "h-4 w-4 text-primary" }), e.name]
80
+ }), /* @__PURE__ */ l(d, {
73
81
  variant: e.status === "COMPLETED" ? "default" : "secondary",
74
82
  className: "capitalize",
75
83
  children: e.status.toLowerCase().replace("_", " ")
76
84
  })]
77
85
  })
78
- }), /* @__PURE__ */ l(f, {
86
+ }), /* @__PURE__ */ u(p, {
79
87
  className: "space-y-3",
80
88
  children: [
81
- /* @__PURE__ */ l("div", {
89
+ /* @__PURE__ */ u("div", {
82
90
  className: "flex gap-2",
83
- children: [/* @__PURE__ */ c("span", {
84
- className: `text-xs px-2 py-0.5 rounded-full capitalize ${g[e.status] ?? "bg-gray-100"}`,
91
+ children: [/* @__PURE__ */ l("span", {
92
+ className: `text-xs px-2 py-0.5 rounded-full capitalize ${_[e.status] ?? "bg-gray-100"}`,
85
93
  children: e.status.toLowerCase().replace("_", " ")
86
- }), /* @__PURE__ */ l("span", {
94
+ }), /* @__PURE__ */ u("span", {
87
95
  className: "text-xs text-muted-foreground flex items-center gap-1",
88
- children: [/* @__PURE__ */ c(a, { className: "h-3 w-3" }), e.projectId]
96
+ children: [/* @__PURE__ */ l(o, { className: "h-3 w-3" }), e.project?.name ?? "Unknown project"]
89
97
  })]
90
98
  }),
91
- e.goal && /* @__PURE__ */ c("p", {
99
+ e.goal && /* @__PURE__ */ l("p", {
92
100
  className: "text-sm text-muted-foreground",
93
101
  children: e.goal
94
102
  }),
95
- /* @__PURE__ */ l("div", {
103
+ /* @__PURE__ */ u("div", {
96
104
  className: "flex gap-3 text-xs text-muted-foreground",
97
- children: [/* @__PURE__ */ l("span", {
105
+ children: [/* @__PURE__ */ u("span", {
98
106
  className: "flex items-center gap-1",
99
107
  children: [
100
- /* @__PURE__ */ c(i, { className: "h-3 w-3" }),
108
+ /* @__PURE__ */ l(a, { className: "h-3 w-3" }),
101
109
  e.startDate ? new Date(e.startDate).toLocaleDateString() : "—",
102
110
  " -",
103
111
  " ",
104
112
  e.endDate ? new Date(e.endDate).toLocaleDateString() : "—"
105
113
  ]
106
- }), /* @__PURE__ */ l("span", { children: [e.workItems.length, " work items"] })]
114
+ }), /* @__PURE__ */ u("span", { children: [e.workItems.length, " work items"] })]
107
115
  }),
108
- o > 0 && /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ l("div", {
116
+ i > 0 && /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ u("div", {
109
117
  className: "flex justify-between text-xs mb-1",
110
- children: [/* @__PURE__ */ c("span", {
118
+ children: [/* @__PURE__ */ l("span", {
111
119
  className: "text-muted-foreground",
112
120
  children: "Capacity"
113
- }), /* @__PURE__ */ l("span", {
121
+ }), /* @__PURE__ */ u("span", {
114
122
  className: "font-medium",
115
123
  children: [
116
124
  t,
117
125
  "/",
118
- o,
126
+ i,
119
127
  " pts (",
120
128
  s,
121
129
  "%)"
122
130
  ]
123
131
  })]
124
- }), /* @__PURE__ */ c("div", {
132
+ }), /* @__PURE__ */ l("div", {
125
133
  className: "w-full h-2 rounded-full bg-muted overflow-hidden",
126
- children: /* @__PURE__ */ c("div", {
134
+ children: /* @__PURE__ */ l("div", {
127
135
  className: `h-full rounded-full ${s > 90 ? "bg-red-400" : "bg-primary"}`,
128
136
  style: { width: `${Math.min(s, 100)}%` }
129
137
  })
@@ -133,7 +141,7 @@ function _() {
133
141
  }, e.id);
134
142
  })
135
143
  }),
136
- x.length === 0 && /* @__PURE__ */ c("p", {
144
+ S.length === 0 && /* @__PURE__ */ l("p", {
137
145
  className: "text-center text-muted-foreground py-8",
138
146
  children: "No planning sessions found."
139
147
  })
@@ -141,6 +149,6 @@ function _() {
141
149
  });
142
150
  }
143
151
  //#endregion
144
- export { _ as ProjectsPlanningPagePage };
152
+ export { v as ProjectsPlanningPagePage };
145
153
 
146
154
  //# sourceMappingURL=ProjectsPlanningPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsPlanningPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsPlanningPagePage.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 { CalendarClock, FolderKanban } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps, detailPath } from '../utils/rowNavigation';\n\nconst GET_SPRINTS = gql`\n query GetSprints($workspaceId: ID!) {\n planmagnetSprints(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n projectId\n status\n startDate\n endDate\n goal\n capacity\n velocity\n workItems {\n id\n status\n storyPoints\n }\n }\n totalCount\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n PLANNING: 'bg-blue-100 text-blue-800',\n ACTIVE: 'bg-green-100 text-green-800',\n REVIEW: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-gray-100 text-gray-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function ProjectsPlanningPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\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_SPRINTS, {\n variables: { workspaceId: workspaceId ?? 'default' },\n });\n\n if (loading)\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)\n return <div className=\"p-6 text-red-500\">Error loading planning sessions: {error.message}</div>;\n\n const sprints = data?.planmagnetSprints?.items ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Planning Sessions</h1>\n <p className=\"text-sm text-muted-foreground\">\n {sprints.length} sprints across all projects\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {sprints.map(\n (sprint: {\n id: string;\n name: string;\n projectId: string;\n status: string;\n startDate: string | null;\n endDate: string | null;\n goal: string | null;\n capacity: number | null;\n velocity: number | null;\n workItems: { id: string; status: string; storyPoints: number | null }[];\n }) => {\n const totalPoints = sprint.workItems.reduce(\n (sum: number, wi: { storyPoints: number | null }) => sum + (wi.storyPoints ?? 0),\n 0\n );\n const allocatedCapacity = sprint.capacity ?? 0;\n const capPct =\n allocatedCapacity > 0 ? Math.round((totalPoints / allocatedCapacity) * 100) : 0;\n return (\n <Card\n key={sprint.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/planning-detail-page', sprint.id)),\n sprint.name\n )}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base flex items-center gap-2\">\n <CalendarClock className=\"h-4 w-4 text-primary\" />\n {sprint.name}\n </CardTitle>\n <Badge\n variant={sprint.status === 'COMPLETED' ? 'default' : 'secondary'}\n className=\"capitalize\"\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"flex gap-2\">\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[sprint.status] ?? 'bg-gray-100'}`}\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </span>\n <span className=\"text-xs text-muted-foreground flex items-center gap-1\">\n <FolderKanban className=\"h-3 w-3\" />\n {sprint.projectId}\n </span>\n </div>\n {sprint.goal && <p className=\"text-sm text-muted-foreground\">{sprint.goal}</p>}\n <div className=\"flex gap-3 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <CalendarClock className=\"h-3 w-3\" />\n {sprint.startDate\n ? new Date(sprint.startDate).toLocaleDateString()\n : '—'} -{' '}\n {sprint.endDate ? new Date(sprint.endDate).toLocaleDateString() : '—'}\n </span>\n <span>{sprint.workItems.length} work items</span>\n </div>\n {allocatedCapacity > 0 && (\n <div>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-muted-foreground\">Capacity</span>\n <span className=\"font-medium\">\n {totalPoints}/{allocatedCapacity} pts ({capPct}%)\n </span>\n </div>\n <div className=\"w-full h-2 rounded-full bg-muted overflow-hidden\">\n <div\n className={`h-full rounded-full ${capPct > 90 ? 'bg-red-400' : 'bg-primary'}`}\n style={{ width: `${Math.min(capPct, 100)}%` }}\n />\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n );\n }\n )}\n </div>\n {sprints.length === 0 && (\n <p className=\"text-center text-muted-foreground py-8\">No planning sessions found.</p>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectsPlanningPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsPlanningPagePage.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 { CalendarClock, FolderKanban } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps, detailPath } from '../utils/rowNavigation';\nimport { NewSprintDialog } from '../sprints/SprintControls';\n\nconst GET_SPRINTS = gql`\n query GetSprints($workspaceId: ID!) {\n planmagnetSprints(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n projectId\n project {\n id\n name\n }\n status\n startDate\n endDate\n goal\n capacity\n velocity\n workItems {\n id\n status\n storyPoints\n }\n }\n totalCount\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n PLANNING: 'bg-blue-100 text-blue-800',\n ACTIVE: 'bg-green-100 text-green-800',\n REVIEW: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-gray-100 text-gray-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function ProjectsPlanningPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\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_SPRINTS, {\n variables: { workspaceId: workspaceId ?? 'default' },\n });\n\n if (loading)\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)\n return <div className=\"p-6 text-red-500\">Error loading planning sessions: {error.message}</div>;\n\n const sprints = data?.planmagnetSprints?.items ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Planning Sessions</h1>\n <p className=\"text-sm text-muted-foreground\">\n {sprints.length} sprints across all projects\n </p>\n </div>\n <NewSprintDialog\n onCreated={(id) => navigate(detailPath('/projects/planning-detail-page', id))}\n />\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {sprints.map(\n (sprint: {\n id: string;\n name: string;\n projectId: string;\n project: { id: string; name: string } | null;\n status: string;\n startDate: string | null;\n endDate: string | null;\n goal: string | null;\n capacity: number | null;\n velocity: number | null;\n workItems: { id: string; status: string; storyPoints: number | null }[];\n }) => {\n const totalPoints = sprint.workItems.reduce(\n (sum: number, wi: { storyPoints: number | null }) => sum + (wi.storyPoints ?? 0),\n 0\n );\n const allocatedCapacity = sprint.capacity ?? 0;\n const capPct =\n allocatedCapacity > 0 ? Math.round((totalPoints / allocatedCapacity) * 100) : 0;\n return (\n <Card\n key={sprint.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/planning-detail-page', sprint.id)),\n sprint.name\n )}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base flex items-center gap-2\">\n <CalendarClock className=\"h-4 w-4 text-primary\" />\n {sprint.name}\n </CardTitle>\n <Badge\n variant={sprint.status === 'COMPLETED' ? 'default' : 'secondary'}\n className=\"capitalize\"\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"flex gap-2\">\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[sprint.status] ?? 'bg-gray-100'}`}\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </span>\n <span className=\"text-xs text-muted-foreground flex items-center gap-1\">\n <FolderKanban className=\"h-3 w-3\" />\n {sprint.project?.name ?? 'Unknown project'}\n </span>\n </div>\n {sprint.goal && <p className=\"text-sm text-muted-foreground\">{sprint.goal}</p>}\n <div className=\"flex gap-3 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <CalendarClock className=\"h-3 w-3\" />\n {sprint.startDate\n ? new Date(sprint.startDate).toLocaleDateString()\n : '—'} -{' '}\n {sprint.endDate ? new Date(sprint.endDate).toLocaleDateString() : '—'}\n </span>\n <span>{sprint.workItems.length} work items</span>\n </div>\n {allocatedCapacity > 0 && (\n <div>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-muted-foreground\">Capacity</span>\n <span className=\"font-medium\">\n {totalPoints}/{allocatedCapacity} pts ({capPct}%)\n </span>\n </div>\n <div className=\"w-full h-2 rounded-full bg-muted overflow-hidden\">\n <div\n className={`h-full rounded-full ${capPct > 90 ? 'bg-red-400' : 'bg-primary'}`}\n style={{ width: `${Math.min(capPct, 100)}%` }}\n />\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n );\n }\n )}\n </div>\n {sprints.length === 0 && (\n <p className=\"text-center text-muted-foreground py-8\">No planning sessions found.</p>\n )}\n </div>\n );\n}\n"],"mappings":"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"}