@burdenoff/microfe-planmagnet 2026.928.2 → 2026.928.4
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/PlanMagnetRoot.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.js +102 -84
- package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +103 -55
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/controls/CompetitorControls.d.ts +20 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/CompetitorControls.js +172 -0
- package/dist/planmagnet/controls/CompetitorControls.js.map +1 -0
- package/dist/planmagnet/controls/FeatureControls.js +29 -29
- package/dist/planmagnet/controls/FeatureTriage.js +11 -11
- package/dist/planmagnet/controls/ObjectiveControls.js +24 -24
- package/dist/planmagnet/controls/Pickers.d.ts +17 -2
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +100 -9
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/controls/PortfolioControls.d.ts +13 -0
- package/dist/planmagnet/controls/PortfolioControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/PortfolioControls.js +114 -0
- package/dist/planmagnet/controls/PortfolioControls.js.map +1 -0
- package/dist/planmagnet/controls/ProgramControls.d.ts +25 -0
- package/dist/planmagnet/controls/ProgramControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ProgramControls.js +187 -0
- package/dist/planmagnet/controls/ProgramControls.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +127 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +129 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +132 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +181 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js +242 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +302 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +335 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +154 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +124 -138
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +221 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +279 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js +178 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +157 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +130 -103
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +156 -136
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksImportPagePage.js +5 -5
- package/dist/planmagnet/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { PersonName as n } from "../people/People.js";
|
|
3
3
|
import { detailPath as r } from "../utils/rowNavigation.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
4
|
+
import { CompetitorLinkCard as i } from "../controls/CompetitorControls.js";
|
|
5
|
+
import { FeatureTriageActions as a, isOpenRequest as o, isSnoozed as s } from "../controls/FeatureTriage.js";
|
|
6
|
+
import { FeatureHeaderActions as c, FeatureVoteButton as l } from "../controls/FeatureControls.js";
|
|
7
|
+
import { useState as u } from "react";
|
|
8
|
+
import { Loader2 as d, MessageSquare as f, Star as p, Target as m, ThumbsUp as h } from "lucide-react";
|
|
9
|
+
import { useParams as g } from "react-router";
|
|
10
|
+
import { gql as _ } from "@apollo/client";
|
|
11
|
+
import { useQuery as v } from "@apollo/client/react";
|
|
12
|
+
import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
|
|
13
|
+
import { Badge as S, Card as C, CardContent as w, CardHeader as T, CardTitle as E } from "@burdenoff/fe-libs/ui";
|
|
13
14
|
//#region src/planmagnet/pages/ProductsFeatureDetailPagePage.tsx
|
|
14
|
-
var
|
|
15
|
+
var D = _`
|
|
15
16
|
query GetFeatureRequest($id: ID!) {
|
|
16
17
|
planmagnetFeatureRequest(id: $id) {
|
|
17
18
|
id
|
|
@@ -54,88 +55,88 @@ var E = g`
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
`;
|
|
57
|
-
function
|
|
58
|
-
let { workspaceId:
|
|
59
|
-
variables: { id:
|
|
60
|
-
skip: !
|
|
58
|
+
function O() {
|
|
59
|
+
let { workspaceId: _, currentUser: O } = e(), k = t(), [A] = u(() => Date.now()), j = g().id ?? "", { data: M, loading: N, error: P } = v(D, {
|
|
60
|
+
variables: { id: j },
|
|
61
|
+
skip: !j
|
|
61
62
|
});
|
|
62
|
-
if (
|
|
63
|
+
if (N && !M) return /* @__PURE__ */ b("div", {
|
|
63
64
|
className: "flex items-center justify-center p-12",
|
|
64
|
-
children: /* @__PURE__ */
|
|
65
|
+
children: /* @__PURE__ */ b(d, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
65
66
|
});
|
|
66
|
-
if (
|
|
67
|
+
if (P) return /* @__PURE__ */ x("div", {
|
|
67
68
|
className: "p-6 text-destructive",
|
|
68
|
-
children: ["Failed to load feature: ",
|
|
69
|
+
children: ["Failed to load feature: ", P.message]
|
|
69
70
|
});
|
|
70
|
-
let
|
|
71
|
-
if (!
|
|
71
|
+
let F = M?.planmagnetFeatureRequest;
|
|
72
|
+
if (!F) return /* @__PURE__ */ b("div", {
|
|
72
73
|
className: "p-6 text-muted-foreground",
|
|
73
74
|
children: "Feature not found."
|
|
74
75
|
});
|
|
75
|
-
let
|
|
76
|
-
return /* @__PURE__ */
|
|
76
|
+
let I = F.votes ?? [], L = F.competitors ?? [];
|
|
77
|
+
return /* @__PURE__ */ x("div", {
|
|
77
78
|
className: "space-y-6 p-6",
|
|
78
79
|
children: [
|
|
79
|
-
/* @__PURE__ */
|
|
80
|
+
/* @__PURE__ */ x("div", {
|
|
80
81
|
className: "flex items-center justify-between",
|
|
81
|
-
children: [/* @__PURE__ */
|
|
82
|
+
children: [/* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("h1", {
|
|
82
83
|
className: "text-2xl font-semibold",
|
|
83
|
-
children:
|
|
84
|
-
}), /* @__PURE__ */
|
|
84
|
+
children: F.title
|
|
85
|
+
}), /* @__PURE__ */ x("p", {
|
|
85
86
|
className: "text-sm text-muted-foreground",
|
|
86
87
|
children: [
|
|
87
88
|
"Submitted by: ",
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
+
/* @__PURE__ */ b(n, { id: F.submittedBy }),
|
|
89
90
|
" · Effort:",
|
|
90
91
|
" ",
|
|
91
|
-
|
|
92
|
+
F.effortEstimate ?? "N/A"
|
|
92
93
|
]
|
|
93
|
-
})] }), /* @__PURE__ */
|
|
94
|
+
})] }), /* @__PURE__ */ x("div", {
|
|
94
95
|
className: "flex flex-col items-end gap-2",
|
|
95
|
-
children: [/* @__PURE__ */
|
|
96
|
-
featureId:
|
|
97
|
-
voted:
|
|
98
|
-
}), /* @__PURE__ */
|
|
96
|
+
children: [/* @__PURE__ */ b(l, {
|
|
97
|
+
featureId: F.id,
|
|
98
|
+
voted: I.some((e) => e.voterId === O?.id)
|
|
99
|
+
}), /* @__PURE__ */ b(c, { feature: F })]
|
|
99
100
|
})]
|
|
100
101
|
}),
|
|
101
|
-
|
|
102
|
+
o(F.status) && /* @__PURE__ */ x(C, {
|
|
102
103
|
"data-testid": "triage-card",
|
|
103
|
-
children: [/* @__PURE__ */
|
|
104
|
+
children: [/* @__PURE__ */ b(T, { children: /* @__PURE__ */ b(E, { children: "Triage" }) }), /* @__PURE__ */ x(w, {
|
|
104
105
|
className: "space-y-2",
|
|
105
|
-
children: [/* @__PURE__ */
|
|
106
|
+
children: [/* @__PURE__ */ b("p", {
|
|
106
107
|
className: "text-sm text-muted-foreground",
|
|
107
|
-
children:
|
|
108
|
-
}), /* @__PURE__ */
|
|
109
|
-
feature:
|
|
110
|
-
now:
|
|
108
|
+
children: s(F.snoozedUntil, A) ? `Snoozed until ${new Date(F.snoozedUntil).toLocaleString()} — it returns to the triage queue then.` : F.status === "SUBMITTED" ? "Waiting for a decision." : "Under review: accept it as planned, decline it, or merge it into its original."
|
|
109
|
+
}), /* @__PURE__ */ b(a, {
|
|
110
|
+
feature: F,
|
|
111
|
+
now: A
|
|
111
112
|
})]
|
|
112
113
|
})]
|
|
113
114
|
}),
|
|
114
|
-
|
|
115
|
+
F.status === "DECLINED" && F.declineReason && /* @__PURE__ */ b(C, {
|
|
115
116
|
"data-testid": "decline-reason",
|
|
116
|
-
children: /* @__PURE__ */
|
|
117
|
+
children: /* @__PURE__ */ x(w, {
|
|
117
118
|
className: "pt-4 text-sm",
|
|
118
|
-
children: [/* @__PURE__ */
|
|
119
|
+
children: [/* @__PURE__ */ b("span", {
|
|
119
120
|
className: "font-medium",
|
|
120
121
|
children: "Declined: "
|
|
121
|
-
}),
|
|
122
|
+
}), F.declineReason]
|
|
122
123
|
})
|
|
123
124
|
}),
|
|
124
|
-
|
|
125
|
+
F.status === "DUPLICATE" && F.duplicateOfId && /* @__PURE__ */ b(C, {
|
|
125
126
|
"data-testid": "duplicate-of",
|
|
126
|
-
children: /* @__PURE__ */
|
|
127
|
+
children: /* @__PURE__ */ x(w, {
|
|
127
128
|
className: "pt-4 text-sm",
|
|
128
129
|
children: [
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ b("span", {
|
|
130
131
|
className: "font-medium",
|
|
131
132
|
children: "Duplicate of "
|
|
132
133
|
}),
|
|
133
|
-
|
|
134
|
+
F.duplicateOf ? /* @__PURE__ */ b("button", {
|
|
134
135
|
type: "button",
|
|
135
136
|
className: "text-primary underline-offset-2 hover:underline",
|
|
136
|
-
onClick: () =>
|
|
137
|
-
children:
|
|
138
|
-
}) : /* @__PURE__ */
|
|
137
|
+
onClick: () => k(r("/products/feature-detail-page", F.duplicateOf.id)),
|
|
138
|
+
children: F.duplicateOf.title
|
|
139
|
+
}) : /* @__PURE__ */ b("span", {
|
|
139
140
|
className: "text-muted-foreground",
|
|
140
141
|
children: "a request that has since been deleted"
|
|
141
142
|
}),
|
|
@@ -144,60 +145,60 @@ function D() {
|
|
|
144
145
|
]
|
|
145
146
|
})
|
|
146
147
|
}),
|
|
147
|
-
/* @__PURE__ */
|
|
148
|
+
/* @__PURE__ */ x("div", {
|
|
148
149
|
className: "grid grid-cols-2 md:grid-cols-4 gap-4",
|
|
149
150
|
children: [
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ b(C, { children: /* @__PURE__ */ x(w, {
|
|
151
152
|
className: "pt-4 text-center",
|
|
152
153
|
children: [
|
|
153
|
-
/* @__PURE__ */
|
|
154
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ b(m, { className: "h-5 w-5 mx-auto text-primary" }),
|
|
155
|
+
/* @__PURE__ */ b("p", {
|
|
155
156
|
className: "text-2xl font-bold mt-1",
|
|
156
|
-
children:
|
|
157
|
+
children: F.priorityScore ?? 0
|
|
157
158
|
}),
|
|
158
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ b("p", {
|
|
159
160
|
className: "text-xs text-muted-foreground",
|
|
160
161
|
children: "Priority Score"
|
|
161
162
|
})
|
|
162
163
|
]
|
|
163
164
|
}) }),
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
+
/* @__PURE__ */ b(C, { children: /* @__PURE__ */ x(w, {
|
|
165
166
|
className: "pt-4 text-center",
|
|
166
167
|
children: [
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
168
|
+
/* @__PURE__ */ b(h, { className: "h-5 w-5 mx-auto text-green-500" }),
|
|
169
|
+
/* @__PURE__ */ b("p", {
|
|
169
170
|
className: "text-2xl font-bold mt-1",
|
|
170
|
-
children:
|
|
171
|
+
children: F.voteCount
|
|
171
172
|
}),
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
+
/* @__PURE__ */ b("p", {
|
|
173
174
|
className: "text-xs text-muted-foreground",
|
|
174
175
|
children: "Votes"
|
|
175
176
|
})
|
|
176
177
|
]
|
|
177
178
|
}) }),
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
+
/* @__PURE__ */ b(C, { children: /* @__PURE__ */ x(w, {
|
|
179
180
|
className: "pt-4 text-center",
|
|
180
181
|
children: [
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ b(p, { className: "h-5 w-5 mx-auto text-yellow-500" }),
|
|
183
|
+
/* @__PURE__ */ b("p", {
|
|
183
184
|
className: "text-2xl font-bold mt-1",
|
|
184
|
-
children:
|
|
185
|
+
children: F.businessValue ?? 0
|
|
185
186
|
}),
|
|
186
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ b("p", {
|
|
187
188
|
className: "text-xs text-muted-foreground",
|
|
188
189
|
children: "Business Value"
|
|
189
190
|
})
|
|
190
191
|
]
|
|
191
192
|
}) }),
|
|
192
|
-
/* @__PURE__ */
|
|
193
|
+
/* @__PURE__ */ b(C, { children: /* @__PURE__ */ x(w, {
|
|
193
194
|
className: "pt-4 text-center",
|
|
194
195
|
children: [
|
|
195
|
-
/* @__PURE__ */
|
|
196
|
-
/* @__PURE__ */
|
|
196
|
+
/* @__PURE__ */ b(f, { className: "h-5 w-5 mx-auto text-blue-500" }),
|
|
197
|
+
/* @__PURE__ */ b("p", {
|
|
197
198
|
className: "text-2xl font-bold mt-1",
|
|
198
|
-
children:
|
|
199
|
+
children: L.length
|
|
199
200
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
201
|
+
/* @__PURE__ */ b("p", {
|
|
201
202
|
className: "text-xs text-muted-foreground",
|
|
202
203
|
children: "Competitors"
|
|
203
204
|
})
|
|
@@ -205,137 +206,122 @@ function D() {
|
|
|
205
206
|
}) })
|
|
206
207
|
]
|
|
207
208
|
}),
|
|
208
|
-
/* @__PURE__ */
|
|
209
|
+
/* @__PURE__ */ x("div", {
|
|
209
210
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
210
|
-
children: [/* @__PURE__ */
|
|
211
|
+
children: [/* @__PURE__ */ x("div", {
|
|
211
212
|
className: "lg:col-span-2 space-y-6",
|
|
212
213
|
children: [
|
|
213
|
-
/* @__PURE__ */
|
|
214
|
+
/* @__PURE__ */ x(C, { children: [/* @__PURE__ */ b(T, { children: /* @__PURE__ */ b(E, { children: "Description" }) }), /* @__PURE__ */ b(w, { children: /* @__PURE__ */ b("p", {
|
|
214
215
|
className: "text-sm",
|
|
215
|
-
children:
|
|
216
|
+
children: F.description ?? "No description provided."
|
|
216
217
|
}) })] }),
|
|
217
|
-
/* @__PURE__ */
|
|
218
|
+
/* @__PURE__ */ x(C, { children: [/* @__PURE__ */ b(T, { children: /* @__PURE__ */ x(E, { children: [
|
|
218
219
|
"Votes (",
|
|
219
|
-
|
|
220
|
+
I.length,
|
|
220
221
|
")"
|
|
221
|
-
] }) }), /* @__PURE__ */
|
|
222
|
+
] }) }), /* @__PURE__ */ x(w, {
|
|
222
223
|
className: "space-y-3",
|
|
223
|
-
children: [
|
|
224
|
+
children: [I.length === 0 && /* @__PURE__ */ b("p", {
|
|
224
225
|
className: "text-sm text-muted-foreground",
|
|
225
226
|
children: "No votes yet."
|
|
226
|
-
}),
|
|
227
|
+
}), I.map((e) => /* @__PURE__ */ x("div", {
|
|
227
228
|
className: "flex items-start justify-between border rounded-md p-3",
|
|
228
|
-
children: [/* @__PURE__ */
|
|
229
|
+
children: [/* @__PURE__ */ x("div", { children: [/* @__PURE__ */ x("p", {
|
|
229
230
|
className: "text-sm font-medium",
|
|
230
|
-
children: ["Voter: ", /* @__PURE__ */
|
|
231
|
-
}), e.comment && /* @__PURE__ */
|
|
231
|
+
children: ["Voter: ", /* @__PURE__ */ b(n, { id: e.voterId })]
|
|
232
|
+
}), e.comment && /* @__PURE__ */ b("p", {
|
|
232
233
|
className: "text-xs text-muted-foreground mt-1",
|
|
233
234
|
children: e.comment
|
|
234
|
-
})] }), /* @__PURE__ */
|
|
235
|
+
})] }), /* @__PURE__ */ x("div", {
|
|
235
236
|
className: "flex items-center gap-1",
|
|
236
|
-
children: [/* @__PURE__ */
|
|
237
|
+
children: [/* @__PURE__ */ b(h, { className: "h-3 w-3 text-green-500" }), /* @__PURE__ */ b("span", {
|
|
237
238
|
className: "text-sm font-bold",
|
|
238
239
|
children: e.weight
|
|
239
240
|
})]
|
|
240
241
|
})]
|
|
241
242
|
}, e.id))]
|
|
242
243
|
})] }),
|
|
243
|
-
|
|
244
|
-
"
|
|
245
|
-
|
|
244
|
+
/* @__PURE__ */ x(C, { children: [/* @__PURE__ */ b(T, { children: /* @__PURE__ */ x(E, { children: [
|
|
245
|
+
"Competitors (",
|
|
246
|
+
L.length,
|
|
246
247
|
")"
|
|
247
|
-
] }) }), /* @__PURE__ */
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
children: [/* @__PURE__ */ b("div", {
|
|
252
|
-
className: "flex items-center justify-between",
|
|
253
|
-
children: [/* @__PURE__ */ y("p", {
|
|
254
|
-
className: "text-sm font-medium",
|
|
255
|
-
children: e.name
|
|
256
|
-
}), e.website && /* @__PURE__ */ y("span", {
|
|
257
|
-
className: "text-xs text-primary",
|
|
258
|
-
children: e.website
|
|
259
|
-
})]
|
|
260
|
-
}), e.description && /* @__PURE__ */ y("p", {
|
|
261
|
-
className: "text-xs text-muted-foreground mt-1",
|
|
262
|
-
children: e.description
|
|
263
|
-
})]
|
|
264
|
-
}, e.id))
|
|
265
|
-
})] })
|
|
248
|
+
] }) }), /* @__PURE__ */ b(w, { children: /* @__PURE__ */ b(i, {
|
|
249
|
+
featureRequestId: F.id,
|
|
250
|
+
competitors: L
|
|
251
|
+
}) })] })
|
|
266
252
|
]
|
|
267
|
-
}), /* @__PURE__ */
|
|
253
|
+
}), /* @__PURE__ */ x("div", {
|
|
268
254
|
className: "space-y-6",
|
|
269
|
-
children: [/* @__PURE__ */
|
|
255
|
+
children: [/* @__PURE__ */ x(C, { children: [/* @__PURE__ */ b(T, { children: /* @__PURE__ */ b(E, { children: "Details" }) }), /* @__PURE__ */ x(w, {
|
|
270
256
|
className: "space-y-3 text-sm",
|
|
271
257
|
children: [
|
|
272
|
-
/* @__PURE__ */
|
|
258
|
+
/* @__PURE__ */ x("div", {
|
|
273
259
|
className: "flex justify-between",
|
|
274
|
-
children: [/* @__PURE__ */
|
|
260
|
+
children: [/* @__PURE__ */ b("span", {
|
|
275
261
|
className: "text-muted-foreground",
|
|
276
262
|
children: "Status"
|
|
277
|
-
}), /* @__PURE__ */
|
|
263
|
+
}), /* @__PURE__ */ b(S, {
|
|
278
264
|
variant: "secondary",
|
|
279
265
|
className: "capitalize",
|
|
280
|
-
children:
|
|
266
|
+
children: F.status.toLowerCase().replace("_", " ")
|
|
281
267
|
})]
|
|
282
268
|
}),
|
|
283
|
-
/* @__PURE__ */
|
|
269
|
+
/* @__PURE__ */ x("div", {
|
|
284
270
|
className: "flex justify-between",
|
|
285
|
-
children: [/* @__PURE__ */
|
|
271
|
+
children: [/* @__PURE__ */ b("span", {
|
|
286
272
|
className: "text-muted-foreground",
|
|
287
273
|
children: "Priority Score"
|
|
288
|
-
}), /* @__PURE__ */
|
|
274
|
+
}), /* @__PURE__ */ b(S, {
|
|
289
275
|
variant: "outline",
|
|
290
|
-
children:
|
|
276
|
+
children: F.priorityScore ?? "N/A"
|
|
291
277
|
})]
|
|
292
278
|
}),
|
|
293
|
-
/* @__PURE__ */
|
|
279
|
+
/* @__PURE__ */ x("div", {
|
|
294
280
|
className: "flex justify-between",
|
|
295
|
-
children: [/* @__PURE__ */
|
|
281
|
+
children: [/* @__PURE__ */ b("span", {
|
|
296
282
|
className: "text-muted-foreground",
|
|
297
283
|
children: "Effort"
|
|
298
|
-
}), /* @__PURE__ */
|
|
284
|
+
}), /* @__PURE__ */ b(S, {
|
|
299
285
|
variant: "outline",
|
|
300
286
|
className: "capitalize",
|
|
301
|
-
children:
|
|
287
|
+
children: F.effortEstimate ?? "N/A"
|
|
302
288
|
})]
|
|
303
289
|
}),
|
|
304
|
-
/* @__PURE__ */
|
|
290
|
+
/* @__PURE__ */ x("div", {
|
|
305
291
|
className: "flex justify-between",
|
|
306
|
-
children: [/* @__PURE__ */
|
|
292
|
+
children: [/* @__PURE__ */ b("span", {
|
|
307
293
|
className: "text-muted-foreground",
|
|
308
294
|
children: "Business Value"
|
|
309
|
-
}), /* @__PURE__ */
|
|
295
|
+
}), /* @__PURE__ */ b("span", {
|
|
310
296
|
className: "font-medium",
|
|
311
|
-
children:
|
|
297
|
+
children: F.businessValue ?? "N/A"
|
|
312
298
|
})]
|
|
313
299
|
}),
|
|
314
|
-
/* @__PURE__ */
|
|
300
|
+
/* @__PURE__ */ x("div", {
|
|
315
301
|
className: "flex justify-between",
|
|
316
|
-
children: [/* @__PURE__ */
|
|
302
|
+
children: [/* @__PURE__ */ b("span", {
|
|
317
303
|
className: "text-muted-foreground",
|
|
318
304
|
children: "Submitted By"
|
|
319
|
-
}), /* @__PURE__ */
|
|
305
|
+
}), /* @__PURE__ */ b(n, { id: F.submittedBy })]
|
|
320
306
|
}),
|
|
321
|
-
|
|
307
|
+
F.triagedAt && /* @__PURE__ */ x("div", {
|
|
322
308
|
className: "flex justify-between",
|
|
323
|
-
children: [/* @__PURE__ */
|
|
309
|
+
children: [/* @__PURE__ */ b("span", {
|
|
324
310
|
className: "text-muted-foreground",
|
|
325
311
|
children: "Decided"
|
|
326
|
-
}), /* @__PURE__ */
|
|
312
|
+
}), /* @__PURE__ */ x("span", { children: [new Date(F.triagedAt).toLocaleDateString(), F.triagedBy && /* @__PURE__ */ x(y, { children: [" by ", /* @__PURE__ */ b(n, { id: F.triagedBy })] })] })]
|
|
327
313
|
}),
|
|
328
|
-
/* @__PURE__ */
|
|
314
|
+
/* @__PURE__ */ x("div", {
|
|
329
315
|
className: "flex justify-between",
|
|
330
|
-
children: [/* @__PURE__ */
|
|
316
|
+
children: [/* @__PURE__ */ b("span", {
|
|
331
317
|
className: "text-muted-foreground",
|
|
332
318
|
children: "Updated"
|
|
333
|
-
}), /* @__PURE__ */
|
|
319
|
+
}), /* @__PURE__ */ b("span", { children: new Date(F.updatedAt).toLocaleDateString() })]
|
|
334
320
|
})
|
|
335
321
|
]
|
|
336
|
-
})] }),
|
|
322
|
+
})] }), F.tags?.length > 0 && /* @__PURE__ */ x(C, { children: [/* @__PURE__ */ b(T, { children: /* @__PURE__ */ b(E, { children: "Tags" }) }), /* @__PURE__ */ b(w, {
|
|
337
323
|
className: "flex flex-wrap gap-1",
|
|
338
|
-
children:
|
|
324
|
+
children: F.tags.map((e) => /* @__PURE__ */ b(S, {
|
|
339
325
|
variant: "outline",
|
|
340
326
|
className: "text-xs",
|
|
341
327
|
children: e
|
|
@@ -347,6 +333,6 @@ function D() {
|
|
|
347
333
|
});
|
|
348
334
|
}
|
|
349
335
|
//#endregion
|
|
350
|
-
export {
|
|
336
|
+
export { O as ProductsFeatureDetailPagePage };
|
|
351
337
|
|
|
352
338
|
//# 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';\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 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 {competitors.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle>Competitor Analysis ({competitors.length})</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {competitors.map((comp) => (\n <div key={comp.id} className=\"border rounded-md p-3\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm font-medium\">{comp.name}</p>\n {comp.website && <span className=\"text-xs text-primary\">{comp.website}</span>}\n </div>\n {comp.description && (\n <p className=\"text-xs text-muted-foreground mt-1\">{comp.description}</p>\n )}\n </div>\n ))}\n </CardContent>\n </Card>\n )}\n </div>\n\n <div className=\"space-y-6\">\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 { FeatureHeaderActions, FeatureVoteButton } from '../controls/FeatureControls';\nimport { CompetitorLinkCard } from '../controls/CompetitorControls';\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 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 <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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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgramsCreateProgramPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProgramsCreateProgramPagePage.tsx"],"names":[],"mappings":"AAoBA,wBAAgB,6BAA6B,4CA+M5C"}
|