@burdenoff/microfe-planmagnet 2026.1001.5 → 2026.1001.6
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/CompetitorControls.d.ts +71 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/CompetitorControls.js +346 -12
- package/dist/planmagnet/controls/CompetitorControls.js.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts +5 -0
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.js +363 -218
- package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
- package/dist/planmagnet/controls/Pickers.d.ts +15 -0
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +61 -1
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/controls/PrioritizationControls.d.ts +36 -0
- package/dist/planmagnet/controls/PrioritizationControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/PrioritizationControls.js +118 -1
- package/dist/planmagnet/controls/PrioritizationControls.js.map +1 -1
- package/dist/planmagnet/dashboards/DashboardUI.js +1 -1
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.d.ts.map +1 -1
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js +67 -59
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +289 -282
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +126 -63
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +14 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +93 -57
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +125 -83
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -1
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +226 -126
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +162 -122
- 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 +135 -109
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +15 -3
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js +59 -53
- package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
- package/dist/planmagnet/pages/analytics/MetricsCard.d.ts +8 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.d.ts.map +1 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.js +164 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.js.map +1 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts +2 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts.map +1 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js +155 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js.map +1 -0
- package/package.json +1 -1
|
@@ -6,15 +6,15 @@ import { enumLabel as o } from "./WorkItemControls.js";
|
|
|
6
6
|
import { detailPath as s } from "../utils/rowNavigation.js";
|
|
7
7
|
import { ProjectSelect as c, WorkItemSearchSelect as l } from "./Pickers.js";
|
|
8
8
|
import { parseIntField as u } from "../utils/formValidation.js";
|
|
9
|
-
import { PrioritizationScoreFields as d, QuadrantBadge as f,
|
|
10
|
-
import { useState as
|
|
11
|
-
import { BarChart3 as
|
|
12
|
-
import { gql as
|
|
13
|
-
import { useMutation as
|
|
14
|
-
import { Fragment as
|
|
15
|
-
import { Button as
|
|
9
|
+
import { PrioritizationScoreFields as d, QuadrantBadge as f, RiceScoreFields as p, kanoLabel as m, moscowLabel as h, prioritizationScoresValid as g, riceInputsValid as _, riceScoreMissingHint as v } from "./PrioritizationControls.js";
|
|
10
|
+
import { useState as y } from "react";
|
|
11
|
+
import { BarChart3 as b, Pencil as x, ThumbsUp as S, Trash2 as C } from "lucide-react";
|
|
12
|
+
import { gql as w } from "@apollo/client";
|
|
13
|
+
import { useMutation as T } from "@apollo/client/react";
|
|
14
|
+
import { Fragment as E, jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
15
|
+
import { Button as k, Card as A, CardContent as j, CardHeader as M, CardTitle as N, Input as P, ResponsiveDialog as F, ResponsiveDialogContent as I, ResponsiveDialogDescription as L, ResponsiveDialogFooter as R, ResponsiveDialogHeader as z, ResponsiveDialogTitle as B, ResponsiveDialogTrigger as V } from "@burdenoff/fe-libs/ui";
|
|
16
16
|
//#region src/planmagnet/controls/FeatureControls.tsx
|
|
17
|
-
var
|
|
17
|
+
var H = [
|
|
18
18
|
"SUBMITTED",
|
|
19
19
|
"UNDER_REVIEW",
|
|
20
20
|
"PLANNED",
|
|
@@ -22,7 +22,7 @@ var z = [
|
|
|
22
22
|
"COMPLETED",
|
|
23
23
|
"DECLINED",
|
|
24
24
|
"DUPLICATE"
|
|
25
|
-
],
|
|
25
|
+
], U = [
|
|
26
26
|
"GetFeatureRequest",
|
|
27
27
|
"ListFeatureRequests",
|
|
28
28
|
"ListFeatureRequestsForProduct",
|
|
@@ -30,17 +30,17 @@ var z = [
|
|
|
30
30
|
"ListAllFeaturesAnalytics",
|
|
31
31
|
"GetFeatureRequestAnalytics",
|
|
32
32
|
"ReleaseCustomerRequests"
|
|
33
|
-
],
|
|
33
|
+
], W = w`
|
|
34
34
|
mutation FeatureControlsVote($id: ID!) {
|
|
35
35
|
planmagnetVoteOnFeature(featureRequestId: $id) {
|
|
36
36
|
id
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
`,
|
|
39
|
+
`, G = w`
|
|
40
40
|
mutation FeatureControlsUnvote($id: ID!) {
|
|
41
41
|
planmagnetRemoveFeatureVote(featureRequestId: $id)
|
|
42
42
|
}
|
|
43
|
-
`,
|
|
43
|
+
`, K = w`
|
|
44
44
|
mutation FeatureControlsUpdate($id: ID!, $input: PlanmagnetUpdateFeatureRequestInput!) {
|
|
45
45
|
planmagnetUpdateFeatureRequest(id: $id, input: $input) {
|
|
46
46
|
id
|
|
@@ -56,18 +56,22 @@ var z = [
|
|
|
56
56
|
valueScore
|
|
57
57
|
effortScore
|
|
58
58
|
valueEffortQuadrant
|
|
59
|
+
reach
|
|
60
|
+
impact
|
|
61
|
+
confidence
|
|
62
|
+
riceScore
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
|
-
`,
|
|
65
|
+
`, q = w`
|
|
62
66
|
mutation FeatureControlsDelete($id: ID!) {
|
|
63
67
|
planmagnetDeleteFeatureRequest(id: $id)
|
|
64
68
|
}
|
|
65
|
-
`,
|
|
66
|
-
refetchQueries:
|
|
69
|
+
`, J = {
|
|
70
|
+
refetchQueries: U,
|
|
67
71
|
awaitRefetchQueries: !0
|
|
68
72
|
};
|
|
69
|
-
function
|
|
70
|
-
let [n, i] =
|
|
73
|
+
function Y({ featureId: e, voted: t }) {
|
|
74
|
+
let [n, i] = T(W, J), [o, s] = T(G, J), [c, l] = y(null), u = i.loading || s.loading, d = async () => {
|
|
71
75
|
l(null);
|
|
72
76
|
try {
|
|
73
77
|
await r((t ? o : n)({ variables: { id: e } }));
|
|
@@ -75,24 +79,24 @@ function K({ featureId: e, voted: t }) {
|
|
|
75
79
|
l(e instanceof Error ? e.message : "Your vote could not be saved.");
|
|
76
80
|
}
|
|
77
81
|
};
|
|
78
|
-
return /* @__PURE__ */
|
|
82
|
+
return /* @__PURE__ */ O("div", {
|
|
79
83
|
className: "flex flex-col items-end gap-1",
|
|
80
|
-
children: [/* @__PURE__ */
|
|
84
|
+
children: [/* @__PURE__ */ O(k, {
|
|
81
85
|
size: "sm",
|
|
82
86
|
variant: t ? "default" : "outline",
|
|
83
87
|
"data-testid": "feature-vote",
|
|
84
88
|
"aria-pressed": t,
|
|
85
89
|
disabled: u,
|
|
86
90
|
onClick: () => void d(),
|
|
87
|
-
children: [/* @__PURE__ */
|
|
88
|
-
}), c && /* @__PURE__ */
|
|
91
|
+
children: [/* @__PURE__ */ D(S, { className: "mr-1 h-4 w-4" }), t ? "Voted" : "Vote"]
|
|
92
|
+
}), c && /* @__PURE__ */ D(a, { message: c })]
|
|
89
93
|
});
|
|
90
94
|
}
|
|
91
|
-
function
|
|
92
|
-
let c = e(), [l, u] =
|
|
93
|
-
refetchQueries:
|
|
95
|
+
function X({ feature: t }) {
|
|
96
|
+
let c = e(), [l, u] = T(K, J), [d, f] = T(q, {
|
|
97
|
+
refetchQueries: U.filter((e) => e !== "GetFeatureRequest"),
|
|
94
98
|
context: n
|
|
95
|
-
}), [p, m] =
|
|
99
|
+
}), [p, m] = y(null), h = u.loading || f.loading, g = H.includes(t.status) ? H : [t.status, ...H], _ = async (e) => {
|
|
96
100
|
m(null);
|
|
97
101
|
try {
|
|
98
102
|
await r(l({ variables: {
|
|
@@ -102,7 +106,7 @@ function q({ feature: t }) {
|
|
|
102
106
|
} catch (e) {
|
|
103
107
|
m(e instanceof Error ? e.message : "The status could not be changed.");
|
|
104
108
|
}
|
|
105
|
-
},
|
|
109
|
+
}, v = async () => {
|
|
106
110
|
m(null);
|
|
107
111
|
try {
|
|
108
112
|
await r(d({ variables: { id: t.id } })), c("/products/features-page");
|
|
@@ -110,49 +114,49 @@ function q({ feature: t }) {
|
|
|
110
114
|
m(e instanceof Error ? e.message : "The request could not be deleted.");
|
|
111
115
|
}
|
|
112
116
|
};
|
|
113
|
-
return /* @__PURE__ */
|
|
117
|
+
return /* @__PURE__ */ O("div", {
|
|
114
118
|
className: "flex flex-col items-end gap-2",
|
|
115
|
-
children: [/* @__PURE__ */
|
|
119
|
+
children: [/* @__PURE__ */ O("div", {
|
|
116
120
|
className: "flex flex-wrap items-center justify-end gap-2",
|
|
117
121
|
children: [
|
|
118
|
-
/* @__PURE__ */
|
|
122
|
+
/* @__PURE__ */ D("select", {
|
|
119
123
|
"aria-label": "Status",
|
|
120
124
|
"data-testid": "feature-status",
|
|
121
125
|
className: "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60",
|
|
122
126
|
value: t.status,
|
|
123
127
|
disabled: h,
|
|
124
128
|
onChange: (e) => {
|
|
125
|
-
e.target.value !== t.status &&
|
|
129
|
+
e.target.value !== t.status && _(e.target.value);
|
|
126
130
|
},
|
|
127
|
-
children:
|
|
131
|
+
children: g.map((e) => /* @__PURE__ */ D("option", {
|
|
128
132
|
value: e,
|
|
129
133
|
children: o(e)
|
|
130
134
|
}, e))
|
|
131
135
|
}),
|
|
132
|
-
/* @__PURE__ */
|
|
133
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ D(Z, { feature: t }),
|
|
137
|
+
/* @__PURE__ */ O(k, {
|
|
134
138
|
size: "sm",
|
|
135
139
|
variant: "outline",
|
|
136
140
|
"data-testid": "feature-analytics",
|
|
137
141
|
onClick: () => c(s("/products/feature-analytics-page", t.id)),
|
|
138
|
-
children: [/* @__PURE__ */
|
|
142
|
+
children: [/* @__PURE__ */ D(b, { className: "mr-1 h-4 w-4" }), "Analytics"]
|
|
139
143
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ D(i, {
|
|
141
145
|
label: "Delete",
|
|
142
146
|
variant: "outline",
|
|
143
|
-
icon: /* @__PURE__ */
|
|
147
|
+
icon: /* @__PURE__ */ D(C, { className: "mr-1 h-4 w-4" }),
|
|
144
148
|
title: `Delete "${t.title}"?`,
|
|
145
149
|
description: "The request and its votes are deleted. This cannot be undone here.",
|
|
146
150
|
confirmLabel: "Delete request",
|
|
147
151
|
destructive: !0,
|
|
148
152
|
disabled: h,
|
|
149
|
-
onConfirm: () => void
|
|
153
|
+
onConfirm: () => void v()
|
|
150
154
|
})
|
|
151
155
|
]
|
|
152
|
-
}), p && /* @__PURE__ */
|
|
156
|
+
}), p && /* @__PURE__ */ D(a, { message: p })]
|
|
153
157
|
});
|
|
154
158
|
}
|
|
155
|
-
function
|
|
159
|
+
function Z({ feature: e }) {
|
|
156
160
|
let n = {
|
|
157
161
|
title: e.title,
|
|
158
162
|
description: e.description ?? "",
|
|
@@ -165,29 +169,45 @@ function J({ feature: e }) {
|
|
|
165
169
|
kano: e.kano ?? "",
|
|
166
170
|
valueScore: e.valueScore == null ? "" : String(e.valueScore),
|
|
167
171
|
effortScore: e.effortScore == null ? "" : String(e.effortScore)
|
|
168
|
-
},
|
|
172
|
+
}, o = {
|
|
173
|
+
reach: e.reach == null ? "" : String(e.reach),
|
|
174
|
+
impact: e.impact == null ? "" : String(e.impact),
|
|
175
|
+
confidence: e.confidence == null ? "" : String(e.confidence)
|
|
176
|
+
}, [s, m] = y(!1), [h, v] = y(n), [b, S] = y(i), [C, w] = y(o), [E, A] = y(null), [j, M] = T(K, J), N = u(h.businessValue, {
|
|
169
177
|
min: 0,
|
|
170
178
|
max: 100
|
|
171
|
-
}),
|
|
172
|
-
|
|
173
|
-
let a = (e) => e.trim() ? e.trim() : null,
|
|
179
|
+
}), H = h.title.trim() !== "" && !N.invalid && g(b) && _(C) && !M.loading, U = async () => {
|
|
180
|
+
A(null);
|
|
181
|
+
let a = (e) => e.trim() ? e.trim() : null, s = u(b.valueScore, {
|
|
174
182
|
min: 1,
|
|
175
183
|
max: 10
|
|
176
|
-
}), c = u(
|
|
184
|
+
}), c = u(b.effortScore, {
|
|
177
185
|
min: 1,
|
|
178
186
|
max: 10
|
|
179
|
-
}), l = {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
187
|
+
}), l = u(C.reach, {
|
|
188
|
+
min: 1,
|
|
189
|
+
max: 10
|
|
190
|
+
}), d = u(C.impact, {
|
|
191
|
+
min: 1,
|
|
192
|
+
max: 10
|
|
193
|
+
}), f = u(C.confidence, {
|
|
194
|
+
min: 1,
|
|
195
|
+
max: 10
|
|
196
|
+
}), p = {
|
|
197
|
+
title: h.title.trim(),
|
|
198
|
+
description: a(h.description),
|
|
199
|
+
businessValue: N.value ?? null,
|
|
200
|
+
effortEstimate: a(h.effortEstimate),
|
|
201
|
+
projectId: h.projectId || null,
|
|
202
|
+
workItemId: h.workItemId || null,
|
|
203
|
+
moscow: b.moscow || null,
|
|
204
|
+
kano: b.kano || null,
|
|
205
|
+
valueScore: s.value ?? null,
|
|
206
|
+
effortScore: c.value ?? null,
|
|
207
|
+
reach: l.value ?? null,
|
|
208
|
+
impact: d.value ?? null,
|
|
209
|
+
confidence: f.value ?? null
|
|
210
|
+
}, g = {
|
|
191
211
|
title: n.title,
|
|
192
212
|
description: a(n.description),
|
|
193
213
|
businessValue: n.businessValue === "" ? null : Number(n.businessValue),
|
|
@@ -197,295 +217,420 @@ function J({ feature: e }) {
|
|
|
197
217
|
moscow: i.moscow || null,
|
|
198
218
|
kano: i.kano || null,
|
|
199
219
|
valueScore: i.valueScore === "" ? null : Number(i.valueScore),
|
|
200
|
-
effortScore: i.effortScore === "" ? null : Number(i.effortScore)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
220
|
+
effortScore: i.effortScore === "" ? null : Number(i.effortScore),
|
|
221
|
+
reach: o.reach === "" ? null : Number(o.reach),
|
|
222
|
+
impact: o.impact === "" ? null : Number(o.impact),
|
|
223
|
+
confidence: o.confidence === "" ? null : Number(o.confidence)
|
|
224
|
+
}, _ = Object.fromEntries(Object.entries(p).filter(([e, t]) => t !== g[e]));
|
|
225
|
+
if (Object.keys(_).length === 0) {
|
|
226
|
+
m(!1);
|
|
204
227
|
return;
|
|
205
228
|
}
|
|
206
229
|
try {
|
|
207
|
-
await r(
|
|
230
|
+
await r(j({ variables: {
|
|
208
231
|
id: e.id,
|
|
209
|
-
input:
|
|
210
|
-
} })),
|
|
232
|
+
input: _
|
|
233
|
+
} })), m(!1);
|
|
211
234
|
} catch (e) {
|
|
212
|
-
|
|
235
|
+
A(t(e, "The request could not be saved."));
|
|
213
236
|
}
|
|
214
|
-
},
|
|
215
|
-
return /* @__PURE__ */
|
|
216
|
-
open:
|
|
237
|
+
}, W = "text-sm font-medium";
|
|
238
|
+
return /* @__PURE__ */ O(F, {
|
|
239
|
+
open: s,
|
|
217
240
|
onOpenChange: (e) => {
|
|
218
|
-
|
|
241
|
+
m(e), e ? (v(n), S(i), w(o)) : A(null);
|
|
219
242
|
},
|
|
220
|
-
children: [/* @__PURE__ */
|
|
243
|
+
children: [/* @__PURE__ */ D(V, {
|
|
221
244
|
asChild: !0,
|
|
222
|
-
children: /* @__PURE__ */
|
|
245
|
+
children: /* @__PURE__ */ O(k, {
|
|
223
246
|
size: "sm",
|
|
224
247
|
variant: "outline",
|
|
225
248
|
"data-testid": "feature-edit",
|
|
226
|
-
children: [/* @__PURE__ */
|
|
249
|
+
children: [/* @__PURE__ */ D(x, { className: "mr-1 h-4 w-4" }), "Edit"]
|
|
227
250
|
})
|
|
228
|
-
}), /* @__PURE__ */
|
|
251
|
+
}), /* @__PURE__ */ O(I, {
|
|
229
252
|
className: "max-w-lg",
|
|
230
253
|
children: [
|
|
231
|
-
/* @__PURE__ */
|
|
232
|
-
/* @__PURE__ */
|
|
254
|
+
/* @__PURE__ */ O(z, { children: [/* @__PURE__ */ D(B, { children: "Edit feature request" }), /* @__PURE__ */ D(L, { children: "Link the request to the work item that delivers it so releases can show who is waiting on it." })] }),
|
|
255
|
+
/* @__PURE__ */ O("div", {
|
|
233
256
|
className: "space-y-3",
|
|
234
257
|
children: [
|
|
235
|
-
/* @__PURE__ */
|
|
258
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("label", {
|
|
236
259
|
htmlFor: "feature-edit-title",
|
|
237
|
-
className:
|
|
260
|
+
className: W,
|
|
238
261
|
children: "Title"
|
|
239
|
-
}), /* @__PURE__ */
|
|
262
|
+
}), /* @__PURE__ */ D(P, {
|
|
240
263
|
id: "feature-edit-title",
|
|
241
264
|
className: "mt-1",
|
|
242
|
-
value:
|
|
243
|
-
onChange: (e) =>
|
|
244
|
-
...
|
|
265
|
+
value: h.title,
|
|
266
|
+
onChange: (e) => v({
|
|
267
|
+
...h,
|
|
245
268
|
title: e.target.value
|
|
246
269
|
})
|
|
247
270
|
})] }),
|
|
248
|
-
/* @__PURE__ */
|
|
271
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("label", {
|
|
249
272
|
htmlFor: "feature-edit-description",
|
|
250
|
-
className:
|
|
273
|
+
className: W,
|
|
251
274
|
children: "Description"
|
|
252
|
-
}), /* @__PURE__ */
|
|
275
|
+
}), /* @__PURE__ */ D("textarea", {
|
|
253
276
|
id: "feature-edit-description",
|
|
254
277
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[72px]",
|
|
255
|
-
value:
|
|
256
|
-
onChange: (e) =>
|
|
257
|
-
...
|
|
278
|
+
value: h.description,
|
|
279
|
+
onChange: (e) => v({
|
|
280
|
+
...h,
|
|
258
281
|
description: e.target.value
|
|
259
282
|
})
|
|
260
283
|
})] }),
|
|
261
|
-
/* @__PURE__ */
|
|
284
|
+
/* @__PURE__ */ O("div", {
|
|
262
285
|
className: "grid grid-cols-2 gap-3",
|
|
263
|
-
children: [/* @__PURE__ */
|
|
286
|
+
children: [/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("label", {
|
|
264
287
|
htmlFor: "feature-edit-value",
|
|
265
|
-
className:
|
|
288
|
+
className: W,
|
|
266
289
|
children: "Business value (0–100)"
|
|
267
|
-
}), /* @__PURE__ */
|
|
290
|
+
}), /* @__PURE__ */ D(P, {
|
|
268
291
|
id: "feature-edit-value",
|
|
269
292
|
type: "number",
|
|
270
293
|
min: 0,
|
|
271
294
|
max: 100,
|
|
272
295
|
className: "mt-1",
|
|
273
|
-
value:
|
|
274
|
-
"aria-invalid":
|
|
275
|
-
onChange: (e) =>
|
|
276
|
-
...
|
|
296
|
+
value: h.businessValue,
|
|
297
|
+
"aria-invalid": N.invalid,
|
|
298
|
+
onChange: (e) => v({
|
|
299
|
+
...h,
|
|
277
300
|
businessValue: e.target.value
|
|
278
301
|
})
|
|
279
|
-
})] }), /* @__PURE__ */
|
|
302
|
+
})] }), /* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("label", {
|
|
280
303
|
htmlFor: "feature-edit-effort",
|
|
281
|
-
className:
|
|
304
|
+
className: W,
|
|
282
305
|
children: "Effort"
|
|
283
|
-
}), /* @__PURE__ */
|
|
306
|
+
}), /* @__PURE__ */ D(P, {
|
|
284
307
|
id: "feature-edit-effort",
|
|
285
308
|
className: "mt-1",
|
|
286
309
|
placeholder: "e.g. M",
|
|
287
|
-
value:
|
|
288
|
-
onChange: (e) =>
|
|
289
|
-
...
|
|
310
|
+
value: h.effortEstimate,
|
|
311
|
+
onChange: (e) => v({
|
|
312
|
+
...h,
|
|
290
313
|
effortEstimate: e.target.value
|
|
291
314
|
})
|
|
292
315
|
})] })]
|
|
293
316
|
}),
|
|
294
|
-
|
|
295
|
-
/* @__PURE__ */
|
|
317
|
+
N.invalid && /* @__PURE__ */ D(a, { message: "Business value is a whole number from 0 to 100." }),
|
|
318
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("label", {
|
|
296
319
|
htmlFor: "feature-edit-project",
|
|
297
|
-
className:
|
|
320
|
+
className: W,
|
|
298
321
|
children: "Project"
|
|
299
|
-
}), /* @__PURE__ */
|
|
322
|
+
}), /* @__PURE__ */ D("div", {
|
|
300
323
|
className: "mt-1",
|
|
301
|
-
children: /* @__PURE__ */
|
|
324
|
+
children: /* @__PURE__ */ D(c, {
|
|
302
325
|
id: "feature-edit-project",
|
|
303
|
-
value:
|
|
326
|
+
value: h.projectId,
|
|
304
327
|
noneLabel: "No project",
|
|
305
|
-
onChange: (e) =>
|
|
306
|
-
...
|
|
328
|
+
onChange: (e) => v({
|
|
329
|
+
...h,
|
|
307
330
|
projectId: e,
|
|
308
331
|
workItemId: ""
|
|
309
332
|
})
|
|
310
333
|
})
|
|
311
334
|
})] }),
|
|
312
|
-
/* @__PURE__ */
|
|
335
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("label", {
|
|
313
336
|
htmlFor: "feature-edit-workitem",
|
|
314
|
-
className:
|
|
337
|
+
className: W,
|
|
315
338
|
children: "Delivered by work item"
|
|
316
|
-
}), /* @__PURE__ */
|
|
339
|
+
}), /* @__PURE__ */ D("div", {
|
|
317
340
|
className: "mt-1",
|
|
318
|
-
children: /* @__PURE__ */
|
|
341
|
+
children: /* @__PURE__ */ D(l, {
|
|
319
342
|
id: "feature-edit-workitem",
|
|
320
|
-
projectId:
|
|
321
|
-
value:
|
|
322
|
-
onChange: (e) =>
|
|
323
|
-
...
|
|
343
|
+
projectId: h.projectId || void 0,
|
|
344
|
+
value: h.workItemId,
|
|
345
|
+
onChange: (e) => v({
|
|
346
|
+
...h,
|
|
324
347
|
workItemId: e
|
|
325
348
|
})
|
|
326
349
|
})
|
|
327
350
|
})] }),
|
|
328
|
-
/* @__PURE__ */
|
|
351
|
+
/* @__PURE__ */ O("div", {
|
|
329
352
|
className: "border-t pt-3",
|
|
330
353
|
children: [
|
|
331
|
-
/* @__PURE__ */
|
|
332
|
-
className:
|
|
354
|
+
/* @__PURE__ */ D("p", {
|
|
355
|
+
className: W,
|
|
333
356
|
children: "Prioritization"
|
|
334
357
|
}),
|
|
335
|
-
/* @__PURE__ */
|
|
358
|
+
/* @__PURE__ */ O("div", {
|
|
336
359
|
className: "mt-1 flex items-center gap-2",
|
|
337
|
-
children: [/* @__PURE__ */
|
|
360
|
+
children: [/* @__PURE__ */ D("span", {
|
|
338
361
|
className: "text-xs text-muted-foreground",
|
|
339
362
|
children: "Current quadrant:"
|
|
340
|
-
}), /* @__PURE__ */
|
|
363
|
+
}), /* @__PURE__ */ D(f, { quadrant: e.valueEffortQuadrant ?? null })]
|
|
341
364
|
}),
|
|
342
|
-
/* @__PURE__ */
|
|
365
|
+
/* @__PURE__ */ D("div", {
|
|
343
366
|
className: "mt-2",
|
|
344
|
-
children: /* @__PURE__ */
|
|
367
|
+
children: /* @__PURE__ */ D(d, {
|
|
345
368
|
idPrefix: "feature-edit",
|
|
346
|
-
values:
|
|
347
|
-
onChange:
|
|
369
|
+
values: b,
|
|
370
|
+
onChange: S
|
|
348
371
|
})
|
|
372
|
+
}),
|
|
373
|
+
/* @__PURE__ */ O("div", {
|
|
374
|
+
className: "mt-3 border-t pt-3",
|
|
375
|
+
children: [
|
|
376
|
+
/* @__PURE__ */ D("p", {
|
|
377
|
+
className: W,
|
|
378
|
+
children: "RICE"
|
|
379
|
+
}),
|
|
380
|
+
/* @__PURE__ */ O("div", {
|
|
381
|
+
className: "mt-1 flex items-center gap-2",
|
|
382
|
+
children: [/* @__PURE__ */ D("span", {
|
|
383
|
+
className: "text-xs text-muted-foreground",
|
|
384
|
+
children: "Current RICE score:"
|
|
385
|
+
}), /* @__PURE__ */ D("span", {
|
|
386
|
+
className: "text-sm font-medium",
|
|
387
|
+
"data-testid": "feature-edit-rice-score",
|
|
388
|
+
children: e.riceScore == null ? "—" : e.riceScore.toFixed(1)
|
|
389
|
+
})]
|
|
390
|
+
}),
|
|
391
|
+
/* @__PURE__ */ D("div", {
|
|
392
|
+
className: "mt-2",
|
|
393
|
+
children: /* @__PURE__ */ D(p, {
|
|
394
|
+
idPrefix: "feature-edit",
|
|
395
|
+
values: C,
|
|
396
|
+
onChange: w,
|
|
397
|
+
effortScoreMissing: u(b.effortScore, {
|
|
398
|
+
min: 1,
|
|
399
|
+
max: 10
|
|
400
|
+
}).value == null
|
|
401
|
+
})
|
|
402
|
+
})
|
|
403
|
+
]
|
|
349
404
|
})
|
|
350
405
|
]
|
|
351
406
|
}),
|
|
352
|
-
|
|
407
|
+
E && /* @__PURE__ */ D(a, { message: E })
|
|
353
408
|
]
|
|
354
409
|
}),
|
|
355
|
-
/* @__PURE__ */
|
|
410
|
+
/* @__PURE__ */ O(R, { children: [/* @__PURE__ */ D(k, {
|
|
356
411
|
variant: "outline",
|
|
357
|
-
onClick: () =>
|
|
412
|
+
onClick: () => m(!1),
|
|
358
413
|
children: "Cancel"
|
|
359
|
-
}), /* @__PURE__ */
|
|
360
|
-
onClick: () => void
|
|
361
|
-
disabled: !
|
|
362
|
-
children:
|
|
414
|
+
}), /* @__PURE__ */ D(k, {
|
|
415
|
+
onClick: () => void U(),
|
|
416
|
+
disabled: !H,
|
|
417
|
+
children: M.loading ? "Saving…" : "Save"
|
|
363
418
|
})] })
|
|
364
419
|
]
|
|
365
420
|
})]
|
|
366
421
|
});
|
|
367
422
|
}
|
|
368
|
-
function
|
|
423
|
+
function Q({ feature: e }) {
|
|
369
424
|
let n = {
|
|
370
425
|
moscow: e.moscow ?? "",
|
|
371
426
|
kano: e.kano ?? "",
|
|
372
427
|
valueScore: e.valueScore == null ? "" : String(e.valueScore),
|
|
373
428
|
effortScore: e.effortScore == null ? "" : String(e.effortScore)
|
|
374
|
-
},
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
429
|
+
}, i = {
|
|
430
|
+
reach: e.reach == null ? "" : String(e.reach),
|
|
431
|
+
impact: e.impact == null ? "" : String(e.impact),
|
|
432
|
+
confidence: e.confidence == null ? "" : String(e.confidence)
|
|
433
|
+
}, [o, s] = y(!1), [c, l] = y(n), [b, S] = y(i), [C, w] = y(null), [P, F] = T(K, J), I = () => {
|
|
434
|
+
l(n), S(i), w(null), s(!0);
|
|
435
|
+
}, L = async () => {
|
|
436
|
+
w(null);
|
|
437
|
+
let n = u(c.valueScore, {
|
|
379
438
|
min: 1,
|
|
380
439
|
max: 10
|
|
381
|
-
}), i = u(
|
|
440
|
+
}), i = u(c.effortScore, {
|
|
382
441
|
min: 1,
|
|
383
442
|
max: 10
|
|
384
|
-
}), a = {
|
|
385
|
-
|
|
386
|
-
|
|
443
|
+
}), a = u(b.reach, {
|
|
444
|
+
min: 1,
|
|
445
|
+
max: 10
|
|
446
|
+
}), o = u(b.impact, {
|
|
447
|
+
min: 1,
|
|
448
|
+
max: 10
|
|
449
|
+
}), l = u(b.confidence, {
|
|
450
|
+
min: 1,
|
|
451
|
+
max: 10
|
|
452
|
+
}), d = {
|
|
453
|
+
moscow: c.moscow || null,
|
|
454
|
+
kano: c.kano || null,
|
|
387
455
|
valueScore: n.value ?? null,
|
|
388
|
-
effortScore: i.value ?? null
|
|
456
|
+
effortScore: i.value ?? null,
|
|
457
|
+
reach: a.value ?? null,
|
|
458
|
+
impact: o.value ?? null,
|
|
459
|
+
confidence: l.value ?? null
|
|
389
460
|
};
|
|
390
461
|
try {
|
|
391
|
-
await r(
|
|
462
|
+
await r(P({ variables: {
|
|
392
463
|
id: e.id,
|
|
393
|
-
input:
|
|
394
|
-
} })),
|
|
464
|
+
input: d
|
|
465
|
+
} })), s(!1);
|
|
395
466
|
} catch (e) {
|
|
396
|
-
|
|
467
|
+
w(t(e, "The prioritization could not be saved."));
|
|
397
468
|
}
|
|
398
469
|
};
|
|
399
|
-
return /* @__PURE__ */
|
|
470
|
+
return /* @__PURE__ */ O(A, {
|
|
400
471
|
"data-testid": "feature-prioritization-card",
|
|
401
|
-
children: [/* @__PURE__ */
|
|
472
|
+
children: [/* @__PURE__ */ O(M, {
|
|
402
473
|
className: "flex flex-row items-center justify-between gap-2",
|
|
403
|
-
children: [/* @__PURE__ */
|
|
474
|
+
children: [/* @__PURE__ */ D(N, { children: "Prioritization" }), !o && /* @__PURE__ */ O(k, {
|
|
404
475
|
size: "sm",
|
|
405
476
|
variant: "outline",
|
|
406
477
|
"data-testid": "feature-prioritization-edit",
|
|
407
|
-
onClick:
|
|
408
|
-
children: [/* @__PURE__ */
|
|
478
|
+
onClick: I,
|
|
479
|
+
children: [/* @__PURE__ */ D(x, { className: "mr-1 h-4 w-4" }), "Edit"]
|
|
409
480
|
})]
|
|
410
|
-
}), /* @__PURE__ */
|
|
481
|
+
}), /* @__PURE__ */ D(j, {
|
|
411
482
|
className: "space-y-3",
|
|
412
|
-
children:
|
|
413
|
-
/* @__PURE__ */
|
|
483
|
+
children: o ? /* @__PURE__ */ O(E, { children: [
|
|
484
|
+
/* @__PURE__ */ D(d, {
|
|
414
485
|
idPrefix: "feature-prio",
|
|
415
|
-
values:
|
|
416
|
-
onChange:
|
|
486
|
+
values: c,
|
|
487
|
+
onChange: l
|
|
488
|
+
}),
|
|
489
|
+
/* @__PURE__ */ O("div", {
|
|
490
|
+
className: "border-t pt-3",
|
|
491
|
+
children: [/* @__PURE__ */ D("p", {
|
|
492
|
+
className: "text-sm font-medium mb-1",
|
|
493
|
+
children: "RICE"
|
|
494
|
+
}), /* @__PURE__ */ D(p, {
|
|
495
|
+
idPrefix: "feature-prio",
|
|
496
|
+
values: b,
|
|
497
|
+
onChange: S,
|
|
498
|
+
effortScoreMissing: u(c.effortScore, {
|
|
499
|
+
min: 1,
|
|
500
|
+
max: 10
|
|
501
|
+
}).value == null
|
|
502
|
+
})]
|
|
417
503
|
}),
|
|
418
|
-
|
|
419
|
-
/* @__PURE__ */
|
|
504
|
+
C && /* @__PURE__ */ D(a, { message: C }),
|
|
505
|
+
/* @__PURE__ */ O("div", {
|
|
420
506
|
className: "flex justify-end gap-2",
|
|
421
|
-
children: [/* @__PURE__ */
|
|
507
|
+
children: [/* @__PURE__ */ D(k, {
|
|
422
508
|
size: "sm",
|
|
423
509
|
variant: "outline",
|
|
424
|
-
onClick: () =>
|
|
510
|
+
onClick: () => s(!1),
|
|
425
511
|
children: "Cancel"
|
|
426
|
-
}), /* @__PURE__ */
|
|
512
|
+
}), /* @__PURE__ */ D(k, {
|
|
427
513
|
size: "sm",
|
|
428
514
|
"data-testid": "feature-prioritization-save",
|
|
429
|
-
disabled:
|
|
430
|
-
onClick: () => void
|
|
431
|
-
children:
|
|
515
|
+
disabled: F.loading || !g(c) || !_(b),
|
|
516
|
+
onClick: () => void L(),
|
|
517
|
+
children: F.loading ? "Saving…" : "Save"
|
|
432
518
|
})]
|
|
433
519
|
})
|
|
434
|
-
] }) : /* @__PURE__ */
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
className: "
|
|
447
|
-
children: "
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
className: "
|
|
457
|
-
children: "
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
className: "
|
|
467
|
-
children: "
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
className: "
|
|
477
|
-
children: "
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
520
|
+
] }) : /* @__PURE__ */ O(E, { children: [
|
|
521
|
+
/* @__PURE__ */ O("div", {
|
|
522
|
+
className: "flex items-center gap-2",
|
|
523
|
+
children: [/* @__PURE__ */ D("span", {
|
|
524
|
+
className: "text-xs text-muted-foreground",
|
|
525
|
+
children: "Quadrant:"
|
|
526
|
+
}), /* @__PURE__ */ D(f, { quadrant: e.valueEffortQuadrant ?? null })]
|
|
527
|
+
}),
|
|
528
|
+
/* @__PURE__ */ O("div", {
|
|
529
|
+
className: "grid grid-cols-2 gap-2 text-sm",
|
|
530
|
+
children: [
|
|
531
|
+
/* @__PURE__ */ O("div", {
|
|
532
|
+
className: "flex justify-between",
|
|
533
|
+
children: [/* @__PURE__ */ D("span", {
|
|
534
|
+
className: "text-muted-foreground",
|
|
535
|
+
children: "MoSCoW"
|
|
536
|
+
}), /* @__PURE__ */ D("span", {
|
|
537
|
+
className: "font-medium",
|
|
538
|
+
children: h(e.moscow)
|
|
539
|
+
})]
|
|
540
|
+
}),
|
|
541
|
+
/* @__PURE__ */ O("div", {
|
|
542
|
+
className: "flex justify-between",
|
|
543
|
+
children: [/* @__PURE__ */ D("span", {
|
|
544
|
+
className: "text-muted-foreground",
|
|
545
|
+
children: "Kano"
|
|
546
|
+
}), /* @__PURE__ */ D("span", {
|
|
547
|
+
className: "font-medium",
|
|
548
|
+
children: m(e.kano)
|
|
549
|
+
})]
|
|
550
|
+
}),
|
|
551
|
+
/* @__PURE__ */ O("div", {
|
|
552
|
+
className: "flex justify-between",
|
|
553
|
+
children: [/* @__PURE__ */ D("span", {
|
|
554
|
+
className: "text-muted-foreground",
|
|
555
|
+
children: "Value score"
|
|
556
|
+
}), /* @__PURE__ */ D("span", {
|
|
557
|
+
className: "font-medium",
|
|
558
|
+
children: e.valueScore ?? "Not set"
|
|
559
|
+
})]
|
|
560
|
+
}),
|
|
561
|
+
/* @__PURE__ */ O("div", {
|
|
562
|
+
className: "flex justify-between",
|
|
563
|
+
children: [/* @__PURE__ */ D("span", {
|
|
564
|
+
className: "text-muted-foreground",
|
|
565
|
+
children: "Effort score"
|
|
566
|
+
}), /* @__PURE__ */ D("span", {
|
|
567
|
+
className: "font-medium",
|
|
568
|
+
children: e.effortScore ?? "Not set"
|
|
569
|
+
})]
|
|
570
|
+
})
|
|
571
|
+
]
|
|
572
|
+
}),
|
|
573
|
+
/* @__PURE__ */ O("div", {
|
|
574
|
+
className: "border-t pt-3",
|
|
575
|
+
children: [
|
|
576
|
+
/* @__PURE__ */ O("div", {
|
|
577
|
+
className: "flex items-center justify-between",
|
|
578
|
+
children: [/* @__PURE__ */ D("span", {
|
|
579
|
+
className: "text-xs text-muted-foreground",
|
|
580
|
+
children: "RICE score"
|
|
581
|
+
}), /* @__PURE__ */ D("span", {
|
|
582
|
+
className: "font-medium",
|
|
583
|
+
"data-testid": "feature-rice-score",
|
|
584
|
+
children: e.riceScore == null ? "—" : e.riceScore.toFixed(1)
|
|
585
|
+
})]
|
|
586
|
+
}),
|
|
587
|
+
e.riceScore == null && /* @__PURE__ */ D("p", {
|
|
588
|
+
className: "text-xs text-muted-foreground mt-0.5",
|
|
589
|
+
"data-testid": "feature-rice-missing-hint",
|
|
590
|
+
children: v(e)
|
|
591
|
+
}),
|
|
592
|
+
/* @__PURE__ */ O("div", {
|
|
593
|
+
className: "grid grid-cols-3 gap-2 text-sm mt-2",
|
|
594
|
+
children: [
|
|
595
|
+
/* @__PURE__ */ O("div", {
|
|
596
|
+
className: "flex justify-between",
|
|
597
|
+
children: [/* @__PURE__ */ D("span", {
|
|
598
|
+
className: "text-muted-foreground",
|
|
599
|
+
children: "Reach"
|
|
600
|
+
}), /* @__PURE__ */ D("span", {
|
|
601
|
+
className: "font-medium",
|
|
602
|
+
children: e.reach ?? "Not set"
|
|
603
|
+
})]
|
|
604
|
+
}),
|
|
605
|
+
/* @__PURE__ */ O("div", {
|
|
606
|
+
className: "flex justify-between",
|
|
607
|
+
children: [/* @__PURE__ */ D("span", {
|
|
608
|
+
className: "text-muted-foreground",
|
|
609
|
+
children: "Impact"
|
|
610
|
+
}), /* @__PURE__ */ D("span", {
|
|
611
|
+
className: "font-medium",
|
|
612
|
+
children: e.impact ?? "Not set"
|
|
613
|
+
})]
|
|
614
|
+
}),
|
|
615
|
+
/* @__PURE__ */ O("div", {
|
|
616
|
+
className: "flex justify-between",
|
|
617
|
+
children: [/* @__PURE__ */ D("span", {
|
|
618
|
+
className: "text-muted-foreground",
|
|
619
|
+
children: "Confidence"
|
|
620
|
+
}), /* @__PURE__ */ D("span", {
|
|
621
|
+
className: "font-medium",
|
|
622
|
+
children: e.confidence ?? "Not set"
|
|
623
|
+
})]
|
|
624
|
+
})
|
|
625
|
+
]
|
|
626
|
+
})
|
|
627
|
+
]
|
|
628
|
+
})
|
|
629
|
+
] })
|
|
485
630
|
})]
|
|
486
631
|
});
|
|
487
632
|
}
|
|
488
633
|
//#endregion
|
|
489
|
-
export {
|
|
634
|
+
export { X as FeatureHeaderActions, Q as FeaturePrioritizationCard, Y as FeatureVoteButton };
|
|
490
635
|
|
|
491
636
|
//# sourceMappingURL=FeatureControls.js.map
|