@burdenoff/microfe-planmagnet 2026.925.15 → 2026.925.16
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 +7 -0
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +67 -59
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/docs/DocStatusBadge.d.ts +8 -0
- package/dist/planmagnet/docs/DocStatusBadge.d.ts.map +1 -0
- package/dist/planmagnet/docs/DocStatusBadge.js +28 -0
- package/dist/planmagnet/docs/DocStatusBadge.js.map +1 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +410 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/DocsDocsPagePage.d.ts +3 -0
- package/dist/planmagnet/pages/DocsDocsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/DocsDocsPagePage.js +224 -0
- package/dist/planmagnet/pages/DocsDocsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +130 -128
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
|
|
2
|
-
import { throwOnError as t } from "../utils/mutationResult.js";
|
|
1
|
+
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
3
2
|
import { MarkdownEditor as n } from "../../components/MarkdownEditor.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
3
|
+
import { throwOnError as r } from "../utils/mutationResult.js";
|
|
4
|
+
import { WorkItemComments as i } from "../comments/WorkItemComments.js";
|
|
5
|
+
import { WorkItemActivity as a } from "../comments/WorkItemActivity.js";
|
|
6
|
+
import { useState as o } from "react";
|
|
7
|
+
import { FileText as s, Plus as c, X as l } from "lucide-react";
|
|
8
|
+
import { gql as u } from "@apollo/client";
|
|
9
|
+
import { useMutation as d, useQuery as f } from "@apollo/client/react";
|
|
10
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
11
|
+
import { Badge as h, Button as g, Card as _, CardContent as v, CardHeader as y, CardTitle as b, Input as x } from "@burdenoff/fe-libs/ui";
|
|
12
12
|
//#region src/planmagnet/pages/TasksTaskDetailPagePage.tsx
|
|
13
|
-
var
|
|
13
|
+
var S = u`
|
|
14
14
|
query GetWorkItemDetail($workItemId: ID!) {
|
|
15
15
|
planmagnetWorkItem(id: $workItemId) {
|
|
16
16
|
id
|
|
@@ -32,7 +32,7 @@ var x = l`
|
|
|
32
32
|
updatedAt
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
`,
|
|
35
|
+
`, C = u`
|
|
36
36
|
query GetWorkItemDocs($workItemId: ID!) {
|
|
37
37
|
planmagnetWorkItemDocs(workItemId: $workItemId) {
|
|
38
38
|
id
|
|
@@ -42,28 +42,28 @@ var x = l`
|
|
|
42
42
|
updatedAt
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
`,
|
|
45
|
+
`, w = u`
|
|
46
46
|
mutation CreateDocForWorkItem($input: PlanmagnetCreateDocInput!) {
|
|
47
47
|
planmagnetCreateDoc(input: $input) {
|
|
48
48
|
id
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
`,
|
|
51
|
+
`, T = u`
|
|
52
52
|
mutation LinkDocToWorkItem($docId: ID!, $workItemId: ID!) {
|
|
53
53
|
planmagnetLinkDocToWorkItem(docId: $docId, workItemId: $workItemId) {
|
|
54
54
|
id
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
`,
|
|
57
|
+
`, E = u`
|
|
58
58
|
mutation UnlinkDocFromWorkItem($docId: ID!, $workItemId: ID!) {
|
|
59
59
|
planmagnetUnlinkDocFromWorkItem(docId: $docId, workItemId: $workItemId)
|
|
60
60
|
}
|
|
61
|
-
`,
|
|
61
|
+
`, D = {
|
|
62
62
|
LOW: "bg-gray-100 text-gray-800",
|
|
63
63
|
MEDIUM: "bg-blue-100 text-blue-800",
|
|
64
64
|
HIGH: "bg-orange-100 text-orange-800",
|
|
65
65
|
CRITICAL: "bg-red-100 text-red-800"
|
|
66
|
-
},
|
|
66
|
+
}, O = {
|
|
67
67
|
BACKLOG: "bg-gray-100 text-gray-800",
|
|
68
68
|
TODO: "bg-blue-100 text-blue-800",
|
|
69
69
|
IN_PROGRESS: "bg-yellow-100 text-yellow-800",
|
|
@@ -72,276 +72,278 @@ var x = l`
|
|
|
72
72
|
BLOCKED: "bg-red-100 text-red-800",
|
|
73
73
|
TESTING: "bg-teal-100 text-teal-800",
|
|
74
74
|
CANCELLED: "bg-gray-100 text-gray-800"
|
|
75
|
-
},
|
|
75
|
+
}, k = {
|
|
76
76
|
DRAFT: "bg-gray-100 text-gray-800",
|
|
77
77
|
PUBLISHED: "bg-green-100 text-green-800",
|
|
78
78
|
ARCHIVED: "bg-gray-100 text-gray-500"
|
|
79
79
|
};
|
|
80
|
-
function
|
|
81
|
-
let [
|
|
80
|
+
function A({ workItemId: e }) {
|
|
81
|
+
let i = t(), [a, u] = o(!1), [h, S] = o(""), [D, O] = o(""), { data: A, loading: j, error: M, refetch: N } = f(C, {
|
|
82
82
|
variables: { workItemId: e },
|
|
83
83
|
skip: !e
|
|
84
|
-
}), [
|
|
85
|
-
if (!(!
|
|
86
|
-
|
|
84
|
+
}), [P, { loading: F }] = d(w), [I] = d(T), [L, { loading: R }] = d(E), [z, B] = o(null), V = A?.planmagnetWorkItemDocs ?? [], H = async () => {
|
|
85
|
+
if (!(!h.trim() || !D.trim())) {
|
|
86
|
+
B(null);
|
|
87
87
|
try {
|
|
88
|
-
let
|
|
89
|
-
title:
|
|
90
|
-
content:
|
|
88
|
+
let t = (await r(P({ variables: { input: {
|
|
89
|
+
title: h.trim(),
|
|
90
|
+
content: D.trim()
|
|
91
91
|
} } }))).data?.planmagnetCreateDoc?.id;
|
|
92
|
-
|
|
93
|
-
docId:
|
|
92
|
+
t && await r(I({ variables: {
|
|
93
|
+
docId: t,
|
|
94
94
|
workItemId: e
|
|
95
95
|
} }));
|
|
96
96
|
} catch (e) {
|
|
97
|
-
|
|
97
|
+
B(e instanceof Error ? e.message : "The doc could not be saved.");
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
S(""), O(""), u(!1), N();
|
|
101
101
|
}
|
|
102
|
-
},
|
|
103
|
-
|
|
102
|
+
}, U = async (t) => {
|
|
103
|
+
B(null);
|
|
104
104
|
try {
|
|
105
|
-
await
|
|
106
|
-
docId:
|
|
105
|
+
await r(L({ variables: {
|
|
106
|
+
docId: t,
|
|
107
107
|
workItemId: e
|
|
108
108
|
} }));
|
|
109
109
|
} catch (e) {
|
|
110
|
-
|
|
110
|
+
B(e instanceof Error ? e.message : "The doc could not be unlinked.");
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
|
-
|
|
113
|
+
N();
|
|
114
114
|
};
|
|
115
|
-
return /* @__PURE__ */
|
|
115
|
+
return /* @__PURE__ */ m(_, { children: [/* @__PURE__ */ m(y, {
|
|
116
116
|
className: "flex flex-row items-center justify-between space-y-0",
|
|
117
|
-
children: [/* @__PURE__ */
|
|
117
|
+
children: [/* @__PURE__ */ p(b, { children: "Linked Docs" }), !a && /* @__PURE__ */ m(g, {
|
|
118
118
|
size: "sm",
|
|
119
119
|
variant: "outline",
|
|
120
|
-
onClick: () =>
|
|
121
|
-
children: [/* @__PURE__ */
|
|
120
|
+
onClick: () => u(!0),
|
|
121
|
+
children: [/* @__PURE__ */ p(c, { className: "h-4 w-4 mr-1" }), "New Doc"]
|
|
122
122
|
})]
|
|
123
|
-
}), /* @__PURE__ */
|
|
123
|
+
}), /* @__PURE__ */ m(v, {
|
|
124
124
|
className: "space-y-4",
|
|
125
125
|
children: [
|
|
126
|
-
|
|
126
|
+
a && /* @__PURE__ */ m("div", {
|
|
127
127
|
className: "space-y-3 rounded-md border border-input p-3",
|
|
128
128
|
children: [
|
|
129
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ p(x, {
|
|
130
130
|
placeholder: "Doc title",
|
|
131
|
-
value:
|
|
132
|
-
onChange: (e) =>
|
|
131
|
+
value: h,
|
|
132
|
+
onChange: (e) => S(e.target.value)
|
|
133
133
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
135
|
-
value:
|
|
136
|
-
onChange:
|
|
134
|
+
/* @__PURE__ */ p(n, {
|
|
135
|
+
value: D,
|
|
136
|
+
onChange: O,
|
|
137
137
|
placeholder: "Write the spec/doc content...",
|
|
138
138
|
minHeight: 140
|
|
139
139
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ m("div", {
|
|
141
141
|
className: "flex gap-2 justify-end",
|
|
142
|
-
children: [/* @__PURE__ */
|
|
142
|
+
children: [/* @__PURE__ */ p(g, {
|
|
143
143
|
size: "sm",
|
|
144
144
|
variant: "ghost",
|
|
145
145
|
onClick: () => {
|
|
146
|
-
|
|
146
|
+
u(!1), S(""), O("");
|
|
147
147
|
},
|
|
148
148
|
children: "Cancel"
|
|
149
|
-
}), /* @__PURE__ */
|
|
149
|
+
}), /* @__PURE__ */ p(g, {
|
|
150
150
|
size: "sm",
|
|
151
|
-
disabled:
|
|
152
|
-
onClick:
|
|
153
|
-
children:
|
|
151
|
+
disabled: F || !h.trim() || !D.trim(),
|
|
152
|
+
onClick: H,
|
|
153
|
+
children: F ? "Creating..." : "Create & Link"
|
|
154
154
|
})]
|
|
155
155
|
})
|
|
156
156
|
]
|
|
157
157
|
}),
|
|
158
|
-
|
|
158
|
+
j && /* @__PURE__ */ p("p", {
|
|
159
159
|
className: "text-sm text-muted-foreground",
|
|
160
160
|
children: "Loading docs..."
|
|
161
161
|
}),
|
|
162
|
-
|
|
162
|
+
M && /* @__PURE__ */ m("p", {
|
|
163
163
|
className: "text-sm text-red-500",
|
|
164
|
-
children: ["Error: ",
|
|
164
|
+
children: ["Error: ", M.message]
|
|
165
165
|
}),
|
|
166
|
-
|
|
166
|
+
z && /* @__PURE__ */ p("p", {
|
|
167
167
|
role: "alert",
|
|
168
168
|
className: "text-sm text-destructive",
|
|
169
|
-
children:
|
|
169
|
+
children: z
|
|
170
170
|
}),
|
|
171
|
-
!
|
|
171
|
+
!j && !M && V.length === 0 && !a && /* @__PURE__ */ p("p", {
|
|
172
172
|
className: "text-sm text-muted-foreground",
|
|
173
173
|
children: "No docs linked to this work item yet."
|
|
174
174
|
}),
|
|
175
|
-
|
|
175
|
+
V.map((e) => /* @__PURE__ */ m("div", {
|
|
176
176
|
className: "flex items-center justify-between gap-3 rounded-md border border-input p-3",
|
|
177
|
-
children: [/* @__PURE__ */
|
|
177
|
+
children: [/* @__PURE__ */ m("div", {
|
|
178
178
|
className: "flex items-center gap-2 min-w-0",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
179
|
+
children: [/* @__PURE__ */ p(s, { className: "h-4 w-4 text-muted-foreground shrink-0" }), /* @__PURE__ */ m("div", {
|
|
180
180
|
className: "min-w-0",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
182
|
-
|
|
181
|
+
children: [/* @__PURE__ */ p("button", {
|
|
182
|
+
type: "button",
|
|
183
|
+
className: "block max-w-full truncate text-left text-sm font-medium hover:underline",
|
|
184
|
+
onClick: () => i(`/docs/doc-detail-page?docId=${encodeURIComponent(e.id)}`),
|
|
183
185
|
children: e.title
|
|
184
|
-
}), /* @__PURE__ */
|
|
186
|
+
}), /* @__PURE__ */ m("p", {
|
|
185
187
|
className: "text-xs text-muted-foreground",
|
|
186
188
|
children: ["v", e.version]
|
|
187
189
|
})]
|
|
188
190
|
})]
|
|
189
|
-
}), /* @__PURE__ */
|
|
191
|
+
}), /* @__PURE__ */ m("div", {
|
|
190
192
|
className: "flex items-center gap-2 shrink-0",
|
|
191
|
-
children: [/* @__PURE__ */
|
|
192
|
-
className: `text-xs px-2 py-0.5 rounded-full capitalize ${
|
|
193
|
+
children: [/* @__PURE__ */ p("span", {
|
|
194
|
+
className: `text-xs px-2 py-0.5 rounded-full capitalize ${k[e.status] ?? ""}`,
|
|
193
195
|
children: e.status.toLowerCase()
|
|
194
|
-
}), /* @__PURE__ */
|
|
196
|
+
}), /* @__PURE__ */ p(g, {
|
|
195
197
|
size: "icon",
|
|
196
198
|
variant: "ghost",
|
|
197
|
-
disabled:
|
|
198
|
-
onClick: () =>
|
|
199
|
+
disabled: R,
|
|
200
|
+
onClick: () => U(e.id),
|
|
199
201
|
"aria-label": `Unlink ${e.title}`,
|
|
200
|
-
children: /* @__PURE__ */
|
|
202
|
+
children: /* @__PURE__ */ p(l, { className: "h-4 w-4" })
|
|
201
203
|
})]
|
|
202
204
|
})]
|
|
203
205
|
}, e.id))
|
|
204
206
|
]
|
|
205
207
|
})] });
|
|
206
208
|
}
|
|
207
|
-
function
|
|
208
|
-
let { workspaceId: t } = e(), n = new URLSearchParams(window.location.search).get("taskId") ?? "", { data:
|
|
209
|
+
function j() {
|
|
210
|
+
let { workspaceId: t } = e(), n = new URLSearchParams(window.location.search).get("taskId") ?? "", { data: r, loading: o, error: s } = f(S, {
|
|
209
211
|
variables: { workItemId: n },
|
|
210
212
|
skip: !t || !n
|
|
211
213
|
});
|
|
212
|
-
if (o && !
|
|
214
|
+
if (o && !r) return /* @__PURE__ */ p("div", {
|
|
213
215
|
className: "flex items-center justify-center p-12",
|
|
214
|
-
children: /* @__PURE__ */
|
|
216
|
+
children: /* @__PURE__ */ p("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
215
217
|
});
|
|
216
|
-
if (s) return /* @__PURE__ */
|
|
218
|
+
if (s) return /* @__PURE__ */ m("div", {
|
|
217
219
|
className: "p-6 text-red-500",
|
|
218
220
|
children: ["Error: ", s.message]
|
|
219
221
|
});
|
|
220
|
-
let c =
|
|
221
|
-
if (!c) return /* @__PURE__ */
|
|
222
|
+
let c = r?.planmagnetWorkItem;
|
|
223
|
+
if (!c) return /* @__PURE__ */ p("div", {
|
|
222
224
|
className: "p-6 text-muted-foreground",
|
|
223
225
|
children: "Task not found."
|
|
224
226
|
});
|
|
225
227
|
let l = c.status.toLowerCase().replace("_", " ");
|
|
226
|
-
return /* @__PURE__ */
|
|
228
|
+
return /* @__PURE__ */ m("div", {
|
|
227
229
|
className: "space-y-6 p-6",
|
|
228
|
-
children: [/* @__PURE__ */
|
|
230
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
|
|
229
231
|
className: "text-2xl font-semibold",
|
|
230
232
|
children: c.title
|
|
231
|
-
}), /* @__PURE__ */
|
|
233
|
+
}), /* @__PURE__ */ m("p", {
|
|
232
234
|
className: "text-sm text-muted-foreground",
|
|
233
235
|
children: [
|
|
234
236
|
c.key,
|
|
235
237
|
" · ",
|
|
236
238
|
c.type.toLowerCase()
|
|
237
239
|
]
|
|
238
|
-
})] }), /* @__PURE__ */
|
|
240
|
+
})] }), /* @__PURE__ */ m("div", {
|
|
239
241
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
240
|
-
children: [/* @__PURE__ */
|
|
242
|
+
children: [/* @__PURE__ */ m("div", {
|
|
241
243
|
className: "lg:col-span-2 space-y-6",
|
|
242
244
|
children: [
|
|
243
|
-
/* @__PURE__ */
|
|
245
|
+
/* @__PURE__ */ m(_, { children: [/* @__PURE__ */ p(y, { children: /* @__PURE__ */ p(b, { children: "Description" }) }), /* @__PURE__ */ p(v, { children: /* @__PURE__ */ p("p", {
|
|
244
246
|
className: "text-sm",
|
|
245
247
|
children: c.description ?? "No description provided."
|
|
246
248
|
}) })] }),
|
|
247
|
-
/* @__PURE__ */
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
/* @__PURE__ */
|
|
249
|
+
/* @__PURE__ */ p(A, { workItemId: c.id }),
|
|
250
|
+
/* @__PURE__ */ p(i, { workItemId: c.id }),
|
|
251
|
+
/* @__PURE__ */ p(a, { workItemId: c.id })
|
|
250
252
|
]
|
|
251
|
-
}), /* @__PURE__ */
|
|
253
|
+
}), /* @__PURE__ */ p("div", {
|
|
252
254
|
className: "space-y-6",
|
|
253
|
-
children: /* @__PURE__ */
|
|
255
|
+
children: /* @__PURE__ */ m(_, { children: [/* @__PURE__ */ p(y, { children: /* @__PURE__ */ p(b, { children: "Details" }) }), /* @__PURE__ */ m(v, {
|
|
254
256
|
className: "space-y-3 text-sm",
|
|
255
257
|
children: [
|
|
256
|
-
/* @__PURE__ */
|
|
258
|
+
/* @__PURE__ */ m("div", {
|
|
257
259
|
className: "flex justify-between",
|
|
258
|
-
children: [/* @__PURE__ */
|
|
260
|
+
children: [/* @__PURE__ */ p("span", {
|
|
259
261
|
className: "text-muted-foreground",
|
|
260
262
|
children: "Status"
|
|
261
|
-
}), /* @__PURE__ */
|
|
262
|
-
className: `text-xs px-2 py-0.5 rounded-full capitalize ${
|
|
263
|
+
}), /* @__PURE__ */ p("span", {
|
|
264
|
+
className: `text-xs px-2 py-0.5 rounded-full capitalize ${O[c.status] ?? ""}`,
|
|
263
265
|
children: l
|
|
264
266
|
})]
|
|
265
267
|
}),
|
|
266
|
-
/* @__PURE__ */
|
|
268
|
+
/* @__PURE__ */ m("div", {
|
|
267
269
|
className: "flex justify-between",
|
|
268
|
-
children: [/* @__PURE__ */
|
|
270
|
+
children: [/* @__PURE__ */ p("span", {
|
|
269
271
|
className: "text-muted-foreground",
|
|
270
272
|
children: "Priority"
|
|
271
|
-
}), /* @__PURE__ */
|
|
272
|
-
className: `text-xs px-2 py-0.5 rounded-full capitalize ${
|
|
273
|
+
}), /* @__PURE__ */ p("span", {
|
|
274
|
+
className: `text-xs px-2 py-0.5 rounded-full capitalize ${D[c.priority] ?? ""}`,
|
|
273
275
|
children: c.priority.toLowerCase()
|
|
274
276
|
})]
|
|
275
277
|
}),
|
|
276
|
-
/* @__PURE__ */
|
|
278
|
+
/* @__PURE__ */ m("div", {
|
|
277
279
|
className: "flex justify-between",
|
|
278
|
-
children: [/* @__PURE__ */
|
|
280
|
+
children: [/* @__PURE__ */ p("span", {
|
|
279
281
|
className: "text-muted-foreground",
|
|
280
282
|
children: "Type"
|
|
281
|
-
}), /* @__PURE__ */
|
|
283
|
+
}), /* @__PURE__ */ p(h, {
|
|
282
284
|
variant: "outline",
|
|
283
285
|
className: "capitalize",
|
|
284
286
|
children: c.type.toLowerCase()
|
|
285
287
|
})]
|
|
286
288
|
}),
|
|
287
|
-
/* @__PURE__ */
|
|
289
|
+
/* @__PURE__ */ m("div", {
|
|
288
290
|
className: "flex justify-between",
|
|
289
|
-
children: [/* @__PURE__ */
|
|
291
|
+
children: [/* @__PURE__ */ p("span", {
|
|
290
292
|
className: "text-muted-foreground",
|
|
291
293
|
children: "Story Points"
|
|
292
|
-
}), /* @__PURE__ */
|
|
294
|
+
}), /* @__PURE__ */ p("span", {
|
|
293
295
|
className: "font-medium",
|
|
294
296
|
children: c.storyPoints ?? 0
|
|
295
297
|
})]
|
|
296
298
|
}),
|
|
297
|
-
/* @__PURE__ */
|
|
299
|
+
/* @__PURE__ */ m("div", {
|
|
298
300
|
className: "flex justify-between",
|
|
299
|
-
children: [/* @__PURE__ */
|
|
301
|
+
children: [/* @__PURE__ */ p("span", {
|
|
300
302
|
className: "text-muted-foreground",
|
|
301
303
|
children: "Assignee"
|
|
302
|
-
}), /* @__PURE__ */
|
|
304
|
+
}), /* @__PURE__ */ p("span", { children: c.assigneeId ?? "Unassigned" })]
|
|
303
305
|
}),
|
|
304
|
-
/* @__PURE__ */
|
|
306
|
+
/* @__PURE__ */ m("div", {
|
|
305
307
|
className: "flex justify-between",
|
|
306
|
-
children: [/* @__PURE__ */
|
|
308
|
+
children: [/* @__PURE__ */ p("span", {
|
|
307
309
|
className: "text-muted-foreground",
|
|
308
310
|
children: "Reporter"
|
|
309
|
-
}), /* @__PURE__ */
|
|
311
|
+
}), /* @__PURE__ */ p("span", { children: c.reporterId ?? "Unknown" })]
|
|
310
312
|
}),
|
|
311
|
-
/* @__PURE__ */
|
|
313
|
+
/* @__PURE__ */ m("div", {
|
|
312
314
|
className: "flex justify-between",
|
|
313
|
-
children: [/* @__PURE__ */
|
|
315
|
+
children: [/* @__PURE__ */ p("span", {
|
|
314
316
|
className: "text-muted-foreground",
|
|
315
317
|
children: "Key"
|
|
316
|
-
}), /* @__PURE__ */
|
|
318
|
+
}), /* @__PURE__ */ p("span", { children: c.key })]
|
|
317
319
|
}),
|
|
318
|
-
/* @__PURE__ */
|
|
320
|
+
/* @__PURE__ */ m("div", {
|
|
319
321
|
className: "flex justify-between",
|
|
320
|
-
children: [/* @__PURE__ */
|
|
322
|
+
children: [/* @__PURE__ */ p("span", {
|
|
321
323
|
className: "text-muted-foreground",
|
|
322
324
|
children: "Due Date"
|
|
323
|
-
}), /* @__PURE__ */
|
|
325
|
+
}), /* @__PURE__ */ p("span", { children: c.dueDate ?? "Not set" })]
|
|
324
326
|
}),
|
|
325
|
-
/* @__PURE__ */
|
|
327
|
+
/* @__PURE__ */ m("div", {
|
|
326
328
|
className: "flex justify-between",
|
|
327
|
-
children: [/* @__PURE__ */
|
|
329
|
+
children: [/* @__PURE__ */ p("span", {
|
|
328
330
|
className: "text-muted-foreground",
|
|
329
331
|
children: "Created"
|
|
330
|
-
}), /* @__PURE__ */
|
|
332
|
+
}), /* @__PURE__ */ p("span", { children: c.createdAt })]
|
|
331
333
|
}),
|
|
332
|
-
/* @__PURE__ */
|
|
334
|
+
/* @__PURE__ */ m("div", {
|
|
333
335
|
className: "flex justify-between",
|
|
334
|
-
children: [/* @__PURE__ */
|
|
336
|
+
children: [/* @__PURE__ */ p("span", {
|
|
335
337
|
className: "text-muted-foreground",
|
|
336
338
|
children: "Updated"
|
|
337
|
-
}), /* @__PURE__ */
|
|
339
|
+
}), /* @__PURE__ */ p("span", { children: c.updatedAt })]
|
|
338
340
|
}),
|
|
339
|
-
/* @__PURE__ */
|
|
341
|
+
/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("span", {
|
|
340
342
|
className: "text-muted-foreground text-xs",
|
|
341
343
|
children: "Labels"
|
|
342
|
-
}), /* @__PURE__ */
|
|
344
|
+
}), /* @__PURE__ */ p("div", {
|
|
343
345
|
className: "flex gap-1 mt-1 flex-wrap",
|
|
344
|
-
children: (c.labels ?? []).map((e) => /* @__PURE__ */
|
|
346
|
+
children: (c.labels ?? []).map((e) => /* @__PURE__ */ p("span", {
|
|
345
347
|
className: "text-xs px-2 py-0.5 rounded bg-muted",
|
|
346
348
|
children: e
|
|
347
349
|
}, e))
|
|
@@ -353,6 +355,6 @@ function A() {
|
|
|
353
355
|
});
|
|
354
356
|
}
|
|
355
357
|
//#endregion
|
|
356
|
-
export {
|
|
358
|
+
export { j as TasksTaskDetailPagePage };
|
|
357
359
|
|
|
358
360
|
//# sourceMappingURL=TasksTaskDetailPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TasksTaskDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { throwOnError } from '../utils/mutationResult';\nimport { WorkItemComments } from '../comments/WorkItemComments';\nimport { WorkItemActivity } from '../comments/WorkItemActivity';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Badge,\n Button,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport { FileText, Plus, X } from 'lucide-react';\nimport { MarkdownEditor } from '#src/components/MarkdownEditor';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\n\nconst GET_WORK_ITEM = gql`\n query GetWorkItemDetail($workItemId: ID!) {\n planmagnetWorkItem(id: $workItemId) {\n id\n title\n description\n type\n status\n priority\n key\n assigneeId\n reporterId\n sprintId\n storyPoints\n estimateMinutes\n dueDate\n labels\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nconst GET_WORK_ITEM_DOCS = gql`\n query GetWorkItemDocs($workItemId: ID!) {\n planmagnetWorkItemDocs(workItemId: $workItemId) {\n id\n title\n status\n version\n updatedAt\n }\n }\n`;\n\nconst CREATE_DOC = gql`\n mutation CreateDocForWorkItem($input: PlanmagnetCreateDocInput!) {\n planmagnetCreateDoc(input: $input) {\n id\n }\n }\n`;\n\nconst LINK_DOC_TO_WORK_ITEM = gql`\n mutation LinkDocToWorkItem($docId: ID!, $workItemId: ID!) {\n planmagnetLinkDocToWorkItem(docId: $docId, workItemId: $workItemId) {\n id\n }\n }\n`;\n\nconst UNLINK_DOC_FROM_WORK_ITEM = gql`\n mutation UnlinkDocFromWorkItem($docId: ID!, $workItemId: ID!) {\n planmagnetUnlinkDocFromWorkItem(docId: $docId, workItemId: $workItemId)\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 assigneeId: string | null;\n reporterId: string | null;\n sprintId: string | null;\n storyPoints: number | null;\n estimateMinutes: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\ninterface WorkItemDocNode {\n id: string;\n title: string;\n status: string;\n version: number;\n updatedAt: string;\n}\n\nconst priorityColor: Record<string, string> = {\n LOW: 'bg-gray-100 text-gray-800',\n MEDIUM: 'bg-blue-100 text-blue-800',\n HIGH: 'bg-orange-100 text-orange-800',\n CRITICAL: 'bg-red-100 text-red-800',\n};\n\nconst statusColor: Record<string, string> = {\n BACKLOG: 'bg-gray-100 text-gray-800',\n TODO: 'bg-blue-100 text-blue-800',\n IN_PROGRESS: 'bg-yellow-100 text-yellow-800',\n IN_REVIEW: 'bg-purple-100 text-purple-800',\n DONE: 'bg-green-100 text-green-800',\n BLOCKED: 'bg-red-100 text-red-800',\n TESTING: 'bg-teal-100 text-teal-800',\n CANCELLED: 'bg-gray-100 text-gray-800',\n};\n\nconst docStatusColor: Record<string, string> = {\n DRAFT: 'bg-gray-100 text-gray-800',\n PUBLISHED: 'bg-green-100 text-green-800',\n ARCHIVED: 'bg-gray-100 text-gray-500',\n};\n\n/**\n * Linked-docs panel (BOFF-4443): create a doc and link it to this work item\n * in one action, view currently-linked docs, and unlink one. Reads/writes go\n * through the real planmagnetWorkItemDocs / planmagnetCreateDoc /\n * planmagnetLinkDocToWorkItem / planmagnetUnlinkDocFromWorkItem GraphQL\n * fields — no fabricated data. Full doc editing (revisions, revert) lives on\n * a dedicated doc detail view; this panel is scoped to linking.\n */\nfunction LinkedDocsPanel({ workItemId }: { workItemId: string }) {\n const [isComposing, setIsComposing] = useState(false);\n const [newTitle, setNewTitle] = useState('');\n const [newContent, setNewContent] = useState('');\n\n const { data, loading, error, refetch } = useQuery<{\n planmagnetWorkItemDocs: WorkItemDocNode[];\n }>(GET_WORK_ITEM_DOCS, {\n variables: { workItemId },\n skip: !workItemId,\n });\n\n const [createDoc, { loading: creating }] = useMutation(CREATE_DOC);\n const [linkDoc] = useMutation(LINK_DOC_TO_WORK_ITEM);\n const [unlinkDoc, { loading: unlinking }] = useMutation(UNLINK_DOC_FROM_WORK_ITEM);\n // A refused mutation resolves with { error } (fe-libs errorPolicy 'all');\n // the composer used to clear itself as if the doc had been saved.\n const [actionError, setActionError] = useState<string | null>(null);\n\n const docs = data?.planmagnetWorkItemDocs ?? [];\n\n const handleCreateAndLink = async () => {\n if (!newTitle.trim() || !newContent.trim()) return;\n setActionError(null);\n try {\n const result = await throwOnError(\n createDoc({ variables: { input: { title: newTitle.trim(), content: newContent.trim() } } })\n );\n const docId = result.data?.planmagnetCreateDoc?.id;\n if (docId) {\n await throwOnError(linkDoc({ variables: { docId, workItemId } }));\n }\n } catch (e) {\n setActionError(e instanceof Error ? e.message : 'The doc could not be saved.');\n return;\n }\n setNewTitle('');\n setNewContent('');\n setIsComposing(false);\n void refetch();\n };\n\n const handleUnlink = async (docId: string) => {\n setActionError(null);\n try {\n await throwOnError(unlinkDoc({ variables: { docId, workItemId } }));\n } catch (e) {\n setActionError(e instanceof Error ? e.message : 'The doc could not be unlinked.');\n return;\n }\n void refetch();\n };\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Linked Docs</CardTitle>\n {!isComposing && (\n <Button size=\"sm\" variant=\"outline\" onClick={() => setIsComposing(true)}>\n <Plus className=\"h-4 w-4 mr-1\" />\n New Doc\n </Button>\n )}\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {isComposing && (\n <div className=\"space-y-3 rounded-md border border-input p-3\">\n <Input\n placeholder=\"Doc title\"\n value={newTitle}\n onChange={(e) => setNewTitle(e.target.value)}\n />\n <MarkdownEditor\n value={newContent}\n onChange={setNewContent}\n placeholder=\"Write the spec/doc content...\"\n minHeight={140}\n />\n <div className=\"flex gap-2 justify-end\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setIsComposing(false);\n setNewTitle('');\n setNewContent('');\n }}\n >\n Cancel\n </Button>\n <Button\n size=\"sm\"\n disabled={creating || !newTitle.trim() || !newContent.trim()}\n onClick={handleCreateAndLink}\n >\n {creating ? 'Creating...' : 'Create & Link'}\n </Button>\n </div>\n </div>\n )}\n\n {loading && <p className=\"text-sm text-muted-foreground\">Loading docs...</p>}\n {error && <p className=\"text-sm text-red-500\">Error: {error.message}</p>}\n {actionError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {actionError}\n </p>\n )}\n {!loading && !error && docs.length === 0 && !isComposing && (\n <p className=\"text-sm text-muted-foreground\">No docs linked to this work item yet.</p>\n )}\n {docs.map((doc) => (\n <div\n key={doc.id}\n className=\"flex items-center justify-between gap-3 rounded-md border border-input p-3\"\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <FileText className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium truncate\">{doc.title}</p>\n <p className=\"text-xs text-muted-foreground\">v{doc.version}</p>\n </div>\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 ${docStatusColor[doc.status] ?? ''}`}\n >\n {doc.status.toLowerCase()}\n </span>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n disabled={unlinking}\n onClick={() => handleUnlink(doc.id)}\n aria-label={`Unlink ${doc.title}`}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n );\n}\n\nexport function TasksTaskDetailPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n // In a real app, workItemId comes from route params.\n const workItemId = new URLSearchParams(window.location.search).get('taskId') ?? '';\n\n const { data, loading, error } = useQuery<{\n planmagnetWorkItem: WorkItemNode;\n }>(GET_WORK_ITEM, {\n variables: { workItemId },\n skip: !workspaceId || !workItemId,\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-red-500\">Error: {error.message}</div>;\n }\n\n const task = data?.planmagnetWorkItem;\n if (!task) return <div className=\"p-6 text-muted-foreground\">Task not found.</div>;\n\n const statusDisplay = task.status.toLowerCase().replace('_', ' ');\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{task.title}</h1>\n <p className=\"text-sm text-muted-foreground\">\n {task.key} · {task.type.toLowerCase()}\n </p>\n </div>\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>Description</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm\">{task.description ?? 'No description provided.'}</p>\n </CardContent>\n </Card>\n <LinkedDocsPanel workItemId={task.id} />\n <WorkItemComments workItemId={task.id} />\n <WorkItemActivity workItemId={task.id} />\n </div>\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Status</span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[task.status] ?? ''}`}\n >\n {statusDisplay}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Priority</span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${priorityColor[task.priority] ?? ''}`}\n >\n {task.priority.toLowerCase()}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Type</span>\n <Badge variant=\"outline\" className=\"capitalize\">\n {task.type.toLowerCase()}\n </Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Story Points</span>\n <span className=\"font-medium\">{task.storyPoints ?? 0}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Assignee</span>\n <span>{task.assigneeId ?? 'Unassigned'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Reporter</span>\n <span>{task.reporterId ?? 'Unknown'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Key</span>\n <span>{task.key}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Due Date</span>\n <span>{task.dueDate ?? 'Not set'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Created</span>\n <span>{task.createdAt}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Updated</span>\n <span>{task.updatedAt}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground text-xs\">Labels</span>\n <div className=\"flex gap-1 mt-1 flex-wrap\">\n {(task.labels ?? []).map((l) => (\n <span key={l} className=\"text-xs px-2 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TasksTaskDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { throwOnError } from '../utils/mutationResult';\nimport { WorkItemComments } from '../comments/WorkItemComments';\nimport { WorkItemActivity } from '../comments/WorkItemActivity';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Badge,\n Button,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport { FileText, Plus, X } from 'lucide-react';\nimport { MarkdownEditor } from '#src/components/MarkdownEditor';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\n\nconst GET_WORK_ITEM = gql`\n query GetWorkItemDetail($workItemId: ID!) {\n planmagnetWorkItem(id: $workItemId) {\n id\n title\n description\n type\n status\n priority\n key\n assigneeId\n reporterId\n sprintId\n storyPoints\n estimateMinutes\n dueDate\n labels\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nconst GET_WORK_ITEM_DOCS = gql`\n query GetWorkItemDocs($workItemId: ID!) {\n planmagnetWorkItemDocs(workItemId: $workItemId) {\n id\n title\n status\n version\n updatedAt\n }\n }\n`;\n\nconst CREATE_DOC = gql`\n mutation CreateDocForWorkItem($input: PlanmagnetCreateDocInput!) {\n planmagnetCreateDoc(input: $input) {\n id\n }\n }\n`;\n\nconst LINK_DOC_TO_WORK_ITEM = gql`\n mutation LinkDocToWorkItem($docId: ID!, $workItemId: ID!) {\n planmagnetLinkDocToWorkItem(docId: $docId, workItemId: $workItemId) {\n id\n }\n }\n`;\n\nconst UNLINK_DOC_FROM_WORK_ITEM = gql`\n mutation UnlinkDocFromWorkItem($docId: ID!, $workItemId: ID!) {\n planmagnetUnlinkDocFromWorkItem(docId: $docId, workItemId: $workItemId)\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 assigneeId: string | null;\n reporterId: string | null;\n sprintId: string | null;\n storyPoints: number | null;\n estimateMinutes: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\ninterface WorkItemDocNode {\n id: string;\n title: string;\n status: string;\n version: number;\n updatedAt: string;\n}\n\nconst priorityColor: Record<string, string> = {\n LOW: 'bg-gray-100 text-gray-800',\n MEDIUM: 'bg-blue-100 text-blue-800',\n HIGH: 'bg-orange-100 text-orange-800',\n CRITICAL: 'bg-red-100 text-red-800',\n};\n\nconst statusColor: Record<string, string> = {\n BACKLOG: 'bg-gray-100 text-gray-800',\n TODO: 'bg-blue-100 text-blue-800',\n IN_PROGRESS: 'bg-yellow-100 text-yellow-800',\n IN_REVIEW: 'bg-purple-100 text-purple-800',\n DONE: 'bg-green-100 text-green-800',\n BLOCKED: 'bg-red-100 text-red-800',\n TESTING: 'bg-teal-100 text-teal-800',\n CANCELLED: 'bg-gray-100 text-gray-800',\n};\n\nconst docStatusColor: Record<string, string> = {\n DRAFT: 'bg-gray-100 text-gray-800',\n PUBLISHED: 'bg-green-100 text-green-800',\n ARCHIVED: 'bg-gray-100 text-gray-500',\n};\n\n/**\n * Linked-docs panel (BOFF-4443): create a doc and link it to this work item\n * in one action, view currently-linked docs, and unlink one. Reads/writes go\n * through the real planmagnetWorkItemDocs / planmagnetCreateDoc /\n * planmagnetLinkDocToWorkItem / planmagnetUnlinkDocFromWorkItem GraphQL\n * fields — no fabricated data. Full doc editing (revisions, revert) lives on\n * a dedicated doc detail view; this panel is scoped to linking.\n */\nfunction LinkedDocsPanel({ workItemId }: { workItemId: string }) {\n const navigate = usePlanMagnetNavigate();\n const [isComposing, setIsComposing] = useState(false);\n const [newTitle, setNewTitle] = useState('');\n const [newContent, setNewContent] = useState('');\n\n const { data, loading, error, refetch } = useQuery<{\n planmagnetWorkItemDocs: WorkItemDocNode[];\n }>(GET_WORK_ITEM_DOCS, {\n variables: { workItemId },\n skip: !workItemId,\n });\n\n const [createDoc, { loading: creating }] = useMutation(CREATE_DOC);\n const [linkDoc] = useMutation(LINK_DOC_TO_WORK_ITEM);\n const [unlinkDoc, { loading: unlinking }] = useMutation(UNLINK_DOC_FROM_WORK_ITEM);\n // A refused mutation resolves with { error } (fe-libs errorPolicy 'all');\n // the composer used to clear itself as if the doc had been saved.\n const [actionError, setActionError] = useState<string | null>(null);\n\n const docs = data?.planmagnetWorkItemDocs ?? [];\n\n const handleCreateAndLink = async () => {\n if (!newTitle.trim() || !newContent.trim()) return;\n setActionError(null);\n try {\n const result = await throwOnError(\n createDoc({ variables: { input: { title: newTitle.trim(), content: newContent.trim() } } })\n );\n const docId = result.data?.planmagnetCreateDoc?.id;\n if (docId) {\n await throwOnError(linkDoc({ variables: { docId, workItemId } }));\n }\n } catch (e) {\n setActionError(e instanceof Error ? e.message : 'The doc could not be saved.');\n return;\n }\n setNewTitle('');\n setNewContent('');\n setIsComposing(false);\n void refetch();\n };\n\n const handleUnlink = async (docId: string) => {\n setActionError(null);\n try {\n await throwOnError(unlinkDoc({ variables: { docId, workItemId } }));\n } catch (e) {\n setActionError(e instanceof Error ? e.message : 'The doc could not be unlinked.');\n return;\n }\n void refetch();\n };\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Linked Docs</CardTitle>\n {!isComposing && (\n <Button size=\"sm\" variant=\"outline\" onClick={() => setIsComposing(true)}>\n <Plus className=\"h-4 w-4 mr-1\" />\n New Doc\n </Button>\n )}\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {isComposing && (\n <div className=\"space-y-3 rounded-md border border-input p-3\">\n <Input\n placeholder=\"Doc title\"\n value={newTitle}\n onChange={(e) => setNewTitle(e.target.value)}\n />\n <MarkdownEditor\n value={newContent}\n onChange={setNewContent}\n placeholder=\"Write the spec/doc content...\"\n minHeight={140}\n />\n <div className=\"flex gap-2 justify-end\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setIsComposing(false);\n setNewTitle('');\n setNewContent('');\n }}\n >\n Cancel\n </Button>\n <Button\n size=\"sm\"\n disabled={creating || !newTitle.trim() || !newContent.trim()}\n onClick={handleCreateAndLink}\n >\n {creating ? 'Creating...' : 'Create & Link'}\n </Button>\n </div>\n </div>\n )}\n\n {loading && <p className=\"text-sm text-muted-foreground\">Loading docs...</p>}\n {error && <p className=\"text-sm text-red-500\">Error: {error.message}</p>}\n {actionError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {actionError}\n </p>\n )}\n {!loading && !error && docs.length === 0 && !isComposing && (\n <p className=\"text-sm text-muted-foreground\">No docs linked to this work item yet.</p>\n )}\n {docs.map((doc) => (\n <div\n key={doc.id}\n className=\"flex items-center justify-between gap-3 rounded-md border border-input p-3\"\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <FileText className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n <div className=\"min-w-0\">\n <button\n type=\"button\"\n className=\"block max-w-full truncate text-left text-sm font-medium hover:underline\"\n onClick={() =>\n navigate(`/docs/doc-detail-page?docId=${encodeURIComponent(doc.id)}`)\n }\n >\n {doc.title}\n </button>\n <p className=\"text-xs text-muted-foreground\">v{doc.version}</p>\n </div>\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 ${docStatusColor[doc.status] ?? ''}`}\n >\n {doc.status.toLowerCase()}\n </span>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n disabled={unlinking}\n onClick={() => handleUnlink(doc.id)}\n aria-label={`Unlink ${doc.title}`}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n );\n}\n\nexport function TasksTaskDetailPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n // In a real app, workItemId comes from route params.\n const workItemId = new URLSearchParams(window.location.search).get('taskId') ?? '';\n\n const { data, loading, error } = useQuery<{\n planmagnetWorkItem: WorkItemNode;\n }>(GET_WORK_ITEM, {\n variables: { workItemId },\n skip: !workspaceId || !workItemId,\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-red-500\">Error: {error.message}</div>;\n }\n\n const task = data?.planmagnetWorkItem;\n if (!task) return <div className=\"p-6 text-muted-foreground\">Task not found.</div>;\n\n const statusDisplay = task.status.toLowerCase().replace('_', ' ');\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{task.title}</h1>\n <p className=\"text-sm text-muted-foreground\">\n {task.key} · {task.type.toLowerCase()}\n </p>\n </div>\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>Description</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm\">{task.description ?? 'No description provided.'}</p>\n </CardContent>\n </Card>\n <LinkedDocsPanel workItemId={task.id} />\n <WorkItemComments workItemId={task.id} />\n <WorkItemActivity workItemId={task.id} />\n </div>\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Status</span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[task.status] ?? ''}`}\n >\n {statusDisplay}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Priority</span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${priorityColor[task.priority] ?? ''}`}\n >\n {task.priority.toLowerCase()}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Type</span>\n <Badge variant=\"outline\" className=\"capitalize\">\n {task.type.toLowerCase()}\n </Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Story Points</span>\n <span className=\"font-medium\">{task.storyPoints ?? 0}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Assignee</span>\n <span>{task.assigneeId ?? 'Unassigned'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Reporter</span>\n <span>{task.reporterId ?? 'Unknown'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Key</span>\n <span>{task.key}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Due Date</span>\n <span>{task.dueDate ?? 'Not set'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Created</span>\n <span>{task.createdAt}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Updated</span>\n <span>{task.updatedAt}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground text-xs\">Labels</span>\n <div className=\"flex gap-1 mt-1 flex-wrap\">\n {(task.labels ?? []).map((l) => (\n <span key={l} className=\"text-xs px-2 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|