@burdenoff/microfe-planmagnet 2026.927.2 → 2026.927.4

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 (106) hide show
  1. package/dist/planmagnet/admin/PlanMagnetAdminRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/admin/PlanMagnetAdminRoot.js +128 -124
  3. package/dist/planmagnet/admin/PlanMagnetAdminRoot.js.map +1 -1
  4. package/dist/planmagnet/controls/ConfirmButton.d.ts +25 -0
  5. package/dist/planmagnet/controls/ConfirmButton.d.ts.map +1 -0
  6. package/dist/planmagnet/controls/ConfirmButton.js +30 -0
  7. package/dist/planmagnet/controls/ConfirmButton.js.map +1 -0
  8. package/dist/planmagnet/controls/FeatureControls.d.ts +26 -0
  9. package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -0
  10. package/dist/planmagnet/controls/FeatureControls.js +318 -0
  11. package/dist/planmagnet/controls/FeatureControls.js.map +1 -0
  12. package/dist/planmagnet/controls/MilestoneControls.d.ts +17 -0
  13. package/dist/planmagnet/controls/MilestoneControls.d.ts.map +1 -0
  14. package/dist/planmagnet/controls/MilestoneControls.js +200 -0
  15. package/dist/planmagnet/controls/MilestoneControls.js.map +1 -0
  16. package/dist/planmagnet/controls/ObjectiveControls.d.ts +31 -0
  17. package/dist/planmagnet/controls/ObjectiveControls.d.ts.map +1 -0
  18. package/dist/planmagnet/controls/ObjectiveControls.js +296 -0
  19. package/dist/planmagnet/controls/ObjectiveControls.js.map +1 -0
  20. package/dist/planmagnet/controls/Pickers.d.ts +26 -0
  21. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -0
  22. package/dist/planmagnet/controls/Pickers.js +171 -0
  23. package/dist/planmagnet/controls/Pickers.js.map +1 -0
  24. package/dist/planmagnet/controls/ProjectControls.d.ts +13 -0
  25. package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -0
  26. package/dist/planmagnet/controls/ProjectControls.js +104 -0
  27. package/dist/planmagnet/controls/ProjectControls.js.map +1 -0
  28. package/dist/planmagnet/controls/ReleaseControls.d.ts +14 -0
  29. package/dist/planmagnet/controls/ReleaseControls.d.ts.map +1 -0
  30. package/dist/planmagnet/controls/ReleaseControls.js +108 -0
  31. package/dist/planmagnet/controls/ReleaseControls.js.map +1 -0
  32. package/dist/planmagnet/controls/WorkItemControls.d.ts +52 -0
  33. package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -0
  34. package/dist/planmagnet/controls/WorkItemControls.js +198 -0
  35. package/dist/planmagnet/controls/WorkItemControls.js.map +1 -0
  36. package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
  37. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +188 -154
  38. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  39. package/dist/planmagnet/pages/DocsDocsPagePage.js +4 -4
  40. package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.d.ts.map +1 -1
  41. package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js +63 -56
  42. package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js.map +1 -1
  43. package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.d.ts.map +1 -1
  44. package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js +229 -214
  45. package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js.map +1 -1
  46. package/dist/planmagnet/pages/ProductsEditProductPagePage.d.ts.map +1 -1
  47. package/dist/planmagnet/pages/ProductsEditProductPagePage.js +142 -114
  48. package/dist/planmagnet/pages/ProductsEditProductPagePage.js.map +1 -1
  49. package/dist/planmagnet/pages/ProductsEditReleasePagePage.d.ts.map +1 -1
  50. package/dist/planmagnet/pages/ProductsEditReleasePagePage.js +134 -105
  51. package/dist/planmagnet/pages/ProductsEditReleasePagePage.js.map +1 -1
  52. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  53. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +102 -108
  54. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  55. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
  56. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +119 -94
  57. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
  58. package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
  59. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +97 -90
  60. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
  61. package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.d.ts.map +1 -1
  62. package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js +107 -106
  63. package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js.map +1 -1
  64. package/dist/planmagnet/pages/ProductsReleasesPagePage.d.ts.map +1 -1
  65. package/dist/planmagnet/pages/ProductsReleasesPagePage.js +2 -0
  66. package/dist/planmagnet/pages/ProductsReleasesPagePage.js.map +1 -1
  67. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
  68. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +150 -111
  69. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
  70. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  71. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +116 -93
  72. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  73. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.d.ts.map +1 -1
  74. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +55 -63
  75. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js.map +1 -1
  76. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +4 -4
  77. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  78. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +134 -132
  79. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  80. package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
  81. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +6 -5
  82. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
  83. package/dist/planmagnet/pages/TasksCreateTaskPagePage.d.ts.map +1 -1
  84. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +167 -116
  85. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +1 -1
  86. package/dist/planmagnet/pages/TasksEditTaskPagePage.d.ts.map +1 -1
  87. package/dist/planmagnet/pages/TasksEditTaskPagePage.js +139 -107
  88. package/dist/planmagnet/pages/TasksEditTaskPagePage.js.map +1 -1
  89. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  90. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +205 -158
  91. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  92. package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
  93. package/dist/planmagnet/pages/TasksTasksPagePage.js +1 -0
  94. package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
  95. package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
  96. package/dist/planmagnet/pages/TeamTeamPagePage.js +1 -1
  97. package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
  98. package/dist/planmagnet/people/People.js +1 -1
  99. package/dist/planmagnet/roadmaps/RoadmapControls.d.ts +34 -0
  100. package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -0
  101. package/dist/planmagnet/roadmaps/RoadmapControls.js +301 -0
  102. package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -0
  103. package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
  104. package/dist/planmagnet/sprints/SprintControls.js +194 -215
  105. package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
  106. package/package.json +1 -1
@@ -1,13 +1,15 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
- import { parseIntField as n } from "../utils/formValidation.js";
3
- import { useMemo as r, useState as i } from "react";
4
- import { ArrowLeft as a, Save as o } from "lucide-react";
5
- import { gql as s } from "@apollo/client";
6
- import { useMutation as c, useQuery as l } from "@apollo/client/react";
7
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
8
- import { Button as f, Card as p, CardContent as m, CardHeader as h, CardTitle as g, Input as _ } from "@burdenoff/fe-libs/ui";
2
+ import { throwOnError as n } from "../utils/mutationResult.js";
3
+ import { parseIntField as r } from "../utils/formValidation.js";
4
+ import { WORK_ITEM_PRIORITIES as i } from "../controls/WorkItemControls.js";
5
+ import { useMemo as a, useState as o } from "react";
6
+ import { ArrowLeft as s, Save as c } from "lucide-react";
7
+ import { gql as l } from "@apollo/client";
8
+ import { useMutation as u, useQuery as d } from "@apollo/client/react";
9
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
10
+ import { Button as m, Card as h, CardContent as g, CardHeader as _, CardTitle as v, Input as y } from "@burdenoff/fe-libs/ui";
9
11
  //#region src/planmagnet/pages/TasksEditTaskPagePage.tsx
10
- var v = s`
12
+ var b = l`
11
13
  query GetWorkItem($workItemId: ID!) {
12
14
  planmagnetWorkItem(id: $workItemId) {
13
15
  id
@@ -25,7 +27,7 @@ var v = s`
25
27
  updatedAt
26
28
  }
27
29
  }
28
- `, y = s`
30
+ `, x = l`
29
31
  mutation UpdateWorkItem($workItemId: ID!, $input: PlanmagnetUpdateWorkItemInput!) {
30
32
  planmagnetUpdateWorkItem(id: $workItemId, input: $input) {
31
33
  id
@@ -41,136 +43,166 @@ var v = s`
41
43
  }
42
44
  }
43
45
  `;
44
- function b() {
45
- let { workspaceId: s } = e(), b = new URLSearchParams(window.location.search).get("taskId") ?? "", x = t(), { data: S, loading: C, error: w } = l(v, {
46
- variables: { workItemId: b },
47
- skip: !s || !b
48
- }), [T, { loading: E, error: D }] = c(y, { refetchQueries: ["GetWorkItems", "GetWorkItem"] }), O = S?.planmagnetWorkItem, k = r(() => ({
49
- title: O?.title ?? "",
50
- description: O?.description ?? "",
51
- priority: O?.priority ?? "MEDIUM",
52
- type: O?.type ?? "STORY",
53
- storyPoints: O?.storyPoints?.toString() ?? "0",
54
- labels: (O?.labels ?? []).join(", "),
55
- dueDate: O?.dueDate ?? ""
56
- }), [O]), [A, j] = i({}), M = {
57
- ...k,
58
- ...A
59
- }, N = (e) => j(e), P = n(M.storyPoints, { min: 0 }), F = async () => {
60
- !s || !b || P.invalid || await T({ variables: {
61
- workItemId: b,
62
- input: {
63
- title: M.title,
64
- description: M.description || void 0,
65
- priority: M.priority,
66
- type: M.type,
67
- storyPoints: P.value,
68
- labels: M.labels ? M.labels.split(",").map((e) => e.trim()).filter(Boolean) : void 0,
69
- dueDate: M.dueDate || void 0
70
- }
71
- } });
46
+ function S() {
47
+ let { workspaceId: l } = e(), S = new URLSearchParams(window.location.search).get("taskId") ?? "", C = t(), { data: w, loading: T, error: E } = d(b, {
48
+ variables: { workItemId: S },
49
+ skip: !l || !S
50
+ }), [D, { loading: O }] = u(x, {
51
+ refetchQueries: [
52
+ "GetWorkItems",
53
+ "GetWorkItemDetail",
54
+ "GetWorkItemCounts",
55
+ "ProjectBoard"
56
+ ],
57
+ awaitRefetchQueries: !0
58
+ }), [k, A] = o(null), [j, M] = o(!1), N = w?.planmagnetWorkItem, P = a(() => ({
59
+ title: N?.title ?? "",
60
+ description: N?.description ?? "",
61
+ priority: N?.priority ?? "MEDIUM",
62
+ type: N?.type ?? "STORY",
63
+ storyPoints: N?.storyPoints?.toString() ?? "",
64
+ labels: (N?.labels ?? []).join(", "),
65
+ dueDate: N?.dueDate ? String(N.dueDate).slice(0, 10) : ""
66
+ }), [N]), [F, I] = o({}), L = {
67
+ ...P,
68
+ ...F
69
+ }, R = (e) => I(e), z = r(L.storyPoints, { min: 0 }), B = async () => {
70
+ if (!l || !S || z.invalid) return;
71
+ if (!L.title.trim()) {
72
+ A("A task needs a title.");
73
+ return;
74
+ }
75
+ let e = (e) => e.split(",").map((e) => e.trim()).filter(Boolean), t = {
76
+ title: L.title.trim(),
77
+ description: L.description.trim() || null,
78
+ priority: L.priority,
79
+ type: L.type,
80
+ storyPoints: z.value ?? null,
81
+ labels: e(L.labels),
82
+ dueDate: L.dueDate || null
83
+ }, r = {
84
+ title: P.title,
85
+ description: P.description.trim() || null,
86
+ priority: P.priority,
87
+ type: P.type,
88
+ storyPoints: P.storyPoints === "" ? null : Number(P.storyPoints),
89
+ labels: e(P.labels),
90
+ dueDate: P.dueDate || null
91
+ }, i = Object.fromEntries(Object.entries(t).filter(([e, t]) => JSON.stringify(t) !== JSON.stringify(r[e])));
92
+ if (A(null), M(!1), Object.keys(i).length === 0) {
93
+ M(!0);
94
+ return;
95
+ }
96
+ try {
97
+ await n(D({ variables: {
98
+ workItemId: S,
99
+ input: i
100
+ } })), M(!0);
101
+ } catch (e) {
102
+ A(e instanceof Error ? e.message : "The task could not be saved.");
103
+ }
72
104
  };
73
- if (C && !S) return /* @__PURE__ */ u("div", {
105
+ if (T && !w) return /* @__PURE__ */ f("div", {
74
106
  className: "flex items-center justify-center p-12",
75
- children: /* @__PURE__ */ u("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
107
+ children: /* @__PURE__ */ f("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
76
108
  });
77
- if (w) return /* @__PURE__ */ d("div", {
109
+ if (E) return /* @__PURE__ */ p("div", {
78
110
  className: "p-6 text-destructive",
79
- children: ["Error: ", w.message]
111
+ children: ["Error: ", E.message]
80
112
  });
81
- if (!S?.planmagnetWorkItem) return /* @__PURE__ */ u("div", {
113
+ if (!w?.planmagnetWorkItem) return /* @__PURE__ */ f("div", {
82
114
  className: "p-6 text-muted-foreground",
83
115
  children: "Task not found."
84
116
  });
85
- let I = S.planmagnetWorkItem;
86
- return /* @__PURE__ */ d("div", {
117
+ let V = w.planmagnetWorkItem;
118
+ return /* @__PURE__ */ p("div", {
87
119
  className: "space-y-6 p-6 max-w-4xl",
88
120
  children: [
89
- /* @__PURE__ */ d("div", {
121
+ /* @__PURE__ */ p("div", {
90
122
  className: "flex items-center justify-between",
91
- children: [/* @__PURE__ */ d("div", {
123
+ children: [/* @__PURE__ */ p("div", {
92
124
  className: "flex items-center gap-3",
93
- children: [/* @__PURE__ */ u(f, {
125
+ children: [/* @__PURE__ */ f(m, {
94
126
  variant: "ghost",
95
127
  size: "sm",
96
128
  "aria-label": "Back to the task",
97
- onClick: () => x(`/tasks/task-detail-page?taskId=${encodeURIComponent(b)}`),
98
- children: /* @__PURE__ */ u(a, { className: "h-4 w-4" })
99
- }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
129
+ onClick: () => C(`/tasks/task-detail-page?taskId=${encodeURIComponent(S)}`),
130
+ children: /* @__PURE__ */ f(s, { className: "h-4 w-4" })
131
+ }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
100
132
  className: "text-2xl font-semibold",
101
133
  children: "Edit Task"
102
- }), /* @__PURE__ */ u("p", {
134
+ }), /* @__PURE__ */ f("p", {
103
135
  className: "text-sm text-muted-foreground",
104
- children: I.title
136
+ children: V.title
105
137
  })] })]
106
- }), /* @__PURE__ */ d(f, {
138
+ }), /* @__PURE__ */ p(m, {
107
139
  size: "sm",
108
- onClick: F,
109
- disabled: E || P.invalid,
110
- children: [/* @__PURE__ */ u(o, { className: "mr-1 h-4 w-4" }), E ? "Saving..." : "Save Changes"]
140
+ onClick: B,
141
+ disabled: O || z.invalid,
142
+ children: [/* @__PURE__ */ f(c, { className: "mr-1 h-4 w-4" }), O ? "Saving..." : "Save Changes"]
111
143
  })]
112
144
  }),
113
- D && /* @__PURE__ */ u("div", {
145
+ j && /* @__PURE__ */ f("div", {
146
+ role: "status",
147
+ className: "p-3 bg-muted text-status-success-text rounded-md text-sm",
148
+ children: "Changes saved."
149
+ }),
150
+ k && /* @__PURE__ */ f("div", {
114
151
  role: "alert",
115
152
  className: "p-3 bg-destructive/10 text-destructive rounded-md text-sm",
116
- children: D.message
153
+ children: k
117
154
  }),
118
- /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Task Details" }) }), /* @__PURE__ */ d(m, {
155
+ /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ f(v, { children: "Task Details" }) }), /* @__PURE__ */ p(g, {
119
156
  className: "space-y-4",
120
157
  children: [
121
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
158
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
122
159
  className: "text-sm font-medium",
123
160
  children: "Title"
124
- }), /* @__PURE__ */ u(_, {
125
- value: M.title,
126
- onChange: (e) => N({
127
- ...M,
161
+ }), /* @__PURE__ */ f(y, {
162
+ value: L.title,
163
+ onChange: (e) => R({
164
+ ...L,
128
165
  title: e.target.value
129
166
  }),
130
167
  className: "mt-1"
131
168
  })] }),
132
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
169
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
133
170
  className: "text-sm font-medium",
134
171
  children: "Description"
135
- }), /* @__PURE__ */ u("textarea", {
172
+ }), /* @__PURE__ */ f("textarea", {
136
173
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]",
137
- value: M.description,
138
- onChange: (e) => N({
139
- ...M,
174
+ value: L.description,
175
+ onChange: (e) => R({
176
+ ...L,
140
177
  description: e.target.value
141
178
  })
142
179
  })] }),
143
- /* @__PURE__ */ d("div", {
180
+ /* @__PURE__ */ p("div", {
144
181
  className: "grid grid-cols-3 gap-4",
145
182
  children: [
146
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
183
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
147
184
  className: "text-sm font-medium",
148
185
  children: "Priority"
149
- }), /* @__PURE__ */ u("select", {
186
+ }), /* @__PURE__ */ f("select", {
150
187
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
151
- value: M.priority,
152
- onChange: (e) => N({
153
- ...M,
188
+ value: L.priority,
189
+ onChange: (e) => R({
190
+ ...L,
154
191
  priority: e.target.value
155
192
  }),
156
- children: [
157
- "LOW",
158
- "MEDIUM",
159
- "HIGH",
160
- "CRITICAL"
161
- ].map((e) => /* @__PURE__ */ u("option", {
193
+ children: i.map((e) => /* @__PURE__ */ f("option", {
162
194
  value: e,
163
195
  children: e.toLowerCase()
164
196
  }, e))
165
197
  })] }),
166
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
198
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
167
199
  className: "text-sm font-medium",
168
200
  children: "Type"
169
- }), /* @__PURE__ */ u("select", {
201
+ }), /* @__PURE__ */ f("select", {
170
202
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
171
- value: M.type,
172
- onChange: (e) => N({
173
- ...M,
203
+ value: L.type,
204
+ onChange: (e) => R({
205
+ ...L,
174
206
  type: e.target.value
175
207
  }),
176
208
  children: [
@@ -179,31 +211,31 @@ function b() {
179
211
  "TASK",
180
212
  "EPIC",
181
213
  "SUB_TASK"
182
- ].map((e) => /* @__PURE__ */ u("option", {
214
+ ].map((e) => /* @__PURE__ */ f("option", {
183
215
  value: e,
184
216
  children: e.toLowerCase().replace("_", " ")
185
217
  }, e))
186
218
  })] }),
187
- /* @__PURE__ */ d("div", { children: [
188
- /* @__PURE__ */ u("label", {
219
+ /* @__PURE__ */ p("div", { children: [
220
+ /* @__PURE__ */ f("label", {
189
221
  htmlFor: "task-story-points",
190
222
  className: "text-sm font-medium",
191
223
  children: "Story Points"
192
224
  }),
193
- /* @__PURE__ */ u(_, {
225
+ /* @__PURE__ */ f(y, {
194
226
  id: "task-story-points",
195
227
  type: "number",
196
228
  min: 0,
197
229
  step: 1,
198
- value: M.storyPoints,
199
- onChange: (e) => N({
200
- ...M,
230
+ value: L.storyPoints,
231
+ onChange: (e) => R({
232
+ ...L,
201
233
  storyPoints: e.target.value
202
234
  }),
203
- "aria-invalid": P.invalid,
235
+ "aria-invalid": z.invalid,
204
236
  className: "mt-1"
205
237
  }),
206
- P.invalid && /* @__PURE__ */ u("p", {
238
+ z.invalid && /* @__PURE__ */ f("p", {
207
239
  role: "alert",
208
240
  className: "mt-1 text-xs text-destructive",
209
241
  children: "Story points must be a whole number, 0 or more."
@@ -211,26 +243,26 @@ function b() {
211
243
  ] })
212
244
  ]
213
245
  }),
214
- /* @__PURE__ */ d("div", {
246
+ /* @__PURE__ */ p("div", {
215
247
  className: "grid grid-cols-2 gap-4",
216
- children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
248
+ children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
217
249
  className: "text-sm font-medium",
218
250
  children: "Due Date"
219
- }), /* @__PURE__ */ u(_, {
251
+ }), /* @__PURE__ */ f(y, {
220
252
  type: "date",
221
- value: M.dueDate,
222
- onChange: (e) => N({
223
- ...M,
253
+ value: L.dueDate,
254
+ onChange: (e) => R({
255
+ ...L,
224
256
  dueDate: e.target.value
225
257
  }),
226
258
  className: "mt-1"
227
- })] }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
259
+ })] }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
228
260
  className: "text-sm font-medium",
229
261
  children: "Labels"
230
- }), /* @__PURE__ */ u(_, {
231
- value: M.labels,
232
- onChange: (e) => N({
233
- ...M,
262
+ }), /* @__PURE__ */ f(y, {
263
+ value: L.labels,
264
+ onChange: (e) => R({
265
+ ...L,
234
266
  labels: e.target.value
235
267
  }),
236
268
  className: "mt-1"
@@ -242,6 +274,6 @@ function b() {
242
274
  });
243
275
  }
244
276
  //#endregion
245
- export { b as TasksEditTaskPagePage };
277
+ export { S as TasksEditTaskPagePage };
246
278
 
247
279
  //# sourceMappingURL=TasksEditTaskPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TasksEditTaskPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksEditTaskPagePage.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, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { parseIntField } from '../utils/formValidation';\n\nconst GET_WORK_ITEM = gql`\n query GetWorkItem($workItemId: ID!) {\n planmagnetWorkItem(id: $workItemId) {\n id\n title\n description\n type\n status\n priority\n key\n storyPoints\n dueDate\n labels\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nconst UPDATE_WORK_ITEM = gql`\n mutation UpdateWorkItem($workItemId: ID!, $input: PlanmagnetUpdateWorkItemInput!) {\n planmagnetUpdateWorkItem(id: $workItemId, input: $input) {\n id\n title\n description\n type\n status\n priority\n storyPoints\n dueDate\n labels\n updatedAt\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\n description: string | null;\n type: string;\n status: string;\n priority: string;\n key: string;\n storyPoints: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport function TasksEditTaskPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n // In a real app, workItemId comes from the route params.\n // For now we use a placeholder that the host shell should provide.\n const workItemId = new URLSearchParams(window.location.search).get('taskId') ?? '';\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{\n planmagnetWorkItem: WorkItemNode;\n }>(GET_WORK_ITEM, {\n variables: { workItemId },\n skip: !workspaceId || !workItemId,\n });\n\n const [updateWorkItem, { loading: saving, error: saveError }] = useMutation(UPDATE_WORK_ITEM, {\n refetchQueries: ['GetWorkItems', 'GetWorkItem'],\n });\n\n const workItem = data?.planmagnetWorkItem;\n\n const defaultForm = useMemo(\n () => ({\n title: workItem?.title ?? '',\n description: workItem?.description ?? '',\n priority: workItem?.priority ?? 'MEDIUM',\n type: workItem?.type ?? 'STORY',\n storyPoints: workItem?.storyPoints?.toString() ?? '0',\n labels: (workItem?.labels ?? []).join(', '),\n dueDate: workItem?.dueDate ?? '',\n }),\n [workItem]\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 // Story points are a whole number, 0 or more (BOFF-7833); the service refuses anything else.\n const storyPoints = parseIntField(form.storyPoints, { min: 0 });\n\n const handleSave = async () => {\n if (!workspaceId || !workItemId || storyPoints.invalid) return;\n // mutation-error: shown from the hook's `error`; nothing runs on failure.\n await updateWorkItem({\n variables: {\n workItemId,\n input: {\n title: form.title,\n description: form.description || undefined,\n priority: form.priority,\n type: form.type,\n storyPoints: storyPoints.value,\n labels: form.labels\n ? form.labels\n .split(',')\n .map((l) => l.trim())\n .filter(Boolean)\n : undefined,\n dueDate: form.dueDate || undefined,\n },\n },\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 <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Error: {error.message}</div>;\n }\n\n if (!data?.planmagnetWorkItem) {\n return <div className=\"p-6 text-muted-foreground\">Task not found.</div>;\n }\n\n const task = data.planmagnetWorkItem;\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\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Back to the task\"\n onClick={() =>\n navigate(`/tasks/task-detail-page?taskId=${encodeURIComponent(workItemId)}`)\n }\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Task</h1>\n <p className=\"text-sm text-muted-foreground\">{task.title}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || storyPoints.invalid}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\n {saveError && (\n <div role=\"alert\" className=\"p-3 bg-destructive/10 text-destructive rounded-md text-sm\">\n {saveError.message}\n </div>\n )}\n <Card>\n <CardHeader>\n <CardTitle>Task Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: 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-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Priority</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.priority}\n onChange={(e) => setForm({ ...form, priority: e.target.value })}\n >\n {['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'].map((p) => (\n <option key={p} value={p}>\n {p.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Type</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.type}\n onChange={(e) => setForm({ ...form, type: e.target.value })}\n >\n {['STORY', 'BUG', 'TASK', 'EPIC', 'SUB_TASK'].map((t) => (\n <option key={t} value={t}>\n {t.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"task-story-points\" className=\"text-sm font-medium\">\n Story Points\n </label>\n <Input\n id=\"task-story-points\"\n type=\"number\"\n min={0}\n step={1}\n value={form.storyPoints}\n onChange={(e) => setForm({ ...form, storyPoints: e.target.value })}\n aria-invalid={storyPoints.invalid}\n className=\"mt-1\"\n />\n {storyPoints.invalid && (\n <p role=\"alert\" className=\"mt-1 text-xs text-destructive\">\n Story points must be a whole number, 0 or more.\n </p>\n )}\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Due Date</label>\n <Input\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm({ ...form, dueDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Labels</label>\n <Input\n value={form.labels}\n onChange={(e) => setForm({ ...form, labels: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TasksEditTaskPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksEditTaskPagePage.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, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { parseIntField } from '../utils/formValidation';\nimport { throwOnError } from '../utils/mutationResult';\nimport { WORK_ITEM_PRIORITIES } from '../controls/WorkItemControls';\n\nconst GET_WORK_ITEM = gql`\n query GetWorkItem($workItemId: ID!) {\n planmagnetWorkItem(id: $workItemId) {\n id\n title\n description\n type\n status\n priority\n key\n storyPoints\n dueDate\n labels\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nconst UPDATE_WORK_ITEM = gql`\n mutation UpdateWorkItem($workItemId: ID!, $input: PlanmagnetUpdateWorkItemInput!) {\n planmagnetUpdateWorkItem(id: $workItemId, input: $input) {\n id\n title\n description\n type\n status\n priority\n storyPoints\n dueDate\n labels\n updatedAt\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\n description: string | null;\n type: string;\n status: string;\n priority: string;\n key: string;\n storyPoints: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport function TasksEditTaskPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n // In a real app, workItemId comes from the route params.\n // For now we use a placeholder that the host shell should provide.\n const workItemId = new URLSearchParams(window.location.search).get('taskId') ?? '';\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{\n planmagnetWorkItem: WorkItemNode;\n }>(GET_WORK_ITEM, {\n variables: { workItemId },\n skip: !workspaceId || !workItemId,\n });\n\n const [updateWorkItem, { loading: saving }] = useMutation(UPDATE_WORK_ITEM, {\n refetchQueries: ['GetWorkItems', 'GetWorkItemDetail', 'GetWorkItemCounts', 'ProjectBoard'],\n awaitRefetchQueries: true,\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const workItem = data?.planmagnetWorkItem;\n\n const defaultForm = useMemo(\n () => ({\n title: workItem?.title ?? '',\n description: workItem?.description ?? '',\n priority: workItem?.priority ?? 'MEDIUM',\n type: workItem?.type ?? 'STORY',\n storyPoints: workItem?.storyPoints?.toString() ?? '',\n labels: (workItem?.labels ?? []).join(', '),\n // A date input needs YYYY-MM-DD; the API returns a full ISO timestamp.\n dueDate: workItem?.dueDate ? String(workItem.dueDate).slice(0, 10) : '',\n }),\n [workItem]\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 // Story points are a whole number, 0 or more (BOFF-7833); the service refuses anything else.\n const storyPoints = parseIntField(form.storyPoints, { min: 0 });\n\n // BOFF-7979: only changed fields are sent; an emptied field is cleared (it used to be omitted, so the old value\n // stayed); success is confirmed (there was no message at all).\n const handleSave = async () => {\n if (!workspaceId || !workItemId || storyPoints.invalid) return;\n if (!form.title.trim()) {\n setSaveError('A task needs a title.');\n return;\n }\n const labelList = (v: string) =>\n v\n .split(',')\n .map((l) => l.trim())\n .filter(Boolean);\n const next: Record<string, unknown> = {\n title: form.title.trim(),\n description: form.description.trim() || null,\n priority: form.priority,\n type: form.type,\n storyPoints: storyPoints.value ?? null,\n labels: labelList(form.labels),\n dueDate: form.dueDate || null,\n };\n const before: Record<string, unknown> = {\n title: defaultForm.title,\n description: defaultForm.description.trim() || null,\n priority: defaultForm.priority,\n type: defaultForm.type,\n storyPoints: defaultForm.storyPoints === '' ? null : Number(defaultForm.storyPoints),\n labels: labelList(defaultForm.labels),\n dueDate: defaultForm.dueDate || null,\n };\n const input = Object.fromEntries(\n Object.entries(next).filter(([k, v]) => JSON.stringify(v) !== JSON.stringify(before[k]))\n );\n setSaveError(null);\n setSaved(false);\n if (Object.keys(input).length === 0) {\n setSaved(true);\n return;\n }\n try {\n await throwOnError(updateWorkItem({ variables: { workItemId, input } }));\n setSaved(true);\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The task could not be saved.');\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 <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Error: {error.message}</div>;\n }\n\n if (!data?.planmagnetWorkItem) {\n return <div className=\"p-6 text-muted-foreground\">Task not found.</div>;\n }\n\n const task = data.planmagnetWorkItem;\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\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Back to the task\"\n onClick={() =>\n navigate(`/tasks/task-detail-page?taskId=${encodeURIComponent(workItemId)}`)\n }\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Task</h1>\n <p className=\"text-sm text-muted-foreground\">{task.title}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || storyPoints.invalid}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\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 bg-destructive/10 text-destructive rounded-md text-sm\">\n {saveError}\n </div>\n )}\n <Card>\n <CardHeader>\n <CardTitle>Task Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: 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-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Priority</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.priority}\n onChange={(e) => setForm({ ...form, priority: e.target.value })}\n >\n {/* Every WorkItemPriority: NONE was missing, so a NONE task showed as \"low\" (BOFF-7985). */}\n {WORK_ITEM_PRIORITIES.map((p) => (\n <option key={p} value={p}>\n {p.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Type</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.type}\n onChange={(e) => setForm({ ...form, type: e.target.value })}\n >\n {['STORY', 'BUG', 'TASK', 'EPIC', 'SUB_TASK'].map((t) => (\n <option key={t} value={t}>\n {t.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"task-story-points\" className=\"text-sm font-medium\">\n Story Points\n </label>\n <Input\n id=\"task-story-points\"\n type=\"number\"\n min={0}\n step={1}\n value={form.storyPoints}\n onChange={(e) => setForm({ ...form, storyPoints: e.target.value })}\n aria-invalid={storyPoints.invalid}\n className=\"mt-1\"\n />\n {storyPoints.invalid && (\n <p role=\"alert\" className=\"mt-1 text-xs text-destructive\">\n Story points must be a whole number, 0 or more.\n </p>\n )}\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Due Date</label>\n <Input\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm({ ...form, dueDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Labels</label>\n <Input\n value={form.labels}\n onChange={(e) => setForm({ ...form, labels: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TasksTaskDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"names":[],"mappings":"AAySA,wBAAgB,uBAAuB,4CAkItC"}
1
+ {"version":3,"file":"TasksTaskDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"names":[],"mappings":"AA+UA,wBAAgB,uBAAuB,4CAuItC"}