@burdenoff/microfe-planmagnet 2026.928.3 → 2026.928.5

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 (245) hide show
  1. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoot.js +126 -84
  3. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  4. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  5. package/dist/planmagnet/PlanMagnetRoutes.js +192 -64
  6. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  7. package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts +5 -0
  8. package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts.map +1 -0
  9. package/dist/planmagnet/automation/AutomationExecutionsPanel.js +107 -0
  10. package/dist/planmagnet/automation/AutomationExecutionsPanel.js.map +1 -0
  11. package/dist/planmagnet/automation/AutomationRuleFields.d.ts +29 -0
  12. package/dist/planmagnet/automation/AutomationRuleFields.d.ts.map +1 -0
  13. package/dist/planmagnet/automation/AutomationRuleFields.js +308 -0
  14. package/dist/planmagnet/automation/AutomationRuleFields.js.map +1 -0
  15. package/dist/planmagnet/automation/automationRuleTypes.d.ts +60 -0
  16. package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -0
  17. package/dist/planmagnet/automation/automationRuleTypes.js +113 -0
  18. package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -0
  19. package/dist/planmagnet/board/BulkActions.d.ts +11 -0
  20. package/dist/planmagnet/board/BulkActions.d.ts.map +1 -0
  21. package/dist/planmagnet/board/BulkActions.js +182 -0
  22. package/dist/planmagnet/board/BulkActions.js.map +1 -0
  23. package/dist/planmagnet/board/ProjectBoard.d.ts.map +1 -1
  24. package/dist/planmagnet/board/ProjectBoard.js +289 -254
  25. package/dist/planmagnet/board/ProjectBoard.js.map +1 -1
  26. package/dist/planmagnet/budgets/BudgetControls.d.ts +30 -0
  27. package/dist/planmagnet/budgets/BudgetControls.d.ts.map +1 -0
  28. package/dist/planmagnet/budgets/BudgetControls.js +470 -0
  29. package/dist/planmagnet/budgets/BudgetControls.js.map +1 -0
  30. package/dist/planmagnet/budgets/ExpenseControls.d.ts +27 -0
  31. package/dist/planmagnet/budgets/ExpenseControls.d.ts.map +1 -0
  32. package/dist/planmagnet/budgets/ExpenseControls.js +366 -0
  33. package/dist/planmagnet/budgets/ExpenseControls.js.map +1 -0
  34. package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts +5 -0
  35. package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts.map +1 -0
  36. package/dist/planmagnet/budgets/ProjectBudgetsSummary.js +112 -0
  37. package/dist/planmagnet/budgets/ProjectBudgetsSummary.js.map +1 -0
  38. package/dist/planmagnet/budgets/budgetMath.d.ts +26 -0
  39. package/dist/planmagnet/budgets/budgetMath.d.ts.map +1 -0
  40. package/dist/planmagnet/budgets/budgetMath.js +49 -0
  41. package/dist/planmagnet/budgets/budgetMath.js.map +1 -0
  42. package/dist/planmagnet/controls/AutomationRuleControls.d.ts +23 -0
  43. package/dist/planmagnet/controls/AutomationRuleControls.d.ts.map +1 -0
  44. package/dist/planmagnet/controls/AutomationRuleControls.js +172 -0
  45. package/dist/planmagnet/controls/AutomationRuleControls.js.map +1 -0
  46. package/dist/planmagnet/controls/CompetitorControls.d.ts +20 -0
  47. package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -0
  48. package/dist/planmagnet/controls/CompetitorControls.js +172 -0
  49. package/dist/planmagnet/controls/CompetitorControls.js.map +1 -0
  50. package/dist/planmagnet/controls/CustomFieldControls.d.ts +42 -0
  51. package/dist/planmagnet/controls/CustomFieldControls.d.ts.map +1 -0
  52. package/dist/planmagnet/controls/CustomFieldControls.js +84 -0
  53. package/dist/planmagnet/controls/CustomFieldControls.js.map +1 -0
  54. package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts +8 -0
  55. package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts.map +1 -0
  56. package/dist/planmagnet/controls/CustomFieldValuesPanel.js +315 -0
  57. package/dist/planmagnet/controls/CustomFieldValuesPanel.js.map +1 -0
  58. package/dist/planmagnet/controls/FeatureControls.js +53 -53
  59. package/dist/planmagnet/controls/FeatureTriage.js +11 -11
  60. package/dist/planmagnet/controls/ObjectiveControls.js +37 -37
  61. package/dist/planmagnet/controls/Pickers.d.ts +17 -2
  62. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  63. package/dist/planmagnet/controls/Pickers.js +100 -9
  64. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  65. package/dist/planmagnet/controls/PortfolioControls.d.ts +13 -0
  66. package/dist/planmagnet/controls/PortfolioControls.d.ts.map +1 -0
  67. package/dist/planmagnet/controls/PortfolioControls.js +114 -0
  68. package/dist/planmagnet/controls/PortfolioControls.js.map +1 -0
  69. package/dist/planmagnet/controls/ProgramControls.d.ts +25 -0
  70. package/dist/planmagnet/controls/ProgramControls.d.ts.map +1 -0
  71. package/dist/planmagnet/controls/ProgramControls.js +187 -0
  72. package/dist/planmagnet/controls/ProgramControls.js.map +1 -0
  73. package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -1
  74. package/dist/planmagnet/controls/ProjectControls.js +54 -47
  75. package/dist/planmagnet/controls/ProjectControls.js.map +1 -1
  76. package/dist/planmagnet/controls/ReleaseControls.js +7 -7
  77. package/dist/planmagnet/controls/RiskControls.d.ts +27 -0
  78. package/dist/planmagnet/controls/RiskControls.d.ts.map +1 -0
  79. package/dist/planmagnet/controls/RiskControls.js +346 -0
  80. package/dist/planmagnet/controls/RiskControls.js.map +1 -0
  81. package/dist/planmagnet/controls/TemplateControls.d.ts +15 -0
  82. package/dist/planmagnet/controls/TemplateControls.d.ts.map +1 -0
  83. package/dist/planmagnet/controls/TemplateControls.js +55 -0
  84. package/dist/planmagnet/controls/TemplateControls.js.map +1 -0
  85. package/dist/planmagnet/controls/WorkItemControls.js +1 -1
  86. package/dist/planmagnet/create/CreateDialogs.d.ts +20 -0
  87. package/dist/planmagnet/create/CreateDialogs.d.ts.map +1 -1
  88. package/dist/planmagnet/create/CreateDialogs.js +455 -116
  89. package/dist/planmagnet/create/CreateDialogs.js.map +1 -1
  90. package/dist/planmagnet/dependency/DependencyPanel.d.ts +6 -0
  91. package/dist/planmagnet/dependency/DependencyPanel.d.ts.map +1 -0
  92. package/dist/planmagnet/dependency/DependencyPanel.js +310 -0
  93. package/dist/planmagnet/dependency/DependencyPanel.js.map +1 -0
  94. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts +2 -0
  95. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts.map +1 -0
  96. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +171 -0
  97. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js.map +1 -0
  98. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts +2 -0
  99. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts.map +1 -0
  100. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js +232 -0
  101. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js.map +1 -0
  102. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts +2 -0
  103. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts.map +1 -0
  104. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +93 -0
  105. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js.map +1 -0
  106. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts +2 -0
  107. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -0
  108. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +127 -0
  109. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -0
  110. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts +2 -0
  111. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -0
  112. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +129 -0
  113. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -0
  114. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts +2 -0
  115. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -0
  116. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +132 -0
  117. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -0
  118. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts +2 -0
  119. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -0
  120. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +181 -0
  121. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -0
  122. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts +2 -0
  123. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts.map +1 -0
  124. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js +242 -0
  125. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js.map +1 -0
  126. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts +2 -0
  127. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts.map +1 -0
  128. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +302 -0
  129. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js.map +1 -0
  130. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts +2 -0
  131. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -0
  132. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +335 -0
  133. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -0
  134. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts +2 -0
  135. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts.map +1 -0
  136. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +154 -0
  137. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js.map +1 -0
  138. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  139. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +124 -138
  140. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  141. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts +2 -0
  142. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts.map +1 -0
  143. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +221 -0
  144. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js.map +1 -0
  145. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts +2 -0
  146. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts.map +1 -0
  147. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +279 -0
  148. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js.map +1 -0
  149. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts +2 -0
  150. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts.map +1 -0
  151. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js +178 -0
  152. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js.map +1 -0
  153. package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts +2 -0
  154. package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts.map +1 -0
  155. package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +157 -0
  156. package/dist/planmagnet/pages/ProgramsProgramsPagePage.js.map +1 -0
  157. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts +2 -0
  158. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts.map +1 -0
  159. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js +315 -0
  160. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js.map +1 -0
  161. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts +2 -0
  162. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts.map +1 -0
  163. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +186 -0
  164. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js.map +1 -0
  165. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts +2 -0
  166. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts.map +1 -0
  167. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js +164 -0
  168. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js.map +1 -0
  169. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts +2 -0
  170. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts.map +1 -0
  171. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js +348 -0
  172. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js.map +1 -0
  173. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  174. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +130 -103
  175. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  176. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +4 -4
  177. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +4 -4
  178. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +6 -6
  179. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  180. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +325 -189
  181. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  182. package/dist/planmagnet/pages/ProjectsProjectsPagePage.d.ts.map +1 -1
  183. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +81 -72
  184. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js.map +1 -1
  185. package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts +2 -0
  186. package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts.map +1 -0
  187. package/dist/planmagnet/pages/RisksRiskDetailPagePage.js +278 -0
  188. package/dist/planmagnet/pages/RisksRiskDetailPagePage.js.map +1 -0
  189. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts +2 -0
  190. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts.map +1 -0
  191. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js +191 -0
  192. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js.map +1 -0
  193. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +5 -5
  194. package/dist/planmagnet/pages/TasksEditTaskPagePage.js +4 -4
  195. package/dist/planmagnet/pages/TasksImportPagePage.js +5 -5
  196. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  197. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +161 -137
  198. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  199. package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
  200. package/dist/planmagnet/pages/TasksTasksPagePage.js +124 -113
  201. package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
  202. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts +2 -0
  203. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts.map +1 -0
  204. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +263 -0
  205. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js.map +1 -0
  206. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts +2 -0
  207. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts.map +1 -0
  208. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js +254 -0
  209. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js.map +1 -0
  210. package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts +2 -0
  211. package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts.map +1 -0
  212. package/dist/planmagnet/pages/TasksTimesheetsPagePage.js +165 -0
  213. package/dist/planmagnet/pages/TasksTimesheetsPagePage.js.map +1 -0
  214. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts +2 -0
  215. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts.map +1 -0
  216. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js +316 -0
  217. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js.map +1 -0
  218. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts +2 -0
  219. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts.map +1 -0
  220. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js +208 -0
  221. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js.map +1 -0
  222. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts +0 -5
  223. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts.map +1 -1
  224. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +47 -89
  225. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js.map +1 -1
  226. package/dist/planmagnet/roadmaps/RoadmapControls.js +24 -24
  227. package/dist/planmagnet/time/TaskTimePanel.d.ts +7 -0
  228. package/dist/planmagnet/time/TaskTimePanel.d.ts.map +1 -0
  229. package/dist/planmagnet/time/TaskTimePanel.js +104 -0
  230. package/dist/planmagnet/time/TaskTimePanel.js.map +1 -0
  231. package/dist/planmagnet/time/TimeEntryControls.d.ts +37 -0
  232. package/dist/planmagnet/time/TimeEntryControls.d.ts.map +1 -0
  233. package/dist/planmagnet/time/TimeEntryControls.js +338 -0
  234. package/dist/planmagnet/time/TimeEntryControls.js.map +1 -0
  235. package/dist/planmagnet/time/TimesheetControls.d.ts +18 -0
  236. package/dist/planmagnet/time/TimesheetControls.d.ts.map +1 -0
  237. package/dist/planmagnet/time/TimesheetControls.js +244 -0
  238. package/dist/planmagnet/time/TimesheetControls.js.map +1 -0
  239. package/dist/planmagnet/time/timeShared.d.ts +29 -0
  240. package/dist/planmagnet/time/timeShared.d.ts.map +1 -0
  241. package/dist/planmagnet/time/timeShared.js +34 -0
  242. package/dist/planmagnet/time/timeShared.js.map +1 -0
  243. package/dist/planmagnet/utils/rowNavigation.js +5 -2
  244. package/dist/planmagnet/utils/rowNavigation.js.map +1 -1
  245. package/package.json +1 -1
@@ -0,0 +1,346 @@
1
+ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
+ import { LEAVES_PAGE_CONTEXT as t, throwOnError as n } from "../utils/mutationResult.js";
3
+ import { ConfirmButton as r, ErrorLine as i } from "./ConfirmButton.js";
4
+ import { AssigneeSelect as a, enumLabel as o } from "./WorkItemControls.js";
5
+ import { useState as s } from "react";
6
+ import { Pencil as c, Trash2 as l } from "lucide-react";
7
+ import { gql as u } from "@apollo/client";
8
+ import { useMutation as d } from "@apollo/client/react";
9
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
10
+ import { Button as m, Input as h, ResponsiveDialog as g, ResponsiveDialogContent as _, ResponsiveDialogDescription as v, ResponsiveDialogFooter as y, ResponsiveDialogHeader as b, ResponsiveDialogTitle as x, ResponsiveDialogTrigger as S } from "@burdenoff/fe-libs/ui";
11
+ //#region src/planmagnet/controls/RiskControls.tsx
12
+ var C = [
13
+ "IDENTIFIED",
14
+ "ANALYZING",
15
+ "MITIGATING",
16
+ "ACCEPTED",
17
+ "RESOLVED",
18
+ "CLOSED"
19
+ ], w = [
20
+ "CRITICAL",
21
+ "HIGH",
22
+ "MEDIUM",
23
+ "LOW",
24
+ "NEGLIGIBLE"
25
+ ], T = [
26
+ "GetRiskDetail",
27
+ "GetRisks",
28
+ "GetRiskMatrix",
29
+ "GetProjectDetail"
30
+ ], E = u`
31
+ mutation RiskControlsUpdate($id: ID!, $input: PlanmagnetUpdateRiskInput!) {
32
+ planmagnetUpdateRisk(id: $id, input: $input) {
33
+ id
34
+ title
35
+ description
36
+ severity
37
+ status
38
+ likelihood
39
+ impact
40
+ riskScore
41
+ category
42
+ mitigationPlan
43
+ contingencyPlan
44
+ ownerId
45
+ dueDate
46
+ resolvedAt
47
+ }
48
+ }
49
+ `, D = u`
50
+ mutation RiskControlsDelete($id: ID!) {
51
+ planmagnetDeleteRisk(id: $id)
52
+ }
53
+ `, O = (e) => e ? e.slice(0, 10) : "";
54
+ function k({ risk: a }) {
55
+ let c = e(), [u, m] = d(E, {
56
+ refetchQueries: T,
57
+ awaitRefetchQueries: !0
58
+ }), [h, g] = d(D, {
59
+ refetchQueries: T.filter((e) => e !== "GetRiskDetail"),
60
+ context: t
61
+ }), [_, v] = s(null), y = m.loading || g.loading, b = C.includes(a.status) ? C : [a.status, ...C], x = async (e) => {
62
+ v(null);
63
+ let t = { status: e };
64
+ (e === "RESOLVED" || e === "CLOSED") && a.status !== "RESOLVED" && a.status !== "CLOSED" ? t.resolvedAt = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10) : e !== "RESOLVED" && e !== "CLOSED" && (t.resolvedAt = null);
65
+ try {
66
+ await n(u({ variables: {
67
+ id: a.id,
68
+ input: t
69
+ } }));
70
+ } catch (e) {
71
+ v(e instanceof Error ? e.message : "The status could not be changed.");
72
+ }
73
+ }, S = async () => {
74
+ v(null);
75
+ try {
76
+ await n(h({ variables: { id: a.id } })), c("/risks/risk-register-page");
77
+ } catch (e) {
78
+ v(e instanceof Error ? e.message : "The risk could not be deleted.");
79
+ }
80
+ };
81
+ return /* @__PURE__ */ p("div", {
82
+ className: "flex flex-col items-end gap-2",
83
+ children: [/* @__PURE__ */ p("div", {
84
+ className: "flex flex-wrap items-center justify-end gap-2",
85
+ children: [
86
+ /* @__PURE__ */ f("select", {
87
+ "aria-label": "Status",
88
+ "data-testid": "risk-status",
89
+ className: "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60",
90
+ value: a.status,
91
+ disabled: y,
92
+ onChange: (e) => {
93
+ e.target.value !== a.status && x(e.target.value);
94
+ },
95
+ children: b.map((e) => /* @__PURE__ */ f("option", {
96
+ value: e,
97
+ children: o(e)
98
+ }, e))
99
+ }),
100
+ /* @__PURE__ */ f(M, { risk: a }),
101
+ /* @__PURE__ */ f(r, {
102
+ label: "Delete",
103
+ variant: "outline",
104
+ icon: /* @__PURE__ */ f(l, { className: "mr-1 h-4 w-4" }),
105
+ title: `Delete "${a.title}"?`,
106
+ description: "The risk is removed from the register. This cannot be undone here.",
107
+ confirmLabel: "Delete risk",
108
+ destructive: !0,
109
+ disabled: y,
110
+ onConfirm: () => void S()
111
+ })
112
+ ]
113
+ }), _ && /* @__PURE__ */ f(i, { message: _ })]
114
+ });
115
+ }
116
+ var A = "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm", j = [
117
+ 1,
118
+ 2,
119
+ 3,
120
+ 4,
121
+ 5
122
+ ];
123
+ function M({ risk: e }) {
124
+ let t = {
125
+ title: e.title,
126
+ description: e.description ?? "",
127
+ severity: e.severity,
128
+ likelihood: e.likelihood,
129
+ impact: e.impact,
130
+ category: e.category ?? "",
131
+ mitigationPlan: e.mitigationPlan ?? "",
132
+ contingencyPlan: e.contingencyPlan ?? "",
133
+ ownerId: e.ownerId ?? "",
134
+ dueDate: O(e.dueDate)
135
+ }, [r, l] = s(!1), [u, C] = s(t), [D, k] = s(null), [M, N] = d(E, {
136
+ refetchQueries: T,
137
+ awaitRefetchQueries: !0
138
+ }), P = async () => {
139
+ k(null);
140
+ let r = {};
141
+ if (u.title.trim() !== t.title && (r.title = u.title.trim()), u.description.trim() !== t.description.trim() && (r.description = u.description.trim() || null), u.severity !== t.severity && (r.severity = u.severity), u.likelihood !== t.likelihood && (r.likelihood = u.likelihood), u.impact !== t.impact && (r.impact = u.impact), u.category.trim() !== t.category.trim() && (r.category = u.category.trim() || null), u.mitigationPlan.trim() !== t.mitigationPlan.trim() && (r.mitigationPlan = u.mitigationPlan.trim() || null), u.contingencyPlan.trim() !== t.contingencyPlan.trim() && (r.contingencyPlan = u.contingencyPlan.trim() || null), u.ownerId !== t.ownerId && (r.ownerId = u.ownerId || null), u.dueDate !== t.dueDate && (r.dueDate = u.dueDate || null), Object.keys(r).length === 0) {
142
+ l(!1);
143
+ return;
144
+ }
145
+ try {
146
+ await n(M({ variables: {
147
+ id: e.id,
148
+ input: r
149
+ } })), l(!1);
150
+ } catch (e) {
151
+ k(e instanceof Error ? e.message : "The risk could not be saved.");
152
+ }
153
+ };
154
+ return /* @__PURE__ */ p(g, {
155
+ open: r,
156
+ onOpenChange: (e) => {
157
+ l(e), e ? C(t) : k(null);
158
+ },
159
+ children: [/* @__PURE__ */ f(S, {
160
+ asChild: !0,
161
+ children: /* @__PURE__ */ p(m, {
162
+ size: "sm",
163
+ variant: "outline",
164
+ "data-testid": "risk-edit",
165
+ children: [/* @__PURE__ */ f(c, { className: "mr-1 h-4 w-4" }), "Edit"]
166
+ })
167
+ }), /* @__PURE__ */ p(_, {
168
+ className: "max-w-lg max-h-[85vh] overflow-y-auto",
169
+ children: [
170
+ /* @__PURE__ */ p(b, { children: [/* @__PURE__ */ f(x, { children: "Edit risk" }), /* @__PURE__ */ f(v, { children: "Only changed fields are saved." })] }),
171
+ /* @__PURE__ */ p("div", {
172
+ className: "space-y-3",
173
+ children: [
174
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
175
+ htmlFor: "risk-edit-title",
176
+ className: "text-sm font-medium",
177
+ children: "Title"
178
+ }), /* @__PURE__ */ f(h, {
179
+ id: "risk-edit-title",
180
+ className: "mt-1",
181
+ value: u.title,
182
+ onChange: (e) => C({
183
+ ...u,
184
+ title: e.target.value
185
+ })
186
+ })] }),
187
+ /* @__PURE__ */ p("div", {
188
+ className: "grid grid-cols-3 gap-3",
189
+ children: [
190
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
191
+ htmlFor: "risk-edit-severity",
192
+ className: "text-sm font-medium",
193
+ children: "Severity"
194
+ }), /* @__PURE__ */ f("select", {
195
+ id: "risk-edit-severity",
196
+ className: A,
197
+ value: u.severity,
198
+ onChange: (e) => C({
199
+ ...u,
200
+ severity: e.target.value
201
+ }),
202
+ children: w.includes(u.severity) ? w.map((e) => /* @__PURE__ */ f("option", {
203
+ value: e,
204
+ children: o(e)
205
+ }, e)) : [u.severity, ...w].map((e) => /* @__PURE__ */ f("option", {
206
+ value: e,
207
+ children: o(e)
208
+ }, e))
209
+ })] }),
210
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
211
+ htmlFor: "risk-edit-likelihood",
212
+ className: "text-sm font-medium",
213
+ children: "Likelihood"
214
+ }), /* @__PURE__ */ f("select", {
215
+ id: "risk-edit-likelihood",
216
+ className: A,
217
+ value: u.likelihood,
218
+ onChange: (e) => C({
219
+ ...u,
220
+ likelihood: Number(e.target.value)
221
+ }),
222
+ children: j.map((e) => /* @__PURE__ */ f("option", {
223
+ value: e,
224
+ children: e
225
+ }, e))
226
+ })] }),
227
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
228
+ htmlFor: "risk-edit-impact",
229
+ className: "text-sm font-medium",
230
+ children: "Impact"
231
+ }), /* @__PURE__ */ f("select", {
232
+ id: "risk-edit-impact",
233
+ className: A,
234
+ value: u.impact,
235
+ onChange: (e) => C({
236
+ ...u,
237
+ impact: Number(e.target.value)
238
+ }),
239
+ children: j.map((e) => /* @__PURE__ */ f("option", {
240
+ value: e,
241
+ children: e
242
+ }, e))
243
+ })] })
244
+ ]
245
+ }),
246
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
247
+ htmlFor: "risk-edit-category",
248
+ className: "text-sm font-medium",
249
+ children: "Category"
250
+ }), /* @__PURE__ */ f(h, {
251
+ id: "risk-edit-category",
252
+ className: "mt-1",
253
+ value: u.category,
254
+ onChange: (e) => C({
255
+ ...u,
256
+ category: e.target.value
257
+ })
258
+ })] }),
259
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
260
+ htmlFor: "risk-edit-owner",
261
+ className: "text-sm font-medium",
262
+ children: "Owner"
263
+ }), /* @__PURE__ */ f("div", {
264
+ className: "mt-1",
265
+ children: /* @__PURE__ */ f(a, {
266
+ id: "risk-edit-owner",
267
+ value: u.ownerId,
268
+ onChange: (e) => C({
269
+ ...u,
270
+ ownerId: e
271
+ })
272
+ })
273
+ })] }),
274
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
275
+ htmlFor: "risk-edit-due",
276
+ className: "text-sm font-medium",
277
+ children: "Due date"
278
+ }), /* @__PURE__ */ f(h, {
279
+ id: "risk-edit-due",
280
+ type: "date",
281
+ className: "mt-1",
282
+ value: u.dueDate,
283
+ onChange: (e) => C({
284
+ ...u,
285
+ dueDate: e.target.value
286
+ })
287
+ })] }),
288
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
289
+ htmlFor: "risk-edit-description",
290
+ className: "text-sm font-medium",
291
+ children: "Description"
292
+ }), /* @__PURE__ */ f("textarea", {
293
+ id: "risk-edit-description",
294
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[64px]",
295
+ value: u.description,
296
+ onChange: (e) => C({
297
+ ...u,
298
+ description: e.target.value
299
+ })
300
+ })] }),
301
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
302
+ htmlFor: "risk-edit-mitigation",
303
+ className: "text-sm font-medium",
304
+ children: "Mitigation plan"
305
+ }), /* @__PURE__ */ f("textarea", {
306
+ id: "risk-edit-mitigation",
307
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[64px]",
308
+ value: u.mitigationPlan,
309
+ onChange: (e) => C({
310
+ ...u,
311
+ mitigationPlan: e.target.value
312
+ })
313
+ })] }),
314
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
315
+ htmlFor: "risk-edit-contingency",
316
+ className: "text-sm font-medium",
317
+ children: "Contingency plan"
318
+ }), /* @__PURE__ */ f("textarea", {
319
+ id: "risk-edit-contingency",
320
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[64px]",
321
+ value: u.contingencyPlan,
322
+ onChange: (e) => C({
323
+ ...u,
324
+ contingencyPlan: e.target.value
325
+ })
326
+ })] }),
327
+ D && /* @__PURE__ */ f(i, { message: D })
328
+ ]
329
+ }),
330
+ /* @__PURE__ */ p(y, { children: [/* @__PURE__ */ f(m, {
331
+ variant: "outline",
332
+ onClick: () => l(!1),
333
+ children: "Cancel"
334
+ }), /* @__PURE__ */ f(m, {
335
+ onClick: () => void P(),
336
+ disabled: u.title.trim() === "" || N.loading,
337
+ children: N.loading ? "Saving…" : "Save"
338
+ })] })
339
+ ]
340
+ })]
341
+ });
342
+ }
343
+ //#endregion
344
+ export { w as RISK_SEVERITIES, C as RISK_STATUSES, k as RiskHeaderActions };
345
+
346
+ //# sourceMappingURL=RiskControls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RiskControls.js","names":[],"sources":["../../../src/planmagnet/controls/RiskControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n Button,\n Input,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { Pencil, Trash2 } from 'lucide-react';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { throwOnError, LEAVES_PAGE_CONTEXT } from '../utils/mutationResult';\nimport { ConfirmButton, ErrorLine } from './ConfirmButton';\nimport { enumLabel, AssigneeSelect } from './WorkItemControls';\n\n/**\n * Risk register controls (BOFF-8047). The register API (planmagnetCreateRisk/UpdateRisk/DeleteRisk,\n * planmagnetRisks, planmagnetRiskMatrix) has been served and prod-verified since the risk module shipped —\n * `CAPABILITY_REGISTER.md` carried it `api-only` because no page reached it. Status moves freely between the\n * six `RiskStatus` values (the service enforces only the 1-5 likelihood/impact range, not a transition table),\n * so — like Milestones — this is a plain select rather than an allowed-moves picker.\n */\n\nexport const RISK_STATUSES = [\n 'IDENTIFIED',\n 'ANALYZING',\n 'MITIGATING',\n 'ACCEPTED',\n 'RESOLVED',\n 'CLOSED',\n] as const;\n\nexport const RISK_SEVERITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'NEGLIGIBLE'] as const;\n\nconst RISK_QUERIES = ['GetRiskDetail', 'GetRisks', 'GetRiskMatrix', 'GetProjectDetail'];\n\nconst UPDATE = gql`\n mutation RiskControlsUpdate($id: ID!, $input: PlanmagnetUpdateRiskInput!) {\n planmagnetUpdateRisk(id: $id, input: $input) {\n id\n title\n description\n severity\n status\n likelihood\n impact\n riskScore\n category\n mitigationPlan\n contingencyPlan\n ownerId\n dueDate\n resolvedAt\n }\n }\n`;\nconst DELETE = gql`\n mutation RiskControlsDelete($id: ID!) {\n planmagnetDeleteRisk(id: $id)\n }\n`;\n\nexport interface RiskValues {\n id: string;\n title: string;\n description: string | null;\n severity: string;\n status: string;\n likelihood: number;\n impact: number;\n category: string | null;\n mitigationPlan: string | null;\n contingencyPlan: string | null;\n ownerId: string | null;\n dueDate: string | null;\n}\n\nconst day = (iso: string | null) => (iso ? iso.slice(0, 10) : '');\n\nexport function RiskHeaderActions({ risk }: { risk: RiskValues }) {\n const navigate = usePlanMagnetNavigate();\n const [update, updateState] = useMutation(UPDATE, {\n refetchQueries: RISK_QUERIES,\n awaitRefetchQueries: true,\n });\n const [remove, removeState] = useMutation(DELETE, {\n refetchQueries: RISK_QUERIES.filter((q) => q !== 'GetRiskDetail'),\n context: LEAVES_PAGE_CONTEXT,\n });\n const [error, setError] = useState<string | null>(null);\n const busy = updateState.loading || removeState.loading;\n const statuses = (RISK_STATUSES as readonly string[]).includes(risk.status)\n ? RISK_STATUSES\n : [risk.status, ...RISK_STATUSES];\n\n const onStatus = async (status: string) => {\n setError(null);\n const input: Record<string, unknown> = { status };\n // Resolving or closing a risk that has never been resolved records the date; re-opening clears it.\n if (\n (status === 'RESOLVED' || status === 'CLOSED') &&\n risk.status !== 'RESOLVED' &&\n risk.status !== 'CLOSED'\n ) {\n input.resolvedAt = new Date().toISOString().slice(0, 10);\n } else if (status !== 'RESOLVED' && status !== 'CLOSED') {\n input.resolvedAt = null;\n }\n try {\n await throwOnError(update({ variables: { id: risk.id, input } }));\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The status could not be changed.');\n }\n };\n const onDelete = async () => {\n setError(null);\n try {\n await throwOnError(remove({ variables: { id: risk.id } }));\n navigate('/risks/risk-register-page');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The risk could not be deleted.');\n }\n };\n\n return (\n <div className=\"flex flex-col items-end gap-2\">\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <select\n aria-label=\"Status\"\n data-testid=\"risk-status\"\n className=\"rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60\"\n value={risk.status}\n disabled={busy}\n onChange={(e) => {\n if (e.target.value !== risk.status) void onStatus(e.target.value);\n }}\n >\n {statuses.map((s) => (\n <option key={s} value={s}>\n {enumLabel(s)}\n </option>\n ))}\n </select>\n <RiskEditDialog risk={risk} />\n <ConfirmButton\n label=\"Delete\"\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete \"${risk.title}\"?`}\n description=\"The risk is removed from the register. This cannot be undone here.\"\n confirmLabel=\"Delete risk\"\n destructive\n disabled={busy}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n\nconst FIELD = 'mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm';\nconst SCORES = [1, 2, 3, 4, 5] as const;\n\n/** Title, severity, likelihood/impact, category, mitigation/contingency plans, owner and due date. */\nfunction RiskEditDialog({ risk }: { risk: RiskValues }) {\n const initial = {\n title: risk.title,\n description: risk.description ?? '',\n severity: risk.severity,\n likelihood: risk.likelihood,\n impact: risk.impact,\n category: risk.category ?? '',\n mitigationPlan: risk.mitigationPlan ?? '',\n contingencyPlan: risk.contingencyPlan ?? '',\n ownerId: risk.ownerId ?? '',\n dueDate: day(risk.dueDate),\n };\n const [open, setOpen] = useState(false);\n const [form, setForm] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n const [update, state] = useMutation(UPDATE, {\n refetchQueries: RISK_QUERIES,\n awaitRefetchQueries: true,\n });\n\n const save = async () => {\n setError(null);\n const input: Record<string, unknown> = {};\n if (form.title.trim() !== initial.title) input.title = form.title.trim();\n if (form.description.trim() !== initial.description.trim())\n input.description = form.description.trim() || null;\n if (form.severity !== initial.severity) input.severity = form.severity;\n if (form.likelihood !== initial.likelihood) input.likelihood = form.likelihood;\n if (form.impact !== initial.impact) input.impact = form.impact;\n if (form.category.trim() !== initial.category.trim())\n input.category = form.category.trim() || null;\n if (form.mitigationPlan.trim() !== initial.mitigationPlan.trim())\n input.mitigationPlan = form.mitigationPlan.trim() || null;\n if (form.contingencyPlan.trim() !== initial.contingencyPlan.trim())\n input.contingencyPlan = form.contingencyPlan.trim() || null;\n if (form.ownerId !== initial.ownerId) input.ownerId = form.ownerId || null;\n if (form.dueDate !== initial.dueDate) input.dueDate = form.dueDate || null;\n if (Object.keys(input).length === 0) {\n setOpen(false);\n return;\n }\n try {\n await throwOnError(update({ variables: { id: risk.id, input } }));\n setOpen(false);\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The risk could not be saved.');\n }\n };\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) setForm(initial);\n else setError(null);\n }}\n >\n <ResponsiveDialogTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" data-testid=\"risk-edit\">\n <Pencil className=\"mr-1 h-4 w-4\" />\n Edit\n </Button>\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg max-h-[85vh] overflow-y-auto\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Edit risk</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>Only changed fields are saved.</ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3\">\n <div>\n <label htmlFor=\"risk-edit-title\" className=\"text-sm font-medium\">\n Title\n </label>\n <Input\n id=\"risk-edit-title\"\n className=\"mt-1\"\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n />\n </div>\n <div className=\"grid grid-cols-3 gap-3\">\n <div>\n <label htmlFor=\"risk-edit-severity\" className=\"text-sm font-medium\">\n Severity\n </label>\n <select\n id=\"risk-edit-severity\"\n className={FIELD}\n value={form.severity}\n onChange={(e) => setForm({ ...form, severity: e.target.value })}\n >\n {(RISK_SEVERITIES as readonly string[]).includes(form.severity)\n ? RISK_SEVERITIES.map((s) => (\n <option key={s} value={s}>\n {enumLabel(s)}\n </option>\n ))\n : [form.severity, ...RISK_SEVERITIES].map((s) => (\n <option key={s} value={s}>\n {enumLabel(s)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"risk-edit-likelihood\" className=\"text-sm font-medium\">\n Likelihood\n </label>\n <select\n id=\"risk-edit-likelihood\"\n className={FIELD}\n value={form.likelihood}\n onChange={(e) => setForm({ ...form, likelihood: Number(e.target.value) })}\n >\n {SCORES.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"risk-edit-impact\" className=\"text-sm font-medium\">\n Impact\n </label>\n <select\n id=\"risk-edit-impact\"\n className={FIELD}\n value={form.impact}\n onChange={(e) => setForm({ ...form, impact: Number(e.target.value) })}\n >\n {SCORES.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div>\n <label htmlFor=\"risk-edit-category\" className=\"text-sm font-medium\">\n Category\n </label>\n <Input\n id=\"risk-edit-category\"\n className=\"mt-1\"\n value={form.category}\n onChange={(e) => setForm({ ...form, category: e.target.value })}\n />\n </div>\n <div>\n <label htmlFor=\"risk-edit-owner\" className=\"text-sm font-medium\">\n Owner\n </label>\n <div className=\"mt-1\">\n <AssigneeSelect\n id=\"risk-edit-owner\"\n value={form.ownerId}\n onChange={(ownerId) => setForm({ ...form, ownerId })}\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"risk-edit-due\" className=\"text-sm font-medium\">\n Due date\n </label>\n <Input\n id=\"risk-edit-due\"\n type=\"date\"\n className=\"mt-1\"\n value={form.dueDate}\n onChange={(e) => setForm({ ...form, dueDate: e.target.value })}\n />\n </div>\n <div>\n <label htmlFor=\"risk-edit-description\" className=\"text-sm font-medium\">\n Description\n </label>\n <textarea\n id=\"risk-edit-description\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[64px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div>\n <label htmlFor=\"risk-edit-mitigation\" className=\"text-sm font-medium\">\n Mitigation plan\n </label>\n <textarea\n id=\"risk-edit-mitigation\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[64px]\"\n value={form.mitigationPlan}\n onChange={(e) => setForm({ ...form, mitigationPlan: e.target.value })}\n />\n </div>\n <div>\n <label htmlFor=\"risk-edit-contingency\" className=\"text-sm font-medium\">\n Contingency plan\n </label>\n <textarea\n id=\"risk-edit-contingency\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[64px]\"\n value={form.contingencyPlan}\n onChange={(e) => setForm({ ...form, contingencyPlan: e.target.value })}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button onClick={() => void save()} disabled={form.title.trim() === '' || state.loading}>\n {state.loading ? 'Saving…' : 'Save'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** Every query that lists or shows a template, so a delete or edit is visible everywhere without a manual reload. */
2
+ export declare const TEMPLATE_QUERIES: string[];
3
+ /**
4
+ * Deleting a built-in template is technically accepted by the service (nothing in `TemplateService.delete`
5
+ * checks `isBuiltIn`), but a system-provided starting point disappearing under an ordinary edit is the kind of
6
+ * surprise a production UI should not hand out for free — so this button stays disabled for one, with the
7
+ * reason in a tooltip, rather than silently letting a click remove it.
8
+ */
9
+ export declare function TemplateDeleteButton({ templateId, name, isBuiltIn, onDeleted, }: {
10
+ templateId: string;
11
+ name: string;
12
+ isBuiltIn: boolean;
13
+ onDeleted?: () => void;
14
+ }): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=TemplateControls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateControls.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/controls/TemplateControls.tsx"],"names":[],"mappings":"AAeA,qHAAqH;AACrH,eAAO,MAAM,gBAAgB,UAAmC,CAAC;AAQjE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,UAAU,EACV,IAAI,EACJ,SAAS,EACT,SAAS,GACV,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,2CAqDA"}
@@ -0,0 +1,55 @@
1
+ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
+ import { LEAVES_PAGE_CONTEXT as t, throwOnError as n } from "../utils/mutationResult.js";
3
+ import { ConfirmButton as r, ErrorLine as i } from "./ConfirmButton.js";
4
+ import { useState as a } from "react";
5
+ import { Trash2 as o } from "lucide-react";
6
+ import { gql as s } from "@apollo/client";
7
+ import { useMutation as c } from "@apollo/client/react";
8
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
9
+ import { Button as d, Tooltip as f, TooltipContent as p, TooltipProvider as m, TooltipTrigger as h } from "@burdenoff/fe-libs/ui";
10
+ //#region src/planmagnet/controls/TemplateControls.tsx
11
+ var g = ["TemplatesList", "GetTemplate"], _ = s`
12
+ mutation TemplateControlsDelete($id: ID!) {
13
+ planmagnetDeleteProjectTemplate(id: $id)
14
+ }
15
+ `;
16
+ function v({ templateId: s, name: v, isBuiltIn: y, onDeleted: b }) {
17
+ let x = e(), [S, { loading: C }] = c(_, {
18
+ refetchQueries: g.filter((e) => e !== "GetTemplate"),
19
+ context: t
20
+ }), [w, T] = a(null), E = async () => {
21
+ T(null);
22
+ try {
23
+ await n(S({ variables: { id: s } })), b ? b() : x("/templates/templates-page");
24
+ } catch (e) {
25
+ T(e instanceof Error ? e.message : "The template could not be deleted.");
26
+ }
27
+ };
28
+ return y ? /* @__PURE__ */ l(m, { children: /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(h, {
29
+ asChild: !0,
30
+ children: /* @__PURE__ */ l("span", { children: /* @__PURE__ */ u(d, {
31
+ size: "sm",
32
+ variant: "outline",
33
+ disabled: !0,
34
+ "data-testid": "template-delete",
35
+ children: [/* @__PURE__ */ l(o, { className: "mr-1 h-4 w-4" }), "Delete"]
36
+ }) })
37
+ }), /* @__PURE__ */ l(p, { children: "Built-in templates can't be deleted." })] }) }) : /* @__PURE__ */ u("div", {
38
+ className: "flex flex-col items-end gap-1",
39
+ children: [/* @__PURE__ */ l(r, {
40
+ label: "Delete",
41
+ variant: "outline",
42
+ icon: /* @__PURE__ */ l(o, { className: "mr-1 h-4 w-4" }),
43
+ title: `Delete "${v}"?`,
44
+ description: "Projects already created from it are unaffected. This cannot be undone here.",
45
+ confirmLabel: "Delete template",
46
+ destructive: !0,
47
+ disabled: C,
48
+ onConfirm: () => void E()
49
+ }), w && /* @__PURE__ */ l(i, { message: w })]
50
+ });
51
+ }
52
+ //#endregion
53
+ export { g as TEMPLATE_QUERIES, v as TemplateDeleteButton };
54
+
55
+ //# sourceMappingURL=TemplateControls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateControls.js","names":[],"sources":["../../../src/planmagnet/controls/TemplateControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n Button,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { Trash2 } from 'lucide-react';\nimport { ConfirmButton, ErrorLine } from './ConfirmButton';\nimport { throwOnError, LEAVES_PAGE_CONTEXT } from '../utils/mutationResult';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\n\n/** Every query that lists or shows a template, so a delete or edit is visible everywhere without a manual reload. */\nexport const TEMPLATE_QUERIES = ['TemplatesList', 'GetTemplate'];\n\nconst DELETE = gql`\n mutation TemplateControlsDelete($id: ID!) {\n planmagnetDeleteProjectTemplate(id: $id)\n }\n`;\n\n/**\n * Deleting a built-in template is technically accepted by the service (nothing in `TemplateService.delete`\n * checks `isBuiltIn`), but a system-provided starting point disappearing under an ordinary edit is the kind of\n * surprise a production UI should not hand out for free — so this button stays disabled for one, with the\n * reason in a tooltip, rather than silently letting a click remove it.\n */\nexport function TemplateDeleteButton({\n templateId,\n name,\n isBuiltIn,\n onDeleted,\n}: {\n templateId: string;\n name: string;\n isBuiltIn: boolean;\n onDeleted?: () => void;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [remove, { loading }] = useMutation(DELETE, {\n refetchQueries: TEMPLATE_QUERIES.filter((q) => q !== 'GetTemplate'),\n context: LEAVES_PAGE_CONTEXT,\n });\n const [error, setError] = useState<string | null>(null);\n\n const onDelete = async () => {\n setError(null);\n try {\n await throwOnError(remove({ variables: { id: templateId } }));\n if (onDeleted) onDeleted();\n else navigate('/templates/templates-page');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The template could not be deleted.');\n }\n };\n\n if (isBuiltIn) {\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span>\n <Button size=\"sm\" variant=\"outline\" disabled data-testid=\"template-delete\">\n <Trash2 className=\"mr-1 h-4 w-4\" />\n Delete\n </Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>Built-in templates can&apos;t be deleted.</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n }\n\n return (\n <div className=\"flex flex-col items-end gap-1\">\n <ConfirmButton\n label=\"Delete\"\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete \"${name}\"?`}\n description=\"Projects already created from it are unaffected. This cannot be undone here.\"\n confirmLabel=\"Delete template\"\n destructive\n disabled={loading}\n onConfirm={() => void onDelete()}\n />\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,IAAa,IAAmB,CAAC,iBAAiB,cAAc,EAE1D,IAAS,CAAG;;;;;AAYlB,SAAgB,EAAqB,EACnC,eACA,SACA,cACA,gBAMC;CACD,IAAM,IAAW,GAAuB,EAClC,CAAC,GAAQ,EAAE,gBAAa,EAAY,GAAQ;EAChD,gBAAgB,EAAiB,QAAQ,MAAM,MAAM,cAAc;EACnE,SAAS;EACV,CAAC,EACI,CAAC,GAAO,KAAY,EAAwB,KAAK,EAEjD,IAAW,YAAY;AAC3B,IAAS,KAAK;AACd,MAAI;AAEF,GADA,MAAM,EAAa,EAAO,EAAE,WAAW,EAAE,IAAI,GAAY,EAAE,CAAC,CAAC,EACzD,IAAW,GAAW,GACrB,EAAS,4BAA4B;WACnC,GAAG;AACV,KAAS,aAAa,QAAQ,EAAE,UAAU,qCAAqC;;;AAsBnF,QAlBI,IAEA,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAgB,SAAA;YACd,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD;GAAQ,MAAK;GAAK,SAAQ;GAAU,UAAA;GAAS,eAAY;aAAzD,CACE,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA,EAAA,SAE5B;MACJ,CAAA;EACQ,CAAA,EACjB,kBAAC,GAAD,EAAA,UAAgB,wCAA0D,CAAA,CAClE,EAAA,CAAA,EACM,CAAA,GAKpB,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD;GACE,OAAM;GACN,SAAQ;GACR,MAAM,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA;GACzC,OAAO,WAAW,EAAK;GACvB,aAAY;GACZ,cAAa;GACb,aAAA;GACA,UAAU;GACV,iBAAiB,KAAK,GAAU;GAChC,CAAA,EACD,KAAS,kBAAC,GAAD,EAAW,SAAS,GAAS,CAAA,CACnC"}
@@ -224,6 +224,6 @@ function N({ workItemId: e, title: n }) {
224
224
  });
225
225
  }
226
226
  //#endregion
227
- export { j as AssigneeSelect, b as WORK_ITEM_PRIORITIES, M as WorkItemAssigneeSelect, O as WorkItemEnumSelect, N as WorkItemHeaderActions, k as WorkItemStatusSelect, x as enumLabel };
227
+ export { j as AssigneeSelect, b as WORK_ITEM_PRIORITIES, y as WORK_ITEM_STATUSES, M as WorkItemAssigneeSelect, O as WorkItemEnumSelect, N as WorkItemHeaderActions, k as WorkItemStatusSelect, x as enumLabel, A as useAssigneeOptions };
228
228
 
229
229
  //# sourceMappingURL=WorkItemControls.js.map
@@ -1,7 +1,27 @@
1
+ import { ReactNode } from 'react';
2
+
1
3
  export declare function NewReleaseDialog({ onCreated }: {
2
4
  onCreated: (releaseId: string) => void;
3
5
  }): import("react/jsx-runtime").JSX.Element;
4
6
  export declare function NewMilestoneDialog({ onCreated }: {
5
7
  onCreated: (milestoneId: string) => void;
6
8
  }): import("react/jsx-runtime").JSX.Element;
9
+ /** `projectId`/`projectName` pre-fill the dialog when opened from a project's own page; otherwise the user
10
+ * picks one. */
11
+ export declare function NewTemplateFromProjectDialog({ projectId: fixedProjectId, projectName, onCreated, trigger, }: {
12
+ projectId?: string;
13
+ projectName?: string;
14
+ onCreated: (templateId: string) => void;
15
+ trigger?: ReactNode;
16
+ }): import("react/jsx-runtime").JSX.Element;
17
+ export declare function ApplyTemplateDialog({ templateId, templateName, onApplied, }: {
18
+ templateId: string;
19
+ templateName: string;
20
+ onApplied: (projectId: string) => void;
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ /** projectId, when given, pins the risk to that project and hides the project picker (opened from a project page). */
23
+ export declare function NewRiskDialog({ projectId: fixedProjectId, onCreated, }: {
24
+ projectId?: string;
25
+ onCreated: (riskId: string) => void;
26
+ }): import("react/jsx-runtime").JSX.Element;
7
27
  //# sourceMappingURL=CreateDialogs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CreateDialogs.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/create/CreateDialogs.tsx"],"names":[],"mappings":"AAwLA,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CAsGzF;AAcD,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CA+F7F"}
1
+ {"version":3,"file":"CreateDialogs.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/create/CreateDialogs.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA0LjD,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CAsGzF;AAcD,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CA+F7F;AAsBD;gBACgB;AAChB,wBAAgB,4BAA4B,CAAC,EAC3C,SAAS,EAAE,cAAc,EACzB,WAAW,EACX,SAAS,EACT,OAAO,GACR,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,2CA0FA;AAaD,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,YAAY,EACZ,SAAS,GACV,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,2CAoGA;AA8CD,sHAAsH;AACtH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EAAE,cAAc,EACzB,SAAS,GACV,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,2CAgJA"}