@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.
- package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.js +126 -84
- package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +192 -64
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts +5 -0
- package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts.map +1 -0
- package/dist/planmagnet/automation/AutomationExecutionsPanel.js +107 -0
- package/dist/planmagnet/automation/AutomationExecutionsPanel.js.map +1 -0
- package/dist/planmagnet/automation/AutomationRuleFields.d.ts +29 -0
- package/dist/planmagnet/automation/AutomationRuleFields.d.ts.map +1 -0
- package/dist/planmagnet/automation/AutomationRuleFields.js +308 -0
- package/dist/planmagnet/automation/AutomationRuleFields.js.map +1 -0
- package/dist/planmagnet/automation/automationRuleTypes.d.ts +60 -0
- package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -0
- package/dist/planmagnet/automation/automationRuleTypes.js +113 -0
- package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -0
- package/dist/planmagnet/board/BulkActions.d.ts +11 -0
- package/dist/planmagnet/board/BulkActions.d.ts.map +1 -0
- package/dist/planmagnet/board/BulkActions.js +182 -0
- package/dist/planmagnet/board/BulkActions.js.map +1 -0
- package/dist/planmagnet/board/ProjectBoard.d.ts.map +1 -1
- package/dist/planmagnet/board/ProjectBoard.js +289 -254
- package/dist/planmagnet/board/ProjectBoard.js.map +1 -1
- package/dist/planmagnet/budgets/BudgetControls.d.ts +30 -0
- package/dist/planmagnet/budgets/BudgetControls.d.ts.map +1 -0
- package/dist/planmagnet/budgets/BudgetControls.js +470 -0
- package/dist/planmagnet/budgets/BudgetControls.js.map +1 -0
- package/dist/planmagnet/budgets/ExpenseControls.d.ts +27 -0
- package/dist/planmagnet/budgets/ExpenseControls.d.ts.map +1 -0
- package/dist/planmagnet/budgets/ExpenseControls.js +366 -0
- package/dist/planmagnet/budgets/ExpenseControls.js.map +1 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts +5 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts.map +1 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.js +112 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.js.map +1 -0
- package/dist/planmagnet/budgets/budgetMath.d.ts +26 -0
- package/dist/planmagnet/budgets/budgetMath.d.ts.map +1 -0
- package/dist/planmagnet/budgets/budgetMath.js +49 -0
- package/dist/planmagnet/budgets/budgetMath.js.map +1 -0
- package/dist/planmagnet/controls/AutomationRuleControls.d.ts +23 -0
- package/dist/planmagnet/controls/AutomationRuleControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/AutomationRuleControls.js +172 -0
- package/dist/planmagnet/controls/AutomationRuleControls.js.map +1 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts +20 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/CompetitorControls.js +172 -0
- package/dist/planmagnet/controls/CompetitorControls.js.map +1 -0
- package/dist/planmagnet/controls/CustomFieldControls.d.ts +42 -0
- package/dist/planmagnet/controls/CustomFieldControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/CustomFieldControls.js +84 -0
- package/dist/planmagnet/controls/CustomFieldControls.js.map +1 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts +8 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts.map +1 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.js +315 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.js.map +1 -0
- package/dist/planmagnet/controls/FeatureControls.js +53 -53
- package/dist/planmagnet/controls/FeatureTriage.js +11 -11
- package/dist/planmagnet/controls/ObjectiveControls.js +37 -37
- package/dist/planmagnet/controls/Pickers.d.ts +17 -2
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +100 -9
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/controls/PortfolioControls.d.ts +13 -0
- package/dist/planmagnet/controls/PortfolioControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/PortfolioControls.js +114 -0
- package/dist/planmagnet/controls/PortfolioControls.js.map +1 -0
- package/dist/planmagnet/controls/ProgramControls.d.ts +25 -0
- package/dist/planmagnet/controls/ProgramControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ProgramControls.js +187 -0
- package/dist/planmagnet/controls/ProgramControls.js.map +1 -0
- package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/ProjectControls.js +54 -47
- package/dist/planmagnet/controls/ProjectControls.js.map +1 -1
- package/dist/planmagnet/controls/ReleaseControls.js +7 -7
- package/dist/planmagnet/controls/RiskControls.d.ts +27 -0
- package/dist/planmagnet/controls/RiskControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/RiskControls.js +346 -0
- package/dist/planmagnet/controls/RiskControls.js.map +1 -0
- package/dist/planmagnet/controls/TemplateControls.d.ts +15 -0
- package/dist/planmagnet/controls/TemplateControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/TemplateControls.js +55 -0
- package/dist/planmagnet/controls/TemplateControls.js.map +1 -0
- package/dist/planmagnet/controls/WorkItemControls.js +1 -1
- package/dist/planmagnet/create/CreateDialogs.d.ts +20 -0
- package/dist/planmagnet/create/CreateDialogs.d.ts.map +1 -1
- package/dist/planmagnet/create/CreateDialogs.js +455 -116
- package/dist/planmagnet/create/CreateDialogs.js.map +1 -1
- package/dist/planmagnet/dependency/DependencyPanel.d.ts +6 -0
- package/dist/planmagnet/dependency/DependencyPanel.d.ts.map +1 -0
- package/dist/planmagnet/dependency/DependencyPanel.js +310 -0
- package/dist/planmagnet/dependency/DependencyPanel.js.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +171 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js +232 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js.map +1 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts +2 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +93 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +127 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +129 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +132 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +181 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js +242 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +302 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +335 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +154 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +124 -138
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +221 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +279 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js +178 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +157 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js +315 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +186 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js +164 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js +348 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +130 -103
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +4 -4
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +4 -4
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +6 -6
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +325 -189
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +81 -72
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.js +278 -0
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js +191 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +5 -5
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js +4 -4
- package/dist/planmagnet/pages/TasksImportPagePage.js +5 -5
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +161 -137
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.js +124 -113
- package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +263 -0
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js +254 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.js +165 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js +316 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js.map +1 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js +208 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js.map +1 -0
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts +0 -5
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts.map +1 -1
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +47 -89
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.js +24 -24
- package/dist/planmagnet/time/TaskTimePanel.d.ts +7 -0
- package/dist/planmagnet/time/TaskTimePanel.d.ts.map +1 -0
- package/dist/planmagnet/time/TaskTimePanel.js +104 -0
- package/dist/planmagnet/time/TaskTimePanel.js.map +1 -0
- package/dist/planmagnet/time/TimeEntryControls.d.ts +37 -0
- package/dist/planmagnet/time/TimeEntryControls.d.ts.map +1 -0
- package/dist/planmagnet/time/TimeEntryControls.js +338 -0
- package/dist/planmagnet/time/TimeEntryControls.js.map +1 -0
- package/dist/planmagnet/time/TimesheetControls.d.ts +18 -0
- package/dist/planmagnet/time/TimesheetControls.d.ts.map +1 -0
- package/dist/planmagnet/time/TimesheetControls.js +244 -0
- package/dist/planmagnet/time/TimesheetControls.js.map +1 -0
- package/dist/planmagnet/time/timeShared.d.ts +29 -0
- package/dist/planmagnet/time/timeShared.d.ts.map +1 -0
- package/dist/planmagnet/time/timeShared.js +34 -0
- package/dist/planmagnet/time/timeShared.js.map +1 -0
- package/dist/planmagnet/utils/rowNavigation.js +5 -2
- package/dist/planmagnet/utils/rowNavigation.js.map +1 -1
- 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'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":"
|
|
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"}
|