@burdenoff/microfe-planmagnet 2026.927.3 → 2026.927.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/controls/FeatureControls.d.ts +26 -0
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/FeatureControls.js +318 -0
- package/dist/planmagnet/controls/FeatureControls.js.map +1 -0
- package/dist/planmagnet/controls/MilestoneControls.d.ts +17 -0
- package/dist/planmagnet/controls/MilestoneControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/MilestoneControls.js +200 -0
- package/dist/planmagnet/controls/MilestoneControls.js.map +1 -0
- package/dist/planmagnet/controls/ObjectiveControls.d.ts +31 -0
- package/dist/planmagnet/controls/ObjectiveControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ObjectiveControls.js +296 -0
- package/dist/planmagnet/controls/ObjectiveControls.js.map +1 -0
- package/dist/planmagnet/controls/Pickers.d.ts +26 -0
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -0
- package/dist/planmagnet/controls/Pickers.js +171 -0
- package/dist/planmagnet/controls/Pickers.js.map +1 -0
- package/dist/planmagnet/controls/ProjectControls.js +7 -7
- package/dist/planmagnet/controls/ReleaseControls.d.ts +14 -0
- package/dist/planmagnet/controls/ReleaseControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ReleaseControls.js +108 -0
- package/dist/planmagnet/controls/ReleaseControls.js.map +1 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +186 -152
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js +63 -56
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js.map +1 -1
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js +229 -214
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js +142 -114
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.js +134 -105
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +102 -108
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +119 -94
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js +107 -106
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsReleasesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsReleasesPagePage.js +2 -0
- package/dist/planmagnet/pages/ProductsReleasesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +6 -6
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +55 -63
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +4 -4
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +123 -128
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksEditTaskPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js +139 -107
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +173 -126
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.js +1 -0
- package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.js +23 -23
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { PersonName as t } from "../people/People.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { FeatureHeaderActions as n, FeatureVoteButton as r } from "../controls/FeatureControls.js";
|
|
4
|
+
import { Loader2 as i, MessageSquare as a, Star as o, Target as s, ThumbsUp as c } from "lucide-react";
|
|
5
|
+
import { useParams as l } from "react-router";
|
|
6
|
+
import { gql as u } from "@apollo/client";
|
|
7
|
+
import { useQuery as d } from "@apollo/client/react";
|
|
8
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
9
|
+
import { Badge as m, Card as h, CardContent as g, CardHeader as _, CardTitle as v } from "@burdenoff/fe-libs/ui";
|
|
9
10
|
//#region src/planmagnet/pages/ProductsFeatureDetailPagePage.tsx
|
|
10
|
-
var
|
|
11
|
+
var y = u`
|
|
11
12
|
query GetFeatureRequest($id: ID!) {
|
|
12
13
|
planmagnetFeatureRequest(id: $id) {
|
|
13
14
|
id
|
|
@@ -41,111 +42,104 @@ var _ = c`
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
`;
|
|
44
|
-
function
|
|
45
|
-
let { workspaceId:
|
|
46
|
-
variables: { id:
|
|
47
|
-
skip: !
|
|
45
|
+
function b() {
|
|
46
|
+
let { workspaceId: u, currentUser: b } = e(), x = l().id ?? "", { data: S, loading: C, error: w } = d(y, {
|
|
47
|
+
variables: { id: x },
|
|
48
|
+
skip: !x
|
|
48
49
|
});
|
|
49
|
-
if (
|
|
50
|
+
if (C && !S) return /* @__PURE__ */ f("div", {
|
|
50
51
|
className: "flex items-center justify-center p-12",
|
|
51
|
-
children: /* @__PURE__ */
|
|
52
|
+
children: /* @__PURE__ */ f(i, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
52
53
|
});
|
|
53
|
-
if (
|
|
54
|
+
if (w) return /* @__PURE__ */ p("div", {
|
|
54
55
|
className: "p-6 text-destructive",
|
|
55
|
-
children: ["Failed to load feature: ",
|
|
56
|
+
children: ["Failed to load feature: ", w.message]
|
|
56
57
|
});
|
|
57
|
-
let
|
|
58
|
-
if (!
|
|
58
|
+
let T = S?.planmagnetFeatureRequest;
|
|
59
|
+
if (!T) return /* @__PURE__ */ f("div", {
|
|
59
60
|
className: "p-6 text-muted-foreground",
|
|
60
61
|
children: "Feature not found."
|
|
61
62
|
});
|
|
62
|
-
let
|
|
63
|
-
return /* @__PURE__ */
|
|
63
|
+
let E = T.votes ?? [], D = T.competitors ?? [];
|
|
64
|
+
return /* @__PURE__ */ p("div", {
|
|
64
65
|
className: "space-y-6 p-6",
|
|
65
66
|
children: [
|
|
66
|
-
/* @__PURE__ */
|
|
67
|
+
/* @__PURE__ */ p("div", {
|
|
67
68
|
className: "flex items-center justify-between",
|
|
68
|
-
children: [/* @__PURE__ */
|
|
69
|
+
children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
|
|
69
70
|
className: "text-2xl font-semibold",
|
|
70
|
-
children:
|
|
71
|
-
}), /* @__PURE__ */
|
|
71
|
+
children: T.title
|
|
72
|
+
}), /* @__PURE__ */ p("p", {
|
|
72
73
|
className: "text-sm text-muted-foreground",
|
|
73
74
|
children: [
|
|
74
75
|
"Submitted by: ",
|
|
75
|
-
/* @__PURE__ */
|
|
76
|
+
/* @__PURE__ */ f(t, { id: T.submittedBy }),
|
|
76
77
|
" · Effort:",
|
|
77
78
|
" ",
|
|
78
|
-
|
|
79
|
+
T.effortEstimate ?? "N/A"
|
|
79
80
|
]
|
|
80
|
-
})] }), /* @__PURE__ */
|
|
81
|
-
className: "flex gap-2",
|
|
82
|
-
children: /* @__PURE__ */
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
PLANNED: "bg-blue-100 text-blue-800",
|
|
87
|
-
IN_PROGRESS: "bg-purple-100 text-purple-800",
|
|
88
|
-
COMPLETED: "bg-green-100 text-green-800",
|
|
89
|
-
DECLINED: "bg-red-100 text-red-800"
|
|
90
|
-
}[S.status] ?? "bg-gray-100"}`,
|
|
91
|
-
children: S.status.toLowerCase().replace("_", " ")
|
|
92
|
-
})
|
|
81
|
+
})] }), /* @__PURE__ */ p("div", {
|
|
82
|
+
className: "flex flex-col items-end gap-2",
|
|
83
|
+
children: [/* @__PURE__ */ f(r, {
|
|
84
|
+
featureId: T.id,
|
|
85
|
+
voted: E.some((e) => e.voterId === b?.id)
|
|
86
|
+
}), /* @__PURE__ */ f(n, { feature: T })]
|
|
93
87
|
})]
|
|
94
88
|
}),
|
|
95
|
-
/* @__PURE__ */
|
|
89
|
+
/* @__PURE__ */ p("div", {
|
|
96
90
|
className: "grid grid-cols-2 md:grid-cols-4 gap-4",
|
|
97
91
|
children: [
|
|
98
|
-
/* @__PURE__ */
|
|
92
|
+
/* @__PURE__ */ f(h, { children: /* @__PURE__ */ p(g, {
|
|
99
93
|
className: "pt-4 text-center",
|
|
100
94
|
children: [
|
|
101
|
-
/* @__PURE__ */
|
|
102
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ f(s, { className: "h-5 w-5 mx-auto text-primary" }),
|
|
96
|
+
/* @__PURE__ */ f("p", {
|
|
103
97
|
className: "text-2xl font-bold mt-1",
|
|
104
|
-
children:
|
|
98
|
+
children: T.priorityScore ?? 0
|
|
105
99
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
100
|
+
/* @__PURE__ */ f("p", {
|
|
107
101
|
className: "text-xs text-muted-foreground",
|
|
108
102
|
children: "Priority Score"
|
|
109
103
|
})
|
|
110
104
|
]
|
|
111
105
|
}) }),
|
|
112
|
-
/* @__PURE__ */
|
|
106
|
+
/* @__PURE__ */ f(h, { children: /* @__PURE__ */ p(g, {
|
|
113
107
|
className: "pt-4 text-center",
|
|
114
108
|
children: [
|
|
115
|
-
/* @__PURE__ */
|
|
116
|
-
/* @__PURE__ */
|
|
109
|
+
/* @__PURE__ */ f(c, { className: "h-5 w-5 mx-auto text-green-500" }),
|
|
110
|
+
/* @__PURE__ */ f("p", {
|
|
117
111
|
className: "text-2xl font-bold mt-1",
|
|
118
|
-
children:
|
|
112
|
+
children: T.voteCount
|
|
119
113
|
}),
|
|
120
|
-
/* @__PURE__ */
|
|
114
|
+
/* @__PURE__ */ f("p", {
|
|
121
115
|
className: "text-xs text-muted-foreground",
|
|
122
116
|
children: "Votes"
|
|
123
117
|
})
|
|
124
118
|
]
|
|
125
119
|
}) }),
|
|
126
|
-
/* @__PURE__ */
|
|
120
|
+
/* @__PURE__ */ f(h, { children: /* @__PURE__ */ p(g, {
|
|
127
121
|
className: "pt-4 text-center",
|
|
128
122
|
children: [
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
-
/* @__PURE__ */
|
|
123
|
+
/* @__PURE__ */ f(o, { className: "h-5 w-5 mx-auto text-yellow-500" }),
|
|
124
|
+
/* @__PURE__ */ f("p", {
|
|
131
125
|
className: "text-2xl font-bold mt-1",
|
|
132
|
-
children:
|
|
126
|
+
children: T.businessValue ?? 0
|
|
133
127
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ f("p", {
|
|
135
129
|
className: "text-xs text-muted-foreground",
|
|
136
130
|
children: "Business Value"
|
|
137
131
|
})
|
|
138
132
|
]
|
|
139
133
|
}) }),
|
|
140
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ f(h, { children: /* @__PURE__ */ p(g, {
|
|
141
135
|
className: "pt-4 text-center",
|
|
142
136
|
children: [
|
|
143
|
-
/* @__PURE__ */
|
|
144
|
-
/* @__PURE__ */
|
|
137
|
+
/* @__PURE__ */ f(a, { className: "h-5 w-5 mx-auto text-blue-500" }),
|
|
138
|
+
/* @__PURE__ */ f("p", {
|
|
145
139
|
className: "text-2xl font-bold mt-1",
|
|
146
|
-
children:
|
|
140
|
+
children: D.length
|
|
147
141
|
}),
|
|
148
|
-
/* @__PURE__ */
|
|
142
|
+
/* @__PURE__ */ f("p", {
|
|
149
143
|
className: "text-xs text-muted-foreground",
|
|
150
144
|
children: "Competitors"
|
|
151
145
|
})
|
|
@@ -153,130 +147,130 @@ function v() {
|
|
|
153
147
|
}) })
|
|
154
148
|
]
|
|
155
149
|
}),
|
|
156
|
-
/* @__PURE__ */
|
|
150
|
+
/* @__PURE__ */ p("div", {
|
|
157
151
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
158
|
-
children: [/* @__PURE__ */
|
|
152
|
+
children: [/* @__PURE__ */ p("div", {
|
|
159
153
|
className: "lg:col-span-2 space-y-6",
|
|
160
154
|
children: [
|
|
161
|
-
/* @__PURE__ */
|
|
155
|
+
/* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ f(v, { children: "Description" }) }), /* @__PURE__ */ f(g, { children: /* @__PURE__ */ f("p", {
|
|
162
156
|
className: "text-sm",
|
|
163
|
-
children:
|
|
157
|
+
children: T.description ?? "No description provided."
|
|
164
158
|
}) })] }),
|
|
165
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ p(v, { children: [
|
|
166
160
|
"Votes (",
|
|
167
|
-
|
|
161
|
+
E.length,
|
|
168
162
|
")"
|
|
169
|
-
] }) }), /* @__PURE__ */
|
|
163
|
+
] }) }), /* @__PURE__ */ p(g, {
|
|
170
164
|
className: "space-y-3",
|
|
171
|
-
children: [
|
|
165
|
+
children: [E.length === 0 && /* @__PURE__ */ f("p", {
|
|
172
166
|
className: "text-sm text-muted-foreground",
|
|
173
167
|
children: "No votes yet."
|
|
174
|
-
}),
|
|
168
|
+
}), E.map((e) => /* @__PURE__ */ p("div", {
|
|
175
169
|
className: "flex items-start justify-between border rounded-md p-3",
|
|
176
|
-
children: [/* @__PURE__ */
|
|
170
|
+
children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("p", {
|
|
177
171
|
className: "text-sm font-medium",
|
|
178
|
-
children: ["Voter: ", /* @__PURE__ */
|
|
179
|
-
}), e.comment && /* @__PURE__ */
|
|
172
|
+
children: ["Voter: ", /* @__PURE__ */ f(t, { id: e.voterId })]
|
|
173
|
+
}), e.comment && /* @__PURE__ */ f("p", {
|
|
180
174
|
className: "text-xs text-muted-foreground mt-1",
|
|
181
175
|
children: e.comment
|
|
182
|
-
})] }), /* @__PURE__ */
|
|
176
|
+
})] }), /* @__PURE__ */ p("div", {
|
|
183
177
|
className: "flex items-center gap-1",
|
|
184
|
-
children: [/* @__PURE__ */
|
|
178
|
+
children: [/* @__PURE__ */ f(c, { className: "h-3 w-3 text-green-500" }), /* @__PURE__ */ f("span", {
|
|
185
179
|
className: "text-sm font-bold",
|
|
186
180
|
children: e.weight
|
|
187
181
|
})]
|
|
188
182
|
})]
|
|
189
183
|
}, e.id))]
|
|
190
184
|
})] }),
|
|
191
|
-
|
|
185
|
+
D.length > 0 && /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ p(v, { children: [
|
|
192
186
|
"Competitor Analysis (",
|
|
193
|
-
|
|
187
|
+
D.length,
|
|
194
188
|
")"
|
|
195
|
-
] }) }), /* @__PURE__ */
|
|
189
|
+
] }) }), /* @__PURE__ */ f(g, {
|
|
196
190
|
className: "space-y-3",
|
|
197
|
-
children:
|
|
191
|
+
children: D.map((e) => /* @__PURE__ */ p("div", {
|
|
198
192
|
className: "border rounded-md p-3",
|
|
199
|
-
children: [/* @__PURE__ */
|
|
193
|
+
children: [/* @__PURE__ */ p("div", {
|
|
200
194
|
className: "flex items-center justify-between",
|
|
201
|
-
children: [/* @__PURE__ */
|
|
195
|
+
children: [/* @__PURE__ */ f("p", {
|
|
202
196
|
className: "text-sm font-medium",
|
|
203
197
|
children: e.name
|
|
204
|
-
}), e.website && /* @__PURE__ */
|
|
198
|
+
}), e.website && /* @__PURE__ */ f("span", {
|
|
205
199
|
className: "text-xs text-primary",
|
|
206
200
|
children: e.website
|
|
207
201
|
})]
|
|
208
|
-
}), e.description && /* @__PURE__ */
|
|
202
|
+
}), e.description && /* @__PURE__ */ f("p", {
|
|
209
203
|
className: "text-xs text-muted-foreground mt-1",
|
|
210
204
|
children: e.description
|
|
211
205
|
})]
|
|
212
206
|
}, e.id))
|
|
213
207
|
})] })
|
|
214
208
|
]
|
|
215
|
-
}), /* @__PURE__ */
|
|
209
|
+
}), /* @__PURE__ */ p("div", {
|
|
216
210
|
className: "space-y-6",
|
|
217
|
-
children: [/* @__PURE__ */
|
|
211
|
+
children: [/* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ f(v, { children: "Details" }) }), /* @__PURE__ */ p(g, {
|
|
218
212
|
className: "space-y-3 text-sm",
|
|
219
213
|
children: [
|
|
220
|
-
/* @__PURE__ */
|
|
214
|
+
/* @__PURE__ */ p("div", {
|
|
221
215
|
className: "flex justify-between",
|
|
222
|
-
children: [/* @__PURE__ */
|
|
216
|
+
children: [/* @__PURE__ */ f("span", {
|
|
223
217
|
className: "text-muted-foreground",
|
|
224
218
|
children: "Status"
|
|
225
|
-
}), /* @__PURE__ */
|
|
219
|
+
}), /* @__PURE__ */ f(m, {
|
|
226
220
|
variant: "secondary",
|
|
227
221
|
className: "capitalize",
|
|
228
|
-
children:
|
|
222
|
+
children: T.status.toLowerCase().replace("_", " ")
|
|
229
223
|
})]
|
|
230
224
|
}),
|
|
231
|
-
/* @__PURE__ */
|
|
225
|
+
/* @__PURE__ */ p("div", {
|
|
232
226
|
className: "flex justify-between",
|
|
233
|
-
children: [/* @__PURE__ */
|
|
227
|
+
children: [/* @__PURE__ */ f("span", {
|
|
234
228
|
className: "text-muted-foreground",
|
|
235
229
|
children: "Priority Score"
|
|
236
|
-
}), /* @__PURE__ */
|
|
230
|
+
}), /* @__PURE__ */ f(m, {
|
|
237
231
|
variant: "outline",
|
|
238
|
-
children:
|
|
232
|
+
children: T.priorityScore ?? "N/A"
|
|
239
233
|
})]
|
|
240
234
|
}),
|
|
241
|
-
/* @__PURE__ */
|
|
235
|
+
/* @__PURE__ */ p("div", {
|
|
242
236
|
className: "flex justify-between",
|
|
243
|
-
children: [/* @__PURE__ */
|
|
237
|
+
children: [/* @__PURE__ */ f("span", {
|
|
244
238
|
className: "text-muted-foreground",
|
|
245
239
|
children: "Effort"
|
|
246
|
-
}), /* @__PURE__ */
|
|
240
|
+
}), /* @__PURE__ */ f(m, {
|
|
247
241
|
variant: "outline",
|
|
248
242
|
className: "capitalize",
|
|
249
|
-
children:
|
|
243
|
+
children: T.effortEstimate ?? "N/A"
|
|
250
244
|
})]
|
|
251
245
|
}),
|
|
252
|
-
/* @__PURE__ */
|
|
246
|
+
/* @__PURE__ */ p("div", {
|
|
253
247
|
className: "flex justify-between",
|
|
254
|
-
children: [/* @__PURE__ */
|
|
248
|
+
children: [/* @__PURE__ */ f("span", {
|
|
255
249
|
className: "text-muted-foreground",
|
|
256
250
|
children: "Business Value"
|
|
257
|
-
}), /* @__PURE__ */
|
|
251
|
+
}), /* @__PURE__ */ f("span", {
|
|
258
252
|
className: "font-medium",
|
|
259
|
-
children:
|
|
253
|
+
children: T.businessValue ?? "N/A"
|
|
260
254
|
})]
|
|
261
255
|
}),
|
|
262
|
-
/* @__PURE__ */
|
|
256
|
+
/* @__PURE__ */ p("div", {
|
|
263
257
|
className: "flex justify-between",
|
|
264
|
-
children: [/* @__PURE__ */
|
|
258
|
+
children: [/* @__PURE__ */ f("span", {
|
|
265
259
|
className: "text-muted-foreground",
|
|
266
260
|
children: "Submitted By"
|
|
267
|
-
}), /* @__PURE__ */
|
|
261
|
+
}), /* @__PURE__ */ f(t, { id: T.submittedBy })]
|
|
268
262
|
}),
|
|
269
|
-
/* @__PURE__ */
|
|
263
|
+
/* @__PURE__ */ p("div", {
|
|
270
264
|
className: "flex justify-between",
|
|
271
|
-
children: [/* @__PURE__ */
|
|
265
|
+
children: [/* @__PURE__ */ f("span", {
|
|
272
266
|
className: "text-muted-foreground",
|
|
273
267
|
children: "Updated"
|
|
274
|
-
}), /* @__PURE__ */
|
|
268
|
+
}), /* @__PURE__ */ f("span", { children: new Date(T.updatedAt).toLocaleDateString() })]
|
|
275
269
|
})
|
|
276
270
|
]
|
|
277
|
-
})] }),
|
|
271
|
+
})] }), T.tags?.length > 0 && /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ f(v, { children: "Tags" }) }), /* @__PURE__ */ f(g, {
|
|
278
272
|
className: "flex flex-wrap gap-1",
|
|
279
|
-
children:
|
|
273
|
+
children: T.tags.map((e) => /* @__PURE__ */ f(m, {
|
|
280
274
|
variant: "outline",
|
|
281
275
|
className: "text-xs",
|
|
282
276
|
children: e
|
|
@@ -288,6 +282,6 @@ function v() {
|
|
|
288
282
|
});
|
|
289
283
|
}
|
|
290
284
|
//#endregion
|
|
291
|
-
export {
|
|
285
|
+
export { b as ProductsFeatureDetailPagePage };
|
|
292
286
|
|
|
293
287
|
//# 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 { 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 } from '../providers/PlanMagnetProvider';\nimport { useParams } from 'react-router';\nimport { PersonName } from '../people/People';\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 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 } = usePlanMagnet();\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 const statusColor: Record<string, string> = {\n SUBMITTED: 'bg-gray-100 text-gray-800',\n UNDER_REVIEW: 'bg-yellow-100 text-yellow-800',\n PLANNED: 'bg-blue-100 text-blue-800',\n IN_PROGRESS: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-green-100 text-green-800',\n DECLINED: 'bg-red-100 text-red-800',\n };\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 <div className=\"flex gap-2\">\n <span\n className={`text-xs px-2 py-1 rounded-full capitalize ${statusColor[feature.status] ?? 'bg-gray-100'}`}\n >\n {feature.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </div>\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 <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 { 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 } from '../providers/PlanMagnetProvider';\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 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 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 <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 <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":"ProductsNewFeaturePagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsNewFeaturePagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductsNewFeaturePagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsNewFeaturePagePage.tsx"],"names":[],"mappings":"AAyBA,wBAAgB,0BAA0B,4CAiPzC"}
|