@burdenoff/microfe-planmagnet 2026.930.23 → 2026.930.24
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/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/index.d.ts +1 -0
- package/dist/planmagnet/index.d.ts.map +1 -1
- package/dist/planmagnet/index.js +1 -0
- 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 +133 -123
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
- 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/package.json +1 -1
|
@@ -3,17 +3,17 @@ import { PersonName as n } from "../people/People.js";
|
|
|
3
3
|
import { detailPath as r } from "../utils/rowNavigation.js";
|
|
4
4
|
import { CompetitorLinkCard as i } from "../controls/CompetitorControls.js";
|
|
5
5
|
import { FeatureTriageActions as a, isOpenRequest as o, isSnoozed as s } from "../controls/FeatureTriage.js";
|
|
6
|
-
import { FeatureHeaderActions as c,
|
|
7
|
-
import { FeatureInitiativeCard as
|
|
8
|
-
import { useState as
|
|
9
|
-
import { Loader2 as
|
|
10
|
-
import { useParams as
|
|
11
|
-
import { gql as
|
|
12
|
-
import { useQuery as
|
|
13
|
-
import { Fragment as
|
|
14
|
-
import { Badge as
|
|
6
|
+
import { FeatureHeaderActions as c, FeaturePrioritizationCard as l, FeatureVoteButton as u } from "../controls/FeatureControls.js";
|
|
7
|
+
import { FeatureInitiativeCard as d } from "../roadmaps/FeatureInitiativeCard.js";
|
|
8
|
+
import { useState as f } from "react";
|
|
9
|
+
import { Loader2 as p, MessageSquare as m, Star as h, Target as g, ThumbsUp as _ } from "lucide-react";
|
|
10
|
+
import { useParams as v } from "react-router";
|
|
11
|
+
import { gql as y } from "@apollo/client";
|
|
12
|
+
import { useQuery as b } from "@apollo/client/react";
|
|
13
|
+
import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
14
|
+
import { Badge as w, Card as T, CardContent as E, CardHeader as D, CardTitle as O } from "@burdenoff/fe-libs/ui";
|
|
15
15
|
//#region src/planmagnet/pages/ProductsFeatureDetailPagePage.tsx
|
|
16
|
-
var
|
|
16
|
+
var k = y`
|
|
17
17
|
query GetFeatureRequest($id: ID!) {
|
|
18
18
|
planmagnetFeatureRequest(id: $id) {
|
|
19
19
|
id
|
|
@@ -30,6 +30,11 @@ var O = v`
|
|
|
30
30
|
workItemId
|
|
31
31
|
tags
|
|
32
32
|
snoozedUntil
|
|
33
|
+
moscow
|
|
34
|
+
kano
|
|
35
|
+
valueScore
|
|
36
|
+
effortScore
|
|
37
|
+
valueEffortQuadrant
|
|
33
38
|
declineReason
|
|
34
39
|
duplicateOfId
|
|
35
40
|
duplicateOf {
|
|
@@ -65,88 +70,88 @@ var O = v`
|
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
`;
|
|
68
|
-
function
|
|
69
|
-
let { workspaceId:
|
|
70
|
-
variables: { id:
|
|
71
|
-
skip: !
|
|
73
|
+
function A() {
|
|
74
|
+
let { workspaceId: y, currentUser: A } = e(), j = t(), [M] = f(() => Date.now()), N = v().id ?? "", { data: P, loading: F, error: I } = b(k, {
|
|
75
|
+
variables: { id: N },
|
|
76
|
+
skip: !N
|
|
72
77
|
});
|
|
73
|
-
if (
|
|
78
|
+
if (F && !P) return /* @__PURE__ */ S("div", {
|
|
74
79
|
className: "flex items-center justify-center p-12",
|
|
75
|
-
children: /* @__PURE__ */
|
|
80
|
+
children: /* @__PURE__ */ S(p, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
76
81
|
});
|
|
77
|
-
if (
|
|
82
|
+
if (I) return /* @__PURE__ */ C("div", {
|
|
78
83
|
className: "p-6 text-destructive",
|
|
79
|
-
children: ["Failed to load feature: ",
|
|
84
|
+
children: ["Failed to load feature: ", I.message]
|
|
80
85
|
});
|
|
81
|
-
let
|
|
82
|
-
if (!
|
|
86
|
+
let L = P?.planmagnetFeatureRequest;
|
|
87
|
+
if (!L) return /* @__PURE__ */ S("div", {
|
|
83
88
|
className: "p-6 text-muted-foreground",
|
|
84
89
|
children: "Feature not found."
|
|
85
90
|
});
|
|
86
|
-
let
|
|
87
|
-
return /* @__PURE__ */
|
|
91
|
+
let R = L.votes ?? [], z = L.competitors ?? [];
|
|
92
|
+
return /* @__PURE__ */ C("div", {
|
|
88
93
|
className: "space-y-6 p-6",
|
|
89
94
|
children: [
|
|
90
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ C("div", {
|
|
91
96
|
className: "flex items-center justify-between",
|
|
92
|
-
children: [/* @__PURE__ */
|
|
97
|
+
children: [/* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("h1", {
|
|
93
98
|
className: "text-2xl font-semibold",
|
|
94
|
-
children:
|
|
95
|
-
}), /* @__PURE__ */
|
|
99
|
+
children: L.title
|
|
100
|
+
}), /* @__PURE__ */ C("p", {
|
|
96
101
|
className: "text-sm text-muted-foreground",
|
|
97
102
|
children: [
|
|
98
103
|
"Submitted by: ",
|
|
99
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ S(n, { id: L.submittedBy }),
|
|
100
105
|
" · Effort:",
|
|
101
106
|
" ",
|
|
102
|
-
|
|
107
|
+
L.effortEstimate ?? "N/A"
|
|
103
108
|
]
|
|
104
|
-
})] }), /* @__PURE__ */
|
|
109
|
+
})] }), /* @__PURE__ */ C("div", {
|
|
105
110
|
className: "flex flex-col items-end gap-2",
|
|
106
|
-
children: [/* @__PURE__ */
|
|
107
|
-
featureId:
|
|
108
|
-
voted:
|
|
109
|
-
}), /* @__PURE__ */
|
|
111
|
+
children: [/* @__PURE__ */ S(u, {
|
|
112
|
+
featureId: L.id,
|
|
113
|
+
voted: R.some((e) => e.voterId === A?.id)
|
|
114
|
+
}), /* @__PURE__ */ S(c, { feature: L })]
|
|
110
115
|
})]
|
|
111
116
|
}),
|
|
112
|
-
o(
|
|
117
|
+
o(L.status) && /* @__PURE__ */ C(T, {
|
|
113
118
|
"data-testid": "triage-card",
|
|
114
|
-
children: [/* @__PURE__ */
|
|
119
|
+
children: [/* @__PURE__ */ S(D, { children: /* @__PURE__ */ S(O, { children: "Triage" }) }), /* @__PURE__ */ C(E, {
|
|
115
120
|
className: "space-y-2",
|
|
116
|
-
children: [/* @__PURE__ */
|
|
121
|
+
children: [/* @__PURE__ */ S("p", {
|
|
117
122
|
className: "text-sm text-muted-foreground",
|
|
118
|
-
children: s(
|
|
119
|
-
}), /* @__PURE__ */
|
|
120
|
-
feature:
|
|
121
|
-
now:
|
|
123
|
+
children: s(L.snoozedUntil, M) ? `Snoozed until ${new Date(L.snoozedUntil).toLocaleString()} — it returns to the triage queue then.` : L.status === "SUBMITTED" ? "Waiting for a decision." : "Under review: accept it as planned, decline it, or merge it into its original."
|
|
124
|
+
}), /* @__PURE__ */ S(a, {
|
|
125
|
+
feature: L,
|
|
126
|
+
now: M
|
|
122
127
|
})]
|
|
123
128
|
})]
|
|
124
129
|
}),
|
|
125
|
-
|
|
130
|
+
L.status === "DECLINED" && L.declineReason && /* @__PURE__ */ S(T, {
|
|
126
131
|
"data-testid": "decline-reason",
|
|
127
|
-
children: /* @__PURE__ */
|
|
132
|
+
children: /* @__PURE__ */ C(E, {
|
|
128
133
|
className: "pt-4 text-sm",
|
|
129
|
-
children: [/* @__PURE__ */
|
|
134
|
+
children: [/* @__PURE__ */ S("span", {
|
|
130
135
|
className: "font-medium",
|
|
131
136
|
children: "Declined: "
|
|
132
|
-
}),
|
|
137
|
+
}), L.declineReason]
|
|
133
138
|
})
|
|
134
139
|
}),
|
|
135
|
-
|
|
140
|
+
L.status === "DUPLICATE" && L.duplicateOfId && /* @__PURE__ */ S(T, {
|
|
136
141
|
"data-testid": "duplicate-of",
|
|
137
|
-
children: /* @__PURE__ */
|
|
142
|
+
children: /* @__PURE__ */ C(E, {
|
|
138
143
|
className: "pt-4 text-sm",
|
|
139
144
|
children: [
|
|
140
|
-
/* @__PURE__ */
|
|
145
|
+
/* @__PURE__ */ S("span", {
|
|
141
146
|
className: "font-medium",
|
|
142
147
|
children: "Duplicate of "
|
|
143
148
|
}),
|
|
144
|
-
|
|
149
|
+
L.duplicateOf ? /* @__PURE__ */ S("button", {
|
|
145
150
|
type: "button",
|
|
146
151
|
className: "text-primary underline-offset-2 hover:underline",
|
|
147
|
-
onClick: () =>
|
|
148
|
-
children:
|
|
149
|
-
}) : /* @__PURE__ */
|
|
152
|
+
onClick: () => j(r("/products/feature-detail-page", L.duplicateOf.id)),
|
|
153
|
+
children: L.duplicateOf.title
|
|
154
|
+
}) : /* @__PURE__ */ S("span", {
|
|
150
155
|
className: "text-muted-foreground",
|
|
151
156
|
children: "a request that has since been deleted"
|
|
152
157
|
}),
|
|
@@ -155,60 +160,60 @@ function k() {
|
|
|
155
160
|
]
|
|
156
161
|
})
|
|
157
162
|
}),
|
|
158
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ C("div", {
|
|
159
164
|
className: "grid grid-cols-2 md:grid-cols-4 gap-4",
|
|
160
165
|
children: [
|
|
161
|
-
/* @__PURE__ */
|
|
166
|
+
/* @__PURE__ */ S(T, { children: /* @__PURE__ */ C(E, {
|
|
162
167
|
className: "pt-4 text-center",
|
|
163
168
|
children: [
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ S(g, { className: "h-5 w-5 mx-auto text-primary" }),
|
|
170
|
+
/* @__PURE__ */ S("p", {
|
|
166
171
|
className: "text-2xl font-bold mt-1",
|
|
167
|
-
children:
|
|
172
|
+
children: L.priorityScore ?? 0
|
|
168
173
|
}),
|
|
169
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ S("p", {
|
|
170
175
|
className: "text-xs text-muted-foreground",
|
|
171
176
|
children: "Priority Score"
|
|
172
177
|
})
|
|
173
178
|
]
|
|
174
179
|
}) }),
|
|
175
|
-
/* @__PURE__ */
|
|
180
|
+
/* @__PURE__ */ S(T, { children: /* @__PURE__ */ C(E, {
|
|
176
181
|
className: "pt-4 text-center",
|
|
177
182
|
children: [
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
-
/* @__PURE__ */
|
|
183
|
+
/* @__PURE__ */ S(_, { className: "h-5 w-5 mx-auto text-green-500" }),
|
|
184
|
+
/* @__PURE__ */ S("p", {
|
|
180
185
|
className: "text-2xl font-bold mt-1",
|
|
181
|
-
children:
|
|
186
|
+
children: L.voteCount
|
|
182
187
|
}),
|
|
183
|
-
/* @__PURE__ */
|
|
188
|
+
/* @__PURE__ */ S("p", {
|
|
184
189
|
className: "text-xs text-muted-foreground",
|
|
185
190
|
children: "Votes"
|
|
186
191
|
})
|
|
187
192
|
]
|
|
188
193
|
}) }),
|
|
189
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ S(T, { children: /* @__PURE__ */ C(E, {
|
|
190
195
|
className: "pt-4 text-center",
|
|
191
196
|
children: [
|
|
192
|
-
/* @__PURE__ */
|
|
193
|
-
/* @__PURE__ */
|
|
197
|
+
/* @__PURE__ */ S(h, { className: "h-5 w-5 mx-auto text-yellow-500" }),
|
|
198
|
+
/* @__PURE__ */ S("p", {
|
|
194
199
|
className: "text-2xl font-bold mt-1",
|
|
195
|
-
children:
|
|
200
|
+
children: L.businessValue ?? 0
|
|
196
201
|
}),
|
|
197
|
-
/* @__PURE__ */
|
|
202
|
+
/* @__PURE__ */ S("p", {
|
|
198
203
|
className: "text-xs text-muted-foreground",
|
|
199
204
|
children: "Business Value"
|
|
200
205
|
})
|
|
201
206
|
]
|
|
202
207
|
}) }),
|
|
203
|
-
/* @__PURE__ */
|
|
208
|
+
/* @__PURE__ */ S(T, { children: /* @__PURE__ */ C(E, {
|
|
204
209
|
className: "pt-4 text-center",
|
|
205
210
|
children: [
|
|
206
|
-
/* @__PURE__ */
|
|
207
|
-
/* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ S(m, { className: "h-5 w-5 mx-auto text-blue-500" }),
|
|
212
|
+
/* @__PURE__ */ S("p", {
|
|
208
213
|
className: "text-2xl font-bold mt-1",
|
|
209
|
-
children:
|
|
214
|
+
children: z.length
|
|
210
215
|
}),
|
|
211
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ S("p", {
|
|
212
217
|
className: "text-xs text-muted-foreground",
|
|
213
218
|
children: "Competitors"
|
|
214
219
|
})
|
|
@@ -216,129 +221,130 @@ function k() {
|
|
|
216
221
|
}) })
|
|
217
222
|
]
|
|
218
223
|
}),
|
|
219
|
-
/* @__PURE__ */
|
|
224
|
+
/* @__PURE__ */ C("div", {
|
|
220
225
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
226
|
+
children: [/* @__PURE__ */ C("div", {
|
|
222
227
|
className: "lg:col-span-2 space-y-6",
|
|
223
228
|
children: [
|
|
224
|
-
/* @__PURE__ */
|
|
229
|
+
/* @__PURE__ */ C(T, { children: [/* @__PURE__ */ S(D, { children: /* @__PURE__ */ S(O, { children: "Description" }) }), /* @__PURE__ */ S(E, { children: /* @__PURE__ */ S("p", {
|
|
225
230
|
className: "text-sm",
|
|
226
|
-
children:
|
|
231
|
+
children: L.description ?? "No description provided."
|
|
227
232
|
}) })] }),
|
|
228
|
-
/* @__PURE__ */
|
|
233
|
+
/* @__PURE__ */ C(T, { children: [/* @__PURE__ */ S(D, { children: /* @__PURE__ */ C(O, { children: [
|
|
229
234
|
"Votes (",
|
|
230
|
-
|
|
235
|
+
R.length,
|
|
231
236
|
")"
|
|
232
|
-
] }) }), /* @__PURE__ */
|
|
237
|
+
] }) }), /* @__PURE__ */ C(E, {
|
|
233
238
|
className: "space-y-3",
|
|
234
|
-
children: [
|
|
239
|
+
children: [R.length === 0 && /* @__PURE__ */ S("p", {
|
|
235
240
|
className: "text-sm text-muted-foreground",
|
|
236
241
|
children: "No votes yet."
|
|
237
|
-
}),
|
|
242
|
+
}), R.map((e) => /* @__PURE__ */ C("div", {
|
|
238
243
|
className: "flex items-start justify-between border rounded-md p-3",
|
|
239
|
-
children: [/* @__PURE__ */
|
|
244
|
+
children: [/* @__PURE__ */ C("div", { children: [/* @__PURE__ */ C("p", {
|
|
240
245
|
className: "text-sm font-medium",
|
|
241
|
-
children: ["Voter: ", /* @__PURE__ */
|
|
242
|
-
}), e.comment && /* @__PURE__ */
|
|
246
|
+
children: ["Voter: ", /* @__PURE__ */ S(n, { id: e.voterId })]
|
|
247
|
+
}), e.comment && /* @__PURE__ */ S("p", {
|
|
243
248
|
className: "text-xs text-muted-foreground mt-1",
|
|
244
249
|
children: e.comment
|
|
245
|
-
})] }), /* @__PURE__ */
|
|
250
|
+
})] }), /* @__PURE__ */ C("div", {
|
|
246
251
|
className: "flex items-center gap-1",
|
|
247
|
-
children: [/* @__PURE__ */
|
|
252
|
+
children: [/* @__PURE__ */ S(_, { className: "h-3 w-3 text-green-500" }), /* @__PURE__ */ S("span", {
|
|
248
253
|
className: "text-sm font-bold",
|
|
249
254
|
children: e.weight
|
|
250
255
|
})]
|
|
251
256
|
})]
|
|
252
257
|
}, e.id))]
|
|
253
258
|
})] }),
|
|
254
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ C(T, { children: [/* @__PURE__ */ S(D, { children: /* @__PURE__ */ C(O, { children: [
|
|
255
260
|
"Competitors (",
|
|
256
|
-
|
|
261
|
+
z.length,
|
|
257
262
|
")"
|
|
258
|
-
] }) }), /* @__PURE__ */
|
|
259
|
-
featureRequestId:
|
|
260
|
-
competitors:
|
|
263
|
+
] }) }), /* @__PURE__ */ S(E, { children: /* @__PURE__ */ S(i, {
|
|
264
|
+
featureRequestId: L.id,
|
|
265
|
+
competitors: z
|
|
261
266
|
}) })] })
|
|
262
267
|
]
|
|
263
|
-
}), /* @__PURE__ */
|
|
268
|
+
}), /* @__PURE__ */ C("div", {
|
|
264
269
|
className: "space-y-6",
|
|
265
270
|
children: [
|
|
266
|
-
/* @__PURE__ */
|
|
267
|
-
featureId:
|
|
268
|
-
productId:
|
|
269
|
-
initiative:
|
|
271
|
+
/* @__PURE__ */ S(d, {
|
|
272
|
+
featureId: L.id,
|
|
273
|
+
productId: L.productId ?? null,
|
|
274
|
+
initiative: L.roadmapItem ?? null
|
|
270
275
|
}),
|
|
271
|
-
/* @__PURE__ */ S(
|
|
276
|
+
/* @__PURE__ */ S(l, { feature: L }),
|
|
277
|
+
/* @__PURE__ */ C(T, { children: [/* @__PURE__ */ S(D, { children: /* @__PURE__ */ S(O, { children: "Details" }) }), /* @__PURE__ */ C(E, {
|
|
272
278
|
className: "space-y-3 text-sm",
|
|
273
279
|
children: [
|
|
274
|
-
/* @__PURE__ */
|
|
280
|
+
/* @__PURE__ */ C("div", {
|
|
275
281
|
className: "flex justify-between",
|
|
276
|
-
children: [/* @__PURE__ */
|
|
282
|
+
children: [/* @__PURE__ */ S("span", {
|
|
277
283
|
className: "text-muted-foreground",
|
|
278
284
|
children: "Status"
|
|
279
|
-
}), /* @__PURE__ */
|
|
285
|
+
}), /* @__PURE__ */ S(w, {
|
|
280
286
|
variant: "secondary",
|
|
281
287
|
className: "capitalize",
|
|
282
|
-
children:
|
|
288
|
+
children: L.status.toLowerCase().replace("_", " ")
|
|
283
289
|
})]
|
|
284
290
|
}),
|
|
285
|
-
/* @__PURE__ */
|
|
291
|
+
/* @__PURE__ */ C("div", {
|
|
286
292
|
className: "flex justify-between",
|
|
287
|
-
children: [/* @__PURE__ */
|
|
293
|
+
children: [/* @__PURE__ */ S("span", {
|
|
288
294
|
className: "text-muted-foreground",
|
|
289
295
|
children: "Priority Score"
|
|
290
|
-
}), /* @__PURE__ */
|
|
296
|
+
}), /* @__PURE__ */ S(w, {
|
|
291
297
|
variant: "outline",
|
|
292
|
-
children:
|
|
298
|
+
children: L.priorityScore ?? "N/A"
|
|
293
299
|
})]
|
|
294
300
|
}),
|
|
295
|
-
/* @__PURE__ */
|
|
301
|
+
/* @__PURE__ */ C("div", {
|
|
296
302
|
className: "flex justify-between",
|
|
297
|
-
children: [/* @__PURE__ */
|
|
303
|
+
children: [/* @__PURE__ */ S("span", {
|
|
298
304
|
className: "text-muted-foreground",
|
|
299
305
|
children: "Effort"
|
|
300
|
-
}), /* @__PURE__ */
|
|
306
|
+
}), /* @__PURE__ */ S(w, {
|
|
301
307
|
variant: "outline",
|
|
302
308
|
className: "capitalize",
|
|
303
|
-
children:
|
|
309
|
+
children: L.effortEstimate ?? "N/A"
|
|
304
310
|
})]
|
|
305
311
|
}),
|
|
306
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ C("div", {
|
|
307
313
|
className: "flex justify-between",
|
|
308
|
-
children: [/* @__PURE__ */
|
|
314
|
+
children: [/* @__PURE__ */ S("span", {
|
|
309
315
|
className: "text-muted-foreground",
|
|
310
316
|
children: "Business Value"
|
|
311
|
-
}), /* @__PURE__ */
|
|
317
|
+
}), /* @__PURE__ */ S("span", {
|
|
312
318
|
className: "font-medium",
|
|
313
|
-
children:
|
|
319
|
+
children: L.businessValue ?? "N/A"
|
|
314
320
|
})]
|
|
315
321
|
}),
|
|
316
|
-
/* @__PURE__ */
|
|
322
|
+
/* @__PURE__ */ C("div", {
|
|
317
323
|
className: "flex justify-between",
|
|
318
|
-
children: [/* @__PURE__ */
|
|
324
|
+
children: [/* @__PURE__ */ S("span", {
|
|
319
325
|
className: "text-muted-foreground",
|
|
320
326
|
children: "Submitted By"
|
|
321
|
-
}), /* @__PURE__ */
|
|
327
|
+
}), /* @__PURE__ */ S(n, { id: L.submittedBy })]
|
|
322
328
|
}),
|
|
323
|
-
|
|
329
|
+
L.triagedAt && /* @__PURE__ */ C("div", {
|
|
324
330
|
className: "flex justify-between",
|
|
325
|
-
children: [/* @__PURE__ */
|
|
331
|
+
children: [/* @__PURE__ */ S("span", {
|
|
326
332
|
className: "text-muted-foreground",
|
|
327
333
|
children: "Decided"
|
|
328
|
-
}), /* @__PURE__ */
|
|
334
|
+
}), /* @__PURE__ */ C("span", { children: [new Date(L.triagedAt).toLocaleDateString(), L.triagedBy && /* @__PURE__ */ C(x, { children: [" by ", /* @__PURE__ */ S(n, { id: L.triagedBy })] })] })]
|
|
329
335
|
}),
|
|
330
|
-
/* @__PURE__ */
|
|
336
|
+
/* @__PURE__ */ C("div", {
|
|
331
337
|
className: "flex justify-between",
|
|
332
|
-
children: [/* @__PURE__ */
|
|
338
|
+
children: [/* @__PURE__ */ S("span", {
|
|
333
339
|
className: "text-muted-foreground",
|
|
334
340
|
children: "Updated"
|
|
335
|
-
}), /* @__PURE__ */
|
|
341
|
+
}), /* @__PURE__ */ S("span", { children: new Date(L.updatedAt).toLocaleDateString() })]
|
|
336
342
|
})
|
|
337
343
|
]
|
|
338
344
|
})] }),
|
|
339
|
-
|
|
345
|
+
L.tags?.length > 0 && /* @__PURE__ */ C(T, { children: [/* @__PURE__ */ S(D, { children: /* @__PURE__ */ S(O, { children: "Tags" }) }), /* @__PURE__ */ S(E, {
|
|
340
346
|
className: "flex flex-wrap gap-1",
|
|
341
|
-
children:
|
|
347
|
+
children: L.tags.map((e) => /* @__PURE__ */ S(w, {
|
|
342
348
|
variant: "outline",
|
|
343
349
|
className: "text-xs",
|
|
344
350
|
children: e
|
|
@@ -351,6 +357,6 @@ function k() {
|
|
|
351
357
|
});
|
|
352
358
|
}
|
|
353
359
|
//#endregion
|
|
354
|
-
export {
|
|
360
|
+
export { A as ProductsFeatureDetailPagePage };
|
|
355
361
|
|
|
356
362
|
//# sourceMappingURL=ProductsFeatureDetailPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsFeatureDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsFeatureDetailPagePage.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, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Star, ThumbsUp, MessageSquare, Target, Loader2 } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { FeatureTriageActions, isOpenRequest, isSnoozed } from '../controls/FeatureTriage';\nimport { useParams } from 'react-router';\nimport { PersonName } from '../people/People';\nimport { FeatureHeaderActions, FeatureVoteButton } from '../controls/FeatureControls';\nimport { CompetitorLinkCard } from '../controls/CompetitorControls';\nimport { FeatureInitiativeCard } from '../roadmaps/FeatureInitiativeCard';\n\nconst GET_FEATURE_REQUEST = gql`\n query GetFeatureRequest($id: ID!) {\n planmagnetFeatureRequest(id: $id) {\n id\n workspaceId\n projectId\n title\n description\n status\n businessValue\n effortEstimate\n priorityScore\n voteCount\n submittedBy\n workItemId\n tags\n snoozedUntil\n declineReason\n duplicateOfId\n duplicateOf {\n id\n title\n }\n triagedAt\n triagedBy\n createdAt\n updatedAt\n productId\n roadmapItem {\n id\n title\n roadmap {\n id\n name\n }\n }\n votes {\n id\n voterId\n weight\n comment\n createdAt\n }\n competitors {\n id\n name\n description\n website\n }\n }\n }\n`;\n\ninterface FeatureVoteNode {\n id: string;\n voterId: string;\n weight: number;\n comment: string | null;\n createdAt: string;\n}\n\ninterface CompetitorNode {\n id: string;\n name: string;\n description: string | null;\n website: string | null;\n}\n\nexport function ProductsFeatureDetailPagePage() {\n const { workspaceId, currentUser } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n // Snooze state is read against the moment the page opened (Date.now() may not run during render).\n const [now] = useState(() => Date.now());\n const params = useParams<{ id: string }>();\n const featureId = params.id ?? '';\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_FEATURE_REQUEST, {\n variables: { id: featureId },\n skip: !featureId,\n });\n\n // Only before the first load: a refetch must not blank the page (it\n\n // unmounts every component on it and loses their state).\n\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load feature: {error.message}</div>;\n }\n\n const feature = data?.planmagnetFeatureRequest;\n if (!feature) return <div className=\"p-6 text-muted-foreground\">Feature not found.</div>;\n\n const votes: FeatureVoteNode[] = feature.votes ?? [];\n const competitors: CompetitorNode[] = feature.competitors ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{feature.title}</h1>\n <p className=\"text-sm text-muted-foreground\">\n Submitted by: <PersonName id={feature.submittedBy} /> · Effort:{' '}\n {feature.effortEstimate ?? 'N/A'}\n </p>\n </div>\n {/* Vote, status, Edit and Delete (BOFF-7951): the request was read-only. */}\n <div className=\"flex flex-col items-end gap-2\">\n <FeatureVoteButton\n featureId={feature.id}\n voted={votes.some((v) => v.voterId === currentUser?.id)}\n />\n <FeatureHeaderActions feature={feature} />\n </div>\n </div>\n\n {/* Triage (P1.3): an undecided request is accepted, declined, snoozed or merged from here. */}\n {isOpenRequest(feature.status) && (\n <Card data-testid=\"triage-card\">\n <CardHeader>\n <CardTitle>Triage</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">\n {isSnoozed(feature.snoozedUntil, now)\n ? `Snoozed until ${new Date(feature.snoozedUntil).toLocaleString()} — it returns to the triage queue then.`\n : feature.status === 'SUBMITTED'\n ? 'Waiting for a decision.'\n : 'Under review: accept it as planned, decline it, or merge it into its original.'}\n </p>\n <FeatureTriageActions feature={feature} now={now} />\n </CardContent>\n </Card>\n )}\n {feature.status === 'DECLINED' && feature.declineReason && (\n <Card data-testid=\"decline-reason\">\n <CardContent className=\"pt-4 text-sm\">\n <span className=\"font-medium\">Declined: </span>\n {feature.declineReason}\n </CardContent>\n </Card>\n )}\n {feature.status === 'DUPLICATE' && feature.duplicateOfId && (\n <Card data-testid=\"duplicate-of\">\n <CardContent className=\"pt-4 text-sm\">\n <span className=\"font-medium\">Duplicate of </span>\n {feature.duplicateOf ? (\n <button\n type=\"button\"\n className=\"text-primary underline-offset-2 hover:underline\"\n onClick={() =>\n navigate(detailPath('/products/feature-detail-page', feature.duplicateOf.id))\n }\n >\n {feature.duplicateOf.title}\n </button>\n ) : (\n <span className=\"text-muted-foreground\">a request that has since been deleted</span>\n )}{' '}\n — its votes were moved there.\n </CardContent>\n </Card>\n )}\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <Target className=\"h-5 w-5 mx-auto text-primary\" />\n <p className=\"text-2xl font-bold mt-1\">{feature.priorityScore ?? 0}</p>\n <p className=\"text-xs text-muted-foreground\">Priority Score</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <ThumbsUp className=\"h-5 w-5 mx-auto text-green-500\" />\n <p className=\"text-2xl font-bold mt-1\">{feature.voteCount}</p>\n <p className=\"text-xs text-muted-foreground\">Votes</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <Star className=\"h-5 w-5 mx-auto text-yellow-500\" />\n <p className=\"text-2xl font-bold mt-1\">{feature.businessValue ?? 0}</p>\n <p className=\"text-xs text-muted-foreground\">Business Value</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <MessageSquare className=\"h-5 w-5 mx-auto text-blue-500\" />\n <p className=\"text-2xl font-bold mt-1\">{competitors.length}</p>\n <p className=\"text-xs text-muted-foreground\">Competitors</p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Description</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm\">{feature.description ?? 'No description provided.'}</p>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Votes ({votes.length})</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {votes.length === 0 && <p className=\"text-sm text-muted-foreground\">No votes yet.</p>}\n {votes.map((vote) => (\n <div\n key={vote.id}\n className=\"flex items-start justify-between border rounded-md p-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">\n Voter: <PersonName id={vote.voterId} />\n </p>\n {vote.comment && (\n <p className=\"text-xs text-muted-foreground mt-1\">{vote.comment}</p>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <ThumbsUp className=\"h-3 w-3 text-green-500\" />\n <span className=\"text-sm font-bold\">{vote.weight}</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n {/* Competitor tracking (BOFF-8047): add, remove and browse to the competitors linked here. */}\n <Card>\n <CardHeader>\n <CardTitle>Competitors ({competitors.length})</CardTitle>\n </CardHeader>\n <CardContent>\n <CompetitorLinkCard featureRequestId={feature.id} competitors={competitors} />\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-6\">\n {/* PRM-24: the roadmap initiative that addresses this request. */}\n <FeatureInitiativeCard\n featureId={feature.id}\n productId={feature.productId ?? null}\n initiative={feature.roadmapItem ?? null}\n />\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Status</span>\n <Badge variant=\"secondary\" className=\"capitalize\">\n {feature.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Priority Score</span>\n <Badge variant=\"outline\">{feature.priorityScore ?? 'N/A'}</Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Effort</span>\n <Badge variant=\"outline\" className=\"capitalize\">\n {feature.effortEstimate ?? 'N/A'}\n </Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Business Value</span>\n <span className=\"font-medium\">{feature.businessValue ?? 'N/A'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Submitted By</span>\n <PersonName id={feature.submittedBy} />\n </div>\n {feature.triagedAt && (\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Decided</span>\n <span>\n {new Date(feature.triagedAt).toLocaleDateString()}\n {feature.triagedBy && (\n <>\n {' by '}\n <PersonName id={feature.triagedBy} />\n </>\n )}\n </span>\n </div>\n )}\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Updated</span>\n <span>{new Date(feature.updatedAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </Card>\n\n {feature.tags?.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle>Tags</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1\">\n {feature.tags.map((tag: string) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </CardContent>\n </Card>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProductsFeatureDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsFeatureDetailPagePage.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, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Star, ThumbsUp, MessageSquare, Target, Loader2 } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { FeatureTriageActions, isOpenRequest, isSnoozed } from '../controls/FeatureTriage';\nimport { useParams } from 'react-router';\nimport { PersonName } from '../people/People';\nimport {\n FeatureHeaderActions,\n FeaturePrioritizationCard,\n FeatureVoteButton,\n} from '../controls/FeatureControls';\nimport { CompetitorLinkCard } from '../controls/CompetitorControls';\nimport { FeatureInitiativeCard } from '../roadmaps/FeatureInitiativeCard';\n\nconst GET_FEATURE_REQUEST = gql`\n query GetFeatureRequest($id: ID!) {\n planmagnetFeatureRequest(id: $id) {\n id\n workspaceId\n projectId\n title\n description\n status\n businessValue\n effortEstimate\n priorityScore\n voteCount\n submittedBy\n workItemId\n tags\n snoozedUntil\n moscow\n kano\n valueScore\n effortScore\n valueEffortQuadrant\n declineReason\n duplicateOfId\n duplicateOf {\n id\n title\n }\n triagedAt\n triagedBy\n createdAt\n updatedAt\n productId\n roadmapItem {\n id\n title\n roadmap {\n id\n name\n }\n }\n votes {\n id\n voterId\n weight\n comment\n createdAt\n }\n competitors {\n id\n name\n description\n website\n }\n }\n }\n`;\n\ninterface FeatureVoteNode {\n id: string;\n voterId: string;\n weight: number;\n comment: string | null;\n createdAt: string;\n}\n\ninterface CompetitorNode {\n id: string;\n name: string;\n description: string | null;\n website: string | null;\n}\n\nexport function ProductsFeatureDetailPagePage() {\n const { workspaceId, currentUser } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n // Snooze state is read against the moment the page opened (Date.now() may not run during render).\n const [now] = useState(() => Date.now());\n const params = useParams<{ id: string }>();\n const featureId = params.id ?? '';\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_FEATURE_REQUEST, {\n variables: { id: featureId },\n skip: !featureId,\n });\n\n // Only before the first load: a refetch must not blank the page (it\n\n // unmounts every component on it and loses their state).\n\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load feature: {error.message}</div>;\n }\n\n const feature = data?.planmagnetFeatureRequest;\n if (!feature) return <div className=\"p-6 text-muted-foreground\">Feature not found.</div>;\n\n const votes: FeatureVoteNode[] = feature.votes ?? [];\n const competitors: CompetitorNode[] = feature.competitors ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{feature.title}</h1>\n <p className=\"text-sm text-muted-foreground\">\n Submitted by: <PersonName id={feature.submittedBy} /> · Effort:{' '}\n {feature.effortEstimate ?? 'N/A'}\n </p>\n </div>\n {/* Vote, status, Edit and Delete (BOFF-7951): the request was read-only. */}\n <div className=\"flex flex-col items-end gap-2\">\n <FeatureVoteButton\n featureId={feature.id}\n voted={votes.some((v) => v.voterId === currentUser?.id)}\n />\n <FeatureHeaderActions feature={feature} />\n </div>\n </div>\n\n {/* Triage (P1.3): an undecided request is accepted, declined, snoozed or merged from here. */}\n {isOpenRequest(feature.status) && (\n <Card data-testid=\"triage-card\">\n <CardHeader>\n <CardTitle>Triage</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">\n {isSnoozed(feature.snoozedUntil, now)\n ? `Snoozed until ${new Date(feature.snoozedUntil).toLocaleString()} — it returns to the triage queue then.`\n : feature.status === 'SUBMITTED'\n ? 'Waiting for a decision.'\n : 'Under review: accept it as planned, decline it, or merge it into its original.'}\n </p>\n <FeatureTriageActions feature={feature} now={now} />\n </CardContent>\n </Card>\n )}\n {feature.status === 'DECLINED' && feature.declineReason && (\n <Card data-testid=\"decline-reason\">\n <CardContent className=\"pt-4 text-sm\">\n <span className=\"font-medium\">Declined: </span>\n {feature.declineReason}\n </CardContent>\n </Card>\n )}\n {feature.status === 'DUPLICATE' && feature.duplicateOfId && (\n <Card data-testid=\"duplicate-of\">\n <CardContent className=\"pt-4 text-sm\">\n <span className=\"font-medium\">Duplicate of </span>\n {feature.duplicateOf ? (\n <button\n type=\"button\"\n className=\"text-primary underline-offset-2 hover:underline\"\n onClick={() =>\n navigate(detailPath('/products/feature-detail-page', feature.duplicateOf.id))\n }\n >\n {feature.duplicateOf.title}\n </button>\n ) : (\n <span className=\"text-muted-foreground\">a request that has since been deleted</span>\n )}{' '}\n — its votes were moved there.\n </CardContent>\n </Card>\n )}\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <Target className=\"h-5 w-5 mx-auto text-primary\" />\n <p className=\"text-2xl font-bold mt-1\">{feature.priorityScore ?? 0}</p>\n <p className=\"text-xs text-muted-foreground\">Priority Score</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <ThumbsUp className=\"h-5 w-5 mx-auto text-green-500\" />\n <p className=\"text-2xl font-bold mt-1\">{feature.voteCount}</p>\n <p className=\"text-xs text-muted-foreground\">Votes</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <Star className=\"h-5 w-5 mx-auto text-yellow-500\" />\n <p className=\"text-2xl font-bold mt-1\">{feature.businessValue ?? 0}</p>\n <p className=\"text-xs text-muted-foreground\">Business Value</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4 text-center\">\n <MessageSquare className=\"h-5 w-5 mx-auto text-blue-500\" />\n <p className=\"text-2xl font-bold mt-1\">{competitors.length}</p>\n <p className=\"text-xs text-muted-foreground\">Competitors</p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Description</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm\">{feature.description ?? 'No description provided.'}</p>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Votes ({votes.length})</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {votes.length === 0 && <p className=\"text-sm text-muted-foreground\">No votes yet.</p>}\n {votes.map((vote) => (\n <div\n key={vote.id}\n className=\"flex items-start justify-between border rounded-md p-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">\n Voter: <PersonName id={vote.voterId} />\n </p>\n {vote.comment && (\n <p className=\"text-xs text-muted-foreground mt-1\">{vote.comment}</p>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <ThumbsUp className=\"h-3 w-3 text-green-500\" />\n <span className=\"text-sm font-bold\">{vote.weight}</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n {/* Competitor tracking (BOFF-8047): add, remove and browse to the competitors linked here. */}\n <Card>\n <CardHeader>\n <CardTitle>Competitors ({competitors.length})</CardTitle>\n </CardHeader>\n <CardContent>\n <CompetitorLinkCard featureRequestId={feature.id} competitors={competitors} />\n </CardContent>\n </Card>\n </div>\n\n <div className=\"space-y-6\">\n {/* PRM-24: the roadmap initiative that addresses this request. */}\n <FeatureInitiativeCard\n featureId={feature.id}\n productId={feature.productId ?? null}\n initiative={feature.roadmapItem ?? null}\n />\n {/* PRM-27: MoSCoW/Kano/Value-Effort scoring, edited in place with the computed quadrant read back\n from the save's own response. */}\n <FeaturePrioritizationCard feature={feature} />\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Status</span>\n <Badge variant=\"secondary\" className=\"capitalize\">\n {feature.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Priority Score</span>\n <Badge variant=\"outline\">{feature.priorityScore ?? 'N/A'}</Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Effort</span>\n <Badge variant=\"outline\" className=\"capitalize\">\n {feature.effortEstimate ?? 'N/A'}\n </Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Business Value</span>\n <span className=\"font-medium\">{feature.businessValue ?? 'N/A'}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Submitted By</span>\n <PersonName id={feature.submittedBy} />\n </div>\n {feature.triagedAt && (\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Decided</span>\n <span>\n {new Date(feature.triagedAt).toLocaleDateString()}\n {feature.triagedBy && (\n <>\n {' by '}\n <PersonName id={feature.triagedBy} />\n </>\n )}\n </span>\n </div>\n )}\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">Updated</span>\n <span>{new Date(feature.updatedAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </Card>\n\n {feature.tags?.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle>Tags</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-wrap gap-1\">\n {feature.tags.map((tag: string) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </CardContent>\n </Card>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsFeaturesPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsFeaturesPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductsFeaturesPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsFeaturesPagePage.tsx"],"names":[],"mappings":"AA6FA,wBAAgB,wBAAwB,4CAyTvC"}
|