@burdenoff/microfe-planmagnet 2026.930.23 → 2026.930.25
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/index.js +6 -5
- package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.js +154 -147
- package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +66 -62
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/comments/CommentThread.d.ts +8 -1
- package/dist/planmagnet/comments/CommentThread.d.ts.map +1 -1
- package/dist/planmagnet/comments/CommentThread.js +188 -181
- package/dist/planmagnet/comments/CommentThread.js.map +1 -1
- package/dist/planmagnet/comments/TargetComments.d.ts +10 -2
- package/dist/planmagnet/comments/TargetComments.d.ts.map +1 -1
- package/dist/planmagnet/comments/TargetComments.js +10 -8
- package/dist/planmagnet/comments/TargetComments.js.map +1 -1
- package/dist/planmagnet/comments/WorkItemComments.d.ts +7 -1
- package/dist/planmagnet/comments/WorkItemComments.d.ts.map +1 -1
- package/dist/planmagnet/comments/WorkItemComments.js +5 -4
- package/dist/planmagnet/comments/WorkItemComments.js.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts +11 -0
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.js +305 -135
- package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
- package/dist/planmagnet/controls/Pickers.d.ts +18 -0
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +78 -1
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/controls/PrioritizationControls.d.ts +72 -0
- package/dist/planmagnet/controls/PrioritizationControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/PrioritizationControls.js +246 -0
- package/dist/planmagnet/controls/PrioritizationControls.js.map +1 -0
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.d.ts +8 -0
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.d.ts.map +1 -0
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js +217 -0
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js.map +1 -0
- package/dist/planmagnet/docs/DocDiffView.d.ts +26 -0
- package/dist/planmagnet/docs/DocDiffView.d.ts.map +1 -0
- package/dist/planmagnet/docs/DocDiffView.js +52 -0
- package/dist/planmagnet/docs/DocDiffView.js.map +1 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.d.ts +13 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.d.ts.map +1 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.js +308 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.js.map +1 -0
- package/dist/planmagnet/docs/DocVersionCompare.d.ts +7 -0
- package/dist/planmagnet/docs/DocVersionCompare.d.ts.map +1 -0
- package/dist/planmagnet/docs/DocVersionCompare.js +105 -0
- package/dist/planmagnet/docs/DocVersionCompare.js.map +1 -0
- package/dist/planmagnet/hooks/usePresence.d.ts +39 -0
- package/dist/planmagnet/hooks/usePresence.d.ts.map +1 -0
- package/dist/planmagnet/hooks/usePresence.js +146 -0
- package/dist/planmagnet/hooks/usePresence.js.map +1 -0
- package/dist/planmagnet/index.d.ts +1 -0
- package/dist/planmagnet/index.d.ts.map +1 -1
- package/dist/planmagnet/index.js +1 -0
- package/dist/planmagnet/links/CodeLinksPanel.d.ts +22 -0
- package/dist/planmagnet/links/CodeLinksPanel.d.ts.map +1 -0
- package/dist/planmagnet/links/CodeLinksPanel.js +94 -0
- package/dist/planmagnet/links/CodeLinksPanel.js.map +1 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +488 -217
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +131 -125
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +183 -99
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +113 -97
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsPrioritizationPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProductsPrioritizationPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProductsPrioritizationPagePage.js +363 -0
- package/dist/planmagnet/pages/ProductsPrioritizationPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +96 -79
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +144 -128
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +205 -196
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +194 -160
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/dist/planmagnet/presence/PresenceAvatars.d.ts +16 -0
- package/dist/planmagnet/presence/PresenceAvatars.d.ts.map +1 -0
- package/dist/planmagnet/presence/PresenceAvatars.js +56 -0
- package/dist/planmagnet/presence/PresenceAvatars.js.map +1 -0
- package/dist/planmagnet/product/ProductControls.d.ts +33 -0
- package/dist/planmagnet/product/ProductControls.d.ts.map +1 -1
- package/dist/planmagnet/product/ProductControls.js +593 -268
- package/dist/planmagnet/product/ProductControls.js.map +1 -1
- package/dist/planmagnet/product/routes.d.ts +10 -0
- package/dist/planmagnet/product/routes.d.ts.map +1 -0
- package/dist/planmagnet/product/routes.js +6 -0
- package/dist/planmagnet/product/routes.js.map +1 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts +10 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.js +235 -184
- package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -1
- package/dist/planmagnet/utils/graphqlErrors.d.ts +6 -0
- package/dist/planmagnet/utils/graphqlErrors.d.ts.map +1 -1
- package/dist/planmagnet/utils/graphqlErrors.js +5 -2
- package/dist/planmagnet/utils/graphqlErrors.js.map +1 -1
- package/dist/planmagnet/utils/lineDiff.d.ts +21 -0
- package/dist/planmagnet/utils/lineDiff.d.ts.map +1 -0
- package/dist/planmagnet/utils/lineDiff.js +36 -0
- package/dist/planmagnet/utils/lineDiff.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
|
+
import { enumLabel as n } from "../controls/WorkItemControls.js";
|
|
3
|
+
import { detailPath as r } from "../utils/rowNavigation.js";
|
|
4
|
+
import { ProductSelect as i, RoadmapSelect as a } from "../controls/Pickers.js";
|
|
5
|
+
import { readUrlParam as o, writeUrlParam as s } from "../utils/urlParam.js";
|
|
6
|
+
import { KANO_META as c, KANO_VALUES as l, MOSCOW_META as u, MOSCOW_VALUES as d, QuadrantBadge as f } from "../controls/PrioritizationControls.js";
|
|
7
|
+
import { useState as p } from "react";
|
|
8
|
+
import { Gauge as m, Loader2 as h } from "lucide-react";
|
|
9
|
+
import { gql as g } from "@apollo/client";
|
|
10
|
+
import { useQuery as _ } from "@apollo/client/react";
|
|
11
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
12
|
+
import { Badge as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w, Tabs as T, TabsContent as E, TabsList as D, TabsTrigger as O } from "@burdenoff/fe-libs/ui";
|
|
13
|
+
//#region src/planmagnet/pages/ProductsPrioritizationPagePage.tsx
|
|
14
|
+
var k = "\n bucket\n count\n truncated\n", A = g`
|
|
15
|
+
query FeaturePrioritizationMatrix($workspaceId: ID!, $productId: ID, $roadmapId: ID) {
|
|
16
|
+
planmagnetFeaturePrioritizationMatrix(
|
|
17
|
+
workspaceId: $workspaceId
|
|
18
|
+
productId: $productId
|
|
19
|
+
roadmapId: $roadmapId
|
|
20
|
+
) {
|
|
21
|
+
source
|
|
22
|
+
moscow {
|
|
23
|
+
method
|
|
24
|
+
unscored
|
|
25
|
+
buckets {
|
|
26
|
+
${k}
|
|
27
|
+
featureRequests {
|
|
28
|
+
id
|
|
29
|
+
title
|
|
30
|
+
status
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
kano {
|
|
35
|
+
method
|
|
36
|
+
unscored
|
|
37
|
+
buckets {
|
|
38
|
+
${k}
|
|
39
|
+
featureRequests {
|
|
40
|
+
id
|
|
41
|
+
title
|
|
42
|
+
status
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
valueEffort {
|
|
47
|
+
method
|
|
48
|
+
unscored
|
|
49
|
+
buckets {
|
|
50
|
+
${k}
|
|
51
|
+
featureRequests {
|
|
52
|
+
id
|
|
53
|
+
title
|
|
54
|
+
status
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`, j = g`
|
|
61
|
+
query RoadmapPrioritizationMatrix($workspaceId: ID!, $productId: ID, $roadmapId: ID) {
|
|
62
|
+
planmagnetRoadmapPrioritizationMatrix(
|
|
63
|
+
workspaceId: $workspaceId
|
|
64
|
+
productId: $productId
|
|
65
|
+
roadmapId: $roadmapId
|
|
66
|
+
) {
|
|
67
|
+
source
|
|
68
|
+
moscow {
|
|
69
|
+
method
|
|
70
|
+
unscored
|
|
71
|
+
buckets {
|
|
72
|
+
${k}
|
|
73
|
+
roadmapItems {
|
|
74
|
+
id
|
|
75
|
+
title
|
|
76
|
+
status
|
|
77
|
+
roadmapId
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
kano {
|
|
82
|
+
method
|
|
83
|
+
unscored
|
|
84
|
+
buckets {
|
|
85
|
+
${k}
|
|
86
|
+
roadmapItems {
|
|
87
|
+
id
|
|
88
|
+
title
|
|
89
|
+
status
|
|
90
|
+
roadmapId
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
valueEffort {
|
|
95
|
+
method
|
|
96
|
+
unscored
|
|
97
|
+
buckets {
|
|
98
|
+
${k}
|
|
99
|
+
roadmapItems {
|
|
100
|
+
id
|
|
101
|
+
title
|
|
102
|
+
status
|
|
103
|
+
roadmapId
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
`, M = [["QUICK_WIN", "MAJOR_PROJECT"], ["FILL_IN", "TIME_SINK"]];
|
|
110
|
+
function N(e, t) {
|
|
111
|
+
return e?.find((e) => e.bucket === t) ?? {
|
|
112
|
+
bucket: t,
|
|
113
|
+
count: 0,
|
|
114
|
+
truncated: !1
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function P({ header: e, bucket: t, source: i, navigate: a }) {
|
|
118
|
+
let o = t.featureRequests ?? t.roadmapItems ?? [], s = (e) => i === "FEATURE_REQUEST" ? r("/products/feature-detail-page", e.id) : r("/products/roadmap-detail-page", e.roadmapId);
|
|
119
|
+
return /* @__PURE__ */ y(x, {
|
|
120
|
+
"data-testid": "prio-bucket",
|
|
121
|
+
className: "flex-1 min-w-[220px]",
|
|
122
|
+
children: [/* @__PURE__ */ v(C, {
|
|
123
|
+
className: "pb-2",
|
|
124
|
+
children: /* @__PURE__ */ y("div", {
|
|
125
|
+
className: "flex items-center justify-between gap-2",
|
|
126
|
+
children: [e, /* @__PURE__ */ v(b, {
|
|
127
|
+
variant: "outline",
|
|
128
|
+
children: t.count
|
|
129
|
+
})]
|
|
130
|
+
})
|
|
131
|
+
}), /* @__PURE__ */ y(S, {
|
|
132
|
+
className: "space-y-1",
|
|
133
|
+
children: [
|
|
134
|
+
o.length === 0 && /* @__PURE__ */ v("p", {
|
|
135
|
+
className: "text-xs text-muted-foreground",
|
|
136
|
+
children: "No items"
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ v("ul", {
|
|
139
|
+
className: "space-y-1",
|
|
140
|
+
children: o.map((e) => /* @__PURE__ */ v("li", { children: /* @__PURE__ */ y("button", {
|
|
141
|
+
type: "button",
|
|
142
|
+
className: "w-full rounded-md border p-2 text-left text-xs hover:bg-muted",
|
|
143
|
+
onClick: () => a(s(e)),
|
|
144
|
+
children: [/* @__PURE__ */ v("span", {
|
|
145
|
+
className: "block truncate font-medium",
|
|
146
|
+
children: e.title
|
|
147
|
+
}), /* @__PURE__ */ v("span", {
|
|
148
|
+
className: "text-[10px] text-muted-foreground capitalize",
|
|
149
|
+
children: n(e.status)
|
|
150
|
+
})]
|
|
151
|
+
}) }, e.id))
|
|
152
|
+
}),
|
|
153
|
+
t.truncated && /* @__PURE__ */ y("p", {
|
|
154
|
+
className: "pt-1 text-xs text-muted-foreground",
|
|
155
|
+
children: [
|
|
156
|
+
"+",
|
|
157
|
+
Math.max(t.count - o.length, 0),
|
|
158
|
+
" more"
|
|
159
|
+
]
|
|
160
|
+
})
|
|
161
|
+
]
|
|
162
|
+
})]
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function F({ count: e, method: t }) {
|
|
166
|
+
return e ? /* @__PURE__ */ y("p", {
|
|
167
|
+
className: "rounded-md border border-dashed p-2 text-xs text-muted-foreground",
|
|
168
|
+
children: [
|
|
169
|
+
e,
|
|
170
|
+
" item",
|
|
171
|
+
e === 1 ? "" : "s",
|
|
172
|
+
" not yet scored for ",
|
|
173
|
+
t,
|
|
174
|
+
" — set it from the item's edit form to see it grouped here."
|
|
175
|
+
]
|
|
176
|
+
}) : null;
|
|
177
|
+
}
|
|
178
|
+
function I() {
|
|
179
|
+
let { workspaceId: n } = e(), r = t(), [g, b] = p(() => o("source") === "ROADMAP_ITEM" ? "ROADMAP_ITEM" : "FEATURE_REQUEST"), x = (e) => {
|
|
180
|
+
b(e), s("source", e === "FEATURE_REQUEST" ? null : e);
|
|
181
|
+
}, [S, C] = p(() => {
|
|
182
|
+
let e = o("method");
|
|
183
|
+
return e === "kano" || e === "valueEffort" ? e : "moscow";
|
|
184
|
+
}), k = (e) => {
|
|
185
|
+
C(e), s("method", e === "moscow" ? null : e);
|
|
186
|
+
}, [I, L] = p(""), [R, z] = p(""), B = {
|
|
187
|
+
workspaceId: n ?? "",
|
|
188
|
+
productId: I || void 0,
|
|
189
|
+
roadmapId: R || void 0
|
|
190
|
+
}, V = _(A, {
|
|
191
|
+
variables: B,
|
|
192
|
+
skip: !n || g !== "FEATURE_REQUEST"
|
|
193
|
+
}), H = _(j, {
|
|
194
|
+
variables: B,
|
|
195
|
+
skip: !n || g !== "ROADMAP_ITEM"
|
|
196
|
+
}), U = g === "FEATURE_REQUEST" ? V.loading : H.loading, W = g === "FEATURE_REQUEST" ? V.error : H.error, G = g === "FEATURE_REQUEST" ? V.data : H.data;
|
|
197
|
+
if (U && !G) return /* @__PURE__ */ v("div", {
|
|
198
|
+
className: "flex items-center justify-center p-12",
|
|
199
|
+
children: /* @__PURE__ */ v(h, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
200
|
+
});
|
|
201
|
+
if (W) return /* @__PURE__ */ y("div", {
|
|
202
|
+
className: "p-6 text-destructive",
|
|
203
|
+
children: ["Failed to load the prioritization matrix: ", W.message]
|
|
204
|
+
});
|
|
205
|
+
let K = g === "FEATURE_REQUEST" ? V.data?.planmagnetFeaturePrioritizationMatrix : H.data?.planmagnetRoadmapPrioritizationMatrix;
|
|
206
|
+
return /* @__PURE__ */ y("div", {
|
|
207
|
+
className: "space-y-6 p-6",
|
|
208
|
+
"data-testid": "prio-page",
|
|
209
|
+
children: [
|
|
210
|
+
/* @__PURE__ */ y("div", {
|
|
211
|
+
className: "flex items-center gap-2",
|
|
212
|
+
children: [/* @__PURE__ */ v(m, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h1", {
|
|
213
|
+
className: "text-2xl font-semibold",
|
|
214
|
+
children: "Prioritization"
|
|
215
|
+
}), /* @__PURE__ */ v("p", {
|
|
216
|
+
className: "text-sm text-muted-foreground",
|
|
217
|
+
children: "MoSCoW, Kano and Value-vs-Effort, over feature requests or roadmap initiatives."
|
|
218
|
+
})] })]
|
|
219
|
+
}),
|
|
220
|
+
/* @__PURE__ */ y("div", {
|
|
221
|
+
className: "flex flex-wrap items-center justify-between gap-3",
|
|
222
|
+
children: [/* @__PURE__ */ v("div", {
|
|
223
|
+
className: "flex items-center gap-2",
|
|
224
|
+
role: "group",
|
|
225
|
+
"aria-label": "Prioritization source",
|
|
226
|
+
"data-testid": "prio-source",
|
|
227
|
+
children: ["FEATURE_REQUEST", "ROADMAP_ITEM"].map((e) => /* @__PURE__ */ v("button", {
|
|
228
|
+
type: "button",
|
|
229
|
+
"aria-pressed": g === e,
|
|
230
|
+
onClick: () => x(e),
|
|
231
|
+
className: `px-3 py-1.5 text-sm rounded-md ${g === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
232
|
+
children: e === "FEATURE_REQUEST" ? "Feature requests" : "Roadmap initiatives"
|
|
233
|
+
}, e))
|
|
234
|
+
}), /* @__PURE__ */ y("div", {
|
|
235
|
+
className: "flex flex-wrap items-end gap-3",
|
|
236
|
+
children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
237
|
+
htmlFor: "prio-product",
|
|
238
|
+
className: "text-xs text-muted-foreground",
|
|
239
|
+
children: "Product"
|
|
240
|
+
}), /* @__PURE__ */ v("div", {
|
|
241
|
+
className: "mt-1",
|
|
242
|
+
children: /* @__PURE__ */ v(i, {
|
|
243
|
+
id: "prio-product",
|
|
244
|
+
value: I,
|
|
245
|
+
noneLabel: "All products",
|
|
246
|
+
onChange: (e) => {
|
|
247
|
+
L(e), z("");
|
|
248
|
+
}
|
|
249
|
+
})
|
|
250
|
+
})] }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
251
|
+
htmlFor: "prio-roadmap",
|
|
252
|
+
className: "text-xs text-muted-foreground",
|
|
253
|
+
children: "Roadmap"
|
|
254
|
+
}), /* @__PURE__ */ v("div", {
|
|
255
|
+
className: "mt-1",
|
|
256
|
+
children: /* @__PURE__ */ v(a, {
|
|
257
|
+
id: "prio-roadmap",
|
|
258
|
+
value: R,
|
|
259
|
+
noneLabel: "All roadmaps",
|
|
260
|
+
productId: I || void 0,
|
|
261
|
+
onChange: z
|
|
262
|
+
})
|
|
263
|
+
})] })]
|
|
264
|
+
})]
|
|
265
|
+
}),
|
|
266
|
+
/* @__PURE__ */ y(T, {
|
|
267
|
+
value: S,
|
|
268
|
+
onValueChange: (e) => k(e),
|
|
269
|
+
children: [
|
|
270
|
+
/* @__PURE__ */ y(D, { children: [
|
|
271
|
+
/* @__PURE__ */ v(O, {
|
|
272
|
+
value: "moscow",
|
|
273
|
+
"data-testid": "prio-method-moscow",
|
|
274
|
+
children: "MoSCoW"
|
|
275
|
+
}),
|
|
276
|
+
/* @__PURE__ */ v(O, {
|
|
277
|
+
value: "kano",
|
|
278
|
+
"data-testid": "prio-method-kano",
|
|
279
|
+
children: "Kano"
|
|
280
|
+
}),
|
|
281
|
+
/* @__PURE__ */ v(O, {
|
|
282
|
+
value: "valueEffort",
|
|
283
|
+
"data-testid": "prio-value-effort",
|
|
284
|
+
children: "Value vs Effort"
|
|
285
|
+
})
|
|
286
|
+
] }),
|
|
287
|
+
/* @__PURE__ */ y(E, {
|
|
288
|
+
value: "moscow",
|
|
289
|
+
className: "mt-4 space-y-3",
|
|
290
|
+
children: [/* @__PURE__ */ v(F, {
|
|
291
|
+
count: K?.moscow.unscored ?? 0,
|
|
292
|
+
method: "MoSCoW"
|
|
293
|
+
}), /* @__PURE__ */ v("div", {
|
|
294
|
+
className: "flex flex-wrap gap-4",
|
|
295
|
+
children: d.map((e) => /* @__PURE__ */ v(P, {
|
|
296
|
+
header: /* @__PURE__ */ v(w, {
|
|
297
|
+
className: "text-sm",
|
|
298
|
+
children: u[e].label
|
|
299
|
+
}),
|
|
300
|
+
bucket: N(K?.moscow.buckets, e),
|
|
301
|
+
source: g,
|
|
302
|
+
navigate: r
|
|
303
|
+
}, e))
|
|
304
|
+
})]
|
|
305
|
+
}),
|
|
306
|
+
/* @__PURE__ */ y(E, {
|
|
307
|
+
value: "kano",
|
|
308
|
+
className: "mt-4 space-y-3",
|
|
309
|
+
children: [/* @__PURE__ */ v(F, {
|
|
310
|
+
count: K?.kano.unscored ?? 0,
|
|
311
|
+
method: "Kano"
|
|
312
|
+
}), /* @__PURE__ */ v("div", {
|
|
313
|
+
className: "flex flex-wrap gap-4",
|
|
314
|
+
children: l.map((e) => /* @__PURE__ */ v(P, {
|
|
315
|
+
header: /* @__PURE__ */ v(w, {
|
|
316
|
+
className: "text-sm",
|
|
317
|
+
children: c[e].label
|
|
318
|
+
}),
|
|
319
|
+
bucket: N(K?.kano.buckets, e),
|
|
320
|
+
source: g,
|
|
321
|
+
navigate: r
|
|
322
|
+
}, e))
|
|
323
|
+
})]
|
|
324
|
+
}),
|
|
325
|
+
/* @__PURE__ */ y(E, {
|
|
326
|
+
value: "valueEffort",
|
|
327
|
+
className: "mt-4 space-y-3",
|
|
328
|
+
children: [
|
|
329
|
+
/* @__PURE__ */ v(F, {
|
|
330
|
+
count: K?.valueEffort.unscored ?? 0,
|
|
331
|
+
method: "Value vs Effort"
|
|
332
|
+
}),
|
|
333
|
+
/* @__PURE__ */ y("div", {
|
|
334
|
+
className: "grid grid-cols-1 sm:grid-cols-2 gap-2 text-center text-xs text-muted-foreground",
|
|
335
|
+
children: [/* @__PURE__ */ v("span", { children: "High value" }), /* @__PURE__ */ v("span", {})]
|
|
336
|
+
}),
|
|
337
|
+
/* @__PURE__ */ v("div", {
|
|
338
|
+
className: "space-y-4",
|
|
339
|
+
children: M.map((e, t) => /* @__PURE__ */ v("div", {
|
|
340
|
+
className: "grid grid-cols-1 sm:grid-cols-2 gap-4",
|
|
341
|
+
children: e.map((e) => /* @__PURE__ */ v(P, {
|
|
342
|
+
header: /* @__PURE__ */ v(f, { quadrant: e }),
|
|
343
|
+
bucket: N(K?.valueEffort.buckets, e),
|
|
344
|
+
source: g,
|
|
345
|
+
navigate: r
|
|
346
|
+
}, e))
|
|
347
|
+
}, t))
|
|
348
|
+
}),
|
|
349
|
+
/* @__PURE__ */ y("div", {
|
|
350
|
+
className: "grid grid-cols-1 sm:grid-cols-2 gap-2 text-center text-xs text-muted-foreground",
|
|
351
|
+
children: [/* @__PURE__ */ v("span", { children: "Low effort" }), /* @__PURE__ */ v("span", { children: "High effort" })]
|
|
352
|
+
})
|
|
353
|
+
]
|
|
354
|
+
})
|
|
355
|
+
]
|
|
356
|
+
})
|
|
357
|
+
]
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
//#endregion
|
|
361
|
+
export { I as ProductsPrioritizationPagePage };
|
|
362
|
+
|
|
363
|
+
//# sourceMappingURL=ProductsPrioritizationPagePage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductsPrioritizationPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsPrioritizationPagePage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { useState, type ReactNode } from 'react';\nimport {\n Badge,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { Gauge, Loader2 } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { readUrlParam, writeUrlParam } from '../utils/urlParam';\nimport { ProductSelect, RoadmapSelect } from '../controls/Pickers';\nimport { enumLabel } from '../controls/WorkItemControls';\nimport {\n KANO_META,\n KANO_VALUES,\n MOSCOW_META,\n MOSCOW_VALUES,\n QuadrantBadge,\n} from '../controls/PrioritizationControls';\n\n/**\n * Prioritization (PRM-27): MoSCoW, Kano and Value-vs-Effort views over either feature requests or roadmap\n * initiatives, each scoped by an optional product/roadmap. Two distinct queries back this page —\n * `planmagnetFeaturePrioritizationMatrix` / `planmagnetRoadmapPrioritizationMatrix` — because the server gates\n * them on different RBAC resources (`planmagnet-feature` vs `planmagnet-roadmap`); the page fetches whichever\n * one the source toggle selects and skips the other.\n *\n * Every bucket the server returns is already the FULL set for its method (even empty ones, all zero) — the\n * column/cell order below is still driven by this file's own MOSCOW_VALUES/KANO_VALUES/QUADRANT_VALUES so a\n * bucket always renders in the same place even if the server ever changed its own array order.\n */\n\nconst BUCKET_FIELDS = `\n bucket\n count\n truncated\n`;\n\nconst FEATURE_MATRIX = gql`\n query FeaturePrioritizationMatrix($workspaceId: ID!, $productId: ID, $roadmapId: ID) {\n planmagnetFeaturePrioritizationMatrix(\n workspaceId: $workspaceId\n productId: $productId\n roadmapId: $roadmapId\n ) {\n source\n moscow {\n method\n unscored\n buckets {\n ${BUCKET_FIELDS}\n featureRequests {\n id\n title\n status\n }\n }\n }\n kano {\n method\n unscored\n buckets {\n ${BUCKET_FIELDS}\n featureRequests {\n id\n title\n status\n }\n }\n }\n valueEffort {\n method\n unscored\n buckets {\n ${BUCKET_FIELDS}\n featureRequests {\n id\n title\n status\n }\n }\n }\n }\n }\n`;\n\nconst ROADMAP_MATRIX = gql`\n query RoadmapPrioritizationMatrix($workspaceId: ID!, $productId: ID, $roadmapId: ID) {\n planmagnetRoadmapPrioritizationMatrix(\n workspaceId: $workspaceId\n productId: $productId\n roadmapId: $roadmapId\n ) {\n source\n moscow {\n method\n unscored\n buckets {\n ${BUCKET_FIELDS}\n roadmapItems {\n id\n title\n status\n roadmapId\n }\n }\n }\n kano {\n method\n unscored\n buckets {\n ${BUCKET_FIELDS}\n roadmapItems {\n id\n title\n status\n roadmapId\n }\n }\n }\n valueEffort {\n method\n unscored\n buckets {\n ${BUCKET_FIELDS}\n roadmapItems {\n id\n title\n status\n roadmapId\n }\n }\n }\n }\n }\n`;\n\ntype Source = 'FEATURE_REQUEST' | 'ROADMAP_ITEM';\ntype Method = 'moscow' | 'kano' | 'valueEffort';\n\nconst VALUE_EFFORT_GRID: readonly (readonly [string, string])[] = [\n ['QUICK_WIN', 'MAJOR_PROJECT'],\n ['FILL_IN', 'TIME_SINK'],\n];\n\n/**\n * One item in a bucket. The two queries below select only one of `featureRequests`/`roadmapItems` each (never\n * both), but both shapes are folded into this single interface — same \"populated only for one branch\" contract\n * the server's own `PlanmagnetPrioritizationBucket` documents — so `BucketCard`/`findBucket` need only one type.\n */\ninterface PrioritizationItem {\n id: string;\n title: string;\n status: string;\n roadmapId?: string;\n}\n\ninterface PrioritizationBucket {\n bucket: string;\n count: number;\n truncated: boolean;\n featureRequests?: PrioritizationItem[] | null;\n roadmapItems?: PrioritizationItem[] | null;\n}\n\ninterface PrioritizationMethodResult {\n method: string;\n unscored: number;\n buckets: PrioritizationBucket[];\n}\n\ninterface PrioritizationMatrix {\n source: string;\n moscow: PrioritizationMethodResult;\n kano: PrioritizationMethodResult;\n valueEffort: PrioritizationMethodResult;\n}\n\ninterface FeatureMatrixData {\n planmagnetFeaturePrioritizationMatrix: PrioritizationMatrix;\n}\n\ninterface RoadmapMatrixData {\n planmagnetRoadmapPrioritizationMatrix: PrioritizationMatrix;\n}\n\nfunction findBucket(\n buckets: PrioritizationBucket[] | undefined,\n value: string\n): PrioritizationBucket {\n return buckets?.find((b) => b.bucket === value) ?? { bucket: value, count: 0, truncated: false };\n}\n\n/** One bucket's items, capped by the server and marked truncated — link each to its own detail page. */\nfunction BucketCard({\n header,\n bucket,\n source,\n navigate,\n}: {\n header: ReactNode;\n bucket: PrioritizationBucket;\n source: Source;\n navigate: (path: string) => void;\n}) {\n const items = bucket.featureRequests ?? bucket.roadmapItems ?? [];\n const linkFor = (item: { id: string; roadmapId?: string }) =>\n source === 'FEATURE_REQUEST'\n ? detailPath('/products/feature-detail-page', item.id)\n : detailPath('/products/roadmap-detail-page', item.roadmapId);\n\n return (\n <Card data-testid=\"prio-bucket\" className=\"flex-1 min-w-[220px]\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between gap-2\">\n {header}\n <Badge variant=\"outline\">{bucket.count}</Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-1\">\n {items.length === 0 && <p className=\"text-xs text-muted-foreground\">No items</p>}\n <ul className=\"space-y-1\">\n {items.map((item) => (\n <li key={item.id}>\n <button\n type=\"button\"\n className=\"w-full rounded-md border p-2 text-left text-xs hover:bg-muted\"\n onClick={() => navigate(linkFor(item))}\n >\n <span className=\"block truncate font-medium\">{item.title}</span>\n <span className=\"text-[10px] text-muted-foreground capitalize\">\n {enumLabel(item.status)}\n </span>\n </button>\n </li>\n ))}\n </ul>\n {bucket.truncated && (\n <p className=\"pt-1 text-xs text-muted-foreground\">\n +{Math.max(bucket.count - items.length, 0)} more\n </p>\n )}\n </CardContent>\n </Card>\n );\n}\n\nfunction UnscoredHint({ count, method }: { count: number; method: string }) {\n if (!count) return null;\n return (\n <p className=\"rounded-md border border-dashed p-2 text-xs text-muted-foreground\">\n {count} item{count === 1 ? '' : 's'} not yet scored for {method} — set it from the item's\n edit form to see it grouped here.\n </p>\n );\n}\n\nexport function ProductsPrioritizationPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const [source, setSourceState] = useState<Source>(() =>\n readUrlParam('source') === 'ROADMAP_ITEM' ? 'ROADMAP_ITEM' : 'FEATURE_REQUEST'\n );\n const setSource = (next: Source) => {\n setSourceState(next);\n writeUrlParam('source', next === 'FEATURE_REQUEST' ? null : next);\n };\n\n const [method, setMethodState] = useState<Method>(() => {\n const fromUrl = readUrlParam('method');\n return fromUrl === 'kano' || fromUrl === 'valueEffort' ? fromUrl : 'moscow';\n });\n const setMethod = (next: Method) => {\n setMethodState(next);\n writeUrlParam('method', next === 'moscow' ? null : next);\n };\n\n const [productId, setProductId] = useState('');\n const [roadmapId, setRoadmapId] = useState('');\n\n const variables = {\n workspaceId: workspaceId ?? '',\n productId: productId || undefined,\n roadmapId: roadmapId || undefined,\n };\n const featureResult = useQuery<FeatureMatrixData>(FEATURE_MATRIX, {\n variables,\n skip: !workspaceId || source !== 'FEATURE_REQUEST',\n });\n const roadmapResult = useQuery<RoadmapMatrixData>(ROADMAP_MATRIX, {\n variables,\n skip: !workspaceId || source !== 'ROADMAP_ITEM',\n });\n const loading = source === 'FEATURE_REQUEST' ? featureResult.loading : roadmapResult.loading;\n const error = source === 'FEATURE_REQUEST' ? featureResult.error : roadmapResult.error;\n const data = source === 'FEATURE_REQUEST' ? featureResult.data : roadmapResult.data;\n\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"p-6 text-destructive\">\n Failed to load the prioritization matrix: {error.message}\n </div>\n );\n }\n\n const matrix: PrioritizationMatrix | undefined =\n source === 'FEATURE_REQUEST'\n ? featureResult.data?.planmagnetFeaturePrioritizationMatrix\n : roadmapResult.data?.planmagnetRoadmapPrioritizationMatrix;\n\n return (\n <div className=\"space-y-6 p-6\" data-testid=\"prio-page\">\n <div className=\"flex items-center gap-2\">\n <Gauge className=\"h-5 w-5 text-primary\" />\n <div>\n <h1 className=\"text-2xl font-semibold\">Prioritization</h1>\n <p className=\"text-sm text-muted-foreground\">\n MoSCoW, Kano and Value-vs-Effort, over feature requests or roadmap initiatives.\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div\n className=\"flex items-center gap-2\"\n role=\"group\"\n aria-label=\"Prioritization source\"\n data-testid=\"prio-source\"\n >\n {(['FEATURE_REQUEST', 'ROADMAP_ITEM'] as const).map((s) => (\n <button\n key={s}\n type=\"button\"\n aria-pressed={source === s}\n onClick={() => setSource(s)}\n className={`px-3 py-1.5 text-sm rounded-md ${source === s ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {s === 'FEATURE_REQUEST' ? 'Feature requests' : 'Roadmap initiatives'}\n </button>\n ))}\n </div>\n\n <div className=\"flex flex-wrap items-end gap-3\">\n <div>\n <label htmlFor=\"prio-product\" className=\"text-xs text-muted-foreground\">\n Product\n </label>\n <div className=\"mt-1\">\n <ProductSelect\n id=\"prio-product\"\n value={productId}\n noneLabel=\"All products\"\n onChange={(next) => {\n setProductId(next);\n setRoadmapId('');\n }}\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"prio-roadmap\" className=\"text-xs text-muted-foreground\">\n Roadmap\n </label>\n <div className=\"mt-1\">\n <RoadmapSelect\n id=\"prio-roadmap\"\n value={roadmapId}\n noneLabel=\"All roadmaps\"\n productId={productId || undefined}\n onChange={setRoadmapId}\n />\n </div>\n </div>\n </div>\n </div>\n\n <Tabs value={method} onValueChange={(next) => setMethod(next as Method)}>\n <TabsList>\n <TabsTrigger value=\"moscow\" data-testid=\"prio-method-moscow\">\n MoSCoW\n </TabsTrigger>\n <TabsTrigger value=\"kano\" data-testid=\"prio-method-kano\">\n Kano\n </TabsTrigger>\n <TabsTrigger value=\"valueEffort\" data-testid=\"prio-value-effort\">\n Value vs Effort\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"moscow\" className=\"mt-4 space-y-3\">\n <UnscoredHint count={matrix?.moscow.unscored ?? 0} method=\"MoSCoW\" />\n <div className=\"flex flex-wrap gap-4\">\n {MOSCOW_VALUES.map((v) => (\n <BucketCard\n key={v}\n header={<CardTitle className=\"text-sm\">{MOSCOW_META[v].label}</CardTitle>}\n bucket={findBucket(matrix?.moscow.buckets, v)}\n source={source}\n navigate={navigate}\n />\n ))}\n </div>\n </TabsContent>\n\n <TabsContent value=\"kano\" className=\"mt-4 space-y-3\">\n <UnscoredHint count={matrix?.kano.unscored ?? 0} method=\"Kano\" />\n <div className=\"flex flex-wrap gap-4\">\n {KANO_VALUES.map((v) => (\n <BucketCard\n key={v}\n header={<CardTitle className=\"text-sm\">{KANO_META[v].label}</CardTitle>}\n bucket={findBucket(matrix?.kano.buckets, v)}\n source={source}\n navigate={navigate}\n />\n ))}\n </div>\n </TabsContent>\n\n <TabsContent value=\"valueEffort\" className=\"mt-4 space-y-3\">\n <UnscoredHint count={matrix?.valueEffort.unscored ?? 0} method=\"Value vs Effort\" />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2 text-center text-xs text-muted-foreground\">\n <span>High value</span>\n <span />\n </div>\n <div className=\"space-y-4\">\n {VALUE_EFFORT_GRID.map((row, rowIndex) => (\n <div key={rowIndex} className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {row.map((v) => (\n <BucketCard\n key={v}\n header={<QuadrantBadge quadrant={v} />}\n bucket={findBucket(matrix?.valueEffort.buckets, v)}\n source={source}\n navigate={navigate}\n />\n ))}\n </div>\n ))}\n </div>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2 text-center text-xs text-muted-foreground\">\n <span>Low effort</span>\n <span>High effort</span>\n </div>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsProductDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsProductDetailPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductsProductDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsProductDetailPagePage.tsx"],"names":[],"mappings":"AAyHA,wBAAgB,6BAA6B,4CAqL5C"}
|