@burdenoff/microfe-planmagnet 2026.930.23 → 2026.930.25

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.
Files changed (111) hide show
  1. package/dist/index.js +6 -5
  2. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  3. package/dist/planmagnet/PlanMagnetRoot.js +154 -147
  4. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  5. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  6. package/dist/planmagnet/PlanMagnetRoutes.js +66 -62
  7. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  8. package/dist/planmagnet/comments/CommentThread.d.ts +8 -1
  9. package/dist/planmagnet/comments/CommentThread.d.ts.map +1 -1
  10. package/dist/planmagnet/comments/CommentThread.js +188 -181
  11. package/dist/planmagnet/comments/CommentThread.js.map +1 -1
  12. package/dist/planmagnet/comments/TargetComments.d.ts +10 -2
  13. package/dist/planmagnet/comments/TargetComments.d.ts.map +1 -1
  14. package/dist/planmagnet/comments/TargetComments.js +10 -8
  15. package/dist/planmagnet/comments/TargetComments.js.map +1 -1
  16. package/dist/planmagnet/comments/WorkItemComments.d.ts +7 -1
  17. package/dist/planmagnet/comments/WorkItemComments.d.ts.map +1 -1
  18. package/dist/planmagnet/comments/WorkItemComments.js +5 -4
  19. package/dist/planmagnet/comments/WorkItemComments.js.map +1 -1
  20. package/dist/planmagnet/controls/FeatureControls.d.ts +11 -0
  21. package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
  22. package/dist/planmagnet/controls/FeatureControls.js +305 -135
  23. package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
  24. package/dist/planmagnet/controls/Pickers.d.ts +18 -0
  25. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  26. package/dist/planmagnet/controls/Pickers.js +78 -1
  27. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  28. package/dist/planmagnet/controls/PrioritizationControls.d.ts +72 -0
  29. package/dist/planmagnet/controls/PrioritizationControls.d.ts.map +1 -0
  30. package/dist/planmagnet/controls/PrioritizationControls.js +246 -0
  31. package/dist/planmagnet/controls/PrioritizationControls.js.map +1 -0
  32. package/dist/planmagnet/discussion/WorkItemDiscussionPanel.d.ts +8 -0
  33. package/dist/planmagnet/discussion/WorkItemDiscussionPanel.d.ts.map +1 -0
  34. package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js +217 -0
  35. package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js.map +1 -0
  36. package/dist/planmagnet/docs/DocDiffView.d.ts +26 -0
  37. package/dist/planmagnet/docs/DocDiffView.d.ts.map +1 -0
  38. package/dist/planmagnet/docs/DocDiffView.js +52 -0
  39. package/dist/planmagnet/docs/DocDiffView.js.map +1 -0
  40. package/dist/planmagnet/docs/DocSuggestionsPanel.d.ts +13 -0
  41. package/dist/planmagnet/docs/DocSuggestionsPanel.d.ts.map +1 -0
  42. package/dist/planmagnet/docs/DocSuggestionsPanel.js +308 -0
  43. package/dist/planmagnet/docs/DocSuggestionsPanel.js.map +1 -0
  44. package/dist/planmagnet/docs/DocVersionCompare.d.ts +7 -0
  45. package/dist/planmagnet/docs/DocVersionCompare.d.ts.map +1 -0
  46. package/dist/planmagnet/docs/DocVersionCompare.js +105 -0
  47. package/dist/planmagnet/docs/DocVersionCompare.js.map +1 -0
  48. package/dist/planmagnet/hooks/usePresence.d.ts +39 -0
  49. package/dist/planmagnet/hooks/usePresence.d.ts.map +1 -0
  50. package/dist/planmagnet/hooks/usePresence.js +146 -0
  51. package/dist/planmagnet/hooks/usePresence.js.map +1 -0
  52. package/dist/planmagnet/index.d.ts +1 -0
  53. package/dist/planmagnet/index.d.ts.map +1 -1
  54. package/dist/planmagnet/index.js +1 -0
  55. package/dist/planmagnet/links/CodeLinksPanel.d.ts +22 -0
  56. package/dist/planmagnet/links/CodeLinksPanel.d.ts.map +1 -0
  57. package/dist/planmagnet/links/CodeLinksPanel.js +94 -0
  58. package/dist/planmagnet/links/CodeLinksPanel.js.map +1 -0
  59. package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
  60. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +488 -217
  61. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  62. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  63. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +131 -125
  64. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  65. package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
  66. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +183 -99
  67. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
  68. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
  69. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +113 -97
  70. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
  71. package/dist/planmagnet/pages/ProductsPrioritizationPagePage.d.ts +2 -0
  72. package/dist/planmagnet/pages/ProductsPrioritizationPagePage.d.ts.map +1 -0
  73. package/dist/planmagnet/pages/ProductsPrioritizationPagePage.js +363 -0
  74. package/dist/planmagnet/pages/ProductsPrioritizationPagePage.js.map +1 -0
  75. package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
  76. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +96 -79
  77. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
  78. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
  79. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +144 -128
  80. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
  81. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  82. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +205 -196
  83. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  84. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  85. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +194 -160
  86. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  87. package/dist/planmagnet/presence/PresenceAvatars.d.ts +16 -0
  88. package/dist/planmagnet/presence/PresenceAvatars.d.ts.map +1 -0
  89. package/dist/planmagnet/presence/PresenceAvatars.js +56 -0
  90. package/dist/planmagnet/presence/PresenceAvatars.js.map +1 -0
  91. package/dist/planmagnet/product/ProductControls.d.ts +33 -0
  92. package/dist/planmagnet/product/ProductControls.d.ts.map +1 -1
  93. package/dist/planmagnet/product/ProductControls.js +593 -268
  94. package/dist/planmagnet/product/ProductControls.js.map +1 -1
  95. package/dist/planmagnet/product/routes.d.ts +10 -0
  96. package/dist/planmagnet/product/routes.d.ts.map +1 -0
  97. package/dist/planmagnet/product/routes.js +6 -0
  98. package/dist/planmagnet/product/routes.js.map +1 -0
  99. package/dist/planmagnet/roadmaps/RoadmapControls.d.ts +10 -0
  100. package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -1
  101. package/dist/planmagnet/roadmaps/RoadmapControls.js +235 -184
  102. package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -1
  103. package/dist/planmagnet/utils/graphqlErrors.d.ts +6 -0
  104. package/dist/planmagnet/utils/graphqlErrors.d.ts.map +1 -1
  105. package/dist/planmagnet/utils/graphqlErrors.js +5 -2
  106. package/dist/planmagnet/utils/graphqlErrors.js.map +1 -1
  107. package/dist/planmagnet/utils/lineDiff.d.ts +21 -0
  108. package/dist/planmagnet/utils/lineDiff.d.ts.map +1 -0
  109. package/dist/planmagnet/utils/lineDiff.js +36 -0
  110. package/dist/planmagnet/utils/lineDiff.js.map +1 -0
  111. package/package.json +1 -1
@@ -2,17 +2,19 @@ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
2
  import { LEAVES_PAGE_CONTEXT as t, throwOnError as n } from "../utils/mutationResult.js";
3
3
  import { ConfirmButton as r, ErrorLine as i } from "./ConfirmButton.js";
4
4
  import { enumLabel as a } from "./WorkItemControls.js";
5
- import { detailPath as o } from "../utils/rowNavigation.js";
6
- import { ProjectSelect as s, WorkItemSearchSelect as c } from "./Pickers.js";
7
- import { parseIntField as l } from "../utils/formValidation.js";
8
- import { useState as u } from "react";
9
- import { BarChart3 as d, Pencil as f, ThumbsUp as p, Trash2 as m } from "lucide-react";
10
- import { gql as h } from "@apollo/client";
11
- import { useMutation as g } from "@apollo/client/react";
12
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
13
- import { Button as y, Input as b, ResponsiveDialog as x, ResponsiveDialogContent as S, ResponsiveDialogDescription as C, ResponsiveDialogFooter as w, ResponsiveDialogHeader as T, ResponsiveDialogTitle as E, ResponsiveDialogTrigger as D } from "@burdenoff/fe-libs/ui";
5
+ import { mutationErrorMessage as o } from "../utils/graphqlErrors.js";
6
+ import { detailPath as s } from "../utils/rowNavigation.js";
7
+ import { ProjectSelect as c, WorkItemSearchSelect as l } from "./Pickers.js";
8
+ import { parseIntField as u } from "../utils/formValidation.js";
9
+ import { PrioritizationScoreFields as d, QuadrantBadge as f, kanoLabel as p, moscowLabel as m, prioritizationScoresValid as h } from "./PrioritizationControls.js";
10
+ import { useState as g } from "react";
11
+ import { BarChart3 as _, Pencil as v, ThumbsUp as y, Trash2 as b } from "lucide-react";
12
+ import { gql as x } from "@apollo/client";
13
+ import { useMutation as S } from "@apollo/client/react";
14
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
15
+ import { Button as E, Card as D, CardContent as O, CardHeader as k, CardTitle as A, Input as j, ResponsiveDialog as M, ResponsiveDialogContent as N, ResponsiveDialogDescription as P, ResponsiveDialogFooter as F, ResponsiveDialogHeader as I, ResponsiveDialogTitle as L, ResponsiveDialogTrigger as R } from "@burdenoff/fe-libs/ui";
14
16
  //#region src/planmagnet/controls/FeatureControls.tsx
15
- var O = [
17
+ var z = [
16
18
  "SUBMITTED",
17
19
  "UNDER_REVIEW",
18
20
  "PLANNED",
@@ -20,7 +22,7 @@ var O = [
20
22
  "COMPLETED",
21
23
  "DECLINED",
22
24
  "DUPLICATE"
23
- ], k = [
25
+ ], B = [
24
26
  "GetFeatureRequest",
25
27
  "ListFeatureRequests",
26
28
  "ListFeatureRequestsForProduct",
@@ -28,17 +30,17 @@ var O = [
28
30
  "ListAllFeaturesAnalytics",
29
31
  "GetFeatureRequestAnalytics",
30
32
  "ReleaseCustomerRequests"
31
- ], A = h`
33
+ ], V = x`
32
34
  mutation FeatureControlsVote($id: ID!) {
33
35
  planmagnetVoteOnFeature(featureRequestId: $id) {
34
36
  id
35
37
  }
36
38
  }
37
- `, j = h`
39
+ `, H = x`
38
40
  mutation FeatureControlsUnvote($id: ID!) {
39
41
  planmagnetRemoveFeatureVote(featureRequestId: $id)
40
42
  }
41
- `, M = h`
43
+ `, U = x`
42
44
  mutation FeatureControlsUpdate($id: ID!, $input: PlanmagnetUpdateFeatureRequestInput!) {
43
45
  planmagnetUpdateFeatureRequest(id: $id, input: $input) {
44
46
  id
@@ -49,18 +51,23 @@ var O = [
49
51
  effortEstimate
50
52
  projectId
51
53
  workItemId
54
+ moscow
55
+ kano
56
+ valueScore
57
+ effortScore
58
+ valueEffortQuadrant
52
59
  }
53
60
  }
54
- `, N = h`
61
+ `, W = x`
55
62
  mutation FeatureControlsDelete($id: ID!) {
56
63
  planmagnetDeleteFeatureRequest(id: $id)
57
64
  }
58
- `, P = {
59
- refetchQueries: k,
65
+ `, G = {
66
+ refetchQueries: B,
60
67
  awaitRefetchQueries: !0
61
68
  };
62
- function F({ featureId: e, voted: t }) {
63
- let [r, a] = g(A, P), [o, s] = g(j, P), [c, l] = u(null), d = a.loading || s.loading, f = async () => {
69
+ function K({ featureId: e, voted: t }) {
70
+ let [r, a] = S(V, G), [o, s] = S(H, G), [c, l] = g(null), u = a.loading || s.loading, d = async () => {
64
71
  l(null);
65
72
  try {
66
73
  await n((t ? o : r)({ variables: { id: e } }));
@@ -68,84 +75,84 @@ function F({ featureId: e, voted: t }) {
68
75
  l(e instanceof Error ? e.message : "Your vote could not be saved.");
69
76
  }
70
77
  };
71
- return /* @__PURE__ */ v("div", {
78
+ return /* @__PURE__ */ T("div", {
72
79
  className: "flex flex-col items-end gap-1",
73
- children: [/* @__PURE__ */ v(y, {
80
+ children: [/* @__PURE__ */ T(E, {
74
81
  size: "sm",
75
82
  variant: t ? "default" : "outline",
76
83
  "data-testid": "feature-vote",
77
84
  "aria-pressed": t,
78
- disabled: d,
79
- onClick: () => void f(),
80
- children: [/* @__PURE__ */ _(p, { className: "mr-1 h-4 w-4" }), t ? "Voted" : "Vote"]
81
- }), c && /* @__PURE__ */ _(i, { message: c })]
85
+ disabled: u,
86
+ onClick: () => void d(),
87
+ children: [/* @__PURE__ */ w(y, { className: "mr-1 h-4 w-4" }), t ? "Voted" : "Vote"]
88
+ }), c && /* @__PURE__ */ w(i, { message: c })]
82
89
  });
83
90
  }
84
- function I({ feature: s }) {
85
- let c = e(), [l, f] = g(M, P), [p, h] = g(N, {
86
- refetchQueries: k.filter((e) => e !== "GetFeatureRequest"),
91
+ function q({ feature: o }) {
92
+ let c = e(), [l, u] = S(U, G), [d, f] = S(W, {
93
+ refetchQueries: B.filter((e) => e !== "GetFeatureRequest"),
87
94
  context: t
88
- }), [b, x] = u(null), S = f.loading || h.loading, C = O.includes(s.status) ? O : [s.status, ...O], w = async (e) => {
89
- x(null);
95
+ }), [p, m] = g(null), h = u.loading || f.loading, v = z.includes(o.status) ? z : [o.status, ...z], y = async (e) => {
96
+ m(null);
90
97
  try {
91
98
  await n(l({ variables: {
92
- id: s.id,
99
+ id: o.id,
93
100
  input: { status: e }
94
101
  } }));
95
102
  } catch (e) {
96
- x(e instanceof Error ? e.message : "The status could not be changed.");
103
+ m(e instanceof Error ? e.message : "The status could not be changed.");
97
104
  }
98
- }, T = async () => {
99
- x(null);
105
+ }, x = async () => {
106
+ m(null);
100
107
  try {
101
- await n(p({ variables: { id: s.id } })), c("/products/features-page");
108
+ await n(d({ variables: { id: o.id } })), c("/products/features-page");
102
109
  } catch (e) {
103
- x(e instanceof Error ? e.message : "The request could not be deleted.");
110
+ m(e instanceof Error ? e.message : "The request could not be deleted.");
104
111
  }
105
112
  };
106
- return /* @__PURE__ */ v("div", {
113
+ return /* @__PURE__ */ T("div", {
107
114
  className: "flex flex-col items-end gap-2",
108
- children: [/* @__PURE__ */ v("div", {
115
+ children: [/* @__PURE__ */ T("div", {
109
116
  className: "flex flex-wrap items-center justify-end gap-2",
110
117
  children: [
111
- /* @__PURE__ */ _("select", {
118
+ /* @__PURE__ */ w("select", {
112
119
  "aria-label": "Status",
113
120
  "data-testid": "feature-status",
114
121
  className: "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60",
115
- value: s.status,
116
- disabled: S,
122
+ value: o.status,
123
+ disabled: h,
117
124
  onChange: (e) => {
118
- e.target.value !== s.status && w(e.target.value);
125
+ e.target.value !== o.status && y(e.target.value);
119
126
  },
120
- children: C.map((e) => /* @__PURE__ */ _("option", {
127
+ children: v.map((e) => /* @__PURE__ */ w("option", {
121
128
  value: e,
122
129
  children: a(e)
123
130
  }, e))
124
131
  }),
125
- /* @__PURE__ */ _(L, { feature: s }),
126
- /* @__PURE__ */ v(y, {
132
+ /* @__PURE__ */ w(J, { feature: o }),
133
+ /* @__PURE__ */ T(E, {
127
134
  size: "sm",
128
135
  variant: "outline",
129
136
  "data-testid": "feature-analytics",
130
- onClick: () => c(o("/products/feature-analytics-page", s.id)),
131
- children: [/* @__PURE__ */ _(d, { className: "mr-1 h-4 w-4" }), "Analytics"]
137
+ onClick: () => c(s("/products/feature-analytics-page", o.id)),
138
+ children: [/* @__PURE__ */ w(_, { className: "mr-1 h-4 w-4" }), "Analytics"]
132
139
  }),
133
- /* @__PURE__ */ _(r, {
140
+ /* @__PURE__ */ w(r, {
134
141
  label: "Delete",
135
142
  variant: "outline",
136
- icon: /* @__PURE__ */ _(m, { className: "mr-1 h-4 w-4" }),
137
- title: `Delete "${s.title}"?`,
143
+ icon: /* @__PURE__ */ w(b, { className: "mr-1 h-4 w-4" }),
144
+ title: `Delete "${o.title}"?`,
138
145
  description: "The request and its votes are deleted. This cannot be undone here.",
139
146
  confirmLabel: "Delete request",
140
147
  destructive: !0,
141
- disabled: S,
142
- onConfirm: () => void T()
148
+ disabled: h,
149
+ onConfirm: () => void x()
143
150
  })
144
151
  ]
145
- }), b && /* @__PURE__ */ _(i, { message: b })]
152
+ }), p && /* @__PURE__ */ w(i, { message: p })]
146
153
  });
147
154
  }
148
- function L({ feature: e }) {
155
+ function J({ feature: e }) {
149
156
  let t = {
150
157
  title: e.title,
151
158
  description: e.description ?? "",
@@ -153,169 +160,332 @@ function L({ feature: e }) {
153
160
  effortEstimate: e.effortEstimate ?? "",
154
161
  projectId: e.projectId ?? "",
155
162
  workItemId: e.workItemId ?? ""
156
- }, [r, a] = u(!1), [o, d] = u(t), [p, m] = u(null), [h, O] = g(M, P), k = l(o.businessValue, {
163
+ }, r = {
164
+ moscow: e.moscow ?? "",
165
+ kano: e.kano ?? "",
166
+ valueScore: e.valueScore == null ? "" : String(e.valueScore),
167
+ effortScore: e.effortScore == null ? "" : String(e.effortScore)
168
+ }, [a, s] = g(!1), [p, m] = g(t), [_, y] = g(r), [b, x] = g(null), [C, D] = S(U, G), O = u(p.businessValue, {
157
169
  min: 0,
158
170
  max: 100
159
- }), A = o.title.trim() !== "" && !k.invalid && !O.loading, j = async () => {
160
- m(null);
161
- let r = (e) => e.trim() ? e.trim() : null, i = {
162
- title: o.title.trim(),
163
- description: r(o.description),
164
- businessValue: k.value ?? null,
165
- effortEstimate: r(o.effortEstimate),
166
- projectId: o.projectId || null,
167
- workItemId: o.workItemId || null
168
- }, s = {
171
+ }), k = p.title.trim() !== "" && !O.invalid && h(_) && !D.loading, A = async () => {
172
+ x(null);
173
+ let i = (e) => e.trim() ? e.trim() : null, a = u(_.valueScore, {
174
+ min: 1,
175
+ max: 10
176
+ }), c = u(_.effortScore, {
177
+ min: 1,
178
+ max: 10
179
+ }), l = {
180
+ title: p.title.trim(),
181
+ description: i(p.description),
182
+ businessValue: O.value ?? null,
183
+ effortEstimate: i(p.effortEstimate),
184
+ projectId: p.projectId || null,
185
+ workItemId: p.workItemId || null,
186
+ moscow: _.moscow || null,
187
+ kano: _.kano || null,
188
+ valueScore: a.value ?? null,
189
+ effortScore: c.value ?? null
190
+ }, d = {
169
191
  title: t.title,
170
- description: r(t.description),
192
+ description: i(t.description),
171
193
  businessValue: t.businessValue === "" ? null : Number(t.businessValue),
172
- effortEstimate: r(t.effortEstimate),
194
+ effortEstimate: i(t.effortEstimate),
173
195
  projectId: t.projectId || null,
174
- workItemId: t.workItemId || null
175
- }, c = Object.fromEntries(Object.entries(i).filter(([e, t]) => t !== s[e]));
176
- if (Object.keys(c).length === 0) {
177
- a(!1);
196
+ workItemId: t.workItemId || null,
197
+ moscow: r.moscow || null,
198
+ kano: r.kano || null,
199
+ valueScore: r.valueScore === "" ? null : Number(r.valueScore),
200
+ effortScore: r.effortScore === "" ? null : Number(r.effortScore)
201
+ }, f = Object.fromEntries(Object.entries(l).filter(([e, t]) => t !== d[e]));
202
+ if (Object.keys(f).length === 0) {
203
+ s(!1);
178
204
  return;
179
205
  }
180
206
  try {
181
- await n(h({ variables: {
207
+ await n(C({ variables: {
182
208
  id: e.id,
183
- input: c
184
- } })), a(!1);
209
+ input: f
210
+ } })), s(!1);
185
211
  } catch (e) {
186
- m(e instanceof Error ? e.message : "The request could not be saved.");
212
+ x(o(e, "The request could not be saved."));
187
213
  }
188
- }, N = "text-sm font-medium";
189
- return /* @__PURE__ */ v(x, {
190
- open: r,
214
+ }, z = "text-sm font-medium";
215
+ return /* @__PURE__ */ T(M, {
216
+ open: a,
191
217
  onOpenChange: (e) => {
192
- a(e), e ? d(t) : m(null);
218
+ s(e), e ? (m(t), y(r)) : x(null);
193
219
  },
194
- children: [/* @__PURE__ */ _(D, {
220
+ children: [/* @__PURE__ */ w(R, {
195
221
  asChild: !0,
196
- children: /* @__PURE__ */ v(y, {
222
+ children: /* @__PURE__ */ T(E, {
197
223
  size: "sm",
198
224
  variant: "outline",
199
225
  "data-testid": "feature-edit",
200
- children: [/* @__PURE__ */ _(f, { className: "mr-1 h-4 w-4" }), "Edit"]
226
+ children: [/* @__PURE__ */ w(v, { className: "mr-1 h-4 w-4" }), "Edit"]
201
227
  })
202
- }), /* @__PURE__ */ v(S, {
228
+ }), /* @__PURE__ */ T(N, {
203
229
  className: "max-w-lg",
204
230
  children: [
205
- /* @__PURE__ */ v(T, { children: [/* @__PURE__ */ _(E, { children: "Edit feature request" }), /* @__PURE__ */ _(C, { children: "Link the request to the work item that delivers it so releases can show who is waiting on it." })] }),
206
- /* @__PURE__ */ v("div", {
231
+ /* @__PURE__ */ T(I, { children: [/* @__PURE__ */ w(L, { children: "Edit feature request" }), /* @__PURE__ */ w(P, { children: "Link the request to the work item that delivers it so releases can show who is waiting on it." })] }),
232
+ /* @__PURE__ */ T("div", {
207
233
  className: "space-y-3",
208
234
  children: [
209
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
235
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
210
236
  htmlFor: "feature-edit-title",
211
- className: N,
237
+ className: z,
212
238
  children: "Title"
213
- }), /* @__PURE__ */ _(b, {
239
+ }), /* @__PURE__ */ w(j, {
214
240
  id: "feature-edit-title",
215
241
  className: "mt-1",
216
- value: o.title,
217
- onChange: (e) => d({
218
- ...o,
242
+ value: p.title,
243
+ onChange: (e) => m({
244
+ ...p,
219
245
  title: e.target.value
220
246
  })
221
247
  })] }),
222
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
248
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
223
249
  htmlFor: "feature-edit-description",
224
- className: N,
250
+ className: z,
225
251
  children: "Description"
226
- }), /* @__PURE__ */ _("textarea", {
252
+ }), /* @__PURE__ */ w("textarea", {
227
253
  id: "feature-edit-description",
228
254
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[72px]",
229
- value: o.description,
230
- onChange: (e) => d({
231
- ...o,
255
+ value: p.description,
256
+ onChange: (e) => m({
257
+ ...p,
232
258
  description: e.target.value
233
259
  })
234
260
  })] }),
235
- /* @__PURE__ */ v("div", {
261
+ /* @__PURE__ */ T("div", {
236
262
  className: "grid grid-cols-2 gap-3",
237
- children: [/* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
263
+ children: [/* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
238
264
  htmlFor: "feature-edit-value",
239
- className: N,
265
+ className: z,
240
266
  children: "Business value (0–100)"
241
- }), /* @__PURE__ */ _(b, {
267
+ }), /* @__PURE__ */ w(j, {
242
268
  id: "feature-edit-value",
243
269
  type: "number",
244
270
  min: 0,
245
271
  max: 100,
246
272
  className: "mt-1",
247
- value: o.businessValue,
248
- "aria-invalid": k.invalid,
249
- onChange: (e) => d({
250
- ...o,
273
+ value: p.businessValue,
274
+ "aria-invalid": O.invalid,
275
+ onChange: (e) => m({
276
+ ...p,
251
277
  businessValue: e.target.value
252
278
  })
253
- })] }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
279
+ })] }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
254
280
  htmlFor: "feature-edit-effort",
255
- className: N,
281
+ className: z,
256
282
  children: "Effort"
257
- }), /* @__PURE__ */ _(b, {
283
+ }), /* @__PURE__ */ w(j, {
258
284
  id: "feature-edit-effort",
259
285
  className: "mt-1",
260
286
  placeholder: "e.g. M",
261
- value: o.effortEstimate,
262
- onChange: (e) => d({
263
- ...o,
287
+ value: p.effortEstimate,
288
+ onChange: (e) => m({
289
+ ...p,
264
290
  effortEstimate: e.target.value
265
291
  })
266
292
  })] })]
267
293
  }),
268
- k.invalid && /* @__PURE__ */ _(i, { message: "Business value is a whole number from 0 to 100." }),
269
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
294
+ O.invalid && /* @__PURE__ */ w(i, { message: "Business value is a whole number from 0 to 100." }),
295
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
270
296
  htmlFor: "feature-edit-project",
271
- className: N,
297
+ className: z,
272
298
  children: "Project"
273
- }), /* @__PURE__ */ _("div", {
299
+ }), /* @__PURE__ */ w("div", {
274
300
  className: "mt-1",
275
- children: /* @__PURE__ */ _(s, {
301
+ children: /* @__PURE__ */ w(c, {
276
302
  id: "feature-edit-project",
277
- value: o.projectId,
303
+ value: p.projectId,
278
304
  noneLabel: "No project",
279
- onChange: (e) => d({
280
- ...o,
305
+ onChange: (e) => m({
306
+ ...p,
281
307
  projectId: e,
282
308
  workItemId: ""
283
309
  })
284
310
  })
285
311
  })] }),
286
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
312
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
287
313
  htmlFor: "feature-edit-workitem",
288
- className: N,
314
+ className: z,
289
315
  children: "Delivered by work item"
290
- }), /* @__PURE__ */ _("div", {
316
+ }), /* @__PURE__ */ w("div", {
291
317
  className: "mt-1",
292
- children: /* @__PURE__ */ _(c, {
318
+ children: /* @__PURE__ */ w(l, {
293
319
  id: "feature-edit-workitem",
294
- projectId: o.projectId || void 0,
295
- value: o.workItemId,
296
- onChange: (e) => d({
297
- ...o,
320
+ projectId: p.projectId || void 0,
321
+ value: p.workItemId,
322
+ onChange: (e) => m({
323
+ ...p,
298
324
  workItemId: e
299
325
  })
300
326
  })
301
327
  })] }),
302
- p && /* @__PURE__ */ _(i, { message: p })
328
+ /* @__PURE__ */ T("div", {
329
+ className: "border-t pt-3",
330
+ children: [
331
+ /* @__PURE__ */ w("p", {
332
+ className: z,
333
+ children: "Prioritization"
334
+ }),
335
+ /* @__PURE__ */ T("div", {
336
+ className: "mt-1 flex items-center gap-2",
337
+ children: [/* @__PURE__ */ w("span", {
338
+ className: "text-xs text-muted-foreground",
339
+ children: "Current quadrant:"
340
+ }), /* @__PURE__ */ w(f, { quadrant: e.valueEffortQuadrant ?? null })]
341
+ }),
342
+ /* @__PURE__ */ w("div", {
343
+ className: "mt-2",
344
+ children: /* @__PURE__ */ w(d, {
345
+ idPrefix: "feature-edit",
346
+ values: _,
347
+ onChange: y
348
+ })
349
+ })
350
+ ]
351
+ }),
352
+ b && /* @__PURE__ */ w(i, { message: b })
303
353
  ]
304
354
  }),
305
- /* @__PURE__ */ v(w, { children: [/* @__PURE__ */ _(y, {
355
+ /* @__PURE__ */ T(F, { children: [/* @__PURE__ */ w(E, {
306
356
  variant: "outline",
307
- onClick: () => a(!1),
357
+ onClick: () => s(!1),
308
358
  children: "Cancel"
309
- }), /* @__PURE__ */ _(y, {
310
- onClick: () => void j(),
311
- disabled: !A,
312
- children: O.loading ? "Saving…" : "Save"
359
+ }), /* @__PURE__ */ w(E, {
360
+ onClick: () => void A(),
361
+ disabled: !k,
362
+ children: D.loading ? "Saving…" : "Save"
313
363
  })] })
314
364
  ]
315
365
  })]
316
366
  });
317
367
  }
368
+ function Y({ feature: e }) {
369
+ let t = {
370
+ moscow: e.moscow ?? "",
371
+ kano: e.kano ?? "",
372
+ valueScore: e.valueScore == null ? "" : String(e.valueScore),
373
+ effortScore: e.effortScore == null ? "" : String(e.effortScore)
374
+ }, [r, a] = g(!1), [s, c] = g(t), [l, _] = g(null), [y, b] = S(U, G), x = () => {
375
+ c(t), _(null), a(!0);
376
+ }, j = async () => {
377
+ _(null);
378
+ let t = u(s.valueScore, {
379
+ min: 1,
380
+ max: 10
381
+ }), r = u(s.effortScore, {
382
+ min: 1,
383
+ max: 10
384
+ }), i = {
385
+ moscow: s.moscow || null,
386
+ kano: s.kano || null,
387
+ valueScore: t.value ?? null,
388
+ effortScore: r.value ?? null
389
+ };
390
+ try {
391
+ await n(y({ variables: {
392
+ id: e.id,
393
+ input: i
394
+ } })), a(!1);
395
+ } catch (e) {
396
+ _(o(e, "The prioritization could not be saved."));
397
+ }
398
+ };
399
+ return /* @__PURE__ */ T(D, {
400
+ "data-testid": "feature-prioritization-card",
401
+ children: [/* @__PURE__ */ T(k, {
402
+ className: "flex flex-row items-center justify-between gap-2",
403
+ children: [/* @__PURE__ */ w(A, { children: "Prioritization" }), !r && /* @__PURE__ */ T(E, {
404
+ size: "sm",
405
+ variant: "outline",
406
+ "data-testid": "feature-prioritization-edit",
407
+ onClick: x,
408
+ children: [/* @__PURE__ */ w(v, { className: "mr-1 h-4 w-4" }), "Edit"]
409
+ })]
410
+ }), /* @__PURE__ */ w(O, {
411
+ className: "space-y-3",
412
+ children: r ? /* @__PURE__ */ T(C, { children: [
413
+ /* @__PURE__ */ w(d, {
414
+ idPrefix: "feature-prio",
415
+ values: s,
416
+ onChange: c
417
+ }),
418
+ l && /* @__PURE__ */ w(i, { message: l }),
419
+ /* @__PURE__ */ T("div", {
420
+ className: "flex justify-end gap-2",
421
+ children: [/* @__PURE__ */ w(E, {
422
+ size: "sm",
423
+ variant: "outline",
424
+ onClick: () => a(!1),
425
+ children: "Cancel"
426
+ }), /* @__PURE__ */ w(E, {
427
+ size: "sm",
428
+ "data-testid": "feature-prioritization-save",
429
+ disabled: b.loading || !h(s),
430
+ onClick: () => void j(),
431
+ children: b.loading ? "Saving…" : "Save"
432
+ })]
433
+ })
434
+ ] }) : /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ T("div", {
435
+ className: "flex items-center gap-2",
436
+ children: [/* @__PURE__ */ w("span", {
437
+ className: "text-xs text-muted-foreground",
438
+ children: "Quadrant:"
439
+ }), /* @__PURE__ */ w(f, { quadrant: e.valueEffortQuadrant ?? null })]
440
+ }), /* @__PURE__ */ T("div", {
441
+ className: "grid grid-cols-2 gap-2 text-sm",
442
+ children: [
443
+ /* @__PURE__ */ T("div", {
444
+ className: "flex justify-between",
445
+ children: [/* @__PURE__ */ w("span", {
446
+ className: "text-muted-foreground",
447
+ children: "MoSCoW"
448
+ }), /* @__PURE__ */ w("span", {
449
+ className: "font-medium",
450
+ children: m(e.moscow)
451
+ })]
452
+ }),
453
+ /* @__PURE__ */ T("div", {
454
+ className: "flex justify-between",
455
+ children: [/* @__PURE__ */ w("span", {
456
+ className: "text-muted-foreground",
457
+ children: "Kano"
458
+ }), /* @__PURE__ */ w("span", {
459
+ className: "font-medium",
460
+ children: p(e.kano)
461
+ })]
462
+ }),
463
+ /* @__PURE__ */ T("div", {
464
+ className: "flex justify-between",
465
+ children: [/* @__PURE__ */ w("span", {
466
+ className: "text-muted-foreground",
467
+ children: "Value score"
468
+ }), /* @__PURE__ */ w("span", {
469
+ className: "font-medium",
470
+ children: e.valueScore ?? "Not set"
471
+ })]
472
+ }),
473
+ /* @__PURE__ */ T("div", {
474
+ className: "flex justify-between",
475
+ children: [/* @__PURE__ */ w("span", {
476
+ className: "text-muted-foreground",
477
+ children: "Effort score"
478
+ }), /* @__PURE__ */ w("span", {
479
+ className: "font-medium",
480
+ children: e.effortScore ?? "Not set"
481
+ })]
482
+ })
483
+ ]
484
+ })] })
485
+ })]
486
+ });
487
+ }
318
488
  //#endregion
319
- export { I as FeatureHeaderActions, F as FeatureVoteButton };
489
+ export { q as FeatureHeaderActions, Y as FeaturePrioritizationCard, K as FeatureVoteButton };
320
490
 
321
491
  //# sourceMappingURL=FeatureControls.js.map