@burdenoff/microfe-planmagnet 2026.1001.6 → 2026.1001.8
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/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +10 -6
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/automation/automationRuleTypes.d.ts +31 -19
- package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -1
- package/dist/planmagnet/automation/automationRuleTypes.js +4 -8
- package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts +18 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.js +259 -202
- package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
- package/dist/planmagnet/controls/FeedbackControls.d.ts +70 -0
- package/dist/planmagnet/controls/FeedbackControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/FeedbackControls.js +153 -0
- package/dist/planmagnet/controls/FeedbackControls.js.map +1 -0
- package/dist/planmagnet/controls/SyncControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/SyncControls.js +1 -0
- package/dist/planmagnet/controls/SyncControls.js.map +1 -1
- package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts +47 -0
- package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/WebhookSubscriptionControls.js +542 -0
- package/dist/planmagnet/controls/WebhookSubscriptionControls.js.map +1 -0
- package/dist/planmagnet/dashboards/DashboardUI.js +7 -7
- package/dist/planmagnet/dashboards/cards/RiskSeverityCard.js +4 -4
- package/dist/planmagnet/forecast/DeliveryForecastCard.js +8 -8
- package/dist/planmagnet/forecast/ProjectOutlookCard.js +10 -10
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +9 -9
- package/dist/planmagnet/forecast/ResourceForecastCard.js +6 -6
- package/dist/planmagnet/hooks/useLiveRefresh.d.ts +33 -2
- package/dist/planmagnet/hooks/useLiveRefresh.d.ts.map +1 -1
- package/dist/planmagnet/hooks/useLiveRefresh.js +71 -42
- package/dist/planmagnet/hooks/useLiveRefresh.js.map +1 -1
- package/dist/planmagnet/integrations/syncTypes.d.ts +2 -1
- package/dist/planmagnet/integrations/syncTypes.d.ts.map +1 -1
- package/dist/planmagnet/integrations/syncTypes.js +19 -9
- package/dist/planmagnet/integrations/syncTypes.js.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +8 -8
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js +23 -23
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +340 -248
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js +172 -167
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js +92 -83
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js +175 -0
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +151 -126
- 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 +136 -129
- 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 +149 -119
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.js +13 -13
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js +153 -117
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +173 -138
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +9 -9
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +8 -8
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +12 -12
- package/dist/planmagnet/pages/ReportsReportsPagePage.js +23 -23
- package/dist/planmagnet/pages/TasksMyDashboardPagePage.js +18 -18
- package/dist/planmagnet/pages/TasksMyWorkPagePage.js +10 -10
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +5 -5
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +8 -8
- package/dist/planmagnet/pages/analytics/DeliveryKpisCard.js +6 -6
- package/dist/planmagnet/pages/analytics/MetricsCard.js +6 -6
- package/dist/planmagnet/pages/analytics/QualityMetricsCard.js +6 -6
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +8 -8
- package/dist/planmagnet/pages/analytics/StatusFlowCard.js +7 -7
- package/dist/planmagnet/pages/analytics/ThroughputCard.js +7 -7
- package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js +7 -7
- package/dist/planmagnet/people/People.d.ts +14 -0
- package/dist/planmagnet/people/People.d.ts.map +1 -1
- package/dist/planmagnet/people/People.js +36 -22
- package/dist/planmagnet/people/People.js.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapNowNextLater.d.ts.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js +171 -153
- package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js.map +1 -1
- package/dist/planmagnet/webhooks/webhookTypes.d.ts +54 -0
- package/dist/planmagnet/webhooks/webhookTypes.d.ts.map +1 -0
- package/dist/planmagnet/webhooks/webhookTypes.js +17 -0
- package/dist/planmagnet/webhooks/webhookTypes.js.map +1 -0
- package/package.json +1 -1
|
@@ -3,17 +3,18 @@ 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 {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
6
|
+
import { CategoryBadge as c, RatingDisplay as l } from "../controls/FeedbackControls.js";
|
|
7
|
+
import { FeatureHeaderActions as u, FeaturePrioritizationCard as d, FeatureVoteButton as f } from "../controls/FeatureControls.js";
|
|
8
|
+
import { FeatureInitiativeCard as p } from "../roadmaps/FeatureInitiativeCard.js";
|
|
9
|
+
import { useState as m } from "react";
|
|
10
|
+
import { Loader2 as h, MessageSquare as g, Star as _, Target as v, ThumbsUp as y } from "lucide-react";
|
|
11
|
+
import { useParams as b } from "react-router";
|
|
12
|
+
import { gql as x } from "@apollo/client";
|
|
13
|
+
import { useQuery as S } from "@apollo/client/react";
|
|
14
|
+
import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
15
|
+
import { Badge as E, Card as D, CardContent as O, CardHeader as k, CardTitle as A } from "@burdenoff/fe-libs/ui";
|
|
15
16
|
//#region src/planmagnet/pages/ProductsFeatureDetailPagePage.tsx
|
|
16
|
-
var
|
|
17
|
+
var j = x`
|
|
17
18
|
query GetFeatureRequest($id: ID!) {
|
|
18
19
|
planmagnetFeatureRequest(id: $id) {
|
|
19
20
|
id
|
|
@@ -30,11 +31,18 @@ var k = y`
|
|
|
30
31
|
workItemId
|
|
31
32
|
tags
|
|
32
33
|
snoozedUntil
|
|
34
|
+
rating
|
|
35
|
+
category
|
|
36
|
+
isAnonymous
|
|
33
37
|
moscow
|
|
34
38
|
kano
|
|
35
39
|
valueScore
|
|
36
40
|
effortScore
|
|
37
41
|
valueEffortQuadrant
|
|
42
|
+
reach
|
|
43
|
+
impact
|
|
44
|
+
confidence
|
|
45
|
+
riceScore
|
|
38
46
|
declineReason
|
|
39
47
|
duplicateOfId
|
|
40
48
|
duplicateOf {
|
|
@@ -70,88 +78,88 @@ var k = y`
|
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
`;
|
|
73
|
-
function
|
|
74
|
-
let { workspaceId:
|
|
75
|
-
variables: { id:
|
|
76
|
-
skip: !
|
|
81
|
+
function M() {
|
|
82
|
+
let { workspaceId: x, currentUser: M } = e(), N = t(), [P] = m(() => Date.now()), F = b().id ?? "", { data: I, loading: L, error: R } = S(j, {
|
|
83
|
+
variables: { id: F },
|
|
84
|
+
skip: !F
|
|
77
85
|
});
|
|
78
|
-
if (
|
|
86
|
+
if (L && !I) return /* @__PURE__ */ w("div", {
|
|
79
87
|
className: "flex items-center justify-center p-12",
|
|
80
|
-
children: /* @__PURE__ */
|
|
88
|
+
children: /* @__PURE__ */ w(h, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
81
89
|
});
|
|
82
|
-
if (
|
|
90
|
+
if (R) return /* @__PURE__ */ T("div", {
|
|
83
91
|
className: "p-6 text-destructive",
|
|
84
|
-
children: ["Failed to load feature: ",
|
|
92
|
+
children: ["Failed to load feature: ", R.message]
|
|
85
93
|
});
|
|
86
|
-
let
|
|
87
|
-
if (!
|
|
94
|
+
let z = I?.planmagnetFeatureRequest;
|
|
95
|
+
if (!z) return /* @__PURE__ */ w("div", {
|
|
88
96
|
className: "p-6 text-muted-foreground",
|
|
89
97
|
children: "Feature not found."
|
|
90
98
|
});
|
|
91
|
-
let
|
|
92
|
-
return /* @__PURE__ */
|
|
99
|
+
let B = z.votes ?? [], V = z.competitors ?? [];
|
|
100
|
+
return /* @__PURE__ */ T("div", {
|
|
93
101
|
className: "space-y-6 p-6",
|
|
94
102
|
children: [
|
|
95
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ T("div", {
|
|
96
104
|
className: "flex items-center justify-between",
|
|
97
|
-
children: [/* @__PURE__ */
|
|
105
|
+
children: [/* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("h1", {
|
|
98
106
|
className: "text-2xl font-semibold",
|
|
99
|
-
children:
|
|
100
|
-
}), /* @__PURE__ */
|
|
107
|
+
children: z.title
|
|
108
|
+
}), /* @__PURE__ */ T("p", {
|
|
101
109
|
className: "text-sm text-muted-foreground",
|
|
102
110
|
children: [
|
|
103
111
|
"Submitted by: ",
|
|
104
|
-
/* @__PURE__ */
|
|
112
|
+
/* @__PURE__ */ w(n, { id: z.submittedBy }),
|
|
105
113
|
" · Effort:",
|
|
106
114
|
" ",
|
|
107
|
-
|
|
115
|
+
z.effortEstimate ?? "N/A"
|
|
108
116
|
]
|
|
109
|
-
})] }), /* @__PURE__ */
|
|
117
|
+
})] }), /* @__PURE__ */ T("div", {
|
|
110
118
|
className: "flex flex-col items-end gap-2",
|
|
111
|
-
children: [/* @__PURE__ */
|
|
112
|
-
featureId:
|
|
113
|
-
voted:
|
|
114
|
-
}), /* @__PURE__ */
|
|
119
|
+
children: [/* @__PURE__ */ w(f, {
|
|
120
|
+
featureId: z.id,
|
|
121
|
+
voted: B.some((e) => e.voterId === M?.id)
|
|
122
|
+
}, z.id), /* @__PURE__ */ w(u, { feature: z })]
|
|
115
123
|
})]
|
|
116
124
|
}),
|
|
117
|
-
o(
|
|
125
|
+
o(z.status) && /* @__PURE__ */ T(D, {
|
|
118
126
|
"data-testid": "triage-card",
|
|
119
|
-
children: [/* @__PURE__ */
|
|
127
|
+
children: [/* @__PURE__ */ w(k, { children: /* @__PURE__ */ w(A, { children: "Triage" }) }), /* @__PURE__ */ T(O, {
|
|
120
128
|
className: "space-y-2",
|
|
121
|
-
children: [/* @__PURE__ */
|
|
129
|
+
children: [/* @__PURE__ */ w("p", {
|
|
122
130
|
className: "text-sm text-muted-foreground",
|
|
123
|
-
children: s(
|
|
124
|
-
}), /* @__PURE__ */
|
|
125
|
-
feature:
|
|
126
|
-
now:
|
|
131
|
+
children: s(z.snoozedUntil, P) ? `Snoozed until ${new Date(z.snoozedUntil).toLocaleString()} — it returns to the triage queue then.` : z.status === "SUBMITTED" ? "Waiting for a decision." : "Under review: accept it as planned, decline it, or merge it into its original."
|
|
132
|
+
}), /* @__PURE__ */ w(a, {
|
|
133
|
+
feature: z,
|
|
134
|
+
now: P
|
|
127
135
|
})]
|
|
128
136
|
})]
|
|
129
137
|
}),
|
|
130
|
-
|
|
138
|
+
z.status === "DECLINED" && z.declineReason && /* @__PURE__ */ w(D, {
|
|
131
139
|
"data-testid": "decline-reason",
|
|
132
|
-
children: /* @__PURE__ */
|
|
140
|
+
children: /* @__PURE__ */ T(O, {
|
|
133
141
|
className: "pt-4 text-sm",
|
|
134
|
-
children: [/* @__PURE__ */
|
|
142
|
+
children: [/* @__PURE__ */ w("span", {
|
|
135
143
|
className: "font-medium",
|
|
136
144
|
children: "Declined: "
|
|
137
|
-
}),
|
|
145
|
+
}), z.declineReason]
|
|
138
146
|
})
|
|
139
147
|
}),
|
|
140
|
-
|
|
148
|
+
z.status === "DUPLICATE" && z.duplicateOfId && /* @__PURE__ */ w(D, {
|
|
141
149
|
"data-testid": "duplicate-of",
|
|
142
|
-
children: /* @__PURE__ */
|
|
150
|
+
children: /* @__PURE__ */ T(O, {
|
|
143
151
|
className: "pt-4 text-sm",
|
|
144
152
|
children: [
|
|
145
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ w("span", {
|
|
146
154
|
className: "font-medium",
|
|
147
155
|
children: "Duplicate of "
|
|
148
156
|
}),
|
|
149
|
-
|
|
157
|
+
z.duplicateOf ? /* @__PURE__ */ w("button", {
|
|
150
158
|
type: "button",
|
|
151
159
|
className: "text-primary underline-offset-2 hover:underline",
|
|
152
|
-
onClick: () =>
|
|
153
|
-
children:
|
|
154
|
-
}) : /* @__PURE__ */
|
|
160
|
+
onClick: () => N(r("/products/feature-detail-page", z.duplicateOf.id)),
|
|
161
|
+
children: z.duplicateOf.title
|
|
162
|
+
}) : /* @__PURE__ */ w("span", {
|
|
155
163
|
className: "text-muted-foreground",
|
|
156
164
|
children: "a request that has since been deleted"
|
|
157
165
|
}),
|
|
@@ -160,60 +168,60 @@ function A() {
|
|
|
160
168
|
]
|
|
161
169
|
})
|
|
162
170
|
}),
|
|
163
|
-
/* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ T("div", {
|
|
164
172
|
className: "grid grid-cols-2 md:grid-cols-4 gap-4",
|
|
165
173
|
children: [
|
|
166
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ w(D, { children: /* @__PURE__ */ T(O, {
|
|
167
175
|
className: "pt-4 text-center",
|
|
168
176
|
children: [
|
|
169
|
-
/* @__PURE__ */
|
|
170
|
-
/* @__PURE__ */
|
|
177
|
+
/* @__PURE__ */ w(v, { className: "h-5 w-5 mx-auto text-primary" }),
|
|
178
|
+
/* @__PURE__ */ w("p", {
|
|
171
179
|
className: "text-2xl font-bold mt-1",
|
|
172
|
-
children:
|
|
180
|
+
children: z.priorityScore ?? 0
|
|
173
181
|
}),
|
|
174
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ w("p", {
|
|
175
183
|
className: "text-xs text-muted-foreground",
|
|
176
184
|
children: "Priority Score"
|
|
177
185
|
})
|
|
178
186
|
]
|
|
179
187
|
}) }),
|
|
180
|
-
/* @__PURE__ */
|
|
188
|
+
/* @__PURE__ */ w(D, { children: /* @__PURE__ */ T(O, {
|
|
181
189
|
className: "pt-4 text-center",
|
|
182
190
|
children: [
|
|
183
|
-
/* @__PURE__ */
|
|
184
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ w(y, { className: "h-5 w-5 mx-auto text-green-500" }),
|
|
192
|
+
/* @__PURE__ */ w("p", {
|
|
185
193
|
className: "text-2xl font-bold mt-1",
|
|
186
|
-
children:
|
|
194
|
+
children: z.voteCount
|
|
187
195
|
}),
|
|
188
|
-
/* @__PURE__ */
|
|
196
|
+
/* @__PURE__ */ w("p", {
|
|
189
197
|
className: "text-xs text-muted-foreground",
|
|
190
198
|
children: "Votes"
|
|
191
199
|
})
|
|
192
200
|
]
|
|
193
201
|
}) }),
|
|
194
|
-
/* @__PURE__ */
|
|
202
|
+
/* @__PURE__ */ w(D, { children: /* @__PURE__ */ T(O, {
|
|
195
203
|
className: "pt-4 text-center",
|
|
196
204
|
children: [
|
|
197
|
-
/* @__PURE__ */
|
|
198
|
-
/* @__PURE__ */
|
|
205
|
+
/* @__PURE__ */ w(_, { className: "h-5 w-5 mx-auto text-yellow-500" }),
|
|
206
|
+
/* @__PURE__ */ w("p", {
|
|
199
207
|
className: "text-2xl font-bold mt-1",
|
|
200
|
-
children:
|
|
208
|
+
children: z.businessValue ?? 0
|
|
201
209
|
}),
|
|
202
|
-
/* @__PURE__ */
|
|
210
|
+
/* @__PURE__ */ w("p", {
|
|
203
211
|
className: "text-xs text-muted-foreground",
|
|
204
212
|
children: "Business Value"
|
|
205
213
|
})
|
|
206
214
|
]
|
|
207
215
|
}) }),
|
|
208
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ w(D, { children: /* @__PURE__ */ T(O, {
|
|
209
217
|
className: "pt-4 text-center",
|
|
210
218
|
children: [
|
|
211
|
-
/* @__PURE__ */
|
|
212
|
-
/* @__PURE__ */
|
|
219
|
+
/* @__PURE__ */ w(g, { className: "h-5 w-5 mx-auto text-blue-500" }),
|
|
220
|
+
/* @__PURE__ */ w("p", {
|
|
213
221
|
className: "text-2xl font-bold mt-1",
|
|
214
|
-
children:
|
|
222
|
+
children: V.length
|
|
215
223
|
}),
|
|
216
|
-
/* @__PURE__ */
|
|
224
|
+
/* @__PURE__ */ w("p", {
|
|
217
225
|
className: "text-xs text-muted-foreground",
|
|
218
226
|
children: "Competitors"
|
|
219
227
|
})
|
|
@@ -221,130 +229,147 @@ function A() {
|
|
|
221
229
|
}) })
|
|
222
230
|
]
|
|
223
231
|
}),
|
|
224
|
-
/* @__PURE__ */
|
|
232
|
+
/* @__PURE__ */ T("div", {
|
|
225
233
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
226
|
-
children: [/* @__PURE__ */
|
|
234
|
+
children: [/* @__PURE__ */ T("div", {
|
|
227
235
|
className: "lg:col-span-2 space-y-6",
|
|
228
236
|
children: [
|
|
229
|
-
/* @__PURE__ */
|
|
237
|
+
/* @__PURE__ */ T(D, { children: [/* @__PURE__ */ w(k, { children: /* @__PURE__ */ w(A, { children: "Description" }) }), /* @__PURE__ */ w(O, { children: /* @__PURE__ */ w("p", {
|
|
230
238
|
className: "text-sm",
|
|
231
|
-
children:
|
|
239
|
+
children: z.description ?? "No description provided."
|
|
232
240
|
}) })] }),
|
|
233
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ T(D, { children: [/* @__PURE__ */ w(k, { children: /* @__PURE__ */ T(A, { children: [
|
|
234
242
|
"Votes (",
|
|
235
|
-
|
|
243
|
+
B.length,
|
|
236
244
|
")"
|
|
237
|
-
] }) }), /* @__PURE__ */
|
|
245
|
+
] }) }), /* @__PURE__ */ T(O, {
|
|
238
246
|
className: "space-y-3",
|
|
239
|
-
children: [
|
|
247
|
+
children: [B.length === 0 && /* @__PURE__ */ w("p", {
|
|
240
248
|
className: "text-sm text-muted-foreground",
|
|
241
249
|
children: "No votes yet."
|
|
242
|
-
}),
|
|
250
|
+
}), B.map((e) => /* @__PURE__ */ T("div", {
|
|
243
251
|
className: "flex items-start justify-between border rounded-md p-3",
|
|
244
|
-
children: [/* @__PURE__ */
|
|
252
|
+
children: [/* @__PURE__ */ T("div", { children: [/* @__PURE__ */ T("p", {
|
|
245
253
|
className: "text-sm font-medium",
|
|
246
|
-
children: ["Voter: ", /* @__PURE__ */
|
|
247
|
-
}), e.comment && /* @__PURE__ */
|
|
254
|
+
children: ["Voter: ", /* @__PURE__ */ w(n, { id: e.voterId })]
|
|
255
|
+
}), e.comment && /* @__PURE__ */ w("p", {
|
|
248
256
|
className: "text-xs text-muted-foreground mt-1",
|
|
249
257
|
children: e.comment
|
|
250
|
-
})] }), /* @__PURE__ */
|
|
258
|
+
})] }), /* @__PURE__ */ T("div", {
|
|
251
259
|
className: "flex items-center gap-1",
|
|
252
|
-
children: [/* @__PURE__ */
|
|
260
|
+
children: [/* @__PURE__ */ w(y, { className: "h-3 w-3 text-green-500" }), /* @__PURE__ */ w("span", {
|
|
253
261
|
className: "text-sm font-bold",
|
|
254
262
|
children: e.weight
|
|
255
263
|
})]
|
|
256
264
|
})]
|
|
257
265
|
}, e.id))]
|
|
258
266
|
})] }),
|
|
259
|
-
/* @__PURE__ */
|
|
267
|
+
/* @__PURE__ */ T(D, { children: [/* @__PURE__ */ w(k, { children: /* @__PURE__ */ T(A, { children: [
|
|
260
268
|
"Competitors (",
|
|
261
|
-
|
|
269
|
+
V.length,
|
|
262
270
|
")"
|
|
263
|
-
] }) }), /* @__PURE__ */
|
|
264
|
-
featureRequestId:
|
|
265
|
-
competitors:
|
|
271
|
+
] }) }), /* @__PURE__ */ w(O, { children: /* @__PURE__ */ w(i, {
|
|
272
|
+
featureRequestId: z.id,
|
|
273
|
+
competitors: V
|
|
266
274
|
}) })] })
|
|
267
275
|
]
|
|
268
|
-
}), /* @__PURE__ */
|
|
276
|
+
}), /* @__PURE__ */ T("div", {
|
|
269
277
|
className: "space-y-6",
|
|
270
278
|
children: [
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
featureId:
|
|
273
|
-
productId:
|
|
274
|
-
initiative:
|
|
279
|
+
/* @__PURE__ */ w(p, {
|
|
280
|
+
featureId: z.id,
|
|
281
|
+
productId: z.productId ?? null,
|
|
282
|
+
initiative: z.roadmapItem ?? null
|
|
275
283
|
}),
|
|
276
|
-
/* @__PURE__ */
|
|
277
|
-
/* @__PURE__ */
|
|
284
|
+
/* @__PURE__ */ w(d, { feature: z }),
|
|
285
|
+
/* @__PURE__ */ T(D, { children: [/* @__PURE__ */ w(k, { children: /* @__PURE__ */ w(A, { children: "Details" }) }), /* @__PURE__ */ T(O, {
|
|
278
286
|
className: "space-y-3 text-sm",
|
|
279
287
|
children: [
|
|
280
|
-
/* @__PURE__ */
|
|
288
|
+
/* @__PURE__ */ T("div", {
|
|
281
289
|
className: "flex justify-between",
|
|
282
|
-
children: [/* @__PURE__ */
|
|
290
|
+
children: [/* @__PURE__ */ w("span", {
|
|
283
291
|
className: "text-muted-foreground",
|
|
284
292
|
children: "Status"
|
|
285
|
-
}), /* @__PURE__ */
|
|
293
|
+
}), /* @__PURE__ */ w(E, {
|
|
286
294
|
variant: "secondary",
|
|
287
295
|
className: "capitalize",
|
|
288
|
-
children:
|
|
296
|
+
children: z.status.toLowerCase().replace("_", " ")
|
|
289
297
|
})]
|
|
290
298
|
}),
|
|
291
|
-
/* @__PURE__ */
|
|
299
|
+
/* @__PURE__ */ T("div", {
|
|
292
300
|
className: "flex justify-between",
|
|
293
|
-
children: [/* @__PURE__ */
|
|
301
|
+
children: [/* @__PURE__ */ w("span", {
|
|
294
302
|
className: "text-muted-foreground",
|
|
295
303
|
children: "Priority Score"
|
|
296
|
-
}), /* @__PURE__ */
|
|
304
|
+
}), /* @__PURE__ */ w(E, {
|
|
297
305
|
variant: "outline",
|
|
298
|
-
children:
|
|
306
|
+
children: z.priorityScore ?? "N/A"
|
|
299
307
|
})]
|
|
300
308
|
}),
|
|
301
|
-
/* @__PURE__ */
|
|
309
|
+
/* @__PURE__ */ T("div", {
|
|
302
310
|
className: "flex justify-between",
|
|
303
|
-
children: [/* @__PURE__ */
|
|
311
|
+
children: [/* @__PURE__ */ w("span", {
|
|
304
312
|
className: "text-muted-foreground",
|
|
305
313
|
children: "Effort"
|
|
306
|
-
}), /* @__PURE__ */
|
|
314
|
+
}), /* @__PURE__ */ w(E, {
|
|
307
315
|
variant: "outline",
|
|
308
316
|
className: "capitalize",
|
|
309
|
-
children:
|
|
317
|
+
children: z.effortEstimate ?? "N/A"
|
|
310
318
|
})]
|
|
311
319
|
}),
|
|
312
|
-
/* @__PURE__ */
|
|
320
|
+
/* @__PURE__ */ T("div", {
|
|
313
321
|
className: "flex justify-between",
|
|
314
|
-
children: [/* @__PURE__ */
|
|
322
|
+
children: [/* @__PURE__ */ w("span", {
|
|
315
323
|
className: "text-muted-foreground",
|
|
316
324
|
children: "Business Value"
|
|
317
|
-
}), /* @__PURE__ */
|
|
325
|
+
}), /* @__PURE__ */ w("span", {
|
|
318
326
|
className: "font-medium",
|
|
319
|
-
children:
|
|
327
|
+
children: z.businessValue ?? "N/A"
|
|
320
328
|
})]
|
|
321
329
|
}),
|
|
322
|
-
/* @__PURE__ */
|
|
330
|
+
/* @__PURE__ */ T("div", {
|
|
331
|
+
className: "flex justify-between items-center",
|
|
332
|
+
children: [/* @__PURE__ */ w("span", {
|
|
333
|
+
className: "text-muted-foreground",
|
|
334
|
+
children: "Rating"
|
|
335
|
+
}), /* @__PURE__ */ w(l, { rating: z.rating ?? null })]
|
|
336
|
+
}),
|
|
337
|
+
/* @__PURE__ */ T("div", {
|
|
338
|
+
className: "flex justify-between items-center",
|
|
339
|
+
children: [/* @__PURE__ */ w("span", {
|
|
340
|
+
className: "text-muted-foreground",
|
|
341
|
+
children: "Category"
|
|
342
|
+
}), z.category ? /* @__PURE__ */ w(c, { category: z.category }) : /* @__PURE__ */ w("span", {
|
|
343
|
+
className: "text-sm text-muted-foreground",
|
|
344
|
+
children: "Not set"
|
|
345
|
+
})]
|
|
346
|
+
}),
|
|
347
|
+
/* @__PURE__ */ T("div", {
|
|
323
348
|
className: "flex justify-between",
|
|
324
|
-
children: [/* @__PURE__ */
|
|
349
|
+
children: [/* @__PURE__ */ w("span", {
|
|
325
350
|
className: "text-muted-foreground",
|
|
326
351
|
children: "Submitted By"
|
|
327
|
-
}), /* @__PURE__ */
|
|
352
|
+
}), /* @__PURE__ */ w(n, { id: z.submittedBy })]
|
|
328
353
|
}),
|
|
329
|
-
|
|
354
|
+
z.triagedAt && /* @__PURE__ */ T("div", {
|
|
330
355
|
className: "flex justify-between",
|
|
331
|
-
children: [/* @__PURE__ */
|
|
356
|
+
children: [/* @__PURE__ */ w("span", {
|
|
332
357
|
className: "text-muted-foreground",
|
|
333
358
|
children: "Decided"
|
|
334
|
-
}), /* @__PURE__ */
|
|
359
|
+
}), /* @__PURE__ */ T("span", { children: [new Date(z.triagedAt).toLocaleDateString(), z.triagedBy && /* @__PURE__ */ T(C, { children: [" by ", /* @__PURE__ */ w(n, { id: z.triagedBy })] })] })]
|
|
335
360
|
}),
|
|
336
|
-
/* @__PURE__ */
|
|
361
|
+
/* @__PURE__ */ T("div", {
|
|
337
362
|
className: "flex justify-between",
|
|
338
|
-
children: [/* @__PURE__ */
|
|
363
|
+
children: [/* @__PURE__ */ w("span", {
|
|
339
364
|
className: "text-muted-foreground",
|
|
340
365
|
children: "Updated"
|
|
341
|
-
}), /* @__PURE__ */
|
|
366
|
+
}), /* @__PURE__ */ w("span", { children: new Date(z.updatedAt).toLocaleDateString() })]
|
|
342
367
|
})
|
|
343
368
|
]
|
|
344
369
|
})] }),
|
|
345
|
-
|
|
370
|
+
z.tags?.length > 0 && /* @__PURE__ */ T(D, { children: [/* @__PURE__ */ w(k, { children: /* @__PURE__ */ w(A, { children: "Tags" }) }), /* @__PURE__ */ w(O, {
|
|
346
371
|
className: "flex flex-wrap gap-1",
|
|
347
|
-
children:
|
|
372
|
+
children: z.tags.map((e) => /* @__PURE__ */ w(E, {
|
|
348
373
|
variant: "outline",
|
|
349
374
|
className: "text-xs",
|
|
350
375
|
children: e
|
|
@@ -357,6 +382,6 @@ function A() {
|
|
|
357
382
|
});
|
|
358
383
|
}
|
|
359
384
|
//#endregion
|
|
360
|
-
export {
|
|
385
|
+
export { M as ProductsFeatureDetailPagePage };
|
|
361
386
|
|
|
362
387
|
//# 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 {\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
|
+
{"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';\nimport { CategoryBadge, RatingDisplay } from '../controls/FeedbackControls';\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 rating\n category\n isAnonymous\n moscow\n kano\n valueScore\n effortScore\n valueEffortQuadrant\n reach\n impact\n confidence\n riceScore\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 key={feature.id}\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 {/* CWF-15 */}\n <div className=\"flex justify-between items-center\">\n <span className=\"text-muted-foreground\">Rating</span>\n <RatingDisplay rating={feature.rating ?? null} />\n </div>\n <div className=\"flex justify-between items-center\">\n <span className=\"text-muted-foreground\">Category</span>\n {feature.category ? (\n <CategoryBadge category={feature.category} />\n ) : (\n <span className=\"text-sm text-muted-foreground\">Not set</span>\n )}\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":"AA8GA,wBAAgB,wBAAwB,4CAkXvC"}
|