@burdenoff/microfe-planmagnet 2026.925.5 → 2026.925.7
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 +126 -0
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/planmagnet/board/ProjectBoard.d.ts +5 -0
- package/dist/planmagnet/board/ProjectBoard.d.ts.map +1 -0
- package/dist/planmagnet/board/ProjectBoard.js +491 -0
- package/dist/planmagnet/board/ProjectBoard.js.map +1 -0
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +216 -193
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/DashboardDashboardPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js +10 -10
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.js +178 -78
- package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
import { PersonName as n } from "../people/People.js";
|
|
3
|
+
import { rowLinkProps as r } from "../utils/rowNavigation.js";
|
|
4
|
+
import { ProjectBoard as i } from "../board/ProjectBoard.js";
|
|
5
|
+
import { useState as a } from "react";
|
|
6
|
+
import { Filter as o } from "lucide-react";
|
|
7
|
+
import { gql as s } from "@apollo/client";
|
|
8
|
+
import { useQuery as c } from "@apollo/client/react";
|
|
9
|
+
import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
10
|
+
import { Card as f, CardContent as p } from "@burdenoff/fe-libs/ui";
|
|
9
11
|
//#region src/planmagnet/pages/TasksTasksPagePage.tsx
|
|
10
|
-
var
|
|
12
|
+
var m = s`
|
|
11
13
|
query GetWorkItems(
|
|
12
14
|
$workspaceId: ID!
|
|
13
15
|
$filter: PlanmagnetWorkItemFilter
|
|
@@ -31,77 +33,163 @@ var d = a`
|
|
|
31
33
|
tags
|
|
32
34
|
createdAt
|
|
33
35
|
}
|
|
36
|
+
pageInfo {
|
|
37
|
+
hasNextPage
|
|
38
|
+
endCursor
|
|
39
|
+
}
|
|
34
40
|
totalCount
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
|
-
`,
|
|
43
|
+
`, h = s`
|
|
44
|
+
query GetWorkItemCounts($workspaceId: ID!, $filter: PlanmagnetWorkItemFilter) {
|
|
45
|
+
planmagnetWorkItemCounts(workspaceId: $workspaceId, filter: $filter) {
|
|
46
|
+
total
|
|
47
|
+
byStatus {
|
|
48
|
+
status
|
|
49
|
+
count
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
`, g = 100, _ = s`
|
|
54
|
+
query GetBoardProjects($workspaceId: ID!) {
|
|
55
|
+
planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {
|
|
56
|
+
items {
|
|
57
|
+
id
|
|
58
|
+
name
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
`, v = [
|
|
38
63
|
"BACKLOG",
|
|
39
64
|
"TODO",
|
|
40
65
|
"IN_PROGRESS",
|
|
41
66
|
"IN_REVIEW",
|
|
42
67
|
"TESTING",
|
|
43
|
-
"DONE"
|
|
44
|
-
|
|
68
|
+
"DONE",
|
|
69
|
+
"CANCELLED"
|
|
70
|
+
], y = {
|
|
45
71
|
BACKLOG: "Backlog",
|
|
46
72
|
TODO: "To Do",
|
|
47
73
|
IN_PROGRESS: "In Progress",
|
|
48
74
|
IN_REVIEW: "In Review",
|
|
49
75
|
TESTING: "Testing",
|
|
50
|
-
DONE: "Done"
|
|
51
|
-
|
|
76
|
+
DONE: "Done",
|
|
77
|
+
CANCELLED: "Cancelled"
|
|
78
|
+
}, b = {
|
|
52
79
|
BACKLOG: "border-t-gray-400",
|
|
53
80
|
TODO: "border-t-blue-400",
|
|
54
81
|
IN_PROGRESS: "border-t-yellow-400",
|
|
55
82
|
IN_REVIEW: "border-t-purple-400",
|
|
56
83
|
TESTING: "border-t-teal-400",
|
|
57
|
-
DONE: "border-t-green-400"
|
|
58
|
-
|
|
84
|
+
DONE: "border-t-green-400",
|
|
85
|
+
CANCELLED: "border-t-muted-foreground"
|
|
86
|
+
}, x = {
|
|
59
87
|
LOW: "bg-gray-100 text-gray-700",
|
|
60
88
|
MEDIUM: "bg-blue-100 text-blue-700",
|
|
61
89
|
HIGH: "bg-orange-100 text-orange-700",
|
|
62
90
|
CRITICAL: "bg-red-100 text-red-700"
|
|
63
|
-
},
|
|
91
|
+
}, S = {
|
|
64
92
|
STORY: "bg-green-100 text-green-700",
|
|
65
93
|
BUG: "bg-red-100 text-red-700",
|
|
66
94
|
TASK: "bg-blue-100 text-blue-700",
|
|
67
95
|
EPIC: "bg-purple-100 text-purple-700",
|
|
68
96
|
SUBTASK: "bg-gray-100 text-gray-700"
|
|
69
97
|
};
|
|
70
|
-
function
|
|
71
|
-
let { workspaceId:
|
|
98
|
+
function C() {
|
|
99
|
+
let { workspaceId: s } = e(), C = t(), [w, T] = a("all"), [E, D] = a("all"), [O, k] = a(null), { data: A } = c(_, {
|
|
100
|
+
variables: { workspaceId: s },
|
|
101
|
+
skip: !s
|
|
102
|
+
}), j = A?.planmagnetProjects?.items ?? [], M = O ?? j[0]?.id ?? "", N = j.find((e) => e.id === M)?.name ?? "", P = {
|
|
103
|
+
...w !== "all" && { priority: w.toUpperCase() },
|
|
104
|
+
...E !== "all" && { type: E.toUpperCase() }
|
|
105
|
+
}, [F, I] = a(!1), { data: L, loading: R, error: z, fetchMore: B } = c(m, {
|
|
72
106
|
variables: {
|
|
73
|
-
workspaceId:
|
|
74
|
-
|
|
107
|
+
workspaceId: s,
|
|
108
|
+
filter: P,
|
|
109
|
+
pagination: { first: g }
|
|
75
110
|
},
|
|
76
|
-
skip: !
|
|
77
|
-
})
|
|
78
|
-
|
|
111
|
+
skip: !s || !!M
|
|
112
|
+
}), { data: V } = c(h, {
|
|
113
|
+
variables: {
|
|
114
|
+
workspaceId: s,
|
|
115
|
+
filter: P
|
|
116
|
+
},
|
|
117
|
+
skip: !s
|
|
118
|
+
}), H = async () => {
|
|
119
|
+
let e = L?.planmagnetWorkItems?.pageInfo?.endCursor;
|
|
120
|
+
if (e) {
|
|
121
|
+
I(!0);
|
|
122
|
+
try {
|
|
123
|
+
await B({
|
|
124
|
+
variables: { pagination: {
|
|
125
|
+
first: g,
|
|
126
|
+
after: e
|
|
127
|
+
} },
|
|
128
|
+
updateQuery: (e, { fetchMoreResult: t }) => ({ planmagnetWorkItems: {
|
|
129
|
+
...t.planmagnetWorkItems,
|
|
130
|
+
items: [...e.planmagnetWorkItems.items, ...t.planmagnetWorkItems.items]
|
|
131
|
+
} })
|
|
132
|
+
});
|
|
133
|
+
} finally {
|
|
134
|
+
I(!1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
if (R && !L) return /* @__PURE__ */ u("div", {
|
|
79
139
|
className: "flex items-center justify-center p-12",
|
|
80
|
-
children: /* @__PURE__ */
|
|
140
|
+
children: /* @__PURE__ */ u("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
81
141
|
});
|
|
82
|
-
if (
|
|
142
|
+
if (z) return /* @__PURE__ */ d("div", {
|
|
83
143
|
className: "p-6 text-red-500",
|
|
84
|
-
children: ["Error: ",
|
|
144
|
+
children: ["Error: ", z.message]
|
|
85
145
|
});
|
|
86
|
-
let
|
|
87
|
-
return /* @__PURE__ */
|
|
146
|
+
let U = L?.planmagnetWorkItems?.items ?? [], W = V?.planmagnetWorkItemCounts, G = W?.total ?? L?.planmagnetWorkItems?.totalCount ?? U.length, K = (e) => W?.byStatus.find((t) => t.status === e)?.count ?? U.filter((t) => t.status === e).length, q = L?.planmagnetWorkItems?.pageInfo?.hasNextPage ?? !1;
|
|
147
|
+
return /* @__PURE__ */ d("div", {
|
|
88
148
|
className: "space-y-4 p-6",
|
|
89
|
-
children: [
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
149
|
+
children: [/* @__PURE__ */ u("div", {
|
|
150
|
+
className: "flex items-center justify-between",
|
|
151
|
+
children: /* @__PURE__ */ d("div", { children: [
|
|
152
|
+
/* @__PURE__ */ u("h1", {
|
|
93
153
|
className: "text-2xl font-semibold",
|
|
94
154
|
children: "Task Board"
|
|
95
|
-
}),
|
|
155
|
+
}),
|
|
156
|
+
/* @__PURE__ */ u("label", {
|
|
157
|
+
className: "sr-only",
|
|
158
|
+
htmlFor: "task-board-project",
|
|
159
|
+
children: "Project"
|
|
160
|
+
}),
|
|
161
|
+
/* @__PURE__ */ d("select", {
|
|
162
|
+
id: "task-board-project",
|
|
163
|
+
className: "mt-2 rounded-md border border-input bg-background px-2 py-1 text-sm",
|
|
164
|
+
value: M,
|
|
165
|
+
onChange: (e) => k(e.target.value),
|
|
166
|
+
children: [j.map((e) => /* @__PURE__ */ u("option", {
|
|
167
|
+
value: e.id,
|
|
168
|
+
children: e.name
|
|
169
|
+
}, e.id)), /* @__PURE__ */ u("option", {
|
|
170
|
+
value: "",
|
|
171
|
+
children: "All projects — status overview"
|
|
172
|
+
})]
|
|
173
|
+
}),
|
|
174
|
+
/* @__PURE__ */ d("p", {
|
|
96
175
|
className: "text-sm text-muted-foreground",
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
176
|
+
"data-testid": "task-board-total",
|
|
177
|
+
children: [
|
|
178
|
+
G,
|
|
179
|
+
" tasks across all projects",
|
|
180
|
+
U.length < G && ` · showing ${U.length}`
|
|
181
|
+
]
|
|
182
|
+
})
|
|
183
|
+
] })
|
|
184
|
+
}), M ? /* @__PURE__ */ u(i, {
|
|
185
|
+
projectId: M,
|
|
186
|
+
projectName: N
|
|
187
|
+
}) : /* @__PURE__ */ d(l, { children: [
|
|
188
|
+
/* @__PURE__ */ d("div", {
|
|
101
189
|
className: "flex gap-4 items-center flex-wrap",
|
|
102
190
|
children: [
|
|
103
|
-
/* @__PURE__ */
|
|
104
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ u(o, { className: "h-4 w-4 text-muted-foreground" }),
|
|
192
|
+
/* @__PURE__ */ u("div", {
|
|
105
193
|
className: "flex gap-1",
|
|
106
194
|
children: [
|
|
107
195
|
"all",
|
|
@@ -109,13 +197,13 @@ function _() {
|
|
|
109
197
|
"medium",
|
|
110
198
|
"high",
|
|
111
199
|
"critical"
|
|
112
|
-
].map((e) => /* @__PURE__ */
|
|
113
|
-
onClick: () =>
|
|
114
|
-
className: `px-2 py-1 text-xs rounded capitalize ${
|
|
200
|
+
].map((e) => /* @__PURE__ */ u("button", {
|
|
201
|
+
onClick: () => T(e),
|
|
202
|
+
className: `px-2 py-1 text-xs rounded capitalize ${w === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
115
203
|
children: e
|
|
116
204
|
}, e))
|
|
117
205
|
}),
|
|
118
|
-
/* @__PURE__ */
|
|
206
|
+
/* @__PURE__ */ u("div", {
|
|
119
207
|
className: "flex gap-1",
|
|
120
208
|
children: [
|
|
121
209
|
"all",
|
|
@@ -123,76 +211,77 @@ function _() {
|
|
|
123
211
|
"bug",
|
|
124
212
|
"task",
|
|
125
213
|
"epic"
|
|
126
|
-
].map((e) => /* @__PURE__ */
|
|
127
|
-
onClick: () =>
|
|
128
|
-
className: `px-2 py-1 text-xs rounded capitalize ${
|
|
214
|
+
].map((e) => /* @__PURE__ */ u("button", {
|
|
215
|
+
onClick: () => D(e),
|
|
216
|
+
className: `px-2 py-1 text-xs rounded capitalize ${E === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
129
217
|
children: e
|
|
130
218
|
}, e))
|
|
131
219
|
})
|
|
132
220
|
]
|
|
133
221
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
135
|
-
className: "grid grid-cols-
|
|
136
|
-
children:
|
|
137
|
-
let t =
|
|
138
|
-
return /* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ u("div", {
|
|
223
|
+
className: "grid grid-cols-7 gap-3 overflow-x-auto",
|
|
224
|
+
children: v.map((e) => {
|
|
225
|
+
let t = U.filter((t) => t.status === e);
|
|
226
|
+
return /* @__PURE__ */ d("div", {
|
|
139
227
|
className: "min-w-[200px]",
|
|
140
|
-
children: [/* @__PURE__ */
|
|
141
|
-
className: `border-t-2 ${
|
|
142
|
-
children: /* @__PURE__ */
|
|
228
|
+
children: [/* @__PURE__ */ u("div", {
|
|
229
|
+
className: `border-t-2 ${b[e]} rounded-t-md p-2 bg-muted/50`,
|
|
230
|
+
children: /* @__PURE__ */ d("div", {
|
|
143
231
|
className: "flex justify-between items-center",
|
|
144
|
-
children: [/* @__PURE__ */
|
|
232
|
+
children: [/* @__PURE__ */ u("span", {
|
|
145
233
|
className: "text-sm font-medium",
|
|
146
|
-
children:
|
|
147
|
-
}), /* @__PURE__ */
|
|
234
|
+
children: y[e]
|
|
235
|
+
}), /* @__PURE__ */ u("span", {
|
|
148
236
|
className: "text-xs bg-muted rounded-full px-1.5",
|
|
149
|
-
|
|
237
|
+
"data-testid": `task-col-count-${e}`,
|
|
238
|
+
children: K(e)
|
|
150
239
|
})]
|
|
151
240
|
})
|
|
152
|
-
}), /* @__PURE__ */
|
|
241
|
+
}), /* @__PURE__ */ u("div", {
|
|
153
242
|
className: "space-y-2 mt-2",
|
|
154
|
-
children: t.map((e) => /* @__PURE__ */
|
|
155
|
-
...
|
|
156
|
-
children: /* @__PURE__ */
|
|
243
|
+
children: t.map((e) => /* @__PURE__ */ u(f, {
|
|
244
|
+
...r(() => C(`/tasks/task-detail-page?taskId=${encodeURIComponent(e.id)}`), e.title),
|
|
245
|
+
children: /* @__PURE__ */ d(p, {
|
|
157
246
|
className: "p-3 space-y-2",
|
|
158
247
|
children: [
|
|
159
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ u("p", {
|
|
160
249
|
className: "text-sm font-medium leading-tight",
|
|
161
250
|
children: e.title
|
|
162
251
|
}),
|
|
163
|
-
/* @__PURE__ */
|
|
252
|
+
/* @__PURE__ */ u("p", {
|
|
164
253
|
className: "text-xs text-muted-foreground",
|
|
165
254
|
children: e.key
|
|
166
255
|
}),
|
|
167
|
-
/* @__PURE__ */
|
|
256
|
+
/* @__PURE__ */ d("div", {
|
|
168
257
|
className: "flex gap-1 flex-wrap",
|
|
169
|
-
children: [/* @__PURE__ */
|
|
170
|
-
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${
|
|
258
|
+
children: [/* @__PURE__ */ u("span", {
|
|
259
|
+
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${x[e.priority] ?? ""}`,
|
|
171
260
|
children: e.priority.toLowerCase()
|
|
172
|
-
}), /* @__PURE__ */
|
|
173
|
-
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${
|
|
261
|
+
}), /* @__PURE__ */ u("span", {
|
|
262
|
+
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${S[e.type] ?? ""}`,
|
|
174
263
|
children: e.type.toLowerCase()
|
|
175
264
|
})]
|
|
176
265
|
}),
|
|
177
|
-
/* @__PURE__ */
|
|
266
|
+
/* @__PURE__ */ d("div", {
|
|
178
267
|
className: "flex items-center justify-between",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
268
|
+
children: [/* @__PURE__ */ u("div", {
|
|
180
269
|
className: "flex gap-1",
|
|
181
|
-
children: (e.labels ?? []).slice(0, 2).map((e) => /* @__PURE__ */
|
|
270
|
+
children: (e.labels ?? []).slice(0, 2).map((e) => /* @__PURE__ */ u("span", {
|
|
182
271
|
className: "text-[9px] px-1 py-0.5 rounded bg-muted",
|
|
183
272
|
children: e
|
|
184
273
|
}, e))
|
|
185
|
-
}), /* @__PURE__ */
|
|
274
|
+
}), /* @__PURE__ */ u("div", {
|
|
186
275
|
className: "flex items-center gap-1",
|
|
187
|
-
children: /* @__PURE__ */
|
|
276
|
+
children: /* @__PURE__ */ u("span", {
|
|
188
277
|
className: "text-[10px] font-medium bg-primary/10 text-primary rounded-full h-5 w-5 flex items-center justify-center",
|
|
189
278
|
children: e.storyPoints ?? 0
|
|
190
279
|
})
|
|
191
280
|
})]
|
|
192
281
|
}),
|
|
193
|
-
/* @__PURE__ */
|
|
282
|
+
/* @__PURE__ */ d("div", {
|
|
194
283
|
className: "flex justify-between text-[10px] text-muted-foreground",
|
|
195
|
-
children: [/* @__PURE__ */
|
|
284
|
+
children: [/* @__PURE__ */ u("span", { children: e.assigneeId ? /* @__PURE__ */ u(n, { id: e.assigneeId }) : "Unassigned" }), /* @__PURE__ */ u("span", { children: e.dueDate ? new Date(e.dueDate).toLocaleDateString() : "" })]
|
|
196
285
|
})
|
|
197
286
|
]
|
|
198
287
|
})
|
|
@@ -200,11 +289,22 @@ function _() {
|
|
|
200
289
|
})]
|
|
201
290
|
}, e);
|
|
202
291
|
})
|
|
292
|
+
}),
|
|
293
|
+
q && /* @__PURE__ */ u("div", {
|
|
294
|
+
className: "flex justify-center",
|
|
295
|
+
children: /* @__PURE__ */ u("button", {
|
|
296
|
+
type: "button",
|
|
297
|
+
onClick: H,
|
|
298
|
+
disabled: F,
|
|
299
|
+
className: "px-3 py-1.5 text-sm rounded-md bg-muted text-foreground hover:bg-muted/80 disabled:opacity-50",
|
|
300
|
+
"data-testid": "task-board-load-more",
|
|
301
|
+
children: F ? "Loading…" : `Load more (${U.length} of ${G})`
|
|
302
|
+
})
|
|
203
303
|
})
|
|
204
|
-
]
|
|
304
|
+
] })]
|
|
205
305
|
});
|
|
206
306
|
}
|
|
207
307
|
//#endregion
|
|
208
|
-
export {
|
|
308
|
+
export { C as TasksTasksPagePage };
|
|
209
309
|
|
|
210
310
|
//# sourceMappingURL=TasksTasksPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TasksTasksPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksTasksPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Filter } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps } from '../utils/rowNavigation';\n\nconst GET_WORK_ITEMS = gql`\n query GetWorkItems(\n $workspaceId: ID!\n $filter: PlanmagnetWorkItemFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetWorkItems(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n title\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 }\n totalCount\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\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}\n\nconst columns = ['BACKLOG', 'TODO', 'IN_PROGRESS', 'IN_REVIEW', 'TESTING', 'DONE'] as const;\n\nconst colLabel: Record<string, string> = {\n BACKLOG: 'Backlog',\n TODO: 'To Do',\n IN_PROGRESS: 'In Progress',\n IN_REVIEW: 'In Review',\n TESTING: 'Testing',\n DONE: 'Done',\n};\n\nconst colColor: Record<string, string> = {\n BACKLOG: 'border-t-gray-400',\n TODO: 'border-t-blue-400',\n IN_PROGRESS: 'border-t-yellow-400',\n IN_REVIEW: 'border-t-purple-400',\n TESTING: 'border-t-teal-400',\n DONE: 'border-t-green-400',\n};\n\nconst priorityColor: Record<string, string> = {\n LOW: 'bg-gray-100 text-gray-700',\n MEDIUM: 'bg-blue-100 text-blue-700',\n HIGH: 'bg-orange-100 text-orange-700',\n CRITICAL: 'bg-red-100 text-red-700',\n};\n\nconst typeColor: Record<string, string> = {\n STORY: 'bg-green-100 text-green-700',\n BUG: 'bg-red-100 text-red-700',\n TASK: 'bg-blue-100 text-blue-700',\n EPIC: 'bg-purple-100 text-purple-700',\n SUBTASK: 'bg-gray-100 text-gray-700',\n};\n\nexport function TasksTasksPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [priorityFilter, setPriorityFilter] = useState<string>('all');\n const [typeFilter, setTypeFilter] = useState<string>('all');\n\n const { data, loading, error } = useQuery<{\n planmagnetWorkItems: { items: WorkItemNode[]; totalCount: number };\n }>(GET_WORK_ITEMS, {\n variables: {\n workspaceId,\n pagination: { first: 200 },\n },\n skip: !workspaceId,\n });\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-red-500\">Error: {error.message}</div>;\n }\n\n const tasks = data?.planmagnetWorkItems?.items ?? [];\n\n const filtered = tasks.filter(\n (t) =>\n (priorityFilter === 'all' || t.priority === priorityFilter.toUpperCase()) &&\n (typeFilter === 'all' || t.type === typeFilter.toUpperCase())\n );\n\n return (\n <div className=\"space-y-4 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Task Board</h1>\n <p className=\"text-sm text-muted-foreground\">{tasks.length} tasks across all projects</p>\n </div>\n </div>\n <div className=\"flex gap-4 items-center flex-wrap\">\n <Filter className=\"h-4 w-4 text-muted-foreground\" />\n <div className=\"flex gap-1\">\n {['all', 'low', 'medium', 'high', 'critical'].map((p) => (\n <button\n key={p}\n onClick={() => setPriorityFilter(p)}\n className={`px-2 py-1 text-xs rounded capitalize ${priorityFilter === p ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {p}\n </button>\n ))}\n </div>\n <div className=\"flex gap-1\">\n {['all', 'story', 'bug', 'task', 'epic'].map((t) => (\n <button\n key={t}\n onClick={() => setTypeFilter(t)}\n className={`px-2 py-1 text-xs rounded capitalize ${typeFilter === t ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {t}\n </button>\n ))}\n </div>\n </div>\n <div className=\"grid grid-cols-6 gap-3 overflow-x-auto\">\n {columns.map((col) => {\n const colTasks = filtered.filter((t) => t.status === col);\n return (\n <div key={col} className=\"min-w-[200px]\">\n <div className={`border-t-2 ${colColor[col]} rounded-t-md p-2 bg-muted/50`}>\n <div className=\"flex justify-between items-center\">\n <span className=\"text-sm font-medium\">{colLabel[col]}</span>\n <span className=\"text-xs bg-muted rounded-full px-1.5\">{colTasks.length}</span>\n </div>\n </div>\n <div className=\"space-y-2 mt-2\">\n {colTasks.map((task) => (\n <Card\n key={task.id}\n {...rowLinkProps(\n () =>\n navigate(`/tasks/task-detail-page?taskId=${encodeURIComponent(task.id)}`),\n task.title\n )}\n >\n <CardContent className=\"p-3 space-y-2\">\n <p className=\"text-sm font-medium leading-tight\">{task.title}</p>\n <p className=\"text-xs text-muted-foreground\">{task.key}</p>\n <div className=\"flex gap-1 flex-wrap\">\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${priorityColor[task.priority] ?? ''}`}\n >\n {task.priority.toLowerCase()}\n </span>\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${typeColor[task.type] ?? ''}`}\n >\n {task.type.toLowerCase()}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex gap-1\">\n {(task.labels ?? []).slice(0, 2).map((l) => (\n <span key={l} className=\"text-[9px] px-1 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] font-medium bg-primary/10 text-primary rounded-full h-5 w-5 flex items-center justify-center\">\n {task.storyPoints ?? 0}\n </span>\n </div>\n </div>\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>{task.assigneeId ?? 'Unassigned'}</span>\n <span>{task.dueDate ?? ''}</span>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TasksTasksPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksTasksPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Filter } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { ProjectBoard } from '../board/ProjectBoard';\n\nconst GET_WORK_ITEMS = gql`\n query GetWorkItems(\n $workspaceId: ID!\n $filter: PlanmagnetWorkItemFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetWorkItems(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n title\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 }\n pageInfo {\n hasNextPage\n endCursor\n }\n totalCount\n }\n }\n`;\n\n// Server-side counts (QA H2): the list returns at most 100 rows per page, so\n// counting the loaded page undercounted every workspace past 100 items.\nconst GET_WORK_ITEM_COUNTS = gql`\n query GetWorkItemCounts($workspaceId: ID!, $filter: PlanmagnetWorkItemFilter) {\n planmagnetWorkItemCounts(workspaceId: $workspaceId, filter: $filter) {\n total\n byStatus {\n status\n count\n }\n }\n }\n`;\n\nconst PAGE_SIZE = 100;\n\nconst GET_BOARD_PROJECTS = gql`\n query GetBoardProjects($workspaceId: ID!) {\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\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}\n\nconst columns = [\n 'BACKLOG',\n 'TODO',\n 'IN_PROGRESS',\n 'IN_REVIEW',\n 'TESTING',\n 'DONE',\n 'CANCELLED',\n] as const;\n\nconst colLabel: Record<string, string> = {\n BACKLOG: 'Backlog',\n TODO: 'To Do',\n IN_PROGRESS: 'In Progress',\n IN_REVIEW: 'In Review',\n TESTING: 'Testing',\n DONE: 'Done',\n CANCELLED: 'Cancelled',\n};\n\nconst colColor: Record<string, string> = {\n BACKLOG: 'border-t-gray-400',\n TODO: 'border-t-blue-400',\n IN_PROGRESS: 'border-t-yellow-400',\n IN_REVIEW: 'border-t-purple-400',\n TESTING: 'border-t-teal-400',\n DONE: 'border-t-green-400',\n CANCELLED: 'border-t-muted-foreground',\n};\n\nconst priorityColor: Record<string, string> = {\n LOW: 'bg-gray-100 text-gray-700',\n MEDIUM: 'bg-blue-100 text-blue-700',\n HIGH: 'bg-orange-100 text-orange-700',\n CRITICAL: 'bg-red-100 text-red-700',\n};\n\nconst typeColor: Record<string, string> = {\n STORY: 'bg-green-100 text-green-700',\n BUG: 'bg-red-100 text-red-700',\n TASK: 'bg-blue-100 text-blue-700',\n EPIC: 'bg-purple-100 text-purple-700',\n SUBTASK: 'bg-gray-100 text-gray-700',\n};\n\nexport function TasksTasksPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [priorityFilter, setPriorityFilter] = useState<string>('all');\n const [typeFilter, setTypeFilter] = useState<string>('all');\n // P1.2: the Task Board is a project's real board (server-side placement,\n // drag-and-drop, WIP limits). null = not chosen yet -> the first project;\n // '' = the cross-project status overview, which is NOT a board.\n const [boardProject, setBoardProject] = useState<string | null>(null);\n const { data: projectsData } = useQuery(GET_BOARD_PROJECTS, {\n variables: { workspaceId },\n skip: !workspaceId,\n });\n const boardProjects = projectsData?.planmagnetProjects?.items ?? [];\n const selectedProject = boardProject ?? boardProjects[0]?.id ?? '';\n const selectedProjectName = boardProjects.find((p) => p.id === selectedProject)?.name ?? '';\n\n // Filters go to the server so the loaded items AND the counts both reflect\n // every matching item, not just the first page.\n const filter = {\n ...(priorityFilter !== 'all' && { priority: priorityFilter.toUpperCase() }),\n ...(typeFilter !== 'all' && { type: typeFilter.toUpperCase() }),\n };\n const [loadingMore, setLoadingMore] = useState(false);\n\n const { data, loading, error, fetchMore } = useQuery<{\n planmagnetWorkItems: {\n items: WorkItemNode[];\n pageInfo: { hasNextPage: boolean; endCursor: string | null };\n totalCount: number;\n };\n }>(GET_WORK_ITEMS, {\n variables: { workspaceId, filter, pagination: { first: PAGE_SIZE } },\n // The list only feeds the cross-project overview; a board loads its own cards.\n skip: !workspaceId || !!selectedProject,\n });\n const { data: countsData } = useQuery<{\n planmagnetWorkItemCounts: { total: number; byStatus: { status: string; count: number }[] };\n }>(GET_WORK_ITEM_COUNTS, { variables: { workspaceId, filter }, skip: !workspaceId });\n\n const loadMore = async () => {\n const after = data?.planmagnetWorkItems?.pageInfo?.endCursor;\n if (!after) return;\n setLoadingMore(true);\n try {\n await fetchMore({\n variables: { pagination: { first: PAGE_SIZE, after } },\n updateQuery: (prev, { fetchMoreResult }) => ({\n planmagnetWorkItems: {\n ...fetchMoreResult.planmagnetWorkItems,\n items: [\n ...prev.planmagnetWorkItems.items,\n ...fetchMoreResult.planmagnetWorkItems.items,\n ],\n },\n }),\n });\n } finally {\n setLoadingMore(false);\n }\n };\n\n // Only before the first load: a refetch or a filter change must not blank the board.\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 tasks = data?.planmagnetWorkItems?.items ?? [];\n\n const counts = countsData?.planmagnetWorkItemCounts;\n const total = counts?.total ?? data?.planmagnetWorkItems?.totalCount ?? tasks.length;\n const countFor = (status: string) =>\n counts?.byStatus.find((c) => c.status === status)?.count ??\n tasks.filter((t) => t.status === status).length;\n const hasMore = data?.planmagnetWorkItems?.pageInfo?.hasNextPage ?? false;\n\n return (\n <div className=\"space-y-4 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Task Board</h1>\n <label className=\"sr-only\" htmlFor=\"task-board-project\">\n Project\n </label>\n <select\n id=\"task-board-project\"\n className=\"mt-2 rounded-md border border-input bg-background px-2 py-1 text-sm\"\n value={selectedProject}\n onChange={(e) => setBoardProject(e.target.value)}\n >\n {boardProjects.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n <option value=\"\">All projects — status overview</option>\n </select>\n <p className=\"text-sm text-muted-foreground\" data-testid=\"task-board-total\">\n {total} tasks across all projects\n {tasks.length < total && ` · showing ${tasks.length}`}\n </p>\n </div>\n </div>\n {selectedProject ? (\n <ProjectBoard projectId={selectedProject} projectName={selectedProjectName} />\n ) : (\n <>\n <div className=\"flex gap-4 items-center flex-wrap\">\n <Filter className=\"h-4 w-4 text-muted-foreground\" />\n <div className=\"flex gap-1\">\n {['all', 'low', 'medium', 'high', 'critical'].map((p) => (\n <button\n key={p}\n onClick={() => setPriorityFilter(p)}\n className={`px-2 py-1 text-xs rounded capitalize ${priorityFilter === p ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {p}\n </button>\n ))}\n </div>\n <div className=\"flex gap-1\">\n {['all', 'story', 'bug', 'task', 'epic'].map((t) => (\n <button\n key={t}\n onClick={() => setTypeFilter(t)}\n className={`px-2 py-1 text-xs rounded capitalize ${typeFilter === t ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {t}\n </button>\n ))}\n </div>\n </div>\n <div className=\"grid grid-cols-7 gap-3 overflow-x-auto\">\n {columns.map((col) => {\n const colTasks = tasks.filter((t) => t.status === col);\n return (\n <div key={col} className=\"min-w-[200px]\">\n <div className={`border-t-2 ${colColor[col]} rounded-t-md p-2 bg-muted/50`}>\n <div className=\"flex justify-between items-center\">\n <span className=\"text-sm font-medium\">{colLabel[col]}</span>\n <span\n className=\"text-xs bg-muted rounded-full px-1.5\"\n data-testid={`task-col-count-${col}`}\n >\n {countFor(col)}\n </span>\n </div>\n </div>\n <div className=\"space-y-2 mt-2\">\n {colTasks.map((task) => (\n <Card\n key={task.id}\n {...rowLinkProps(\n () =>\n navigate(\n `/tasks/task-detail-page?taskId=${encodeURIComponent(task.id)}`\n ),\n task.title\n )}\n >\n <CardContent className=\"p-3 space-y-2\">\n <p className=\"text-sm font-medium leading-tight\">{task.title}</p>\n <p className=\"text-xs text-muted-foreground\">{task.key}</p>\n <div className=\"flex gap-1 flex-wrap\">\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${priorityColor[task.priority] ?? ''}`}\n >\n {task.priority.toLowerCase()}\n </span>\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${typeColor[task.type] ?? ''}`}\n >\n {task.type.toLowerCase()}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex gap-1\">\n {(task.labels ?? []).slice(0, 2).map((l) => (\n <span key={l} className=\"text-[9px] px-1 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] font-medium bg-primary/10 text-primary rounded-full h-5 w-5 flex items-center justify-center\">\n {task.storyPoints ?? 0}\n </span>\n </div>\n </div>\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>\n {task.assigneeId ? <PersonName id={task.assigneeId} /> : 'Unassigned'}\n </span>\n <span>\n {task.dueDate ? new Date(task.dueDate).toLocaleDateString() : ''}\n </span>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n {hasMore && (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loadingMore}\n className=\"px-3 py-1.5 text-sm rounded-md bg-muted text-foreground hover:bg-muted/80 disabled:opacity-50\"\n data-testid=\"task-board-load-more\"\n >\n {loadingMore ? 'Loading…' : `Load more (${tasks.length} of ${total})`}\n </button>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|