@burdenoff/microfe-planmagnet 2026.925.5 → 2026.925.6
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 +109 -0
- package/dist/generated/wspace-types.d.ts.map +1 -1
- 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 +137 -73
- package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
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 { useState as i } from "react";
|
|
5
|
+
import { Filter as a } from "lucide-react";
|
|
6
|
+
import { gql as o } from "@apollo/client";
|
|
7
|
+
import { useQuery as s } from "@apollo/client/react";
|
|
8
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
9
|
+
import { Card as u, CardContent as d } from "@burdenoff/fe-libs/ui";
|
|
9
10
|
//#region src/planmagnet/pages/TasksTasksPagePage.tsx
|
|
10
|
-
var
|
|
11
|
+
var f = o`
|
|
11
12
|
query GetWorkItems(
|
|
12
13
|
$workspaceId: ID!
|
|
13
14
|
$filter: PlanmagnetWorkItemFilter
|
|
@@ -31,77 +32,128 @@ var d = a`
|
|
|
31
32
|
tags
|
|
32
33
|
createdAt
|
|
33
34
|
}
|
|
35
|
+
pageInfo {
|
|
36
|
+
hasNextPage
|
|
37
|
+
endCursor
|
|
38
|
+
}
|
|
34
39
|
totalCount
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
|
-
`,
|
|
42
|
+
`, p = o`
|
|
43
|
+
query GetWorkItemCounts($workspaceId: ID!, $filter: PlanmagnetWorkItemFilter) {
|
|
44
|
+
planmagnetWorkItemCounts(workspaceId: $workspaceId, filter: $filter) {
|
|
45
|
+
total
|
|
46
|
+
byStatus {
|
|
47
|
+
status
|
|
48
|
+
count
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`, m = 100, h = [
|
|
38
53
|
"BACKLOG",
|
|
39
54
|
"TODO",
|
|
40
55
|
"IN_PROGRESS",
|
|
41
56
|
"IN_REVIEW",
|
|
42
57
|
"TESTING",
|
|
43
|
-
"DONE"
|
|
44
|
-
|
|
58
|
+
"DONE",
|
|
59
|
+
"CANCELLED"
|
|
60
|
+
], g = {
|
|
45
61
|
BACKLOG: "Backlog",
|
|
46
62
|
TODO: "To Do",
|
|
47
63
|
IN_PROGRESS: "In Progress",
|
|
48
64
|
IN_REVIEW: "In Review",
|
|
49
65
|
TESTING: "Testing",
|
|
50
|
-
DONE: "Done"
|
|
51
|
-
|
|
66
|
+
DONE: "Done",
|
|
67
|
+
CANCELLED: "Cancelled"
|
|
68
|
+
}, _ = {
|
|
52
69
|
BACKLOG: "border-t-gray-400",
|
|
53
70
|
TODO: "border-t-blue-400",
|
|
54
71
|
IN_PROGRESS: "border-t-yellow-400",
|
|
55
72
|
IN_REVIEW: "border-t-purple-400",
|
|
56
73
|
TESTING: "border-t-teal-400",
|
|
57
|
-
DONE: "border-t-green-400"
|
|
58
|
-
|
|
74
|
+
DONE: "border-t-green-400",
|
|
75
|
+
CANCELLED: "border-t-muted-foreground"
|
|
76
|
+
}, v = {
|
|
59
77
|
LOW: "bg-gray-100 text-gray-700",
|
|
60
78
|
MEDIUM: "bg-blue-100 text-blue-700",
|
|
61
79
|
HIGH: "bg-orange-100 text-orange-700",
|
|
62
80
|
CRITICAL: "bg-red-100 text-red-700"
|
|
63
|
-
},
|
|
81
|
+
}, y = {
|
|
64
82
|
STORY: "bg-green-100 text-green-700",
|
|
65
83
|
BUG: "bg-red-100 text-red-700",
|
|
66
84
|
TASK: "bg-blue-100 text-blue-700",
|
|
67
85
|
EPIC: "bg-purple-100 text-purple-700",
|
|
68
86
|
SUBTASK: "bg-gray-100 text-gray-700"
|
|
69
87
|
};
|
|
70
|
-
function
|
|
71
|
-
let { workspaceId:
|
|
88
|
+
function b() {
|
|
89
|
+
let { workspaceId: o } = e(), b = t(), [x, S] = i("all"), [C, w] = i("all"), T = {
|
|
90
|
+
...x !== "all" && { priority: x.toUpperCase() },
|
|
91
|
+
...C !== "all" && { type: C.toUpperCase() }
|
|
92
|
+
}, [E, D] = i(!1), { data: O, loading: k, error: A, fetchMore: j } = s(f, {
|
|
72
93
|
variables: {
|
|
73
|
-
workspaceId:
|
|
74
|
-
|
|
94
|
+
workspaceId: o,
|
|
95
|
+
filter: T,
|
|
96
|
+
pagination: { first: m }
|
|
75
97
|
},
|
|
76
|
-
skip: !
|
|
77
|
-
})
|
|
78
|
-
|
|
98
|
+
skip: !o
|
|
99
|
+
}), { data: M } = s(p, {
|
|
100
|
+
variables: {
|
|
101
|
+
workspaceId: o,
|
|
102
|
+
filter: T
|
|
103
|
+
},
|
|
104
|
+
skip: !o
|
|
105
|
+
}), N = async () => {
|
|
106
|
+
let e = O?.planmagnetWorkItems?.pageInfo?.endCursor;
|
|
107
|
+
if (e) {
|
|
108
|
+
D(!0);
|
|
109
|
+
try {
|
|
110
|
+
await j({
|
|
111
|
+
variables: { pagination: {
|
|
112
|
+
first: m,
|
|
113
|
+
after: e
|
|
114
|
+
} },
|
|
115
|
+
updateQuery: (e, { fetchMoreResult: t }) => ({ planmagnetWorkItems: {
|
|
116
|
+
...t.planmagnetWorkItems,
|
|
117
|
+
items: [...e.planmagnetWorkItems.items, ...t.planmagnetWorkItems.items]
|
|
118
|
+
} })
|
|
119
|
+
});
|
|
120
|
+
} finally {
|
|
121
|
+
D(!1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
if (k && !O) return /* @__PURE__ */ c("div", {
|
|
79
126
|
className: "flex items-center justify-center p-12",
|
|
80
|
-
children: /* @__PURE__ */
|
|
127
|
+
children: /* @__PURE__ */ c("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
81
128
|
});
|
|
82
|
-
if (
|
|
129
|
+
if (A) return /* @__PURE__ */ l("div", {
|
|
83
130
|
className: "p-6 text-red-500",
|
|
84
|
-
children: ["Error: ",
|
|
131
|
+
children: ["Error: ", A.message]
|
|
85
132
|
});
|
|
86
|
-
let
|
|
87
|
-
return /* @__PURE__ */
|
|
133
|
+
let P = O?.planmagnetWorkItems?.items ?? [], F = M?.planmagnetWorkItemCounts, I = F?.total ?? O?.planmagnetWorkItems?.totalCount ?? P.length, L = (e) => F?.byStatus.find((t) => t.status === e)?.count ?? P.filter((t) => t.status === e).length, R = O?.planmagnetWorkItems?.pageInfo?.hasNextPage ?? !1;
|
|
134
|
+
return /* @__PURE__ */ l("div", {
|
|
88
135
|
className: "space-y-4 p-6",
|
|
89
136
|
children: [
|
|
90
|
-
/* @__PURE__ */
|
|
137
|
+
/* @__PURE__ */ c("div", {
|
|
91
138
|
className: "flex items-center justify-between",
|
|
92
|
-
children: /* @__PURE__ */
|
|
139
|
+
children: /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
|
|
93
140
|
className: "text-2xl font-semibold",
|
|
94
141
|
children: "Task Board"
|
|
95
|
-
}), /* @__PURE__ */
|
|
142
|
+
}), /* @__PURE__ */ l("p", {
|
|
96
143
|
className: "text-sm text-muted-foreground",
|
|
97
|
-
|
|
144
|
+
"data-testid": "task-board-total",
|
|
145
|
+
children: [
|
|
146
|
+
I,
|
|
147
|
+
" tasks across all projects",
|
|
148
|
+
P.length < I && ` · showing ${P.length}`
|
|
149
|
+
]
|
|
98
150
|
})] })
|
|
99
151
|
}),
|
|
100
|
-
/* @__PURE__ */
|
|
152
|
+
/* @__PURE__ */ l("div", {
|
|
101
153
|
className: "flex gap-4 items-center flex-wrap",
|
|
102
154
|
children: [
|
|
103
|
-
/* @__PURE__ */
|
|
104
|
-
/* @__PURE__ */
|
|
155
|
+
/* @__PURE__ */ c(a, { className: "h-4 w-4 text-muted-foreground" }),
|
|
156
|
+
/* @__PURE__ */ c("div", {
|
|
105
157
|
className: "flex gap-1",
|
|
106
158
|
children: [
|
|
107
159
|
"all",
|
|
@@ -109,13 +161,13 @@ function _() {
|
|
|
109
161
|
"medium",
|
|
110
162
|
"high",
|
|
111
163
|
"critical"
|
|
112
|
-
].map((e) => /* @__PURE__ */
|
|
113
|
-
onClick: () =>
|
|
114
|
-
className: `px-2 py-1 text-xs rounded capitalize ${
|
|
164
|
+
].map((e) => /* @__PURE__ */ c("button", {
|
|
165
|
+
onClick: () => S(e),
|
|
166
|
+
className: `px-2 py-1 text-xs rounded capitalize ${x === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
115
167
|
children: e
|
|
116
168
|
}, e))
|
|
117
169
|
}),
|
|
118
|
-
/* @__PURE__ */
|
|
170
|
+
/* @__PURE__ */ c("div", {
|
|
119
171
|
className: "flex gap-1",
|
|
120
172
|
children: [
|
|
121
173
|
"all",
|
|
@@ -123,76 +175,77 @@ function _() {
|
|
|
123
175
|
"bug",
|
|
124
176
|
"task",
|
|
125
177
|
"epic"
|
|
126
|
-
].map((e) => /* @__PURE__ */
|
|
127
|
-
onClick: () =>
|
|
128
|
-
className: `px-2 py-1 text-xs rounded capitalize ${
|
|
178
|
+
].map((e) => /* @__PURE__ */ c("button", {
|
|
179
|
+
onClick: () => w(e),
|
|
180
|
+
className: `px-2 py-1 text-xs rounded capitalize ${C === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
129
181
|
children: e
|
|
130
182
|
}, e))
|
|
131
183
|
})
|
|
132
184
|
]
|
|
133
185
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
135
|
-
className: "grid grid-cols-
|
|
136
|
-
children:
|
|
137
|
-
let t =
|
|
138
|
-
return /* @__PURE__ */
|
|
186
|
+
/* @__PURE__ */ c("div", {
|
|
187
|
+
className: "grid grid-cols-7 gap-3 overflow-x-auto",
|
|
188
|
+
children: h.map((e) => {
|
|
189
|
+
let t = P.filter((t) => t.status === e);
|
|
190
|
+
return /* @__PURE__ */ l("div", {
|
|
139
191
|
className: "min-w-[200px]",
|
|
140
|
-
children: [/* @__PURE__ */
|
|
141
|
-
className: `border-t-2 ${
|
|
142
|
-
children: /* @__PURE__ */
|
|
192
|
+
children: [/* @__PURE__ */ c("div", {
|
|
193
|
+
className: `border-t-2 ${_[e]} rounded-t-md p-2 bg-muted/50`,
|
|
194
|
+
children: /* @__PURE__ */ l("div", {
|
|
143
195
|
className: "flex justify-between items-center",
|
|
144
|
-
children: [/* @__PURE__ */
|
|
196
|
+
children: [/* @__PURE__ */ c("span", {
|
|
145
197
|
className: "text-sm font-medium",
|
|
146
|
-
children:
|
|
147
|
-
}), /* @__PURE__ */
|
|
198
|
+
children: g[e]
|
|
199
|
+
}), /* @__PURE__ */ c("span", {
|
|
148
200
|
className: "text-xs bg-muted rounded-full px-1.5",
|
|
149
|
-
|
|
201
|
+
"data-testid": `task-col-count-${e}`,
|
|
202
|
+
children: L(e)
|
|
150
203
|
})]
|
|
151
204
|
})
|
|
152
|
-
}), /* @__PURE__ */
|
|
205
|
+
}), /* @__PURE__ */ c("div", {
|
|
153
206
|
className: "space-y-2 mt-2",
|
|
154
|
-
children: t.map((e) => /* @__PURE__ */
|
|
155
|
-
...
|
|
156
|
-
children: /* @__PURE__ */
|
|
207
|
+
children: t.map((e) => /* @__PURE__ */ c(u, {
|
|
208
|
+
...r(() => b(`/tasks/task-detail-page?taskId=${encodeURIComponent(e.id)}`), e.title),
|
|
209
|
+
children: /* @__PURE__ */ l(d, {
|
|
157
210
|
className: "p-3 space-y-2",
|
|
158
211
|
children: [
|
|
159
|
-
/* @__PURE__ */
|
|
212
|
+
/* @__PURE__ */ c("p", {
|
|
160
213
|
className: "text-sm font-medium leading-tight",
|
|
161
214
|
children: e.title
|
|
162
215
|
}),
|
|
163
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ c("p", {
|
|
164
217
|
className: "text-xs text-muted-foreground",
|
|
165
218
|
children: e.key
|
|
166
219
|
}),
|
|
167
|
-
/* @__PURE__ */
|
|
220
|
+
/* @__PURE__ */ l("div", {
|
|
168
221
|
className: "flex gap-1 flex-wrap",
|
|
169
|
-
children: [/* @__PURE__ */
|
|
170
|
-
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${
|
|
222
|
+
children: [/* @__PURE__ */ c("span", {
|
|
223
|
+
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${v[e.priority] ?? ""}`,
|
|
171
224
|
children: e.priority.toLowerCase()
|
|
172
|
-
}), /* @__PURE__ */
|
|
173
|
-
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${
|
|
225
|
+
}), /* @__PURE__ */ c("span", {
|
|
226
|
+
className: `text-[10px] px-1.5 py-0.5 rounded-full capitalize ${y[e.type] ?? ""}`,
|
|
174
227
|
children: e.type.toLowerCase()
|
|
175
228
|
})]
|
|
176
229
|
}),
|
|
177
|
-
/* @__PURE__ */
|
|
230
|
+
/* @__PURE__ */ l("div", {
|
|
178
231
|
className: "flex items-center justify-between",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
232
|
+
children: [/* @__PURE__ */ c("div", {
|
|
180
233
|
className: "flex gap-1",
|
|
181
|
-
children: (e.labels ?? []).slice(0, 2).map((e) => /* @__PURE__ */
|
|
234
|
+
children: (e.labels ?? []).slice(0, 2).map((e) => /* @__PURE__ */ c("span", {
|
|
182
235
|
className: "text-[9px] px-1 py-0.5 rounded bg-muted",
|
|
183
236
|
children: e
|
|
184
237
|
}, e))
|
|
185
|
-
}), /* @__PURE__ */
|
|
238
|
+
}), /* @__PURE__ */ c("div", {
|
|
186
239
|
className: "flex items-center gap-1",
|
|
187
|
-
children: /* @__PURE__ */
|
|
240
|
+
children: /* @__PURE__ */ c("span", {
|
|
188
241
|
className: "text-[10px] font-medium bg-primary/10 text-primary rounded-full h-5 w-5 flex items-center justify-center",
|
|
189
242
|
children: e.storyPoints ?? 0
|
|
190
243
|
})
|
|
191
244
|
})]
|
|
192
245
|
}),
|
|
193
|
-
/* @__PURE__ */
|
|
246
|
+
/* @__PURE__ */ l("div", {
|
|
194
247
|
className: "flex justify-between text-[10px] text-muted-foreground",
|
|
195
|
-
children: [/* @__PURE__ */
|
|
248
|
+
children: [/* @__PURE__ */ c("span", { children: e.assigneeId ? /* @__PURE__ */ c(n, { id: e.assigneeId }) : "Unassigned" }), /* @__PURE__ */ c("span", { children: e.dueDate ? new Date(e.dueDate).toLocaleDateString() : "" })]
|
|
196
249
|
})
|
|
197
250
|
]
|
|
198
251
|
})
|
|
@@ -200,11 +253,22 @@ function _() {
|
|
|
200
253
|
})]
|
|
201
254
|
}, e);
|
|
202
255
|
})
|
|
256
|
+
}),
|
|
257
|
+
R && /* @__PURE__ */ c("div", {
|
|
258
|
+
className: "flex justify-center",
|
|
259
|
+
children: /* @__PURE__ */ c("button", {
|
|
260
|
+
type: "button",
|
|
261
|
+
onClick: N,
|
|
262
|
+
disabled: E,
|
|
263
|
+
className: "px-3 py-1.5 text-sm rounded-md bg-muted text-foreground hover:bg-muted/80 disabled:opacity-50",
|
|
264
|
+
"data-testid": "task-board-load-more",
|
|
265
|
+
children: E ? "Loading…" : `Load more (${P.length} of ${I})`
|
|
266
|
+
})
|
|
203
267
|
})
|
|
204
268
|
]
|
|
205
269
|
});
|
|
206
270
|
}
|
|
207
271
|
//#endregion
|
|
208
|
-
export {
|
|
272
|
+
export { b as TasksTasksPagePage };
|
|
209
273
|
|
|
210
274
|
//# 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';\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\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\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 skip: !workspaceId,\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 <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 <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(`/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>\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 </div>\n );\n}\n"],"mappings":"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"}
|