@burdenoff/microfe-planmagnet 2026.928.8 → 2026.928.10

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 (42) hide show
  1. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoot.js +1 -1
  3. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  4. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  5. package/dist/planmagnet/PlanMagnetRoutes.js +219 -207
  6. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  7. package/dist/planmagnet/controls/WorkItemControls.d.ts +21 -0
  8. package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -1
  9. package/dist/planmagnet/controls/WorkItemControls.js +34 -15
  10. package/dist/planmagnet/controls/WorkItemControls.js.map +1 -1
  11. package/dist/planmagnet/pages/ProductsCreateProductPagePage.d.ts.map +1 -1
  12. package/dist/planmagnet/pages/ProductsCreateProductPagePage.js +198 -99
  13. package/dist/planmagnet/pages/ProductsCreateProductPagePage.js.map +1 -1
  14. package/dist/planmagnet/pages/ProductsEditProductPagePage.d.ts.map +1 -1
  15. package/dist/planmagnet/pages/ProductsEditProductPagePage.js +260 -170
  16. package/dist/planmagnet/pages/ProductsEditProductPagePage.js.map +1 -1
  17. package/dist/planmagnet/pages/ProductsEditRoadmapPagePage.d.ts +2 -0
  18. package/dist/planmagnet/pages/ProductsEditRoadmapPagePage.d.ts.map +1 -0
  19. package/dist/planmagnet/pages/ProductsEditRoadmapPagePage.js +283 -0
  20. package/dist/planmagnet/pages/ProductsEditRoadmapPagePage.js.map +1 -0
  21. package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
  22. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +166 -246
  23. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
  24. package/dist/planmagnet/pages/ProductsProductsPagePage.d.ts.map +1 -1
  25. package/dist/planmagnet/pages/ProductsProductsPagePage.js +147 -117
  26. package/dist/planmagnet/pages/ProductsProductsPagePage.js.map +1 -1
  27. package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts +0 -7
  28. package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts.map +1 -1
  29. package/dist/planmagnet/pages/ReportsReportsPagePage.js +517 -39
  30. package/dist/planmagnet/pages/ReportsReportsPagePage.js.map +1 -1
  31. package/dist/planmagnet/pages/TasksMyWorkPagePage.d.ts +2 -0
  32. package/dist/planmagnet/pages/TasksMyWorkPagePage.d.ts.map +1 -0
  33. package/dist/planmagnet/pages/TasksMyWorkPagePage.js +257 -0
  34. package/dist/planmagnet/pages/TasksMyWorkPagePage.js.map +1 -0
  35. package/dist/planmagnet/product/ProductControls.d.ts +52 -0
  36. package/dist/planmagnet/product/ProductControls.d.ts.map +1 -0
  37. package/dist/planmagnet/product/ProductControls.js +780 -0
  38. package/dist/planmagnet/product/ProductControls.js.map +1 -0
  39. package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -1
  40. package/dist/planmagnet/roadmaps/RoadmapControls.js +1 -1
  41. package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -1
  42. package/package.json +1 -1
@@ -1,278 +1,368 @@
1
- import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
- import { PersonName as n } from "../people/People.js";
3
- import { LEAVES_PAGE_CONTEXT as r, throwOnError as i } from "../utils/mutationResult.js";
4
- import { ConfirmButton as a } from "../controls/ConfirmButton.js";
5
- import { PlanningFocusBadge as o, PlanningFocusSelect as s } from "../roadmaps/planningFocus.js";
6
- import { useMemo as c, useState as l } from "react";
7
- import { ArrowLeft as u, Loader2 as d, Package as f, Save as p, Trash2 as m } from "lucide-react";
8
- import { useParams as h } from "react-router";
9
- import { gql as g } from "@apollo/client";
10
- import { useMutation as _, useQuery as v } from "@apollo/client/react";
11
- import { jsx as y, jsxs as b } from "react/jsx-runtime";
12
- import { Button as x, Card as S, CardContent as C, CardHeader as w, CardTitle as T, Input as E } from "@burdenoff/fe-libs/ui";
1
+ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
+ import { PersonName as t } from "../people/People.js";
3
+ import { throwOnError as n } from "../utils/mutationResult.js";
4
+ import { useEntityId as r } from "../hooks/useEntityId.js";
5
+ import { enumLabel as i } from "../controls/WorkItemControls.js";
6
+ import { detailPath as a } from "../utils/rowNavigation.js";
7
+ import { ProductHeaderActions as o } from "../product/ProductControls.js";
8
+ import { useMemo as s, useState as c } from "react";
9
+ import { ArrowLeft as l, Loader2 as u, Package as d, Save as f } from "lucide-react";
10
+ import { gql as p } from "@apollo/client";
11
+ import { useMutation as m, useQuery as h } from "@apollo/client/react";
12
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
13
+ import { Button as v, Card as y, CardContent as b, CardHeader as x, CardTitle as S, Input as C } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/planmagnet/pages/ProductsEditProductPagePage.tsx
14
- var D = g`
15
- query GetRoadmapForEdit($id: ID!) {
16
- planmagnetRoadmap(id: $id) {
15
+ var w = [
16
+ "CONCEPT",
17
+ "DEVELOPMENT",
18
+ "BETA",
19
+ "LAUNCHED",
20
+ "MATURE",
21
+ "DEPRECATED"
22
+ ], T = p`
23
+ query GetProductForEdit($id: ID!) {
24
+ planmagnetProduct(id: $id) {
17
25
  id
18
26
  workspaceId
19
27
  name
20
28
  description
21
- type
22
- planningFocus
23
- isPublic
29
+ vision
30
+ lifecycleStage
24
31
  ownerId
32
+ archivedAt
33
+ northStar {
34
+ name
35
+ unit
36
+ target
37
+ current
38
+ window
39
+ }
25
40
  createdAt
26
41
  updatedAt
27
- items {
28
- id
29
- status
30
- }
31
42
  }
32
43
  }
33
- `, O = g`
34
- mutation UpdateRoadmap($id: ID!, $input: PlanmagnetUpdateRoadmapInput!) {
35
- planmagnetUpdateRoadmap(id: $id, input: $input) {
44
+ `, E = p`
45
+ mutation UpdateProduct($id: ID!, $input: PlanmagnetUpdateProductInput!) {
46
+ planmagnetUpdateProduct(id: $id, input: $input) {
36
47
  id
37
48
  name
38
49
  description
39
- type
40
- planningFocus
41
- isPublic
50
+ vision
51
+ lifecycleStage
42
52
  ownerId
53
+ northStar {
54
+ name
55
+ unit
56
+ target
57
+ current
58
+ window
59
+ }
43
60
  updatedAt
44
61
  }
45
62
  }
46
- `, k = g`
47
- mutation DeleteRoadmap($id: ID!) {
48
- planmagnetDeleteRoadmap(id: $id)
49
- }
50
- `;
51
- function A() {
52
- let { workspaceId: g } = e(), A = t(), j = h().id ?? "", { data: M, loading: N, error: P } = v(D, {
53
- variables: { id: j },
54
- skip: !j
55
- }), [F, { loading: I }] = _(O, {
63
+ `, D = {
64
+ name: "",
65
+ unit: "",
66
+ target: "",
67
+ current: "",
68
+ window: ""
69
+ };
70
+ function O() {
71
+ let p = e(), O = r("productId") ?? "", { data: k, loading: A, error: j } = h(T, {
72
+ variables: { id: O },
73
+ skip: !O
74
+ }), [M, { loading: N }] = m(E, {
56
75
  refetchQueries: [
57
- "ListRoadmaps",
58
- "ListRoadmapsPage",
59
- "GetRoadmapForEdit",
60
- "GetRoadmapDetail",
61
- "GetRoadmapDetailPage"
76
+ "GetProducts",
77
+ "GetProductForEdit",
78
+ "GetProductDetail"
62
79
  ],
63
80
  awaitRefetchQueries: !0
64
- }), [L, { loading: R }] = _(k, {
65
- refetchQueries: ["ListRoadmaps", "ListRoadmapsPage"],
66
- context: r
67
- }), [z, B] = l(null), [V, H] = l(!1), U = M?.planmagnetRoadmap, W = c(() => ({
68
- name: U?.name ?? "",
69
- description: U?.description ?? "",
70
- planningFocus: U?.planningFocus ?? null,
71
- isPublic: U?.isPublic ?? !1
72
- }), [U]), [G, K] = l({}), q = {
73
- ...W,
81
+ }), [P, F] = c(null), [I, L] = c(!1), R = k?.planmagnetProduct, z = s(() => ({
82
+ name: R?.name ?? "",
83
+ description: R?.description ?? "",
84
+ vision: R?.vision ?? "",
85
+ lifecycleStage: R?.lifecycleStage ?? "CONCEPT"
86
+ }), [R]), B = s(() => R?.northStar ? {
87
+ name: R.northStar.name,
88
+ unit: R.northStar.unit,
89
+ target: String(R.northStar.target),
90
+ current: String(R.northStar.current),
91
+ window: R.northStar.window
92
+ } : D, [R]), [V, H] = c({}), U = {
93
+ ...z,
94
+ ...V
95
+ }, W = (e) => H(e), [G, K] = c({}), q = {
96
+ ...B,
74
97
  ...G
75
- }, J = (e) => K(e), Y = async () => {
76
- B(null), H(!1);
98
+ }, J = (e) => K(e), Y = Object.values(q).some((e) => e.trim() !== ""), X = q.name.trim() && q.unit.trim() && q.window.trim() && q.target.trim() !== "" && !Number.isNaN(Number(q.target)) && q.current.trim() !== "" && !Number.isNaN(Number(q.current)), Z = async () => {
99
+ F(null), L(!1);
77
100
  try {
78
- await i(F({ variables: {
79
- id: j,
101
+ await n(M({ variables: {
102
+ id: O,
80
103
  input: {
81
- name: q.name,
82
- description: q.description.trim() || null,
83
- planningFocus: q.planningFocus,
84
- isPublic: q.isPublic
104
+ name: U.name,
105
+ description: U.description.trim() || null,
106
+ vision: U.vision,
107
+ lifecycleStage: U.lifecycleStage,
108
+ ...X ? { northStar: {
109
+ name: q.name,
110
+ unit: q.unit,
111
+ target: Number(q.target),
112
+ current: Number(q.current),
113
+ window: q.window
114
+ } } : {}
85
115
  }
86
- } })), H(!0);
116
+ } })), L(!0);
87
117
  } catch (e) {
88
- B(e instanceof Error ? e.message : "The product could not be saved.");
89
- }
90
- }, X = async () => {
91
- B(null);
92
- try {
93
- await i(L({ variables: { id: j } })), A("/products/products-page");
94
- } catch (e) {
95
- B(e instanceof Error ? e.message : "The product could not be deleted.");
118
+ F(e instanceof Error ? e.message : "The product could not be saved.");
96
119
  }
97
120
  };
98
- return N && !M ? /* @__PURE__ */ y("div", {
121
+ return A && !k ? /* @__PURE__ */ g("div", {
99
122
  className: "flex items-center justify-center p-12",
100
- children: /* @__PURE__ */ y(d, { className: "h-8 w-8 animate-spin text-muted-foreground" })
101
- }) : P ? /* @__PURE__ */ b("div", {
123
+ children: /* @__PURE__ */ g(u, { className: "h-8 w-8 animate-spin text-muted-foreground" })
124
+ }) : j ? /* @__PURE__ */ _("div", {
102
125
  className: "p-6 text-destructive",
103
- children: ["Failed to load product: ", P.message]
104
- }) : U ? /* @__PURE__ */ b("div", {
126
+ children: ["Failed to load product: ", j.message]
127
+ }) : R ? /* @__PURE__ */ _("div", {
105
128
  className: "space-y-6 p-6",
106
129
  children: [
107
- /* @__PURE__ */ b("div", {
130
+ /* @__PURE__ */ _("div", {
108
131
  className: "flex items-center justify-between",
109
- children: [/* @__PURE__ */ b("div", {
132
+ children: [/* @__PURE__ */ _("div", {
110
133
  className: "flex items-center gap-3",
111
- children: [/* @__PURE__ */ y(x, {
134
+ children: [/* @__PURE__ */ g(v, {
112
135
  variant: "ghost",
113
136
  size: "sm",
114
- onClick: () => A("/products/products-page"),
115
- children: /* @__PURE__ */ y(u, { className: "h-4 w-4" })
116
- }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h1", {
137
+ onClick: () => p(a("/products/product-detail-page", R.id)),
138
+ children: /* @__PURE__ */ g(l, { className: "h-4 w-4" })
139
+ }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("h1", {
117
140
  className: "text-2xl font-semibold",
118
141
  children: "Edit Product"
119
- }), /* @__PURE__ */ b("p", {
142
+ }), /* @__PURE__ */ _("p", {
120
143
  className: "text-sm text-muted-foreground",
121
- children: ["Editing ", U.name]
144
+ children: ["Editing ", R.name]
122
145
  })] })]
123
- }), /* @__PURE__ */ b(x, {
124
- size: "sm",
125
- onClick: Y,
126
- disabled: I,
127
- children: [I ? /* @__PURE__ */ y(d, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ y(p, { className: "mr-1 h-4 w-4" }), "Save Changes"]
146
+ }), /* @__PURE__ */ _("div", {
147
+ className: "flex items-center gap-2",
148
+ children: [/* @__PURE__ */ _(v, {
149
+ size: "sm",
150
+ onClick: () => void Z(),
151
+ disabled: N || Y && !X,
152
+ children: [N ? /* @__PURE__ */ g(u, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ g(f, { className: "mr-1 h-4 w-4" }), "Save Changes"]
153
+ }), /* @__PURE__ */ g(o, {
154
+ productId: R.id,
155
+ name: R.name,
156
+ archivedAt: R.archivedAt
157
+ })]
128
158
  })]
129
159
  }),
130
- V && /* @__PURE__ */ y("div", {
160
+ I && /* @__PURE__ */ g("div", {
131
161
  role: "status",
132
162
  className: "p-3 bg-muted text-status-success-text rounded-md text-sm",
133
163
  children: "Changes saved."
134
164
  }),
135
- z && /* @__PURE__ */ y("div", {
165
+ P && /* @__PURE__ */ g("div", {
136
166
  role: "alert",
137
167
  className: "p-3 rounded-md bg-destructive/10 text-destructive text-sm",
138
- children: z
168
+ children: P
139
169
  }),
140
- /* @__PURE__ */ b("div", {
170
+ /* @__PURE__ */ _("div", {
141
171
  className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
142
- children: [/* @__PURE__ */ y("div", {
172
+ children: [/* @__PURE__ */ _("div", {
143
173
  className: "lg:col-span-2 space-y-6",
144
- children: /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(w, { children: /* @__PURE__ */ y(T, { children: "Basic Information" }) }), /* @__PURE__ */ b(C, {
174
+ children: [/* @__PURE__ */ _(y, { children: [/* @__PURE__ */ g(x, { children: /* @__PURE__ */ g(S, { children: "Basic Information" }) }), /* @__PURE__ */ _(b, {
145
175
  className: "space-y-4",
146
176
  children: [
147
- /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
177
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
148
178
  className: "text-sm font-medium",
149
179
  children: "Product Name"
150
- }), /* @__PURE__ */ y(E, {
151
- value: q.name,
152
- onChange: (e) => J({
153
- ...q,
180
+ }), /* @__PURE__ */ g(C, {
181
+ value: U.name,
182
+ onChange: (e) => W({
183
+ ...U,
154
184
  name: e.target.value
155
185
  }),
156
186
  className: "mt-1"
157
187
  })] }),
158
- /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
188
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
159
189
  className: "text-sm font-medium",
160
190
  children: "Description"
161
- }), /* @__PURE__ */ y("textarea", {
162
- className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]",
163
- value: q.description,
164
- onChange: (e) => J({
165
- ...q,
191
+ }), /* @__PURE__ */ g("textarea", {
192
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]",
193
+ value: U.description,
194
+ onChange: (e) => W({
195
+ ...U,
166
196
  description: e.target.value
167
197
  })
168
198
  })] }),
169
- /* @__PURE__ */ y(s, {
170
- value: q.planningFocus,
171
- onChange: (e) => J({
172
- ...q,
173
- planningFocus: e
199
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
200
+ className: "text-sm font-medium",
201
+ children: "Vision"
202
+ }), /* @__PURE__ */ g("textarea", {
203
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]",
204
+ value: U.vision,
205
+ onChange: (e) => W({
206
+ ...U,
207
+ vision: e.target.value
174
208
  })
175
- }),
176
- /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
209
+ })] }),
210
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
177
211
  className: "text-sm font-medium",
178
- children: "Visibility"
179
- }), /* @__PURE__ */ y("div", {
180
- className: "mt-1 flex gap-2",
181
- children: [!1, !0].map((e) => /* @__PURE__ */ y("button", {
182
- onClick: () => J({
183
- ...q,
184
- isPublic: e
185
- }),
186
- className: `rounded-md px-3 py-1.5 text-sm ${q.isPublic === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
187
- children: e ? "Public" : "Private"
188
- }, String(e)))
212
+ children: "Lifecycle Stage"
213
+ }), /* @__PURE__ */ g("select", {
214
+ "aria-label": "Lifecycle stage",
215
+ "data-testid": "product-lifecycle-stage",
216
+ className: "mt-1 w-full rounded-md border border-input bg-background px-2 py-1.5 text-sm",
217
+ value: U.lifecycleStage,
218
+ onChange: (e) => W({
219
+ ...U,
220
+ lifecycleStage: e.target.value
221
+ }),
222
+ children: w.map((e) => /* @__PURE__ */ g("option", {
223
+ value: e,
224
+ children: i(e)
225
+ }, e))
189
226
  })] })
190
227
  ]
191
- })] })
192
- }), /* @__PURE__ */ b("div", {
228
+ })] }), /* @__PURE__ */ _(y, { children: [/* @__PURE__ */ g(x, { children: /* @__PURE__ */ g(S, { children: "North Star metric" }) }), /* @__PURE__ */ _(b, {
229
+ className: "space-y-4",
230
+ children: [/* @__PURE__ */ _("div", {
231
+ className: "grid grid-cols-2 gap-4",
232
+ children: [
233
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
234
+ className: "text-sm font-medium",
235
+ children: "Metric name"
236
+ }), /* @__PURE__ */ g(C, {
237
+ value: q.name,
238
+ onChange: (e) => J({
239
+ ...q,
240
+ name: e.target.value
241
+ }),
242
+ className: "mt-1"
243
+ })] }),
244
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
245
+ className: "text-sm font-medium",
246
+ children: "Unit"
247
+ }), /* @__PURE__ */ g(C, {
248
+ value: q.unit,
249
+ onChange: (e) => J({
250
+ ...q,
251
+ unit: e.target.value
252
+ }),
253
+ className: "mt-1"
254
+ })] }),
255
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
256
+ className: "text-sm font-medium",
257
+ children: "Target"
258
+ }), /* @__PURE__ */ g(C, {
259
+ type: "number",
260
+ value: q.target,
261
+ onChange: (e) => J({
262
+ ...q,
263
+ target: e.target.value
264
+ }),
265
+ className: "mt-1"
266
+ })] }),
267
+ /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
268
+ className: "text-sm font-medium",
269
+ children: "Current"
270
+ }), /* @__PURE__ */ g(C, {
271
+ type: "number",
272
+ value: q.current,
273
+ onChange: (e) => J({
274
+ ...q,
275
+ current: e.target.value
276
+ }),
277
+ className: "mt-1"
278
+ })] }),
279
+ /* @__PURE__ */ _("div", {
280
+ className: "col-span-2",
281
+ children: [/* @__PURE__ */ g("label", {
282
+ className: "text-sm font-medium",
283
+ children: "Window"
284
+ }), /* @__PURE__ */ g(C, {
285
+ value: q.window,
286
+ onChange: (e) => J({
287
+ ...q,
288
+ window: e.target.value
289
+ }),
290
+ className: "mt-1"
291
+ })]
292
+ })
293
+ ]
294
+ }), Y && !X && /* @__PURE__ */ g("p", {
295
+ className: "text-xs text-destructive",
296
+ children: "Fill in every North Star field (or clear them all) — name, unit, target, current and window are all required together."
297
+ })]
298
+ })] })]
299
+ }), /* @__PURE__ */ g("div", {
193
300
  className: "space-y-6",
194
- children: [/* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(w, { children: /* @__PURE__ */ y(T, { children: "Product Info" }) }), /* @__PURE__ */ b(C, {
301
+ children: /* @__PURE__ */ _(y, { children: [/* @__PURE__ */ g(x, { children: /* @__PURE__ */ g(S, { children: "Product Info" }) }), /* @__PURE__ */ _(b, {
195
302
  className: "space-y-3 text-sm",
196
303
  children: [
197
- /* @__PURE__ */ b("div", {
304
+ /* @__PURE__ */ _("div", {
198
305
  className: "flex items-center gap-2",
199
- children: [/* @__PURE__ */ y(f, { className: "h-4 w-4 text-primary" }), /* @__PURE__ */ y("span", {
306
+ children: [/* @__PURE__ */ g(d, { className: "h-4 w-4 text-primary" }), /* @__PURE__ */ g("span", {
200
307
  className: "font-medium",
201
- children: U.name
308
+ children: R.name
202
309
  })]
203
310
  }),
204
- /* @__PURE__ */ b("div", {
311
+ /* @__PURE__ */ _("div", {
205
312
  className: "flex justify-between",
206
- children: [/* @__PURE__ */ y("span", {
313
+ children: [/* @__PURE__ */ g("span", {
207
314
  className: "text-muted-foreground",
208
- children: "Items"
209
- }), /* @__PURE__ */ y("span", {
210
- className: "font-medium",
211
- children: U.items?.length ?? 0
315
+ children: "Lifecycle stage"
316
+ }), /* @__PURE__ */ g("span", {
317
+ className: "font-medium capitalize",
318
+ children: i(R.lifecycleStage)
212
319
  })]
213
320
  }),
214
- /* @__PURE__ */ b("div", {
321
+ /* @__PURE__ */ _("div", {
215
322
  className: "flex justify-between",
216
- children: [/* @__PURE__ */ y("span", {
323
+ children: [/* @__PURE__ */ g("span", {
217
324
  className: "text-muted-foreground",
218
- children: "Planning focus"
219
- }), /* @__PURE__ */ y(o, { focus: U.planningFocus })]
220
- }),
221
- /* @__PURE__ */ b("div", {
222
- className: "flex justify-between",
223
- children: [/* @__PURE__ */ y("span", {
224
- className: "text-muted-foreground",
225
- children: "Visibility"
226
- }), /* @__PURE__ */ y("span", {
325
+ children: "Status"
326
+ }), /* @__PURE__ */ g("span", {
227
327
  className: "font-medium",
228
- children: U.isPublic ? "Public" : "Private"
328
+ children: R.archivedAt ? "Archived" : "Active"
229
329
  })]
230
330
  }),
231
- /* @__PURE__ */ b("div", {
331
+ /* @__PURE__ */ _("div", {
232
332
  className: "flex justify-between",
233
- children: [/* @__PURE__ */ y("span", {
333
+ children: [/* @__PURE__ */ g("span", {
234
334
  className: "text-muted-foreground",
235
335
  children: "Owner"
236
- }), /* @__PURE__ */ y("span", {
336
+ }), /* @__PURE__ */ g("span", {
237
337
  className: "font-medium",
238
- children: /* @__PURE__ */ y(n, { id: U.ownerId })
338
+ children: /* @__PURE__ */ g(t, { id: R.ownerId })
239
339
  })]
240
340
  }),
241
- /* @__PURE__ */ b("div", {
341
+ /* @__PURE__ */ _("div", {
242
342
  className: "flex justify-between",
243
- children: [/* @__PURE__ */ y("span", {
343
+ children: [/* @__PURE__ */ g("span", {
244
344
  className: "text-muted-foreground",
245
345
  children: "Created"
246
- }), /* @__PURE__ */ y("span", { children: new Date(U.createdAt).toLocaleDateString() })]
346
+ }), /* @__PURE__ */ g("span", { children: new Date(R.createdAt).toLocaleDateString() })]
247
347
  }),
248
- /* @__PURE__ */ b("div", {
348
+ /* @__PURE__ */ _("div", {
249
349
  className: "flex justify-between",
250
- children: [/* @__PURE__ */ y("span", {
350
+ children: [/* @__PURE__ */ g("span", {
251
351
  className: "text-muted-foreground",
252
352
  children: "Updated"
253
- }), /* @__PURE__ */ y("span", { children: new Date(U.updatedAt).toLocaleDateString() })]
353
+ }), /* @__PURE__ */ g("span", { children: new Date(R.updatedAt).toLocaleDateString() })]
254
354
  })
255
355
  ]
256
- })] }), /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(w, { children: /* @__PURE__ */ y(T, { children: "Danger Zone" }) }), /* @__PURE__ */ y(C, { children: /* @__PURE__ */ y(a, {
257
- label: R ? "Deleting…" : "Delete product",
258
- variant: "outline",
259
- icon: /* @__PURE__ */ y(m, { className: "mr-1 h-4 w-4" }),
260
- title: `Delete ${U.name}?`,
261
- description: "The product's roadmap and its items are deleted. This cannot be undone here.",
262
- confirmLabel: "Delete product",
263
- destructive: !0,
264
- disabled: R,
265
- onConfirm: () => void X()
266
- }) })] })]
356
+ })] })
267
357
  })]
268
358
  })
269
359
  ]
270
- }) : /* @__PURE__ */ y("div", {
360
+ }) : /* @__PURE__ */ g("div", {
271
361
  className: "p-6 text-muted-foreground",
272
362
  children: "No product found."
273
363
  });
274
364
  }
275
365
  //#endregion
276
- export { A as ProductsEditProductPagePage };
366
+ export { O as ProductsEditProductPagePage };
277
367
 
278
368
  //# sourceMappingURL=ProductsEditProductPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsEditProductPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsEditProductPagePage.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 {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Button,\n Input,\n Badge,\n} from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft, Package, Loader2, Trash2 } from 'lucide-react';\nimport { throwOnError, LEAVES_PAGE_CONTEXT } from '../utils/mutationResult';\nimport { ConfirmButton } from '../controls/ConfirmButton';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { useParams } from 'react-router';\nimport { PersonName } from '../people/People';\nimport {\n PlanningFocusBadge,\n PlanningFocusSelect,\n type PlanningFocus,\n} from '../roadmaps/planningFocus';\n\nconst GET_ROADMAP = gql`\n query GetRoadmapForEdit($id: ID!) {\n planmagnetRoadmap(id: $id) {\n id\n workspaceId\n name\n description\n type\n planningFocus\n isPublic\n ownerId\n createdAt\n updatedAt\n items {\n id\n status\n }\n }\n }\n`;\n\nconst UPDATE_ROADMAP = gql`\n mutation UpdateRoadmap($id: ID!, $input: PlanmagnetUpdateRoadmapInput!) {\n planmagnetUpdateRoadmap(id: $id, input: $input) {\n id\n name\n description\n type\n planningFocus\n isPublic\n ownerId\n updatedAt\n }\n }\n`;\n\nconst DELETE_ROADMAP = gql`\n mutation DeleteRoadmap($id: ID!) {\n planmagnetDeleteRoadmap(id: $id)\n }\n`;\n\nexport function ProductsEditProductPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const params = useParams<{ id: string }>();\n const roadmapId = params.id ?? '';\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_ROADMAP, {\n variables: { id: roadmapId },\n skip: !roadmapId,\n });\n\n const [updateRoadmap, { loading: saving }] = useMutation(UPDATE_ROADMAP, {\n refetchQueries: [\n 'ListRoadmaps',\n 'ListRoadmapsPage',\n 'GetRoadmapForEdit',\n 'GetRoadmapDetail',\n 'GetRoadmapDetailPage',\n ],\n awaitRefetchQueries: true,\n });\n // BOFF-7980: the button said \"Archive\" but deleted, on the first click, without awaiting — a refusal showed nothing.\n const [deleteRoadmap, { loading: deleting }] = useMutation(DELETE_ROADMAP, {\n refetchQueries: ['ListRoadmaps', 'ListRoadmapsPage'],\n context: LEAVES_PAGE_CONTEXT,\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const roadmap = data?.planmagnetRoadmap;\n\n const defaultForm = useMemo(\n () => ({\n name: roadmap?.name ?? '',\n description: roadmap?.description ?? '',\n planningFocus: (roadmap?.planningFocus ?? null) as PlanningFocus | null,\n isPublic: roadmap?.isPublic ?? false,\n }),\n [roadmap]\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [formOverrides, setFormOverrides] = useState<Record<string, any>>({});\n const form = { ...defaultForm, ...formOverrides } as {\n name: string;\n description: string;\n planningFocus: PlanningFocus | null;\n isPublic: boolean;\n };\n const setForm = (val: typeof form) => setFormOverrides(val);\n\n // BOFF-7979: an emptied description is cleared (null), not silently kept; success is confirmed.\n const handleSave = async () => {\n setSaveError(null);\n setSaved(false);\n try {\n await throwOnError(\n updateRoadmap({\n variables: {\n id: roadmapId,\n input: {\n name: form.name,\n description: form.description.trim() || null,\n // The display is not editable: the page has one layout (BOFF-7934).\n // null clears a focus that was set by mistake.\n planningFocus: form.planningFocus,\n isPublic: form.isPublic,\n },\n },\n })\n );\n setSaved(true);\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The product could not be saved.');\n }\n };\n\n const handleDelete = async () => {\n setSaveError(null);\n try {\n await throwOnError(deleteRoadmap({ variables: { id: roadmapId } }));\n navigate('/products/products-page');\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The product could not be deleted.');\n }\n };\n\n // Only before the first load: a refetch must not blank the page (it\n\n // unmounts every component on it and loses their state).\n\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load product: {error.message}</div>;\n }\n\n if (!roadmap) {\n return <div className=\"p-6 text-muted-foreground\">No product found.</div>;\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigate('/products/products-page')}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Product</h1>\n <p className=\"text-sm text-muted-foreground\">Editing {roadmap.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving}>\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Save Changes\n </Button>\n </div>\n\n {saved && (\n <div role=\"status\" className=\"p-3 bg-muted text-status-success-text rounded-md text-sm\">\n Changes saved.\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n {saveError}\n </div>\n )}\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>Basic Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Product 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>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <PlanningFocusSelect\n value={form.planningFocus}\n onChange={(planningFocus) => setForm({ ...form, planningFocus })}\n />\n <div>\n <label className=\"text-sm font-medium\">Visibility</label>\n <div className=\"mt-1 flex gap-2\">\n {[false, true].map((pub) => (\n <button\n key={String(pub)}\n onClick={() => setForm({ ...form, isPublic: pub })}\n className={`rounded-md px-3 py-1.5 text-sm ${form.isPublic === pub ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {pub ? 'Public' : 'Private'}\n </button>\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Product Info</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Package className=\"h-4 w-4 text-primary\" />\n <span className=\"font-medium\">{roadmap.name}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Items</span>\n <span className=\"font-medium\">{roadmap.items?.length ?? 0}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Planning focus</span>\n <PlanningFocusBadge focus={roadmap.planningFocus} />\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Visibility</span>\n <span className=\"font-medium\">{roadmap.isPublic ? 'Public' : 'Private'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Owner</span>\n <span className=\"font-medium\">\n <PersonName id={roadmap.ownerId} />\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Created</span>\n <span>{new Date(roadmap.createdAt).toLocaleDateString()}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Updated</span>\n <span>{new Date(roadmap.updatedAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Danger Zone</CardTitle>\n </CardHeader>\n <CardContent>\n <ConfirmButton\n label={deleting ? 'Deleting…' : 'Delete product'}\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete ${roadmap.name}?`}\n description=\"The product's roadmap and its items are deleted. This cannot be undone here.\"\n confirmLabel=\"Delete product\"\n destructive\n disabled={deleting}\n onConfirm={() => void handleDelete()}\n />\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AA0BA,IAAM,IAAc,CAAG;;;;;;;;;;;;;;;;;;;GAqBjB,IAAiB,CAAG;;;;;;;;;;;;;GAepB,IAAiB,CAAG;;;;;AAM1B,SAAgB,IAA8B;CAC5C,IAAM,EAAE,mBAAgB,GAAe,EACjC,IAAW,GAAuB,EAElC,IADS,GAA2B,CACjB,MAAM,IAEzB,EACJ,SACA,YACA,aAGA,EAA8B,GAAa;EACzC,WAAW,EAAE,IAAI,GAAW;EAC5B,MAAM,CAAC;EACR,CAAC,EAEE,CAAC,GAAe,EAAE,SAAS,OAAY,EAAY,GAAgB;EACvE,gBAAgB;GACd;GACA;GACA;GACA;GACA;GACD;EACD,qBAAqB;EACtB,CAAC,EAEI,CAAC,GAAe,EAAE,SAAS,OAAc,EAAY,GAAgB;EACzE,gBAAgB,CAAC,gBAAgB,mBAAmB;EACpD,SAAS;EACV,CAAC,EACI,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAO,KAAY,EAAS,GAAM,EAEnC,IAAU,GAAM,mBAEhB,IAAc,SACX;EACL,MAAM,GAAS,QAAQ;EACvB,aAAa,GAAS,eAAe;EACrC,eAAgB,GAAS,iBAAiB;EAC1C,UAAU,GAAS,YAAY;EAChC,GACD,CAAC,EAAQ,CACV,EAGK,CAAC,GAAe,KAAoB,EAA8B,EAAE,CAAC,EACrE,IAAO;EAAE,GAAG;EAAa,GAAG;EAAe,EAM3C,KAAW,MAAqB,EAAiB,EAAI,EAGrD,IAAa,YAAY;AAE7B,EADA,EAAa,KAAK,EAClB,EAAS,GAAM;AACf,MAAI;AAgBF,GAfA,MAAM,EACJ,EAAc,EACZ,WAAW;IACT,IAAI;IACJ,OAAO;KACL,MAAM,EAAK;KACX,aAAa,EAAK,YAAY,MAAM,IAAI;KAGxC,eAAe,EAAK;KACpB,UAAU,EAAK;KAChB;IACF,EACF,CAAC,CACH,EACD,EAAS,GAAK;WACP,GAAG;AACV,KAAa,aAAa,QAAQ,EAAE,UAAU,kCAAkC;;IAI9E,IAAe,YAAY;AAC/B,IAAa,KAAK;AAClB,MAAI;AAEF,GADA,MAAM,EAAa,EAAc,EAAE,WAAW,EAAE,IAAI,GAAW,EAAE,CAAC,CAAC,EACnE,EAAS,0BAA0B;WAC5B,GAAG;AACV,KAAa,aAAa,QAAQ,EAAE,UAAU,oCAAoC;;;AAwBtF,QAhBI,KAAW,CAAC,IAEZ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAS,WAAU,8CAA+C,CAAA;EAC9D,CAAA,GAIN,IACK,kBAAC,OAAD;EAAK,WAAU;YAAf,CAAsC,4BAAyB,EAAM,QAAc;MAGvF,IAKH,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAQ,SAAQ;MAAQ,MAAK;MAAK,eAAe,EAAS,0BAA0B;gBAClF,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;MAC1B,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAyB;MAAiB,CAAA,EACxD,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAA6C,YAAS,EAAQ,KAAS;QACnE,EAAA,CAAA,CACF;QACN,kBAAC,GAAD;KAAQ,MAAK;KAAK,SAAS;KAAY,UAAU;eAAjD,CACG,IACC,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,GAEjD,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EACjC,eAEK;OACL;;GAEL,KACC,kBAAC,OAAD;IAAK,MAAK;IAAS,WAAU;cAA2D;IAElF,CAAA;GAEP,KACC,kBAAC,OAAD;IAAK,MAAK;IAAQ,WAAU;cACzB;IACG,CAAA;GAGR,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,qBAA6B,CAAA,EAC7B,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAsB;QAAoB,CAAA,EAC3D,kBAAC,GAAD;QACE,OAAO,EAAK;QACZ,WAAW,MAAM,EAAQ;SAAE,GAAG;SAAM,MAAM,EAAE,OAAO;SAAO,CAAC;QAC3D,WAAU;QACV,CAAA,CACE,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAsB;QAAmB,CAAA,EAC1D,kBAAC,YAAD;QACE,WAAU;QACV,OAAO,EAAK;QACZ,WAAW,MAAM,EAAQ;SAAE,GAAG;SAAM,aAAa,EAAE,OAAO;SAAO,CAAC;QAClE,CAAA,CACE,EAAA,CAAA;OACN,kBAAC,GAAD;QACE,OAAO,EAAK;QACZ,WAAW,MAAkB,EAAQ;SAAE,GAAG;SAAM;SAAe,CAAC;QAChE,CAAA;OACF,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAsB;QAAkB,CAAA,EACzD,kBAAC,OAAD;QAAK,WAAU;kBACZ,CAAC,IAAO,GAAK,CAAC,KAAK,MAClB,kBAAC,UAAD;SAEE,eAAe,EAAQ;UAAE,GAAG;UAAM,UAAU;UAAK,CAAC;SAClD,WAAW,kCAAkC,EAAK,aAAa,IAAM,uCAAuC;mBAE3G,IAAM,WAAW;SACX,EALF,OAAO,EAAI,CAKT,CACT;QACE,CAAA,CACF,EAAA,CAAA;OACM;QACT,EAAA,CAAA;KACH,CAAA,EAEN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,gBAAwB,CAAA,EACxB,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,EAC5C,kBAAC,QAAD;SAAM,WAAU;mBAAe,EAAQ;SAAY,CAAA,CAC/C;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAwB;SAAY,CAAA,EACpD,kBAAC,QAAD;SAAM,WAAU;mBAAe,EAAQ,OAAO,UAAU;SAAS,CAAA,CAC7D;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAwB;SAAqB,CAAA,EAC7D,kBAAC,GAAD,EAAoB,OAAO,EAAQ,eAAiB,CAAA,CAChD;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAwB;SAAiB,CAAA,EACzD,kBAAC,QAAD;SAAM,WAAU;mBAAe,EAAQ,WAAW,WAAW;SAAiB,CAAA,CAC1E;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAwB;SAAY,CAAA,EACpD,kBAAC,QAAD;SAAM,WAAU;mBACd,kBAAC,GAAD,EAAY,IAAI,EAAQ,SAAW,CAAA;SAC9B,CAAA,CACH;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAwB;SAAc,CAAA,EACtD,kBAAC,QAAD,EAAA,UAAO,IAAI,KAAK,EAAQ,UAAU,CAAC,oBAAoB,EAAQ,CAAA,CAC3D;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAwB;SAAc,CAAA,EACtD,kBAAC,QAAD,EAAA,UAAO,IAAI,KAAK,EAAQ,UAAU,CAAC,oBAAoB,EAAQ,CAAA,CAC3D;;OACM;QACT,EAAA,CAAA,EAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,eAAuB,CAAA,EACvB,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MACE,OAAO,IAAW,cAAc;MAChC,SAAQ;MACR,MAAM,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA;MACzC,OAAO,UAAU,EAAQ,KAAK;MAC9B,aAAY;MACZ,cAAa;MACb,aAAA;MACA,UAAU;MACV,iBAAiB,KAAK,GAAc;MACpC,CAAA,EACU,CAAA,CACT,EAAA,CAAA,CACH;OACF;;GACF;MA5IC,kBAAC,OAAD;EAAK,WAAU;YAA4B;EAAuB,CAAA"}
1
+ {"version":3,"file":"ProductsEditProductPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsEditProductPagePage.tsx"],"sourcesContent":["import { 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, Package, Loader2 } from 'lucide-react';\nimport { throwOnError } from '../utils/mutationResult';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { detailPath } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { enumLabel } from '../controls/WorkItemControls';\nimport { ProductHeaderActions } from '../product/ProductControls';\n\n/**\n * Edit a Product's own fields (BOFF-8045): name, description, vision, lifecycle stage,\n * owner and North Star metric. Archive/unarchive and delete live in ProductHeaderActions\n * (shared with the detail page). Lifecycle stage has no enforced transition graph — any\n * stage to any stage is a valid save, deliberately (the owner decision only asks for the\n * field, not a workflow).\n */\n\nconst PRODUCT_LIFECYCLE_STAGES = [\n 'CONCEPT',\n 'DEVELOPMENT',\n 'BETA',\n 'LAUNCHED',\n 'MATURE',\n 'DEPRECATED',\n] as const;\ntype ProductLifecycleStage = (typeof PRODUCT_LIFECYCLE_STAGES)[number];\n\nconst GET_PRODUCT = gql`\n query GetProductForEdit($id: ID!) {\n planmagnetProduct(id: $id) {\n id\n workspaceId\n name\n description\n vision\n lifecycleStage\n ownerId\n archivedAt\n northStar {\n name\n unit\n target\n current\n window\n }\n createdAt\n updatedAt\n }\n }\n`;\n\nconst UPDATE_PRODUCT = gql`\n mutation UpdateProduct($id: ID!, $input: PlanmagnetUpdateProductInput!) {\n planmagnetUpdateProduct(id: $id, input: $input) {\n id\n name\n description\n vision\n lifecycleStage\n ownerId\n northStar {\n name\n unit\n target\n current\n window\n }\n updatedAt\n }\n }\n`;\n\ninterface ProductNorthStarFull {\n name: string;\n unit: string;\n target: number;\n current: number;\n window: string;\n}\n\ninterface ProductForEdit {\n id: string;\n workspaceId: string;\n name: string;\n description: string | null;\n vision: string;\n lifecycleStage: string;\n ownerId: string;\n archivedAt: string | null;\n northStar: ProductNorthStarFull | null;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface EditProductForm {\n name: string;\n description: string;\n vision: string;\n lifecycleStage: ProductLifecycleStage;\n}\n\ninterface NorthStarForm {\n name: string;\n unit: string;\n target: string;\n current: string;\n window: string;\n}\n\nconst EMPTY_NORTH_STAR: NorthStarForm = { name: '', unit: '', target: '', current: '', window: '' };\n\nexport function ProductsEditProductPagePage() {\n const navigate = usePlanMagnetNavigate();\n const productId = useEntityId('productId') ?? '';\n\n const { data, loading, error } = useQuery<{ planmagnetProduct: ProductForEdit | null }>(\n GET_PRODUCT,\n { variables: { id: productId }, skip: !productId }\n );\n\n const [updateProduct, { loading: saving }] = useMutation(UPDATE_PRODUCT, {\n refetchQueries: ['GetProducts', 'GetProductForEdit', 'GetProductDetail'],\n awaitRefetchQueries: true,\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const product = data?.planmagnetProduct;\n\n const defaultForm = useMemo<EditProductForm>(\n () => ({\n name: product?.name ?? '',\n description: product?.description ?? '',\n vision: product?.vision ?? '',\n lifecycleStage: (product?.lifecycleStage ?? 'CONCEPT') as ProductLifecycleStage,\n }),\n [product]\n );\n const defaultNorthStar = useMemo<NorthStarForm>(\n () =>\n product?.northStar\n ? {\n name: product.northStar.name,\n unit: product.northStar.unit,\n target: String(product.northStar.target),\n current: String(product.northStar.current),\n window: product.northStar.window,\n }\n : EMPTY_NORTH_STAR,\n [product]\n );\n\n const [formOverrides, setFormOverrides] = useState<Partial<EditProductForm>>({});\n const form: EditProductForm = { ...defaultForm, ...formOverrides };\n const setForm = (val: EditProductForm) => setFormOverrides(val);\n\n const [northStarOverrides, setNorthStarOverrides] = useState<Partial<NorthStarForm>>({});\n const northStar: NorthStarForm = { ...defaultNorthStar, ...northStarOverrides };\n const setNorthStar = (val: NorthStarForm) => setNorthStarOverrides(val);\n\n const northStarStarted = Object.values(northStar).some((v) => v.trim() !== '');\n const northStarComplete =\n northStar.name.trim() &&\n northStar.unit.trim() &&\n northStar.window.trim() &&\n northStar.target.trim() !== '' &&\n !Number.isNaN(Number(northStar.target)) &&\n northStar.current.trim() !== '' &&\n !Number.isNaN(Number(northStar.current));\n\n // An emptied description is cleared (null), not silently kept; success is confirmed.\n const handleSave = async () => {\n setSaveError(null);\n setSaved(false);\n try {\n await throwOnError(\n updateProduct({\n variables: {\n id: productId,\n input: {\n name: form.name,\n description: form.description.trim() || null,\n vision: form.vision,\n lifecycleStage: form.lifecycleStage,\n ...(northStarComplete\n ? {\n northStar: {\n name: northStar.name,\n unit: northStar.unit,\n target: Number(northStar.target),\n current: Number(northStar.current),\n window: northStar.window,\n },\n }\n : {}),\n },\n },\n })\n );\n setSaved(true);\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The product could not be saved.');\n }\n };\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 <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load product: {error.message}</div>;\n }\n\n if (!product) {\n return <div className=\"p-6 text-muted-foreground\">No product found.</div>;\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => navigate(detailPath('/products/product-detail-page', product.id))}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Product</h1>\n <p className=\"text-sm text-muted-foreground\">Editing {product.name}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n size=\"sm\"\n onClick={() => void handleSave()}\n disabled={saving || (northStarStarted && !northStarComplete)}\n >\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Save Changes\n </Button>\n <ProductHeaderActions\n productId={product.id}\n name={product.name}\n archivedAt={product.archivedAt}\n />\n </div>\n </div>\n\n {saved && (\n <div role=\"status\" className=\"p-3 bg-muted text-status-success-text rounded-md text-sm\">\n Changes saved.\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n {saveError}\n </div>\n )}\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>Basic Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Product 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>\n <label className=\"text-sm font-medium\">Description</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.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Vision</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.vision}\n onChange={(e) => setForm({ ...form, vision: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Lifecycle Stage</label>\n <select\n aria-label=\"Lifecycle stage\"\n data-testid=\"product-lifecycle-stage\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-2 py-1.5 text-sm\"\n value={form.lifecycleStage}\n onChange={(e) =>\n setForm({ ...form, lifecycleStage: e.target.value as ProductLifecycleStage })\n }\n >\n {PRODUCT_LIFECYCLE_STAGES.map((stage) => (\n <option key={stage} value={stage}>\n {enumLabel(stage)}\n </option>\n ))}\n </select>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>North Star metric</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Metric name</label>\n <Input\n value={northStar.name}\n onChange={(e) => setNorthStar({ ...northStar, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Unit</label>\n <Input\n value={northStar.unit}\n onChange={(e) => setNorthStar({ ...northStar, unit: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Target</label>\n <Input\n type=\"number\"\n value={northStar.target}\n onChange={(e) => setNorthStar({ ...northStar, target: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Current</label>\n <Input\n type=\"number\"\n value={northStar.current}\n onChange={(e) => setNorthStar({ ...northStar, current: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div className=\"col-span-2\">\n <label className=\"text-sm font-medium\">Window</label>\n <Input\n value={northStar.window}\n onChange={(e) => setNorthStar({ ...northStar, window: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n {northStarStarted && !northStarComplete && (\n <p className=\"text-xs text-destructive\">\n Fill in every North Star field (or clear them all) — name, unit, target, current\n and window are all required together.\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Product Info</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Package className=\"h-4 w-4 text-primary\" />\n <span className=\"font-medium\">{product.name}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Lifecycle stage</span>\n <span className=\"font-medium capitalize\">{enumLabel(product.lifecycleStage)}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Status</span>\n <span className=\"font-medium\">{product.archivedAt ? 'Archived' : 'Active'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Owner</span>\n <span className=\"font-medium\">\n <PersonName id={product.ownerId} />\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Created</span>\n <span>{new Date(product.createdAt).toLocaleDateString()}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Updated</span>\n <span>{new Date(product.updatedAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function ProductsEditRoadmapPagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=ProductsEditRoadmapPagePage.d.ts.map