@burdenoff/microfe-planmagnet 2026.730.2 → 2026.730.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/wspace-types.d.ts +189 -0
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.js +116 -98
- package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +33 -21
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.d.ts +2 -0
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js +126 -0
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js.map +1 -0
- package/dist/planmagnet/pages/GoalsGoalsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/GoalsGoalsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/GoalsGoalsPagePage.js +160 -0
- package/dist/planmagnet/pages/GoalsGoalsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js +426 -0
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
|
+
import { useState as n } from "react";
|
|
3
|
+
import { ArrowLeft as r, Calendar as i, Flag as a, Plus as o, Trash2 as s, User as c } from "lucide-react";
|
|
4
|
+
import { gql as l } from "@apollo/client";
|
|
5
|
+
import { useMutation as u, useQuery as d } from "@apollo/client/react";
|
|
6
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
7
|
+
import { Badge as m, Button as h, Card as g, CardContent as _, CardHeader as v, CardTitle as y, Input as b } from "@burdenoff/fe-libs/ui";
|
|
8
|
+
//#region src/planmagnet/pages/GoalsObjectiveDetailPagePage.tsx
|
|
9
|
+
var x = l`
|
|
10
|
+
query GetObjectiveDetail($id: ID!) {
|
|
11
|
+
planmagnetObjective(id: $id) {
|
|
12
|
+
id
|
|
13
|
+
workspaceId
|
|
14
|
+
title
|
|
15
|
+
description
|
|
16
|
+
ownerId
|
|
17
|
+
periodLabel
|
|
18
|
+
startDate
|
|
19
|
+
endDate
|
|
20
|
+
status
|
|
21
|
+
progress
|
|
22
|
+
createdAt
|
|
23
|
+
keyResults {
|
|
24
|
+
id
|
|
25
|
+
title
|
|
26
|
+
description
|
|
27
|
+
metricType
|
|
28
|
+
startValue
|
|
29
|
+
targetValue
|
|
30
|
+
currentValue
|
|
31
|
+
unit
|
|
32
|
+
status
|
|
33
|
+
ownerId
|
|
34
|
+
progress
|
|
35
|
+
linkedWorkItemRollup {
|
|
36
|
+
totalLinked
|
|
37
|
+
doneCount
|
|
38
|
+
completionRatio
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
`, S = l`
|
|
44
|
+
mutation CreateKeyResult($input: PlanmagnetCreateKeyResultInput!) {
|
|
45
|
+
planmagnetCreateKeyResult(input: $input) {
|
|
46
|
+
id
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
`, C = l`
|
|
50
|
+
mutation UpdateKeyResult($id: ID!, $input: PlanmagnetUpdateKeyResultInput!) {
|
|
51
|
+
planmagnetUpdateKeyResult(id: $id, input: $input) {
|
|
52
|
+
id
|
|
53
|
+
currentValue
|
|
54
|
+
status
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
`, w = l`
|
|
58
|
+
mutation DeleteKeyResult($id: ID!) {
|
|
59
|
+
planmagnetDeleteKeyResult(id: $id)
|
|
60
|
+
}
|
|
61
|
+
`, T = l`
|
|
62
|
+
mutation DeleteObjective($id: ID!) {
|
|
63
|
+
planmagnetDeleteObjective(id: $id)
|
|
64
|
+
}
|
|
65
|
+
`, E = {
|
|
66
|
+
DRAFT: "bg-gray-100 text-gray-800",
|
|
67
|
+
ACTIVE: "bg-blue-100 text-blue-800",
|
|
68
|
+
COMPLETED: "bg-green-100 text-green-800",
|
|
69
|
+
CANCELLED: "bg-red-100 text-red-800"
|
|
70
|
+
}, D = {
|
|
71
|
+
NOT_STARTED: "bg-gray-100 text-gray-800",
|
|
72
|
+
IN_PROGRESS: "bg-blue-100 text-blue-800",
|
|
73
|
+
AT_RISK: "bg-orange-100 text-orange-800",
|
|
74
|
+
COMPLETED: "bg-green-100 text-green-800"
|
|
75
|
+
};
|
|
76
|
+
function O({ progress: e }) {
|
|
77
|
+
return /* @__PURE__ */ f("div", {
|
|
78
|
+
className: "h-2 w-full rounded-full bg-muted overflow-hidden",
|
|
79
|
+
children: /* @__PURE__ */ f("div", {
|
|
80
|
+
className: "h-full rounded-full bg-primary transition-all",
|
|
81
|
+
style: { width: `${Math.max(0, Math.min(100, Math.round(e)))}%` }
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function k({ kr: e, onUpdated: t, onDeleted: r }) {
|
|
86
|
+
let [i, a] = n(String(e.currentValue)), [o, { loading: c }] = u(C), [l, { loading: d }] = u(w);
|
|
87
|
+
return /* @__PURE__ */ p("div", {
|
|
88
|
+
className: "rounded-md border border-input p-4 space-y-3",
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ p("div", {
|
|
91
|
+
className: "flex items-start justify-between gap-3",
|
|
92
|
+
children: [/* @__PURE__ */ p("div", {
|
|
93
|
+
className: "min-w-0",
|
|
94
|
+
children: [/* @__PURE__ */ f("p", {
|
|
95
|
+
className: "text-sm font-medium",
|
|
96
|
+
children: e.title
|
|
97
|
+
}), e.description && /* @__PURE__ */ f("p", {
|
|
98
|
+
className: "text-xs text-muted-foreground mt-0.5",
|
|
99
|
+
children: e.description
|
|
100
|
+
})]
|
|
101
|
+
}), /* @__PURE__ */ p("div", {
|
|
102
|
+
className: "flex items-center gap-2 shrink-0",
|
|
103
|
+
children: [/* @__PURE__ */ f("span", {
|
|
104
|
+
className: `text-xs px-2 py-0.5 rounded-full capitalize ${D[e.status] ?? ""}`,
|
|
105
|
+
children: e.status.toLowerCase().replace("_", " ")
|
|
106
|
+
}), /* @__PURE__ */ f(h, {
|
|
107
|
+
size: "icon",
|
|
108
|
+
variant: "ghost",
|
|
109
|
+
disabled: d,
|
|
110
|
+
onClick: async () => {
|
|
111
|
+
await l({ variables: { id: e.id } }), r();
|
|
112
|
+
},
|
|
113
|
+
"aria-label": `Delete ${e.title}`,
|
|
114
|
+
children: /* @__PURE__ */ f(s, { className: "h-4 w-4" })
|
|
115
|
+
})]
|
|
116
|
+
})]
|
|
117
|
+
}),
|
|
118
|
+
/* @__PURE__ */ f(O, { progress: e.progress }),
|
|
119
|
+
/* @__PURE__ */ p("div", {
|
|
120
|
+
className: "flex items-center justify-between text-xs text-muted-foreground",
|
|
121
|
+
children: [/* @__PURE__ */ f("span", { children: e.metricType === "BOOLEAN" ? e.currentValue > 0 ? "Done" : "Not done" : `${e.currentValue}${e.unit ? ` ${e.unit}` : ""} of ${e.targetValue}${e.unit ? ` ${e.unit}` : ""}` }), /* @__PURE__ */ p("span", { children: [Math.round(e.progress), "%"] })]
|
|
122
|
+
}),
|
|
123
|
+
e.linkedWorkItemRollup.totalLinked > 0 && /* @__PURE__ */ p("p", {
|
|
124
|
+
className: "text-xs text-muted-foreground",
|
|
125
|
+
children: [
|
|
126
|
+
e.linkedWorkItemRollup.doneCount,
|
|
127
|
+
"/",
|
|
128
|
+
e.linkedWorkItemRollup.totalLinked,
|
|
129
|
+
" linked work items done (",
|
|
130
|
+
Math.round(e.linkedWorkItemRollup.completionRatio * 100),
|
|
131
|
+
"%) — informational, update progress above manually"
|
|
132
|
+
]
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ p("div", {
|
|
135
|
+
className: "flex items-center gap-2",
|
|
136
|
+
children: [e.metricType === "BOOLEAN" ? /* @__PURE__ */ p("select", {
|
|
137
|
+
className: "rounded-md border border-input bg-background px-3 py-1.5 text-sm",
|
|
138
|
+
value: i,
|
|
139
|
+
onChange: (e) => a(e.target.value),
|
|
140
|
+
children: [/* @__PURE__ */ f("option", {
|
|
141
|
+
value: "0",
|
|
142
|
+
children: "Not done"
|
|
143
|
+
}), /* @__PURE__ */ f("option", {
|
|
144
|
+
value: "1",
|
|
145
|
+
children: "Done"
|
|
146
|
+
})]
|
|
147
|
+
}) : /* @__PURE__ */ f(b, {
|
|
148
|
+
type: "number",
|
|
149
|
+
value: i,
|
|
150
|
+
onChange: (e) => a(e.target.value),
|
|
151
|
+
className: "w-32"
|
|
152
|
+
}), /* @__PURE__ */ f(h, {
|
|
153
|
+
size: "sm",
|
|
154
|
+
variant: "outline",
|
|
155
|
+
disabled: c,
|
|
156
|
+
onClick: async () => {
|
|
157
|
+
let n = e.metricType === "BOOLEAN" ? +(i === "1") : Number(i);
|
|
158
|
+
Number.isNaN(n) || (await o({ variables: {
|
|
159
|
+
id: e.id,
|
|
160
|
+
input: { currentValue: n }
|
|
161
|
+
} }), t());
|
|
162
|
+
},
|
|
163
|
+
children: c ? "Saving..." : "Update progress"
|
|
164
|
+
})]
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
function A() {
|
|
170
|
+
let { workspaceId: l } = e(), C = t(), w = new URLSearchParams(window.location.search).get("objectiveId") ?? "", [D, A] = n(!1), [j, M] = n({
|
|
171
|
+
title: "",
|
|
172
|
+
metricType: "NUMERIC",
|
|
173
|
+
targetValue: "100",
|
|
174
|
+
unit: ""
|
|
175
|
+
}), { data: N, loading: P, error: F, refetch: I } = d(x, {
|
|
176
|
+
variables: { id: w },
|
|
177
|
+
skip: !l || !w
|
|
178
|
+
}), [L, { loading: R }] = u(S), [z, { loading: B }] = u(T);
|
|
179
|
+
if (P) return /* @__PURE__ */ f("div", {
|
|
180
|
+
className: "flex items-center justify-center p-12",
|
|
181
|
+
children: /* @__PURE__ */ f("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
182
|
+
});
|
|
183
|
+
if (F) return /* @__PURE__ */ p("div", {
|
|
184
|
+
className: "p-6 text-red-500",
|
|
185
|
+
children: ["Error: ", F.message]
|
|
186
|
+
});
|
|
187
|
+
let V = N?.planmagnetObjective;
|
|
188
|
+
return V ? /* @__PURE__ */ p("div", {
|
|
189
|
+
className: "space-y-6 p-6",
|
|
190
|
+
children: [/* @__PURE__ */ p("div", {
|
|
191
|
+
className: "flex items-center justify-between",
|
|
192
|
+
children: [/* @__PURE__ */ p("div", {
|
|
193
|
+
className: "flex items-center gap-3",
|
|
194
|
+
children: [
|
|
195
|
+
/* @__PURE__ */ f(h, {
|
|
196
|
+
variant: "ghost",
|
|
197
|
+
size: "icon",
|
|
198
|
+
onClick: () => C("/goals/goals-page"),
|
|
199
|
+
children: /* @__PURE__ */ f(r, { className: "h-4 w-4" })
|
|
200
|
+
}),
|
|
201
|
+
/* @__PURE__ */ f(a, { className: "h-6 w-6 text-primary" }),
|
|
202
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
|
|
203
|
+
className: "text-2xl font-semibold",
|
|
204
|
+
children: V.title
|
|
205
|
+
}), /* @__PURE__ */ f("p", {
|
|
206
|
+
className: "text-sm text-muted-foreground",
|
|
207
|
+
children: V.periodLabel
|
|
208
|
+
})] })
|
|
209
|
+
]
|
|
210
|
+
}), /* @__PURE__ */ p("div", {
|
|
211
|
+
className: "flex items-center gap-2",
|
|
212
|
+
children: [/* @__PURE__ */ f("span", {
|
|
213
|
+
className: `text-xs px-3 py-1 rounded-full capitalize ${E[V.status] ?? "bg-gray-100"}`,
|
|
214
|
+
children: V.status.toLowerCase()
|
|
215
|
+
}), /* @__PURE__ */ p(h, {
|
|
216
|
+
variant: "outline",
|
|
217
|
+
size: "sm",
|
|
218
|
+
disabled: B,
|
|
219
|
+
onClick: async () => {
|
|
220
|
+
await z({ variables: { id: w } }), C("/goals/goals-page");
|
|
221
|
+
},
|
|
222
|
+
children: [/* @__PURE__ */ f(s, { className: "mr-1 h-4 w-4" }), "Delete"]
|
|
223
|
+
})]
|
|
224
|
+
})]
|
|
225
|
+
}), /* @__PURE__ */ p("div", {
|
|
226
|
+
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
227
|
+
children: [/* @__PURE__ */ p("div", {
|
|
228
|
+
className: "lg:col-span-2 space-y-6",
|
|
229
|
+
children: [/* @__PURE__ */ p(g, { children: [/* @__PURE__ */ p(v, {
|
|
230
|
+
className: "flex flex-row items-center justify-between space-y-0",
|
|
231
|
+
children: [/* @__PURE__ */ f(y, { children: "Overview" }), /* @__PURE__ */ p(m, {
|
|
232
|
+
variant: "outline",
|
|
233
|
+
children: [Math.round(V.progress), "% complete"]
|
|
234
|
+
})]
|
|
235
|
+
}), /* @__PURE__ */ p(_, {
|
|
236
|
+
className: "space-y-4",
|
|
237
|
+
children: [/* @__PURE__ */ f("p", {
|
|
238
|
+
className: "text-sm",
|
|
239
|
+
children: V.description ?? "No description provided."
|
|
240
|
+
}), /* @__PURE__ */ f(O, { progress: V.progress })]
|
|
241
|
+
})] }), /* @__PURE__ */ p(g, { children: [/* @__PURE__ */ p(v, {
|
|
242
|
+
className: "flex flex-row items-center justify-between space-y-0",
|
|
243
|
+
children: [/* @__PURE__ */ f(y, { children: "Key Results" }), !D && /* @__PURE__ */ p(h, {
|
|
244
|
+
size: "sm",
|
|
245
|
+
variant: "outline",
|
|
246
|
+
onClick: () => A(!0),
|
|
247
|
+
children: [/* @__PURE__ */ f(o, { className: "mr-1 h-4 w-4" }), "Add Key Result"]
|
|
248
|
+
})]
|
|
249
|
+
}), /* @__PURE__ */ p(_, {
|
|
250
|
+
className: "space-y-4",
|
|
251
|
+
children: [
|
|
252
|
+
D && /* @__PURE__ */ p("div", {
|
|
253
|
+
className: "space-y-3 rounded-md border border-input p-3",
|
|
254
|
+
children: [
|
|
255
|
+
/* @__PURE__ */ f(b, {
|
|
256
|
+
placeholder: "Key result title, e.g. Sign 10 new enterprise customers",
|
|
257
|
+
value: j.title,
|
|
258
|
+
onChange: (e) => M({
|
|
259
|
+
...j,
|
|
260
|
+
title: e.target.value
|
|
261
|
+
})
|
|
262
|
+
}),
|
|
263
|
+
/* @__PURE__ */ p("div", {
|
|
264
|
+
className: "grid grid-cols-3 gap-3",
|
|
265
|
+
children: [
|
|
266
|
+
/* @__PURE__ */ p("select", {
|
|
267
|
+
className: "rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
268
|
+
value: j.metricType,
|
|
269
|
+
onChange: (e) => M({
|
|
270
|
+
...j,
|
|
271
|
+
metricType: e.target.value
|
|
272
|
+
}),
|
|
273
|
+
children: [
|
|
274
|
+
/* @__PURE__ */ f("option", {
|
|
275
|
+
value: "NUMERIC",
|
|
276
|
+
children: "Numeric"
|
|
277
|
+
}),
|
|
278
|
+
/* @__PURE__ */ f("option", {
|
|
279
|
+
value: "PERCENTAGE",
|
|
280
|
+
children: "Percentage"
|
|
281
|
+
}),
|
|
282
|
+
/* @__PURE__ */ f("option", {
|
|
283
|
+
value: "BOOLEAN",
|
|
284
|
+
children: "Yes / No"
|
|
285
|
+
})
|
|
286
|
+
]
|
|
287
|
+
}),
|
|
288
|
+
j.metricType !== "BOOLEAN" && /* @__PURE__ */ f(b, {
|
|
289
|
+
type: "number",
|
|
290
|
+
placeholder: "Target value",
|
|
291
|
+
value: j.targetValue,
|
|
292
|
+
onChange: (e) => M({
|
|
293
|
+
...j,
|
|
294
|
+
targetValue: e.target.value
|
|
295
|
+
})
|
|
296
|
+
}),
|
|
297
|
+
j.metricType === "NUMERIC" && /* @__PURE__ */ f(b, {
|
|
298
|
+
placeholder: "Unit (optional)",
|
|
299
|
+
value: j.unit,
|
|
300
|
+
onChange: (e) => M({
|
|
301
|
+
...j,
|
|
302
|
+
unit: e.target.value
|
|
303
|
+
})
|
|
304
|
+
})
|
|
305
|
+
]
|
|
306
|
+
}),
|
|
307
|
+
/* @__PURE__ */ p("div", {
|
|
308
|
+
className: "flex gap-2 justify-end",
|
|
309
|
+
children: [/* @__PURE__ */ f(h, {
|
|
310
|
+
size: "sm",
|
|
311
|
+
variant: "ghost",
|
|
312
|
+
onClick: () => {
|
|
313
|
+
A(!1), M({
|
|
314
|
+
title: "",
|
|
315
|
+
metricType: "NUMERIC",
|
|
316
|
+
targetValue: "100",
|
|
317
|
+
unit: ""
|
|
318
|
+
});
|
|
319
|
+
},
|
|
320
|
+
children: "Cancel"
|
|
321
|
+
}), /* @__PURE__ */ f(h, {
|
|
322
|
+
size: "sm",
|
|
323
|
+
disabled: R || !j.title.trim(),
|
|
324
|
+
onClick: async () => {
|
|
325
|
+
if (!j.title.trim() || !w) return;
|
|
326
|
+
let e = Number(j.metricType === "BOOLEAN" ? 1 : j.targetValue);
|
|
327
|
+
Number.isNaN(e) || (await L({ variables: { input: {
|
|
328
|
+
objectiveId: w,
|
|
329
|
+
title: j.title.trim(),
|
|
330
|
+
metricType: j.metricType,
|
|
331
|
+
targetValue: e,
|
|
332
|
+
unit: j.unit.trim() || void 0
|
|
333
|
+
} } }), M({
|
|
334
|
+
title: "",
|
|
335
|
+
metricType: "NUMERIC",
|
|
336
|
+
targetValue: "100",
|
|
337
|
+
unit: ""
|
|
338
|
+
}), A(!1), I());
|
|
339
|
+
},
|
|
340
|
+
children: R ? "Adding..." : "Add Key Result"
|
|
341
|
+
})]
|
|
342
|
+
})
|
|
343
|
+
]
|
|
344
|
+
}),
|
|
345
|
+
V.keyResults.length === 0 && !D && /* @__PURE__ */ f("p", {
|
|
346
|
+
className: "text-sm text-muted-foreground",
|
|
347
|
+
children: "No key results yet. Add one to make this objective measurable."
|
|
348
|
+
}),
|
|
349
|
+
V.keyResults.map((e) => /* @__PURE__ */ f(k, {
|
|
350
|
+
kr: e,
|
|
351
|
+
onUpdated: () => void I(),
|
|
352
|
+
onDeleted: () => void I()
|
|
353
|
+
}, e.id))
|
|
354
|
+
]
|
|
355
|
+
})] })]
|
|
356
|
+
}), /* @__PURE__ */ p(g, { children: [/* @__PURE__ */ f(v, { children: /* @__PURE__ */ f(y, { children: "Details" }) }), /* @__PURE__ */ p(_, {
|
|
357
|
+
className: "space-y-3 text-sm",
|
|
358
|
+
children: [
|
|
359
|
+
/* @__PURE__ */ p("div", {
|
|
360
|
+
className: "flex items-center gap-2",
|
|
361
|
+
children: [
|
|
362
|
+
/* @__PURE__ */ f(c, { className: "h-4 w-4 text-muted-foreground" }),
|
|
363
|
+
/* @__PURE__ */ f("span", {
|
|
364
|
+
className: "text-muted-foreground",
|
|
365
|
+
children: "Owner:"
|
|
366
|
+
}),
|
|
367
|
+
/* @__PURE__ */ f("span", {
|
|
368
|
+
className: "font-medium",
|
|
369
|
+
children: V.ownerId
|
|
370
|
+
})
|
|
371
|
+
]
|
|
372
|
+
}),
|
|
373
|
+
/* @__PURE__ */ p("div", {
|
|
374
|
+
className: "flex items-center gap-2",
|
|
375
|
+
children: [
|
|
376
|
+
/* @__PURE__ */ f(i, { className: "h-4 w-4 text-muted-foreground" }),
|
|
377
|
+
/* @__PURE__ */ f("span", {
|
|
378
|
+
className: "text-muted-foreground",
|
|
379
|
+
children: "Period:"
|
|
380
|
+
}),
|
|
381
|
+
/* @__PURE__ */ f("span", {
|
|
382
|
+
className: "font-medium",
|
|
383
|
+
children: V.periodLabel
|
|
384
|
+
})
|
|
385
|
+
]
|
|
386
|
+
}),
|
|
387
|
+
V.endDate && /* @__PURE__ */ p("div", {
|
|
388
|
+
className: "flex items-center gap-2",
|
|
389
|
+
children: [
|
|
390
|
+
/* @__PURE__ */ f(i, { className: "h-4 w-4 text-muted-foreground" }),
|
|
391
|
+
/* @__PURE__ */ f("span", {
|
|
392
|
+
className: "text-muted-foreground",
|
|
393
|
+
children: "Target end:"
|
|
394
|
+
}),
|
|
395
|
+
/* @__PURE__ */ f("span", {
|
|
396
|
+
className: "font-medium",
|
|
397
|
+
children: new Date(V.endDate).toLocaleDateString()
|
|
398
|
+
})
|
|
399
|
+
]
|
|
400
|
+
}),
|
|
401
|
+
/* @__PURE__ */ p("div", {
|
|
402
|
+
className: "flex items-center gap-2",
|
|
403
|
+
children: [
|
|
404
|
+
/* @__PURE__ */ f(i, { className: "h-4 w-4 text-muted-foreground" }),
|
|
405
|
+
/* @__PURE__ */ f("span", {
|
|
406
|
+
className: "text-muted-foreground",
|
|
407
|
+
children: "Created:"
|
|
408
|
+
}),
|
|
409
|
+
/* @__PURE__ */ f("span", {
|
|
410
|
+
className: "font-medium",
|
|
411
|
+
children: V.createdAt ? new Date(V.createdAt).toLocaleDateString() : "—"
|
|
412
|
+
})
|
|
413
|
+
]
|
|
414
|
+
})
|
|
415
|
+
]
|
|
416
|
+
})] })]
|
|
417
|
+
})]
|
|
418
|
+
}) : /* @__PURE__ */ f("div", {
|
|
419
|
+
className: "p-6 text-muted-foreground",
|
|
420
|
+
children: "Objective not found."
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
//#endregion
|
|
424
|
+
export { A as GoalsObjectiveDetailPagePage };
|
|
425
|
+
|
|
426
|
+
//# sourceMappingURL=GoalsObjectiveDetailPagePage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoalsObjectiveDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/GoalsObjectiveDetailPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } 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 { Flag, Calendar, User, Plus, Trash2, ArrowLeft } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\n\n// BOFF-4441: OKR detail — real Objective + KeyResult data via GraphQL.\n// `progress` (on both the objective and each key result) is computed live\n// server-side from current/target values; this page only ever reads it,\n// never derives it client-side. `linkedWorkItemRollup` surfaces a real,\n// live-computed completion ratio over WorkItems linked to a key result --\n// informational only, it does not drive `currentValue` (see the backend\n// module header for the explicit deferral of that automation).\nconst GET_OBJECTIVE = gql`\n query GetObjectiveDetail($id: ID!) {\n planmagnetObjective(id: $id) {\n id\n workspaceId\n title\n description\n ownerId\n periodLabel\n startDate\n endDate\n status\n progress\n createdAt\n keyResults {\n id\n title\n description\n metricType\n startValue\n targetValue\n currentValue\n unit\n status\n ownerId\n progress\n linkedWorkItemRollup {\n totalLinked\n doneCount\n completionRatio\n }\n }\n }\n }\n`;\n\nconst CREATE_KEY_RESULT = gql`\n mutation CreateKeyResult($input: PlanmagnetCreateKeyResultInput!) {\n planmagnetCreateKeyResult(input: $input) {\n id\n }\n }\n`;\n\nconst UPDATE_KEY_RESULT = gql`\n mutation UpdateKeyResult($id: ID!, $input: PlanmagnetUpdateKeyResultInput!) {\n planmagnetUpdateKeyResult(id: $id, input: $input) {\n id\n currentValue\n status\n }\n }\n`;\n\nconst DELETE_KEY_RESULT = gql`\n mutation DeleteKeyResult($id: ID!) {\n planmagnetDeleteKeyResult(id: $id)\n }\n`;\n\nconst DELETE_OBJECTIVE = gql`\n mutation DeleteObjective($id: ID!) {\n planmagnetDeleteObjective(id: $id)\n }\n`;\n\nconst objectiveStatusColor: Record<string, string> = {\n DRAFT: 'bg-gray-100 text-gray-800',\n ACTIVE: 'bg-blue-100 text-blue-800',\n COMPLETED: 'bg-green-100 text-green-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nconst krStatusColor: Record<string, string> = {\n NOT_STARTED: 'bg-gray-100 text-gray-800',\n IN_PROGRESS: 'bg-blue-100 text-blue-800',\n AT_RISK: 'bg-orange-100 text-orange-800',\n COMPLETED: 'bg-green-100 text-green-800',\n};\n\nfunction ProgressBar({ progress }: { progress: number }) {\n const pct = Math.max(0, Math.min(100, Math.round(progress)));\n return (\n <div className=\"h-2 w-full rounded-full bg-muted overflow-hidden\">\n <div className=\"h-full rounded-full bg-primary transition-all\" style={{ width: `${pct}%` }} />\n </div>\n );\n}\n\ninterface KeyResultNode {\n id: string;\n title: string;\n description: string | null;\n metricType: 'NUMERIC' | 'PERCENTAGE' | 'BOOLEAN';\n startValue: number;\n targetValue: number;\n currentValue: number;\n unit: string | null;\n status: string;\n ownerId: string | null;\n progress: number;\n linkedWorkItemRollup: { totalLinked: number; doneCount: number; completionRatio: number };\n}\n\nfunction KeyResultRow({\n kr,\n onUpdated,\n onDeleted,\n}: {\n kr: KeyResultNode;\n onUpdated: () => void;\n onDeleted: () => void;\n}) {\n const [draftValue, setDraftValue] = useState(String(kr.currentValue));\n const [updateKeyResult, { loading: updating }] = useMutation(UPDATE_KEY_RESULT);\n const [deleteKeyResult, { loading: deleting }] = useMutation(DELETE_KEY_RESULT);\n\n const handleSaveProgress = async () => {\n const parsed = kr.metricType === 'BOOLEAN' ? (draftValue === '1' ? 1 : 0) : Number(draftValue);\n if (Number.isNaN(parsed)) return;\n await updateKeyResult({ variables: { id: kr.id, input: { currentValue: parsed } } });\n onUpdated();\n };\n\n const handleDelete = async () => {\n await deleteKeyResult({ variables: { id: kr.id } });\n onDeleted();\n };\n\n return (\n <div className=\"rounded-md border border-input p-4 space-y-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium\">{kr.title}</p>\n {kr.description && (\n <p className=\"text-xs text-muted-foreground mt-0.5\">{kr.description}</p>\n )}\n </div>\n <div className=\"flex items-center gap-2 shrink-0\">\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${krStatusColor[kr.status] ?? ''}`}\n >\n {kr.status.toLowerCase().replace('_', ' ')}\n </span>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n disabled={deleting}\n onClick={handleDelete}\n aria-label={`Delete ${kr.title}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n <ProgressBar progress={kr.progress} />\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>\n {kr.metricType === 'BOOLEAN'\n ? kr.currentValue > 0\n ? 'Done'\n : 'Not done'\n : `${kr.currentValue}${kr.unit ? ` ${kr.unit}` : ''} of ${kr.targetValue}${kr.unit ? ` ${kr.unit}` : ''}`}\n </span>\n <span>{Math.round(kr.progress)}%</span>\n </div>\n {kr.linkedWorkItemRollup.totalLinked > 0 && (\n <p className=\"text-xs text-muted-foreground\">\n {kr.linkedWorkItemRollup.doneCount}/{kr.linkedWorkItemRollup.totalLinked} linked work\n items done ({Math.round(kr.linkedWorkItemRollup.completionRatio * 100)}%) —\n informational, update progress above manually\n </p>\n )}\n <div className=\"flex items-center gap-2\">\n {kr.metricType === 'BOOLEAN' ? (\n <select\n className=\"rounded-md border border-input bg-background px-3 py-1.5 text-sm\"\n value={draftValue}\n onChange={(e) => setDraftValue(e.target.value)}\n >\n <option value=\"0\">Not done</option>\n <option value=\"1\">Done</option>\n </select>\n ) : (\n <Input\n type=\"number\"\n value={draftValue}\n onChange={(e) => setDraftValue(e.target.value)}\n className=\"w-32\"\n />\n )}\n <Button size=\"sm\" variant=\"outline\" disabled={updating} onClick={handleSaveProgress}>\n {updating ? 'Saving...' : 'Update progress'}\n </Button>\n </div>\n </div>\n );\n}\n\nexport function GoalsObjectiveDetailPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const objectiveId = new URLSearchParams(window.location.search).get('objectiveId') ?? '';\n\n const [isAddingKr, setIsAddingKr] = useState(false);\n const [krForm, setKrForm] = useState({\n title: '',\n metricType: 'NUMERIC',\n targetValue: '100',\n unit: '',\n });\n\n const { data, loading, error, refetch } = useQuery<{\n planmagnetObjective: {\n id: string;\n title: string;\n description: string | null;\n ownerId: string;\n periodLabel: string;\n startDate: string | null;\n endDate: string | null;\n status: string;\n progress: number;\n createdAt: string;\n keyResults: KeyResultNode[];\n } | null;\n }>(GET_OBJECTIVE, {\n variables: { id: objectiveId },\n skip: !workspaceId || !objectiveId,\n });\n\n const [createKeyResult, { loading: creatingKr }] = useMutation(CREATE_KEY_RESULT);\n const [deleteObjective, { loading: deletingObjective }] = useMutation(DELETE_OBJECTIVE);\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 }\n if (error) return <div className=\"p-6 text-red-500\">Error: {error.message}</div>;\n\n const objective = data?.planmagnetObjective;\n if (!objective) return <div className=\"p-6 text-muted-foreground\">Objective not found.</div>;\n\n const handleAddKeyResult = async () => {\n if (!krForm.title.trim() || !objectiveId) return;\n const target = Number(krForm.metricType === 'BOOLEAN' ? 1 : krForm.targetValue);\n if (Number.isNaN(target)) return;\n await createKeyResult({\n variables: {\n input: {\n objectiveId,\n title: krForm.title.trim(),\n metricType: krForm.metricType,\n targetValue: target,\n unit: krForm.unit.trim() || undefined,\n },\n },\n });\n setKrForm({ title: '', metricType: 'NUMERIC', targetValue: '100', unit: '' });\n setIsAddingKr(false);\n void refetch();\n };\n\n const handleDeleteObjective = async () => {\n await deleteObjective({ variables: { id: objectiveId } });\n navigate('/goals/goals-page');\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=\"icon\" onClick={() => navigate('/goals/goals-page')}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <Flag className=\"h-6 w-6 text-primary\" />\n <div>\n <h1 className=\"text-2xl font-semibold\">{objective.title}</h1>\n <p className=\"text-sm text-muted-foreground\">{objective.periodLabel}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span\n className={`text-xs px-3 py-1 rounded-full capitalize ${objectiveStatusColor[objective.status] ?? 'bg-gray-100'}`}\n >\n {objective.status.toLowerCase()}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={deletingObjective}\n onClick={handleDeleteObjective}\n >\n <Trash2 className=\"mr-1 h-4 w-4\" />\n Delete\n </Button>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Overview</CardTitle>\n <Badge variant=\"outline\">{Math.round(objective.progress)}% complete</Badge>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm\">{objective.description ?? 'No description provided.'}</p>\n <ProgressBar progress={objective.progress} />\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Key Results</CardTitle>\n {!isAddingKr && (\n <Button size=\"sm\" variant=\"outline\" onClick={() => setIsAddingKr(true)}>\n <Plus className=\"mr-1 h-4 w-4\" />\n Add Key Result\n </Button>\n )}\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {isAddingKr && (\n <div className=\"space-y-3 rounded-md border border-input p-3\">\n <Input\n placeholder=\"Key result title, e.g. Sign 10 new enterprise customers\"\n value={krForm.title}\n onChange={(e) => setKrForm({ ...krForm, title: e.target.value })}\n />\n <div className=\"grid grid-cols-3 gap-3\">\n <select\n className=\"rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={krForm.metricType}\n onChange={(e) => setKrForm({ ...krForm, metricType: e.target.value })}\n >\n <option value=\"NUMERIC\">Numeric</option>\n <option value=\"PERCENTAGE\">Percentage</option>\n <option value=\"BOOLEAN\">Yes / No</option>\n </select>\n {krForm.metricType !== 'BOOLEAN' && (\n <Input\n type=\"number\"\n placeholder=\"Target value\"\n value={krForm.targetValue}\n onChange={(e) => setKrForm({ ...krForm, targetValue: e.target.value })}\n />\n )}\n {krForm.metricType === 'NUMERIC' && (\n <Input\n placeholder=\"Unit (optional)\"\n value={krForm.unit}\n onChange={(e) => setKrForm({ ...krForm, unit: e.target.value })}\n />\n )}\n </div>\n <div className=\"flex gap-2 justify-end\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setIsAddingKr(false);\n setKrForm({\n title: '',\n metricType: 'NUMERIC',\n targetValue: '100',\n unit: '',\n });\n }}\n >\n Cancel\n </Button>\n <Button\n size=\"sm\"\n disabled={creatingKr || !krForm.title.trim()}\n onClick={handleAddKeyResult}\n >\n {creatingKr ? 'Adding...' : 'Add Key Result'}\n </Button>\n </div>\n </div>\n )}\n {objective.keyResults.length === 0 && !isAddingKr && (\n <p className=\"text-sm text-muted-foreground\">\n No key results yet. Add one to make this objective measurable.\n </p>\n )}\n {objective.keyResults.map((kr) => (\n <KeyResultRow\n key={kr.id}\n kr={kr}\n onUpdated={() => void refetch()}\n onDeleted={() => void refetch()}\n />\n ))}\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Owner:</span>\n <span className=\"font-medium\">{objective.ownerId}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Period:</span>\n <span className=\"font-medium\">{objective.periodLabel}</span>\n </div>\n {objective.endDate && (\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Target end:</span>\n <span className=\"font-medium\">\n {new Date(objective.endDate).toLocaleDateString()}\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Created:</span>\n <span className=\"font-medium\">\n {objective.createdAt ? new Date(objective.createdAt).toLocaleDateString() : '—'}\n </span>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|