@burdenoff/microfe-planmagnet 2026.927.3 → 2026.927.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/generated/global-types.d.ts +9 -1
- package/dist/generated/global-types.d.ts.map +1 -1
- package/dist/generated/wspace-operations.d.ts +0 -12
- package/dist/generated/wspace-operations.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +14 -10
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.d.ts.map +1 -1
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js +149 -127
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts +26 -0
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/FeatureControls.js +321 -0
- package/dist/planmagnet/controls/FeatureControls.js.map +1 -0
- package/dist/planmagnet/controls/FeatureTriage.d.ts +21 -0
- package/dist/planmagnet/controls/FeatureTriage.d.ts.map +1 -0
- package/dist/planmagnet/controls/FeatureTriage.js +398 -0
- package/dist/planmagnet/controls/FeatureTriage.js.map +1 -0
- package/dist/planmagnet/controls/MilestoneControls.d.ts +17 -0
- package/dist/planmagnet/controls/MilestoneControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/MilestoneControls.js +203 -0
- package/dist/planmagnet/controls/MilestoneControls.js.map +1 -0
- package/dist/planmagnet/controls/ObjectiveControls.d.ts +31 -0
- package/dist/planmagnet/controls/ObjectiveControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ObjectiveControls.js +296 -0
- package/dist/planmagnet/controls/ObjectiveControls.js.map +1 -0
- package/dist/planmagnet/controls/Pickers.d.ts +26 -0
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -0
- package/dist/planmagnet/controls/Pickers.js +171 -0
- package/dist/planmagnet/controls/Pickers.js.map +1 -0
- package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/ProjectControls.js +47 -44
- package/dist/planmagnet/controls/ProjectControls.js.map +1 -1
- package/dist/planmagnet/controls/ReleaseControls.d.ts +14 -0
- package/dist/planmagnet/controls/ReleaseControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ReleaseControls.js +111 -0
- package/dist/planmagnet/controls/ReleaseControls.js.map +1 -0
- package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/WorkItemControls.js +68 -65
- package/dist/planmagnet/controls/WorkItemControls.js.map +1 -1
- package/dist/planmagnet/hooks/useCounts.d.ts +39 -0
- package/dist/planmagnet/hooks/useCounts.d.ts.map +1 -0
- package/dist/planmagnet/hooks/useCounts.js +209 -0
- package/dist/planmagnet/hooks/useCounts.js.map +1 -0
- package/dist/planmagnet/import/exportColumns.d.ts +52 -0
- package/dist/planmagnet/import/exportColumns.d.ts.map +1 -0
- package/dist/planmagnet/import/exportColumns.js +81 -0
- package/dist/planmagnet/import/exportColumns.js.map +1 -0
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +255 -242
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/DashboardDashboardPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js +199 -160
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +190 -153
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js +63 -56
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js.map +1 -1
- package/dist/planmagnet/pages/GoalsGoalsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/GoalsGoalsPagePage.js +2 -7
- package/dist/planmagnet/pages/GoalsGoalsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js +229 -214
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js +145 -114
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.js +134 -105
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureAnalyticsPagePage.js +97 -117
- package/dist/planmagnet/pages/ProductsFeatureAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +169 -110
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +117 -103
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +119 -94
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +4 -8
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.js +85 -90
- package/dist/planmagnet/pages/ProductsProductsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js +118 -107
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsReleasesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsReleasesPagePage.js +4 -2
- package/dist/planmagnet/pages/ProductsReleasesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js +48 -71
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js +17 -13
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsActiveProjectsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsActiveProjectsPagePage.js +1 -1
- package/dist/planmagnet/pages/ProjectsActiveProjectsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +55 -63
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +11 -8
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningPagePage.js +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +152 -139
- 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 +75 -74
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts +7 -0
- package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ReportsReportsPagePage.js +39 -201
- package/dist/planmagnet/pages/ReportsReportsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +118 -99
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +123 -128
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksEditTaskPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js +139 -107
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksImportPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TasksImportPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TasksImportPagePage.js +309 -0
- package/dist/planmagnet/pages/TasksImportPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +173 -126
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.js +111 -104
- package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js +99 -177
- package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts.map +1 -1
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +8 -4
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js.map +1 -1
- package/dist/planmagnet/releases/ReleaseWorkItemsCard.d.ts.map +1 -1
- package/dist/planmagnet/releases/ReleaseWorkItemsCard.js +10 -4
- package/dist/planmagnet/releases/ReleaseWorkItemsCard.js.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.js +150 -137
- package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -1
- package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
- package/dist/planmagnet/sprints/SprintControls.js +32 -30
- package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
- package/dist/planmagnet/utils/mutationResult.d.ts +10 -0
- package/dist/planmagnet/utils/mutationResult.d.ts.map +1 -1
- package/dist/planmagnet/utils/mutationResult.js +2 -1
- package/dist/planmagnet/utils/mutationResult.js.map +1 -1
- package/dist/planmagnet/utils/rowNavigation.d.ts +2 -0
- package/dist/planmagnet/utils/rowNavigation.d.ts.map +1 -1
- package/dist/planmagnet/utils/rowNavigation.js +9 -8
- package/dist/planmagnet/utils/rowNavigation.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,104 +1,107 @@
|
|
|
1
1
|
import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import { detailPath as
|
|
4
|
-
import { ConfirmButton as
|
|
5
|
-
import { enumLabel as
|
|
6
|
-
import { useState as
|
|
7
|
-
import { Pencil as
|
|
8
|
-
import { gql as
|
|
9
|
-
import { useMutation as
|
|
10
|
-
import { jsx as
|
|
11
|
-
import { Button as
|
|
2
|
+
import { LEAVES_PAGE_CONTEXT as t, throwOnError as n } from "../utils/mutationResult.js";
|
|
3
|
+
import { detailPath as r } from "../utils/rowNavigation.js";
|
|
4
|
+
import { ConfirmButton as i, ErrorLine as a } from "./ConfirmButton.js";
|
|
5
|
+
import { enumLabel as o } from "./WorkItemControls.js";
|
|
6
|
+
import { useState as s } from "react";
|
|
7
|
+
import { Pencil as c, Trash2 as l } from "lucide-react";
|
|
8
|
+
import { gql as u } from "@apollo/client";
|
|
9
|
+
import { useMutation as d } from "@apollo/client/react";
|
|
10
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
11
|
+
import { Button as m } from "@burdenoff/fe-libs/ui";
|
|
12
12
|
//#region src/planmagnet/controls/ProjectControls.tsx
|
|
13
|
-
var
|
|
13
|
+
var h = [
|
|
14
14
|
"PLANNING",
|
|
15
15
|
"ACTIVE",
|
|
16
16
|
"ON_HOLD",
|
|
17
17
|
"COMPLETED",
|
|
18
18
|
"CANCELLED",
|
|
19
19
|
"ARCHIVED"
|
|
20
|
-
],
|
|
20
|
+
], g = u`
|
|
21
21
|
mutation ProjectControlsStatus($id: ID!, $input: PlanmagnetUpdateProjectInput!) {
|
|
22
22
|
planmagnetUpdateProject(id: $id, input: $input) {
|
|
23
23
|
id
|
|
24
24
|
status
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
`,
|
|
27
|
+
`, _ = u`
|
|
28
28
|
mutation ProjectControlsDelete($id: ID!) {
|
|
29
29
|
planmagnetDeleteProject(id: $id)
|
|
30
30
|
}
|
|
31
|
-
`,
|
|
31
|
+
`, v = [
|
|
32
32
|
"GetProjects",
|
|
33
33
|
"GetActiveProjects",
|
|
34
34
|
"GetBoardProjects",
|
|
35
35
|
"GetDashboardData",
|
|
36
36
|
"AdminPlanmagnetProjects"
|
|
37
37
|
];
|
|
38
|
-
function
|
|
39
|
-
let
|
|
40
|
-
refetchQueries: ["GetProjectDetail", ...
|
|
38
|
+
function y({ projectId: u, name: y, status: b }) {
|
|
39
|
+
let x = e(), [S, C] = d(g, {
|
|
40
|
+
refetchQueries: ["GetProjectDetail", ...v],
|
|
41
41
|
awaitRefetchQueries: !0
|
|
42
|
-
}), [
|
|
43
|
-
|
|
42
|
+
}), [w, T] = d(_, {
|
|
43
|
+
refetchQueries: v,
|
|
44
|
+
context: t
|
|
45
|
+
}), [E, D] = s(null), O = C.loading || T.loading, k = h.includes(b) ? h : [b, ...h], A = async (e) => {
|
|
46
|
+
D(null);
|
|
44
47
|
try {
|
|
45
|
-
await
|
|
46
|
-
id:
|
|
48
|
+
await n(S({ variables: {
|
|
49
|
+
id: u,
|
|
47
50
|
input: { status: e }
|
|
48
51
|
} }));
|
|
49
52
|
} catch (e) {
|
|
50
|
-
|
|
53
|
+
D(e instanceof Error ? e.message : "The status could not be changed.");
|
|
51
54
|
}
|
|
52
|
-
},
|
|
53
|
-
|
|
55
|
+
}, j = async () => {
|
|
56
|
+
D(null);
|
|
54
57
|
try {
|
|
55
|
-
await
|
|
58
|
+
await n(w({ variables: { id: u } })), x("/projects/projects-page");
|
|
56
59
|
} catch (e) {
|
|
57
|
-
|
|
60
|
+
D(e instanceof Error ? e.message : "The project could not be deleted.");
|
|
58
61
|
}
|
|
59
62
|
};
|
|
60
|
-
return /* @__PURE__ */
|
|
63
|
+
return /* @__PURE__ */ p("div", {
|
|
61
64
|
className: "flex flex-col items-end gap-2",
|
|
62
|
-
children: [/* @__PURE__ */
|
|
65
|
+
children: [/* @__PURE__ */ p("div", {
|
|
63
66
|
className: "flex flex-wrap items-center justify-end gap-2",
|
|
64
67
|
children: [
|
|
65
|
-
/* @__PURE__ */
|
|
68
|
+
/* @__PURE__ */ f("select", {
|
|
66
69
|
"aria-label": "Project status",
|
|
67
70
|
"data-testid": "project-status",
|
|
68
71
|
className: "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60",
|
|
69
|
-
value:
|
|
70
|
-
disabled:
|
|
72
|
+
value: b,
|
|
73
|
+
disabled: O,
|
|
71
74
|
onChange: (e) => {
|
|
72
|
-
e.target.value !==
|
|
75
|
+
e.target.value !== b && A(e.target.value);
|
|
73
76
|
},
|
|
74
|
-
children:
|
|
77
|
+
children: k.map((e) => /* @__PURE__ */ f("option", {
|
|
75
78
|
value: e,
|
|
76
|
-
children:
|
|
79
|
+
children: o(e)
|
|
77
80
|
}, e))
|
|
78
81
|
}),
|
|
79
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ p(m, {
|
|
80
83
|
size: "sm",
|
|
81
84
|
variant: "outline",
|
|
82
85
|
"data-testid": "project-edit",
|
|
83
|
-
onClick: () =>
|
|
84
|
-
children: [/* @__PURE__ */
|
|
86
|
+
onClick: () => x(r("/projects/edit-project-page", u)),
|
|
87
|
+
children: [/* @__PURE__ */ f(c, { className: "mr-1 h-4 w-4" }), "Edit"]
|
|
85
88
|
}),
|
|
86
|
-
/* @__PURE__ */
|
|
89
|
+
/* @__PURE__ */ f(i, {
|
|
87
90
|
label: "Delete",
|
|
88
91
|
variant: "outline",
|
|
89
|
-
icon: /* @__PURE__ */
|
|
90
|
-
title: `Delete ${
|
|
92
|
+
icon: /* @__PURE__ */ f(l, { className: "mr-1 h-4 w-4" }),
|
|
93
|
+
title: `Delete ${y}?`,
|
|
91
94
|
description: "The project is deleted. Its tasks, sprints, boards, milestones and budgets disappear from every list, and so do releases that belong to no other project. This cannot be undone here.",
|
|
92
95
|
confirmLabel: "Delete project",
|
|
93
96
|
destructive: !0,
|
|
94
|
-
disabled:
|
|
95
|
-
onConfirm: () => void
|
|
97
|
+
disabled: O,
|
|
98
|
+
onConfirm: () => void j()
|
|
96
99
|
})
|
|
97
100
|
]
|
|
98
|
-
}),
|
|
101
|
+
}), E && /* @__PURE__ */ f(a, { message: E })]
|
|
99
102
|
});
|
|
100
103
|
}
|
|
101
104
|
//#endregion
|
|
102
|
-
export {
|
|
105
|
+
export { h as PROJECT_STATUSES, y as ProjectHeaderActions };
|
|
103
106
|
|
|
104
107
|
//# sourceMappingURL=ProjectControls.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectControls.js","names":[],"sources":["../../../src/planmagnet/controls/ProjectControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Pencil, Trash2 } from 'lucide-react';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\nimport { ConfirmButton, ErrorLine } from './ConfirmButton';\nimport { enumLabel } from './WorkItemControls';\n\n/**\n * Project controls (BOFF-7940). A new project starts in PLANNING and, until 2026-09-27, nothing in the UI could\n * move it: no status control, and the Edit Project page (which had no Status field) was linked from nowhere. So\n * Projects > Active, the Dashboard's project status card and the admin Bulk Archive never showed a project created\n * in the UI.\n */\n\nexport const PROJECT_STATUSES = [\n 'PLANNING',\n 'ACTIVE',\n 'ON_HOLD',\n 'COMPLETED',\n 'CANCELLED',\n 'ARCHIVED',\n] as const;\n\nconst UPDATE_PROJECT_STATUS = gql`\n mutation ProjectControlsStatus($id: ID!, $input: PlanmagnetUpdateProjectInput!) {\n planmagnetUpdateProject(id: $id, input: $input) {\n id\n status\n }\n }\n`;\nconst DELETE_PROJECT = gql`\n mutation ProjectControlsDelete($id: ID!) {\n planmagnetDeleteProject(id: $id)\n }\n`;\n\n/** Every query that lists projects or shows a project's status. */\nconst PROJECT_LIST_QUERIES = [\n 'GetProjects',\n 'GetActiveProjects',\n 'GetBoardProjects',\n 'GetDashboardData',\n 'AdminPlanmagnetProjects',\n];\n\nexport function ProjectHeaderActions({\n projectId,\n name,\n status,\n}: {\n projectId: string;\n name: string;\n status: string;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [updateStatus, statusState] = useMutation(UPDATE_PROJECT_STATUS, {\n refetchQueries: ['GetProjectDetail', ...PROJECT_LIST_QUERIES],\n awaitRefetchQueries: true,\n });\n const [remove, removeState] = useMutation(DELETE_PROJECT, {\n refetchQueries: PROJECT_LIST_QUERIES,\n });\n const [error, setError] = useState<string | null>(null);\n const busy = statusState.loading || removeState.loading;\n const statuses = (PROJECT_STATUSES as readonly string[]).includes(status)\n ? PROJECT_STATUSES\n : [status, ...PROJECT_STATUSES];\n\n const onStatus = async (next: string) => {\n setError(null);\n try {\n await throwOnError(updateStatus({ variables: { id: projectId, input: { status: next } } }));\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: projectId } }));\n navigate('/projects/projects-page');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The project 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=\"Project status\"\n data-testid=\"project-status\"\n className=\"rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60\"\n value={status}\n disabled={busy}\n onChange={(e) => {\n if (e.target.value !== 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 <Button\n size=\"sm\"\n variant=\"outline\"\n data-testid=\"project-edit\"\n onClick={() => navigate(detailPath('/projects/edit-project-page', projectId))}\n >\n <Pencil className=\"mr-1 h-4 w-4\" />\n Edit\n </Button>\n <ConfirmButton\n label=\"Delete\"\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete ${name}?`}\n description=\"The project is deleted. Its tasks, sprints, boards, milestones and budgets disappear from every list, and so do releases that belong to no other project. This cannot be undone here.\"\n confirmLabel=\"Delete project\"\n destructive\n disabled={busy}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,IAAa,IAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACD,EAEK,IAAwB,CAAG;;;;;;;GAQ3B,IAAiB,CAAG;;;;GAOpB,IAAuB;CAC3B;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,EAAqB,EACnC,cACA,SACA,aAKC;CACD,IAAM,IAAW,GAAuB,EAClC,CAAC,GAAc,KAAe,EAAY,GAAuB;EACrE,gBAAgB,CAAC,oBAAoB,GAAG,EAAqB;EAC7D,qBAAqB;EACtB,CAAC,EACI,CAAC,GAAQ,KAAe,EAAY,GAAgB
|
|
1
|
+
{"version":3,"file":"ProjectControls.js","names":[],"sources":["../../../src/planmagnet/controls/ProjectControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Pencil, Trash2 } from 'lucide-react';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError, LEAVES_PAGE_CONTEXT } from '../utils/mutationResult';\nimport { ConfirmButton, ErrorLine } from './ConfirmButton';\nimport { enumLabel } from './WorkItemControls';\n\n/**\n * Project controls (BOFF-7940). A new project starts in PLANNING and, until 2026-09-27, nothing in the UI could\n * move it: no status control, and the Edit Project page (which had no Status field) was linked from nowhere. So\n * Projects > Active, the Dashboard's project status card and the admin Bulk Archive never showed a project created\n * in the UI.\n */\n\nexport const PROJECT_STATUSES = [\n 'PLANNING',\n 'ACTIVE',\n 'ON_HOLD',\n 'COMPLETED',\n 'CANCELLED',\n 'ARCHIVED',\n] as const;\n\nconst UPDATE_PROJECT_STATUS = gql`\n mutation ProjectControlsStatus($id: ID!, $input: PlanmagnetUpdateProjectInput!) {\n planmagnetUpdateProject(id: $id, input: $input) {\n id\n status\n }\n }\n`;\nconst DELETE_PROJECT = gql`\n mutation ProjectControlsDelete($id: ID!) {\n planmagnetDeleteProject(id: $id)\n }\n`;\n\n/** Every query that lists projects or shows a project's status. */\nconst PROJECT_LIST_QUERIES = [\n 'GetProjects',\n 'GetActiveProjects',\n 'GetBoardProjects',\n 'GetDashboardData',\n 'AdminPlanmagnetProjects',\n];\n\nexport function ProjectHeaderActions({\n projectId,\n name,\n status,\n}: {\n projectId: string;\n name: string;\n status: string;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [updateStatus, statusState] = useMutation(UPDATE_PROJECT_STATUS, {\n refetchQueries: ['GetProjectDetail', ...PROJECT_LIST_QUERIES],\n awaitRefetchQueries: true,\n });\n const [remove, removeState] = useMutation(DELETE_PROJECT, {\n refetchQueries: PROJECT_LIST_QUERIES,\n context: LEAVES_PAGE_CONTEXT,\n });\n const [error, setError] = useState<string | null>(null);\n const busy = statusState.loading || removeState.loading;\n const statuses = (PROJECT_STATUSES as readonly string[]).includes(status)\n ? PROJECT_STATUSES\n : [status, ...PROJECT_STATUSES];\n\n const onStatus = async (next: string) => {\n setError(null);\n try {\n await throwOnError(updateStatus({ variables: { id: projectId, input: { status: next } } }));\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: projectId } }));\n navigate('/projects/projects-page');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The project 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=\"Project status\"\n data-testid=\"project-status\"\n className=\"rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60\"\n value={status}\n disabled={busy}\n onChange={(e) => {\n if (e.target.value !== 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 <Button\n size=\"sm\"\n variant=\"outline\"\n data-testid=\"project-edit\"\n onClick={() => navigate(detailPath('/projects/edit-project-page', projectId))}\n >\n <Pencil className=\"mr-1 h-4 w-4\" />\n Edit\n </Button>\n <ConfirmButton\n label=\"Delete\"\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete ${name}?`}\n description=\"The project is deleted. Its tasks, sprints, boards, milestones and budgets disappear from every list, and so do releases that belong to no other project. This cannot be undone here.\"\n confirmLabel=\"Delete project\"\n destructive\n disabled={busy}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,IAAa,IAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACD,EAEK,IAAwB,CAAG;;;;;;;GAQ3B,IAAiB,CAAG;;;;GAOpB,IAAuB;CAC3B;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,EAAqB,EACnC,cACA,SACA,aAKC;CACD,IAAM,IAAW,GAAuB,EAClC,CAAC,GAAc,KAAe,EAAY,GAAuB;EACrE,gBAAgB,CAAC,oBAAoB,GAAG,EAAqB;EAC7D,qBAAqB;EACtB,CAAC,EACI,CAAC,GAAQ,KAAe,EAAY,GAAgB;EACxD,gBAAgB;EAChB,SAAS;EACV,CAAC,EACI,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,IAAO,EAAY,WAAW,EAAY,SAC1C,IAAY,EAAuC,SAAS,EAAO,GACrE,IACA,CAAC,GAAQ,GAAG,EAAiB,EAE3B,IAAW,OAAO,MAAiB;AACvC,IAAS,KAAK;AACd,MAAI;AACF,SAAM,EAAa,EAAa,EAAE,WAAW;IAAE,IAAI;IAAW,OAAO,EAAE,QAAQ,GAAM;IAAE,EAAE,CAAC,CAAC;WACpF,GAAG;AACV,KAAS,aAAa,QAAQ,EAAE,UAAU,mCAAmC;;IAG3E,IAAW,YAAY;AAC3B,IAAS,KAAK;AACd,MAAI;AAEF,GADA,MAAM,EAAa,EAAO,EAAE,WAAW,EAAE,IAAI,GAAW,EAAE,CAAC,CAAC,EAC5D,EAAS,0BAA0B;WAC5B,GAAG;AACV,KAAS,aAAa,QAAQ,EAAE,UAAU,oCAAoC;;;AAIlF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,UAAD;KACE,cAAW;KACX,eAAY;KACZ,WAAU;KACV,OAAO;KACP,UAAU;KACV,WAAW,MAAM;AACf,MAAI,EAAE,OAAO,UAAU,KAAa,EAAS,EAAE,OAAO,MAAM;;eAG7D,EAAS,KAAK,MACb,kBAAC,UAAD;MAAgB,OAAO;gBACpB,EAAU,EAAE;MACN,EAFI,EAEJ,CACT;KACK,CAAA;IACT,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,eAAY;KACZ,eAAe,EAAS,EAAW,+BAA+B,EAAU,CAAC;eAJ/E,CAME,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA,EAAA,OAE5B;;IACT,kBAAC,GAAD;KACE,OAAM;KACN,SAAQ;KACR,MAAM,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA;KACzC,OAAO,UAAU,EAAK;KACtB,aAAY;KACZ,cAAa;KACb,aAAA;KACA,UAAU;KACV,iBAAiB,KAAK,GAAU;KAChC,CAAA;IACE;MACL,KAAS,kBAAC,GAAD,EAAW,SAAS,GAAS,CAAA,CACnC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Release controls (BOFF-7952). A release started in Planning and could never be released: status showed only as
|
|
3
|
+
* badges, the Edit Release page was linked from nowhere, and nothing deleted a release. The Quality Gates card even
|
|
4
|
+
* said the release "cannot be released until the gates pass" — with nothing to click once they had. The service
|
|
5
|
+
* refuses RELEASED while a gate is open; that reason is shown here.
|
|
6
|
+
*/
|
|
7
|
+
/** Every ReleaseStatus value (the Edit page's list omitted STAGING — BOFF-7985). */
|
|
8
|
+
export declare const RELEASE_STATUSES: readonly ["DRAFT", "PLANNING", "IN_PROGRESS", "READY", "STAGING", "RELEASED", "ROLLED_BACK", "CANCELLED"];
|
|
9
|
+
export declare function ReleaseHeaderActions({ releaseId, version, status, }: {
|
|
10
|
+
releaseId: string;
|
|
11
|
+
version: string;
|
|
12
|
+
status: string;
|
|
13
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=ReleaseControls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReleaseControls.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/controls/ReleaseControls.tsx"],"names":[],"mappings":"AAWA;;;;;GAKG;AAEH,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,2GASnB,CAAC;AA0BX,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,OAAO,EACP,MAAM,GACP,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,2CA6EA"}
|
|
@@ -0,0 +1,111 @@
|
|
|
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 { detailPath as r } from "../utils/rowNavigation.js";
|
|
4
|
+
import { ConfirmButton as i, ErrorLine as a } from "./ConfirmButton.js";
|
|
5
|
+
import { enumLabel as o } from "./WorkItemControls.js";
|
|
6
|
+
import { useState as s } from "react";
|
|
7
|
+
import { Pencil as c, Trash2 as l } from "lucide-react";
|
|
8
|
+
import { gql as u } from "@apollo/client";
|
|
9
|
+
import { useMutation as d } from "@apollo/client/react";
|
|
10
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
11
|
+
import { Button as m } from "@burdenoff/fe-libs/ui";
|
|
12
|
+
//#region src/planmagnet/controls/ReleaseControls.tsx
|
|
13
|
+
var h = [
|
|
14
|
+
"DRAFT",
|
|
15
|
+
"PLANNING",
|
|
16
|
+
"IN_PROGRESS",
|
|
17
|
+
"READY",
|
|
18
|
+
"STAGING",
|
|
19
|
+
"RELEASED",
|
|
20
|
+
"ROLLED_BACK",
|
|
21
|
+
"CANCELLED"
|
|
22
|
+
], g = [
|
|
23
|
+
"GetRelease",
|
|
24
|
+
"ListReleases",
|
|
25
|
+
"ListReleasesForProduct",
|
|
26
|
+
"ListReleasesForProducts",
|
|
27
|
+
"ReleaseReadiness",
|
|
28
|
+
"GetReleaseForEdit"
|
|
29
|
+
], _ = u`
|
|
30
|
+
mutation ReleaseControlsStatus($id: ID!, $input: PlanmagnetUpdateReleaseInput!) {
|
|
31
|
+
planmagnetUpdateRelease(id: $id, input: $input) {
|
|
32
|
+
id
|
|
33
|
+
status
|
|
34
|
+
releasedAt
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`, v = u`
|
|
38
|
+
mutation ReleaseControlsDelete($id: ID!) {
|
|
39
|
+
planmagnetDeleteRelease(id: $id)
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
function y({ releaseId: u, version: y, status: b }) {
|
|
43
|
+
let x = e(), [S, C] = d(_, {
|
|
44
|
+
refetchQueries: g,
|
|
45
|
+
awaitRefetchQueries: !0
|
|
46
|
+
}), [w, T] = d(v, {
|
|
47
|
+
refetchQueries: g.filter((e) => e !== "GetRelease" && e !== "ReleaseReadiness"),
|
|
48
|
+
context: t
|
|
49
|
+
}), [E, D] = s(null), O = C.loading || T.loading, k = h.includes(b) ? h : [b, ...h], A = async (e) => {
|
|
50
|
+
D(null);
|
|
51
|
+
try {
|
|
52
|
+
await n(S({ variables: {
|
|
53
|
+
id: u,
|
|
54
|
+
input: { status: e }
|
|
55
|
+
} }));
|
|
56
|
+
} catch (e) {
|
|
57
|
+
D(e instanceof Error ? e.message : "The status could not be changed.");
|
|
58
|
+
}
|
|
59
|
+
}, j = async () => {
|
|
60
|
+
D(null);
|
|
61
|
+
try {
|
|
62
|
+
await n(w({ variables: { id: u } })), x("/products/releases-page");
|
|
63
|
+
} catch (e) {
|
|
64
|
+
D(e instanceof Error ? e.message : "The release could not be deleted.");
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return /* @__PURE__ */ p("div", {
|
|
68
|
+
className: "flex flex-col items-end gap-2",
|
|
69
|
+
children: [/* @__PURE__ */ p("div", {
|
|
70
|
+
className: "flex flex-wrap items-center justify-end gap-2",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ f("select", {
|
|
73
|
+
"aria-label": "Release status",
|
|
74
|
+
"data-testid": "release-status",
|
|
75
|
+
className: "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60",
|
|
76
|
+
value: b,
|
|
77
|
+
disabled: O,
|
|
78
|
+
onChange: (e) => {
|
|
79
|
+
e.target.value !== b && A(e.target.value);
|
|
80
|
+
},
|
|
81
|
+
children: k.map((e) => /* @__PURE__ */ f("option", {
|
|
82
|
+
value: e,
|
|
83
|
+
children: o(e)
|
|
84
|
+
}, e))
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ p(m, {
|
|
87
|
+
size: "sm",
|
|
88
|
+
variant: "outline",
|
|
89
|
+
"data-testid": "release-edit",
|
|
90
|
+
onClick: () => x(r("/products/edit-release-page", u)),
|
|
91
|
+
children: [/* @__PURE__ */ f(c, { className: "mr-1 h-4 w-4" }), "Edit"]
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ f(i, {
|
|
94
|
+
label: "Delete",
|
|
95
|
+
variant: "outline",
|
|
96
|
+
icon: /* @__PURE__ */ f(l, { className: "mr-1 h-4 w-4" }),
|
|
97
|
+
title: `Delete release ${y}?`,
|
|
98
|
+
description: "The release is deleted; its work items stay. This cannot be undone here.",
|
|
99
|
+
confirmLabel: "Delete release",
|
|
100
|
+
destructive: !0,
|
|
101
|
+
disabled: O,
|
|
102
|
+
onConfirm: () => void j()
|
|
103
|
+
})
|
|
104
|
+
]
|
|
105
|
+
}), E && /* @__PURE__ */ f(a, { message: E })]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { h as RELEASE_STATUSES, y as ReleaseHeaderActions };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=ReleaseControls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReleaseControls.js","names":[],"sources":["../../../src/planmagnet/controls/ReleaseControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Pencil, Trash2 } from 'lucide-react';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError, LEAVES_PAGE_CONTEXT } from '../utils/mutationResult';\nimport { ConfirmButton, ErrorLine } from './ConfirmButton';\nimport { enumLabel } from './WorkItemControls';\n\n/**\n * Release controls (BOFF-7952). A release started in Planning and could never be released: status showed only as\n * badges, the Edit Release page was linked from nowhere, and nothing deleted a release. The Quality Gates card even\n * said the release \"cannot be released until the gates pass\" — with nothing to click once they had. The service\n * refuses RELEASED while a gate is open; that reason is shown here.\n */\n\n/** Every ReleaseStatus value (the Edit page's list omitted STAGING — BOFF-7985). */\nexport const RELEASE_STATUSES = [\n 'DRAFT',\n 'PLANNING',\n 'IN_PROGRESS',\n 'READY',\n 'STAGING',\n 'RELEASED',\n 'ROLLED_BACK',\n 'CANCELLED',\n] as const;\n\nconst RELEASE_QUERIES = [\n 'GetRelease',\n 'ListReleases',\n 'ListReleasesForProduct',\n 'ListReleasesForProducts',\n 'ReleaseReadiness',\n 'GetReleaseForEdit',\n];\n\nconst UPDATE = gql`\n mutation ReleaseControlsStatus($id: ID!, $input: PlanmagnetUpdateReleaseInput!) {\n planmagnetUpdateRelease(id: $id, input: $input) {\n id\n status\n releasedAt\n }\n }\n`;\nconst DELETE = gql`\n mutation ReleaseControlsDelete($id: ID!) {\n planmagnetDeleteRelease(id: $id)\n }\n`;\n\nexport function ReleaseHeaderActions({\n releaseId,\n version,\n status,\n}: {\n releaseId: string;\n version: string;\n status: string;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [update, updateState] = useMutation(UPDATE, {\n refetchQueries: RELEASE_QUERIES,\n awaitRefetchQueries: true,\n });\n const [remove, removeState] = useMutation(DELETE, {\n refetchQueries: RELEASE_QUERIES.filter((q) => q !== 'GetRelease' && q !== 'ReleaseReadiness'),\n context: LEAVES_PAGE_CONTEXT,\n });\n const [error, setError] = useState<string | null>(null);\n const busy = updateState.loading || removeState.loading;\n const statuses = (RELEASE_STATUSES as readonly string[]).includes(status)\n ? RELEASE_STATUSES\n : [status, ...RELEASE_STATUSES];\n\n const onStatus = async (next: string) => {\n setError(null);\n try {\n await throwOnError(update({ variables: { id: releaseId, input: { status: next } } }));\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: releaseId } }));\n navigate('/products/releases-page');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The release 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=\"Release status\"\n data-testid=\"release-status\"\n className=\"rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60\"\n value={status}\n disabled={busy}\n onChange={(e) => {\n if (e.target.value !== 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 <Button\n size=\"sm\"\n variant=\"outline\"\n data-testid=\"release-edit\"\n onClick={() => navigate(detailPath('/products/edit-release-page', releaseId))}\n >\n <Pencil className=\"mr-1 h-4 w-4\" />\n Edit\n </Button>\n <ConfirmButton\n label=\"Delete\"\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete release ${version}?`}\n description=\"The release is deleted; its work items stay. This cannot be undone here.\"\n confirmLabel=\"Delete release\"\n destructive\n disabled={busy}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAmBA,IAAa,IAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,EAEK,IAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACD,EAEK,IAAS,CAAG;;;;;;;;GASZ,IAAS,CAAG;;;;;AAMlB,SAAgB,EAAqB,EACnC,cACA,YACA,aAKC;CACD,IAAM,IAAW,GAAuB,EAClC,CAAC,GAAQ,KAAe,EAAY,GAAQ;EAChD,gBAAgB;EAChB,qBAAqB;EACtB,CAAC,EACI,CAAC,GAAQ,KAAe,EAAY,GAAQ;EAChD,gBAAgB,EAAgB,QAAQ,MAAM,MAAM,gBAAgB,MAAM,mBAAmB;EAC7F,SAAS;EACV,CAAC,EACI,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,IAAO,EAAY,WAAW,EAAY,SAC1C,IAAY,EAAuC,SAAS,EAAO,GACrE,IACA,CAAC,GAAQ,GAAG,EAAiB,EAE3B,IAAW,OAAO,MAAiB;AACvC,IAAS,KAAK;AACd,MAAI;AACF,SAAM,EAAa,EAAO,EAAE,WAAW;IAAE,IAAI;IAAW,OAAO,EAAE,QAAQ,GAAM;IAAE,EAAE,CAAC,CAAC;WAC9E,GAAG;AACV,KAAS,aAAa,QAAQ,EAAE,UAAU,mCAAmC;;IAG3E,IAAW,YAAY;AAC3B,IAAS,KAAK;AACd,MAAI;AAEF,GADA,MAAM,EAAa,EAAO,EAAE,WAAW,EAAE,IAAI,GAAW,EAAE,CAAC,CAAC,EAC5D,EAAS,0BAA0B;WAC5B,GAAG;AACV,KAAS,aAAa,QAAQ,EAAE,UAAU,oCAAoC;;;AAIlF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,UAAD;KACE,cAAW;KACX,eAAY;KACZ,WAAU;KACV,OAAO;KACP,UAAU;KACV,WAAW,MAAM;AACf,MAAI,EAAE,OAAO,UAAU,KAAa,EAAS,EAAE,OAAO,MAAM;;eAG7D,EAAS,KAAK,MACb,kBAAC,UAAD;MAAgB,OAAO;gBACpB,EAAU,EAAE;MACN,EAFI,EAEJ,CACT;KACK,CAAA;IACT,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,eAAY;KACZ,eAAe,EAAS,EAAW,+BAA+B,EAAU,CAAC;eAJ/E,CAME,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA,EAAA,OAE5B;;IACT,kBAAC,GAAD;KACE,OAAM;KACN,SAAQ;KACR,MAAM,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA;KACzC,OAAO,kBAAkB,EAAQ;KACjC,aAAY;KACZ,cAAa;KACb,aAAA;KACA,UAAU;KACV,iBAAiB,KAAK,GAAU;KAChC,CAAA;IACE;MACL,KAAS,kBAAC,GAAD,EAAW,SAAS,GAAS,CAAA,CACnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkItemControls.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/controls/WorkItemControls.tsx"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AAEH,eAAO,MAAM,kBAAkB,0FAQrB,CAAC;AACX,eAAO,MAAM,oBAAoB,wDAAyD,CAAC;AAE3F,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/C;AA0CD,wDAAwD;AACxD,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,KAAK,EACL,KAAK,EACL,OAAO,EACP,KAAK,GACN,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,2CAyBA;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;;;;;;;;EAmBtE;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,EAC7B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,2CAkCA;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,EACrC,UAAU,EACV,UAAU,GACX,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,2CAcA;AAED,kDAAkD;AAClD,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,KAAK,GACN,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,
|
|
1
|
+
{"version":3,"file":"WorkItemControls.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/controls/WorkItemControls.tsx"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AAEH,eAAO,MAAM,kBAAkB,0FAQrB,CAAC;AACX,eAAO,MAAM,oBAAoB,wDAAyD,CAAC;AAE3F,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/C;AA0CD,wDAAwD;AACxD,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,KAAK,EACL,KAAK,EACL,OAAO,EACP,KAAK,GACN,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,2CAyBA;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;;;;;;;;EAmBtE;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,EAC7B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,2CAkCA;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,EACrC,UAAU,EACV,UAAU,GACX,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,2CAcA;AAED,kDAAkD;AAClD,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,KAAK,GACN,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,2CA6CA"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { usePersonProfile as n } from "../people/People.js";
|
|
3
|
-
import {
|
|
4
|
-
import { ConfirmButton as
|
|
5
|
-
import { useState as
|
|
6
|
-
import { Pencil as
|
|
7
|
-
import { gql as
|
|
8
|
-
import { useMutation as
|
|
9
|
-
import { jsx as
|
|
10
|
-
import { Button as
|
|
11
|
-
import { useWorkspaceDirectory as
|
|
3
|
+
import { LEAVES_PAGE_CONTEXT as r, throwOnError as i } from "../utils/mutationResult.js";
|
|
4
|
+
import { ConfirmButton as a, ErrorLine as o } from "./ConfirmButton.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 } from "@burdenoff/fe-libs/ui";
|
|
11
|
+
import { useWorkspaceDirectory as h } from "@burdenoff/fe-libs/sharing";
|
|
12
12
|
//#region src/planmagnet/controls/WorkItemControls.tsx
|
|
13
|
-
var
|
|
13
|
+
var g = [
|
|
14
14
|
"BACKLOG",
|
|
15
15
|
"TODO",
|
|
16
16
|
"IN_PROGRESS",
|
|
@@ -18,18 +18,18 @@ var h = [
|
|
|
18
18
|
"TESTING",
|
|
19
19
|
"DONE",
|
|
20
20
|
"CANCELLED"
|
|
21
|
-
],
|
|
21
|
+
], _ = [
|
|
22
22
|
"NONE",
|
|
23
23
|
"LOW",
|
|
24
24
|
"MEDIUM",
|
|
25
25
|
"HIGH",
|
|
26
26
|
"CRITICAL"
|
|
27
27
|
];
|
|
28
|
-
function
|
|
28
|
+
function v(e) {
|
|
29
29
|
let t = e.toLowerCase().replace(/_/g, " ");
|
|
30
30
|
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
31
31
|
}
|
|
32
|
-
var
|
|
32
|
+
var y = u`
|
|
33
33
|
mutation WorkItemControlsUpdate($id: ID!, $input: PlanmagnetUpdateWorkItemInput!) {
|
|
34
34
|
planmagnetUpdateWorkItem(id: $id, input: $input) {
|
|
35
35
|
id
|
|
@@ -38,30 +38,30 @@ var v = l`
|
|
|
38
38
|
assigneeId
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
`,
|
|
41
|
+
`, b = u`
|
|
42
42
|
mutation WorkItemControlsDelete($id: ID!) {
|
|
43
43
|
planmagnetDeleteWorkItem(id: $id)
|
|
44
44
|
}
|
|
45
|
-
`,
|
|
45
|
+
`, x = [
|
|
46
46
|
"GetWorkItems",
|
|
47
47
|
"GetWorkItemCounts",
|
|
48
48
|
"ProjectBoard",
|
|
49
49
|
"GetDashboardData"
|
|
50
|
-
],
|
|
50
|
+
], S = [
|
|
51
51
|
"GetWorkItemDetail",
|
|
52
52
|
"WorkItemActivity",
|
|
53
|
-
...
|
|
54
|
-
],
|
|
55
|
-
function
|
|
56
|
-
let [t, n] =
|
|
57
|
-
refetchQueries:
|
|
53
|
+
...x
|
|
54
|
+
], C = "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60 max-w-[12rem]";
|
|
55
|
+
function w(e) {
|
|
56
|
+
let [t, n] = d(y, {
|
|
57
|
+
refetchQueries: S,
|
|
58
58
|
awaitRefetchQueries: !0
|
|
59
|
-
}), [
|
|
59
|
+
}), [r, a] = s(null);
|
|
60
60
|
return {
|
|
61
61
|
save: async (n) => {
|
|
62
62
|
a(null);
|
|
63
63
|
try {
|
|
64
|
-
await
|
|
64
|
+
await i(t({ variables: {
|
|
65
65
|
id: e,
|
|
66
66
|
input: n
|
|
67
67
|
} }));
|
|
@@ -70,31 +70,31 @@ function C(e) {
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
saving: n.loading,
|
|
73
|
-
error:
|
|
73
|
+
error: r
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
function
|
|
77
|
-
let { save:
|
|
78
|
-
return /* @__PURE__ */
|
|
76
|
+
function T({ workItemId: e, field: t, value: n, options: r, label: i }) {
|
|
77
|
+
let { save: a, saving: s, error: c } = w(e), l = r.includes(n) ? r : [n, ...r];
|
|
78
|
+
return /* @__PURE__ */ p("div", {
|
|
79
79
|
className: "flex flex-col items-end gap-1",
|
|
80
|
-
children: [/* @__PURE__ */
|
|
80
|
+
children: [/* @__PURE__ */ f("select", {
|
|
81
81
|
"aria-label": i,
|
|
82
82
|
"data-testid": `task-${t}`,
|
|
83
|
-
className:
|
|
83
|
+
className: C,
|
|
84
84
|
value: n,
|
|
85
85
|
disabled: s,
|
|
86
86
|
onChange: (e) => {
|
|
87
|
-
e.target.value !== n &&
|
|
87
|
+
e.target.value !== n && a({ [t]: e.target.value });
|
|
88
88
|
},
|
|
89
|
-
children: l.map((e) => /* @__PURE__ */
|
|
89
|
+
children: l.map((e) => /* @__PURE__ */ f("option", {
|
|
90
90
|
value: e,
|
|
91
|
-
children:
|
|
91
|
+
children: v(e)
|
|
92
92
|
}, e))
|
|
93
|
-
}), c && /* @__PURE__ */
|
|
93
|
+
}), c && /* @__PURE__ */ f(o, { message: c })]
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
|
-
function
|
|
97
|
-
let { workspaceId: r, authToken: i, apiGatewayUrl: a } = e(), o =
|
|
96
|
+
function E(t) {
|
|
97
|
+
let { workspaceId: r, authToken: i, apiGatewayUrl: a } = e(), o = h({
|
|
98
98
|
workspaceId: r ?? "",
|
|
99
99
|
authToken: i ?? void 0,
|
|
100
100
|
apiGatewayUrl: a ?? void 0
|
|
@@ -112,32 +112,32 @@ function T(t) {
|
|
|
112
112
|
fetchMore: o.fetchMore
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
|
-
function
|
|
116
|
-
let { options: i, loading: a, hasMore: o, fetchMore: s } =
|
|
117
|
-
return /* @__PURE__ */
|
|
115
|
+
function D({ id: e, value: t, onChange: n, disabled: r = !1 }) {
|
|
116
|
+
let { options: i, loading: a, hasMore: o, fetchMore: s } = E(t || null);
|
|
117
|
+
return /* @__PURE__ */ p("div", {
|
|
118
118
|
className: "flex flex-col gap-1",
|
|
119
119
|
children: [
|
|
120
|
-
/* @__PURE__ */
|
|
120
|
+
/* @__PURE__ */ p("select", {
|
|
121
121
|
id: e,
|
|
122
122
|
"aria-label": e ? void 0 : "Assignee",
|
|
123
123
|
"data-testid": "assignee-select",
|
|
124
|
-
className:
|
|
124
|
+
className: C,
|
|
125
125
|
value: t,
|
|
126
126
|
disabled: r,
|
|
127
127
|
onChange: (e) => n(e.target.value),
|
|
128
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ f("option", {
|
|
129
129
|
value: "",
|
|
130
130
|
children: "Unassigned"
|
|
131
|
-
}), i.map((e) => /* @__PURE__ */
|
|
131
|
+
}), i.map((e) => /* @__PURE__ */ f("option", {
|
|
132
132
|
value: e.id,
|
|
133
133
|
children: e.name
|
|
134
134
|
}, e.id))]
|
|
135
135
|
}),
|
|
136
|
-
a && i.length === 0 && /* @__PURE__ */
|
|
136
|
+
a && i.length === 0 && /* @__PURE__ */ f("span", {
|
|
137
137
|
className: "text-xs text-muted-foreground",
|
|
138
138
|
children: "Loading members…"
|
|
139
139
|
}),
|
|
140
|
-
o && /* @__PURE__ */
|
|
140
|
+
o && /* @__PURE__ */ f("button", {
|
|
141
141
|
type: "button",
|
|
142
142
|
className: "self-start text-xs text-primary hover:underline",
|
|
143
143
|
onClick: s,
|
|
@@ -146,53 +146,56 @@ function E({ id: e, value: t, onChange: n, disabled: r = !1 }) {
|
|
|
146
146
|
]
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
|
-
function
|
|
150
|
-
let { save: n, saving: r, error: i } =
|
|
151
|
-
return /* @__PURE__ */
|
|
149
|
+
function O({ workItemId: e, assigneeId: t }) {
|
|
150
|
+
let { save: n, saving: r, error: i } = w(e);
|
|
151
|
+
return /* @__PURE__ */ p("div", {
|
|
152
152
|
className: "flex flex-col items-end gap-1",
|
|
153
|
-
children: [/* @__PURE__ */
|
|
153
|
+
children: [/* @__PURE__ */ f(D, {
|
|
154
154
|
value: t ?? "",
|
|
155
155
|
disabled: r,
|
|
156
156
|
onChange: (e) => {
|
|
157
157
|
e !== (t ?? "") && n({ assigneeId: e || null });
|
|
158
158
|
}
|
|
159
|
-
}), i && /* @__PURE__ */
|
|
159
|
+
}), i && /* @__PURE__ */ f(o, { message: i })]
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
|
-
function
|
|
163
|
-
let
|
|
164
|
-
|
|
162
|
+
function k({ workItemId: e, title: n }) {
|
|
163
|
+
let u = t(), [h, g] = d(b, {
|
|
164
|
+
refetchQueries: x,
|
|
165
|
+
context: r
|
|
166
|
+
}), [_, v] = s(null), y = async () => {
|
|
167
|
+
v(null);
|
|
165
168
|
try {
|
|
166
|
-
await
|
|
169
|
+
await i(h({ variables: { id: e } })), u("/tasks/tasks-page");
|
|
167
170
|
} catch (e) {
|
|
168
|
-
|
|
171
|
+
v(e instanceof Error ? e.message : "The task could not be deleted.");
|
|
169
172
|
}
|
|
170
173
|
};
|
|
171
|
-
return /* @__PURE__ */
|
|
174
|
+
return /* @__PURE__ */ p("div", {
|
|
172
175
|
className: "flex flex-col items-end gap-2",
|
|
173
|
-
children: [/* @__PURE__ */
|
|
176
|
+
children: [/* @__PURE__ */ p("div", {
|
|
174
177
|
className: "flex gap-2",
|
|
175
|
-
children: [/* @__PURE__ */
|
|
178
|
+
children: [/* @__PURE__ */ p(m, {
|
|
176
179
|
size: "sm",
|
|
177
180
|
variant: "outline",
|
|
178
181
|
"data-testid": "task-edit",
|
|
179
|
-
onClick: () =>
|
|
180
|
-
children: [/* @__PURE__ */
|
|
181
|
-
}), /* @__PURE__ */
|
|
182
|
+
onClick: () => u(`/tasks/edit-task-page?taskId=${encodeURIComponent(e)}`),
|
|
183
|
+
children: [/* @__PURE__ */ f(c, { className: "mr-1 h-4 w-4" }), "Edit"]
|
|
184
|
+
}), /* @__PURE__ */ f(a, {
|
|
182
185
|
label: "Delete",
|
|
183
186
|
variant: "outline",
|
|
184
|
-
icon: /* @__PURE__ */
|
|
187
|
+
icon: /* @__PURE__ */ f(l, { className: "mr-1 h-4 w-4" }),
|
|
185
188
|
title: `Delete "${n}"?`,
|
|
186
189
|
description: "The task is deleted and disappears from boards, sprints and releases. This cannot be undone here.",
|
|
187
190
|
confirmLabel: "Delete task",
|
|
188
191
|
destructive: !0,
|
|
189
|
-
disabled:
|
|
190
|
-
onConfirm: () => void
|
|
192
|
+
disabled: g.loading,
|
|
193
|
+
onConfirm: () => void y()
|
|
191
194
|
})]
|
|
192
|
-
}),
|
|
195
|
+
}), _ && /* @__PURE__ */ f(o, { message: _ })]
|
|
193
196
|
});
|
|
194
197
|
}
|
|
195
198
|
//#endregion
|
|
196
|
-
export {
|
|
199
|
+
export { D as AssigneeSelect, _ as WORK_ITEM_PRIORITIES, g as WORK_ITEM_STATUSES, O as WorkItemAssigneeSelect, T as WorkItemEnumSelect, k as WorkItemHeaderActions, v as enumLabel };
|
|
197
200
|
|
|
198
201
|
//# sourceMappingURL=WorkItemControls.js.map
|