@burdenoff/microfe-planmagnet 2026.927.2 → 2026.927.4
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/admin/PlanMagnetAdminRoot.d.ts.map +1 -1
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js +128 -124
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js.map +1 -1
- package/dist/planmagnet/controls/ConfirmButton.d.ts +25 -0
- package/dist/planmagnet/controls/ConfirmButton.d.ts.map +1 -0
- package/dist/planmagnet/controls/ConfirmButton.js +30 -0
- package/dist/planmagnet/controls/ConfirmButton.js.map +1 -0
- 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 +318 -0
- package/dist/planmagnet/controls/FeatureControls.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 +200 -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 +13 -0
- package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ProjectControls.js +104 -0
- package/dist/planmagnet/controls/ProjectControls.js.map +1 -0
- 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 +108 -0
- package/dist/planmagnet/controls/ReleaseControls.js.map +1 -0
- package/dist/planmagnet/controls/WorkItemControls.d.ts +52 -0
- package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/WorkItemControls.js +198 -0
- package/dist/planmagnet/controls/WorkItemControls.js.map +1 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +188 -154
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/DocsDocsPagePage.js +4 -4
- 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/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 +142 -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/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +102 -108
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.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 +97 -90
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js +107 -106
- 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 +2 -0
- package/dist/planmagnet/pages/ProductsReleasesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +150 -111
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +116 -93
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.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/ProjectsPlanningEditPagePage.js +4 -4
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +134 -132
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +6 -5
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +167 -116
- 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/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +205 -158
- 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 +1 -0
- 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 +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
- package/dist/planmagnet/people/People.js +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts +34 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.js +301 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -0
- package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
- package/dist/planmagnet/sprints/SprintControls.js +194 -215
- package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { throwOnError as t } from "../utils/mutationResult.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
3
|
+
import { endBeforeStart as n } from "../utils/formValidation.js";
|
|
4
|
+
import { enumLabel as r } from "../controls/WorkItemControls.js";
|
|
5
|
+
import { detailPath as i } from "../utils/rowNavigation.js";
|
|
6
|
+
import { useEntityId as a } from "../hooks/useEntityId.js";
|
|
7
|
+
import { PROJECT_STATUSES as o } from "../controls/ProjectControls.js";
|
|
8
|
+
import { useMemo as s, useState as c } from "react";
|
|
9
|
+
import { ArrowLeft as l, Save as u } from "lucide-react";
|
|
10
|
+
import { gql as d } from "@apollo/client";
|
|
11
|
+
import { useMutation as f, useQuery as p } from "@apollo/client/react";
|
|
12
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
13
|
+
import { Button as g, Card as _, CardContent as v, CardHeader as y, CardTitle as b, Input as x } from "@burdenoff/fe-libs/ui";
|
|
12
14
|
//#region src/planmagnet/pages/ProjectsEditProjectPagePage.tsx
|
|
13
|
-
var
|
|
15
|
+
var S = d`
|
|
14
16
|
query GetProjectsForEdit($id: ID!) {
|
|
15
17
|
planmagnetProject(id: $id) {
|
|
16
18
|
id
|
|
@@ -25,7 +27,7 @@ var b = l`
|
|
|
25
27
|
tags
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
|
-
`,
|
|
30
|
+
`, C = d`
|
|
29
31
|
mutation UpdateProject($id: ID!, $input: PlanmagnetUpdateProjectInput!) {
|
|
30
32
|
planmagnetUpdateProject(id: $id, input: $input) {
|
|
31
33
|
id
|
|
@@ -41,121 +43,125 @@ var b = l`
|
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
`;
|
|
44
|
-
function
|
|
45
|
-
let
|
|
46
|
-
variables: { id:
|
|
47
|
-
skip: !
|
|
48
|
-
}), [
|
|
49
|
-
name:
|
|
50
|
-
description:
|
|
51
|
-
methodology:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
...
|
|
57
|
-
|
|
46
|
+
function w() {
|
|
47
|
+
let d = a("projectId"), w = e(), { data: T, loading: E, error: D } = p(S, {
|
|
48
|
+
variables: { id: d },
|
|
49
|
+
skip: !d
|
|
50
|
+
}), [O, k] = c(null), A = T?.planmagnetProject, j = s(() => ({
|
|
51
|
+
name: A?.name ?? "",
|
|
52
|
+
description: A?.description ?? "",
|
|
53
|
+
methodology: A?.methodology ?? "SCRUM",
|
|
54
|
+
status: A?.status ?? "PLANNING",
|
|
55
|
+
startDate: A?.startDate ? A.startDate.split("T")[0] : "",
|
|
56
|
+
endDate: A?.endDate ? A.endDate.split("T")[0] : ""
|
|
57
|
+
}), [A]), [M, N] = c({}), P = {
|
|
58
|
+
...j,
|
|
59
|
+
...M
|
|
60
|
+
}, F = (e) => N(e), [I, { loading: L }] = f(C, { refetchQueries: [
|
|
58
61
|
"GetProjects",
|
|
59
62
|
"GetActiveProjects",
|
|
60
63
|
"GetDashboardData",
|
|
61
|
-
"GetProjectsForEdit"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
"GetProjectsForEdit",
|
|
65
|
+
"GetProjectDetail",
|
|
66
|
+
"AdminPlanmagnetProjects"
|
|
67
|
+
] }), [R, z] = c(null), B = n(P.startDate, P.endDate);
|
|
68
|
+
return d ? E && !T ? /* @__PURE__ */ m("div", {
|
|
64
69
|
className: "flex items-center justify-center p-12",
|
|
65
|
-
children: /* @__PURE__ */
|
|
66
|
-
}) :
|
|
70
|
+
children: /* @__PURE__ */ m("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
71
|
+
}) : D ? /* @__PURE__ */ h("div", {
|
|
67
72
|
className: "p-6 text-destructive",
|
|
68
|
-
children: ["Error loading project: ",
|
|
69
|
-
}) :
|
|
73
|
+
children: ["Error loading project: ", D.message]
|
|
74
|
+
}) : A ? /* @__PURE__ */ h("div", {
|
|
70
75
|
className: "space-y-6 p-6 max-w-4xl",
|
|
71
76
|
children: [
|
|
72
|
-
/* @__PURE__ */
|
|
77
|
+
/* @__PURE__ */ h("div", {
|
|
73
78
|
className: "flex items-center justify-between",
|
|
74
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ h("div", {
|
|
75
80
|
className: "flex items-center gap-3",
|
|
76
|
-
children: [/* @__PURE__ */
|
|
81
|
+
children: [/* @__PURE__ */ m(g, {
|
|
77
82
|
variant: "ghost",
|
|
78
83
|
size: "sm",
|
|
79
84
|
"aria-label": "Back to the project",
|
|
80
|
-
onClick: () =>
|
|
81
|
-
children: /* @__PURE__ */
|
|
82
|
-
}), /* @__PURE__ */
|
|
85
|
+
onClick: () => w(i("/projects/project-detail-page", d)),
|
|
86
|
+
children: /* @__PURE__ */ m(l, { className: "h-4 w-4" })
|
|
87
|
+
}), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h1", {
|
|
83
88
|
className: "text-2xl font-semibold",
|
|
84
89
|
children: "Edit Project"
|
|
85
|
-
}), /* @__PURE__ */
|
|
90
|
+
}), /* @__PURE__ */ h("p", {
|
|
86
91
|
className: "text-sm text-muted-foreground",
|
|
87
|
-
children: ["Editing ",
|
|
92
|
+
children: ["Editing ", A.name]
|
|
88
93
|
})] })]
|
|
89
|
-
}), /* @__PURE__ */
|
|
94
|
+
}), /* @__PURE__ */ h(g, {
|
|
90
95
|
size: "sm",
|
|
91
96
|
onClick: async () => {
|
|
92
|
-
if (!
|
|
93
|
-
|
|
97
|
+
if (!A || B) return;
|
|
98
|
+
z(null), k(null);
|
|
94
99
|
let e = {
|
|
95
|
-
...
|
|
96
|
-
...
|
|
100
|
+
...P.startDate !== j.startDate && { startDate: P.startDate || void 0 },
|
|
101
|
+
...P.endDate !== j.endDate && { endDate: P.endDate || void 0 }
|
|
97
102
|
};
|
|
98
103
|
try {
|
|
99
|
-
await t(
|
|
100
|
-
id:
|
|
104
|
+
await t(I({ variables: {
|
|
105
|
+
id: A.id,
|
|
101
106
|
input: {
|
|
102
|
-
name:
|
|
103
|
-
description:
|
|
104
|
-
methodology:
|
|
107
|
+
name: P.name || void 0,
|
|
108
|
+
description: P.description || void 0,
|
|
109
|
+
methodology: P.methodology || void 0,
|
|
110
|
+
...P.status !== j.status && { status: P.status },
|
|
105
111
|
...e
|
|
106
112
|
}
|
|
107
|
-
} })),
|
|
113
|
+
} })), k("Project updated successfully.");
|
|
108
114
|
} catch (e) {
|
|
109
|
-
|
|
115
|
+
z(e instanceof Error ? e.message : "The project could not be saved.");
|
|
110
116
|
}
|
|
111
117
|
},
|
|
112
|
-
disabled:
|
|
113
|
-
children: [/* @__PURE__ */
|
|
118
|
+
disabled: L || B,
|
|
119
|
+
children: [/* @__PURE__ */ m(u, { className: "mr-1 h-4 w-4" }), L ? "Saving..." : "Save Changes"]
|
|
114
120
|
})]
|
|
115
121
|
}),
|
|
116
|
-
|
|
122
|
+
O && /* @__PURE__ */ m("div", {
|
|
117
123
|
role: "status",
|
|
118
124
|
className: "p-3 bg-muted text-status-success-text rounded-md text-sm",
|
|
119
|
-
children:
|
|
125
|
+
children: O
|
|
120
126
|
}),
|
|
121
|
-
|
|
127
|
+
R && /* @__PURE__ */ m("div", {
|
|
122
128
|
role: "alert",
|
|
123
129
|
className: "p-3 bg-destructive/10 text-destructive rounded-md text-sm",
|
|
124
|
-
children:
|
|
130
|
+
children: R
|
|
125
131
|
}),
|
|
126
|
-
/* @__PURE__ */
|
|
132
|
+
/* @__PURE__ */ h(_, { children: [/* @__PURE__ */ m(y, { children: /* @__PURE__ */ m(b, { children: "Project Details" }) }), /* @__PURE__ */ h(v, {
|
|
127
133
|
className: "space-y-4",
|
|
128
134
|
children: [
|
|
129
|
-
/* @__PURE__ */
|
|
135
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
130
136
|
className: "text-sm font-medium",
|
|
131
137
|
children: "Project Name"
|
|
132
|
-
}), /* @__PURE__ */
|
|
133
|
-
value:
|
|
134
|
-
onChange: (e) =>
|
|
135
|
-
...
|
|
138
|
+
}), /* @__PURE__ */ m(x, {
|
|
139
|
+
value: P.name,
|
|
140
|
+
onChange: (e) => F({
|
|
141
|
+
...P,
|
|
136
142
|
name: e.target.value
|
|
137
143
|
}),
|
|
138
144
|
className: "mt-1"
|
|
139
145
|
})] }),
|
|
140
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
141
147
|
className: "text-sm font-medium",
|
|
142
148
|
children: "Description"
|
|
143
|
-
}), /* @__PURE__ */
|
|
149
|
+
}), /* @__PURE__ */ m("textarea", {
|
|
144
150
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]",
|
|
145
|
-
value:
|
|
146
|
-
onChange: (e) =>
|
|
147
|
-
...
|
|
151
|
+
value: P.description,
|
|
152
|
+
onChange: (e) => F({
|
|
153
|
+
...P,
|
|
148
154
|
description: e.target.value
|
|
149
155
|
})
|
|
150
156
|
})] }),
|
|
151
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
152
158
|
className: "text-sm font-medium",
|
|
153
159
|
children: "Methodology"
|
|
154
|
-
}), /* @__PURE__ */
|
|
160
|
+
}), /* @__PURE__ */ m("select", {
|
|
155
161
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm capitalize",
|
|
156
|
-
value:
|
|
157
|
-
onChange: (e) =>
|
|
158
|
-
...
|
|
162
|
+
value: P.methodology,
|
|
163
|
+
onChange: (e) => F({
|
|
164
|
+
...P,
|
|
159
165
|
methodology: e.target.value
|
|
160
166
|
}),
|
|
161
167
|
children: [
|
|
@@ -165,45 +171,62 @@ function S() {
|
|
|
165
171
|
"HYBRID",
|
|
166
172
|
"AGILE",
|
|
167
173
|
"CUSTOM"
|
|
168
|
-
].map((e) => /* @__PURE__ */
|
|
174
|
+
].map((e) => /* @__PURE__ */ m("option", {
|
|
169
175
|
value: e,
|
|
170
176
|
children: e.toLowerCase()
|
|
171
177
|
}, e))
|
|
172
178
|
})] }),
|
|
173
|
-
/* @__PURE__ */
|
|
179
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
180
|
+
htmlFor: "project-status",
|
|
181
|
+
className: "text-sm font-medium",
|
|
182
|
+
children: "Status"
|
|
183
|
+
}), /* @__PURE__ */ m("select", {
|
|
184
|
+
id: "project-status",
|
|
185
|
+
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
186
|
+
value: P.status,
|
|
187
|
+
onChange: (e) => F({
|
|
188
|
+
...P,
|
|
189
|
+
status: e.target.value
|
|
190
|
+
}),
|
|
191
|
+
children: (o.includes(P.status) ? o : [P.status, ...o]).map((e) => /* @__PURE__ */ m("option", {
|
|
192
|
+
value: e,
|
|
193
|
+
children: r(e)
|
|
194
|
+
}, e))
|
|
195
|
+
})] }),
|
|
196
|
+
/* @__PURE__ */ h("div", {
|
|
174
197
|
className: "grid grid-cols-2 gap-4",
|
|
175
|
-
children: [/* @__PURE__ */
|
|
198
|
+
children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
176
199
|
htmlFor: "project-start",
|
|
177
200
|
className: "text-sm font-medium",
|
|
178
201
|
children: "Start Date"
|
|
179
|
-
}), /* @__PURE__ */
|
|
202
|
+
}), /* @__PURE__ */ m(x, {
|
|
180
203
|
id: "project-start",
|
|
181
204
|
type: "date",
|
|
182
|
-
value:
|
|
183
|
-
max:
|
|
184
|
-
onChange: (e) =>
|
|
185
|
-
...
|
|
205
|
+
value: P.startDate,
|
|
206
|
+
max: P.endDate || void 0,
|
|
207
|
+
onChange: (e) => F({
|
|
208
|
+
...P,
|
|
186
209
|
startDate: e.target.value
|
|
187
210
|
}),
|
|
188
211
|
className: "mt-1"
|
|
189
|
-
})] }), /* @__PURE__ */
|
|
212
|
+
})] }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
|
|
190
213
|
htmlFor: "project-end",
|
|
191
214
|
className: "text-sm font-medium",
|
|
192
215
|
children: "End Date"
|
|
193
|
-
}), /* @__PURE__ */
|
|
216
|
+
}), /* @__PURE__ */ m(x, {
|
|
194
217
|
id: "project-end",
|
|
195
218
|
type: "date",
|
|
196
|
-
value:
|
|
197
|
-
min:
|
|
198
|
-
onChange: (e) =>
|
|
199
|
-
...
|
|
219
|
+
value: P.endDate,
|
|
220
|
+
min: P.startDate || void 0,
|
|
221
|
+
onChange: (e) => F({
|
|
222
|
+
...P,
|
|
200
223
|
endDate: e.target.value
|
|
201
224
|
}),
|
|
202
|
-
"aria-invalid":
|
|
225
|
+
"aria-invalid": B,
|
|
203
226
|
className: "mt-1"
|
|
204
227
|
})] })]
|
|
205
228
|
}),
|
|
206
|
-
|
|
229
|
+
B && /* @__PURE__ */ m("p", {
|
|
207
230
|
role: "alert",
|
|
208
231
|
className: "text-sm text-destructive",
|
|
209
232
|
children: "The end date is before the start date."
|
|
@@ -211,15 +234,15 @@ function S() {
|
|
|
211
234
|
]
|
|
212
235
|
})] })
|
|
213
236
|
]
|
|
214
|
-
}) : /* @__PURE__ */
|
|
237
|
+
}) : /* @__PURE__ */ m("div", {
|
|
215
238
|
className: "p-6 text-muted-foreground",
|
|
216
239
|
children: "Project not found."
|
|
217
|
-
}) : /* @__PURE__ */
|
|
240
|
+
}) : /* @__PURE__ */ m("div", {
|
|
218
241
|
className: "p-6 text-muted-foreground",
|
|
219
242
|
children: "No project selected. Open one from the list."
|
|
220
243
|
});
|
|
221
244
|
}
|
|
222
245
|
//#endregion
|
|
223
|
-
export {
|
|
246
|
+
export { w as ProjectsEditProjectPagePage };
|
|
224
247
|
|
|
225
248
|
//# sourceMappingURL=ProjectsEditProjectPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectsEditProjectPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsEditProjectPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery, useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\nimport { endBeforeStart } from '../utils/formValidation';\n\nconst GET_PROJECTS = gql`\n query GetProjectsForEdit($id: ID!) {\n planmagnetProject(id: $id) {\n id\n name\n key\n description\n status\n methodology\n ownerId\n startDate\n endDate\n tags\n }\n }\n`;\n\nconst UPDATE_PROJECT = gql`\n mutation UpdateProject($id: ID!, $input: PlanmagnetUpdateProjectInput!) {\n planmagnetUpdateProject(id: $id, input: $input) {\n id\n name\n key\n description\n status\n methodology\n ownerId\n startDate\n endDate\n tags\n }\n }\n`;\n\nexport function ProjectsEditProjectPagePage() {\n const projectId = useEntityId('projectId');\n const navigate = usePlanMagnetNavigate();\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_PROJECTS, {\n variables: { id: projectId },\n skip: !projectId,\n });\n\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const project = data?.planmagnetProject;\n\n const defaultForm = useMemo(\n () => ({\n name: project?.name ?? '',\n description: project?.description ?? '',\n methodology: project?.methodology ?? 'SCRUM',\n startDate: project?.startDate ? project.startDate.split('T')[0] : '',\n endDate: project?.endDate ? project.endDate.split('T')[0] : '',\n }),\n [project]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (updates: Record<string, string>) => setFormOverrides(updates);\n\n // Success only after the service accepted the change (errorPolicy 'all' resolves refused mutations).\n const [updateProject, { loading: saving }] = useMutation(UPDATE_PROJECT, {\n refetchQueries: ['GetProjects', 'GetActiveProjects', 'GetDashboardData', 'GetProjectsForEdit'],\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const invalidDates = endBeforeStart(form.startDate, form.endDate);\n\n const methodologies = ['SCRUM', 'KANBAN', 'WATERFALL', 'HYBRID', 'AGILE', 'CUSTOM'] as const;\n\n const handleSave = async () => {\n if (!project || invalidDates) return;\n setSaveError(null);\n setSuccessMessage(null);\n // Dates are sent only when they were changed: the service checks the pair the project would end up\n // with, so re-sending untouched dates of an older project stored with inverted dates would refuse a\n // plain rename (BOFF-7833).\n const dateChanges = {\n ...(form.startDate !== defaultForm.startDate && { startDate: form.startDate || undefined }),\n ...(form.endDate !== defaultForm.endDate && { endDate: form.endDate || undefined }),\n };\n try {\n await throwOnError(\n updateProject({\n variables: {\n id: project.id,\n input: {\n name: form.name || undefined,\n description: form.description || undefined,\n methodology: form.methodology || undefined,\n ...dateChanges,\n },\n },\n })\n );\n setSuccessMessage('Project updated successfully.');\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The project could not be saved.');\n }\n };\n\n if (!projectId)\n return (\n <div className=\"p-6 text-muted-foreground\">No project selected. Open one from the list.</div>\n );\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\n if (loading && !data)\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n if (error)\n return <div className=\"p-6 text-destructive\">Error loading project: {error.message}</div>;\n if (!project) return <div className=\"p-6 text-muted-foreground\">Project not found.</div>;\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Back to the project\"\n onClick={() => navigate(detailPath('/projects/project-detail-page', projectId))}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Project</h1>\n <p className=\"text-sm text-muted-foreground\">Editing {project.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || invalidDates}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\n\n {successMessage && (\n <div role=\"status\" className=\"p-3 bg-muted text-status-success-text rounded-md text-sm\">\n {successMessage}\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 bg-destructive/10 text-destructive rounded-md text-sm\">\n {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Project Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Project Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Methodology</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm capitalize\"\n value={form.methodology}\n onChange={(e) => setForm({ ...form, methodology: e.target.value })}\n >\n {methodologies.map((m) => (\n <option key={m} value={m}>\n {m.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"project-start\" className=\"text-sm font-medium\">\n Start Date\n </label>\n <Input\n id=\"project-start\"\n type=\"date\"\n value={form.startDate}\n max={form.endDate || undefined}\n onChange={(e) => setForm({ ...form, startDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label htmlFor=\"project-end\" className=\"text-sm font-medium\">\n End Date\n </label>\n <Input\n id=\"project-end\"\n type=\"date\"\n value={form.endDate}\n min={form.startDate || undefined}\n onChange={(e) => setForm({ ...form, endDate: e.target.value })}\n aria-invalid={invalidDates}\n className=\"mt-1\"\n />\n </div>\n </div>\n {invalidDates && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n The end date is before the start date.\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProjectsEditProjectPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsEditProjectPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery, useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\nimport { endBeforeStart } from '../utils/formValidation';\nimport { PROJECT_STATUSES } from '../controls/ProjectControls';\nimport { enumLabel } from '../controls/WorkItemControls';\n\nconst GET_PROJECTS = gql`\n query GetProjectsForEdit($id: ID!) {\n planmagnetProject(id: $id) {\n id\n name\n key\n description\n status\n methodology\n ownerId\n startDate\n endDate\n tags\n }\n }\n`;\n\nconst UPDATE_PROJECT = gql`\n mutation UpdateProject($id: ID!, $input: PlanmagnetUpdateProjectInput!) {\n planmagnetUpdateProject(id: $id, input: $input) {\n id\n name\n key\n description\n status\n methodology\n ownerId\n startDate\n endDate\n tags\n }\n }\n`;\n\nexport function ProjectsEditProjectPagePage() {\n const projectId = useEntityId('projectId');\n const navigate = usePlanMagnetNavigate();\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_PROJECTS, {\n variables: { id: projectId },\n skip: !projectId,\n });\n\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const project = data?.planmagnetProject;\n\n const defaultForm = useMemo(\n () => ({\n name: project?.name ?? '',\n description: project?.description ?? '',\n methodology: project?.methodology ?? 'SCRUM',\n status: project?.status ?? 'PLANNING',\n startDate: project?.startDate ? project.startDate.split('T')[0] : '',\n endDate: project?.endDate ? project.endDate.split('T')[0] : '',\n }),\n [project]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (updates: Record<string, string>) => setFormOverrides(updates);\n\n // Success only after the service accepted the change (errorPolicy 'all' resolves refused mutations).\n const [updateProject, { loading: saving }] = useMutation(UPDATE_PROJECT, {\n refetchQueries: [\n 'GetProjects',\n 'GetActiveProjects',\n 'GetDashboardData',\n 'GetProjectsForEdit',\n 'GetProjectDetail',\n 'AdminPlanmagnetProjects',\n ],\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const invalidDates = endBeforeStart(form.startDate, form.endDate);\n\n const methodologies = ['SCRUM', 'KANBAN', 'WATERFALL', 'HYBRID', 'AGILE', 'CUSTOM'] as const;\n\n const handleSave = async () => {\n if (!project || invalidDates) return;\n setSaveError(null);\n setSuccessMessage(null);\n // Dates are sent only when they were changed: the service checks the pair the project would end up\n // with, so re-sending untouched dates of an older project stored with inverted dates would refuse a\n // plain rename (BOFF-7833).\n const dateChanges = {\n ...(form.startDate !== defaultForm.startDate && { startDate: form.startDate || undefined }),\n ...(form.endDate !== defaultForm.endDate && { endDate: form.endDate || undefined }),\n };\n try {\n await throwOnError(\n updateProject({\n variables: {\n id: project.id,\n input: {\n name: form.name || undefined,\n description: form.description || undefined,\n methodology: form.methodology || undefined,\n // Only when changed: a status set elsewhere meanwhile (the detail page's select) is not overwritten.\n ...(form.status !== defaultForm.status && { status: form.status }),\n ...dateChanges,\n },\n },\n })\n );\n setSuccessMessage('Project updated successfully.');\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The project could not be saved.');\n }\n };\n\n if (!projectId)\n return (\n <div className=\"p-6 text-muted-foreground\">No project selected. Open one from the list.</div>\n );\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\n if (loading && !data)\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n if (error)\n return <div className=\"p-6 text-destructive\">Error loading project: {error.message}</div>;\n if (!project) return <div className=\"p-6 text-muted-foreground\">Project not found.</div>;\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Back to the project\"\n onClick={() => navigate(detailPath('/projects/project-detail-page', projectId))}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Project</h1>\n <p className=\"text-sm text-muted-foreground\">Editing {project.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || invalidDates}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\n\n {successMessage && (\n <div role=\"status\" className=\"p-3 bg-muted text-status-success-text rounded-md text-sm\">\n {successMessage}\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 bg-destructive/10 text-destructive rounded-md text-sm\">\n {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Project Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Project Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Methodology</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm capitalize\"\n value={form.methodology}\n onChange={(e) => setForm({ ...form, methodology: e.target.value })}\n >\n {methodologies.map((m) => (\n <option key={m} value={m}>\n {m.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n {/* BOFF-7940: the form had no Status, so a project could never leave PLANNING. */}\n <label htmlFor=\"project-status\" className=\"text-sm font-medium\">\n Status\n </label>\n <select\n id=\"project-status\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.status}\n onChange={(e) => setForm({ ...form, status: e.target.value })}\n >\n {((PROJECT_STATUSES as readonly string[]).includes(form.status)\n ? PROJECT_STATUSES\n : [form.status, ...PROJECT_STATUSES]\n ).map((s) => (\n <option key={s} value={s}>\n {enumLabel(s)}\n </option>\n ))}\n </select>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"project-start\" className=\"text-sm font-medium\">\n Start Date\n </label>\n <Input\n id=\"project-start\"\n type=\"date\"\n value={form.startDate}\n max={form.endDate || undefined}\n onChange={(e) => setForm({ ...form, startDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label htmlFor=\"project-end\" className=\"text-sm font-medium\">\n End Date\n </label>\n <Input\n id=\"project-end\"\n type=\"date\"\n value={form.endDate}\n min={form.startDate || undefined}\n onChange={(e) => setForm({ ...form, endDate: e.target.value })}\n aria-invalid={invalidDates}\n className=\"mt-1\"\n />\n </div>\n </div>\n {invalidDates && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n The end date is before the start date.\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,IAAM,IAAe,CAAG;;;;;;;;;;;;;;;GAiBlB,IAAiB,CAAG;;;;;;;;;;;;;;;;AAiB1B,SAAgB,IAA8B;CAC5C,IAAM,IAAY,EAAY,YAAY,EACpC,IAAW,GAAuB,EAElC,EACJ,SACA,YACA,aAGA,EAA8B,GAAc;EAC1C,WAAW,EAAE,IAAI,GAAW;EAC5B,MAAM,CAAC;EACR,CAAC,EAEE,CAAC,GAAgB,KAAqB,EAAwB,KAAK,EAEnE,IAAU,GAAM,mBAEhB,IAAc,SACX;EACL,MAAM,GAAS,QAAQ;EACvB,aAAa,GAAS,eAAe;EACrC,aAAa,GAAS,eAAe;EACrC,QAAQ,GAAS,UAAU;EAC3B,WAAW,GAAS,YAAY,EAAQ,UAAU,MAAM,IAAI,CAAC,KAAK;EAClE,SAAS,GAAS,UAAU,EAAQ,QAAQ,MAAM,IAAI,CAAC,KAAK;EAC7D,GACD,CAAC,EAAQ,CACV,EAEK,CAAC,GAAe,KAAoB,EAAiC,EAAE,CAAC,EACxE,IAAO;EAAE,GAAG;EAAa,GAAG;EAAe,EAC3C,KAAW,MAAoC,EAAiB,EAAQ,EAGxE,CAAC,GAAe,EAAE,SAAS,OAAY,EAAY,GAAgB,EACvE,gBAAgB;EACd;EACA;EACA;EACA;EACA;EACA;EACD,EACF,CAAC,EACI,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,IAAe,EAAe,EAAK,WAAW,EAAK,QAAQ;AAqDjE,QAhBK,IAMD,KAAW,CAAC,IAEZ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAK,WAAU,kFAAmF,CAAA;EAC9F,CAAA,GAEN,IACK,kBAAC,OAAD;EAAK,WAAU;YAAf,CAAsC,2BAAwB,EAAM,QAAc;MACtF,IAGH,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,SAAQ;MACR,MAAK;MACL,cAAW;MACX,eAAe,EAAS,EAAW,iCAAiC,EAAU,CAAC;gBAE/E,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;MAC1B,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAyB;MAAiB,CAAA,EACxD,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAA6C,YAAS,EAAQ,KAAS;QACnE,EAAA,CAAA,CACF;QACN,kBAAC,GAAD;KAAQ,MAAK;KAAK,SAlEL,YAAY;AAC7B,UAAI,CAAC,KAAW,EAAc;AAE9B,MADA,EAAa,KAAK,EAClB,EAAkB,KAAK;MAIvB,IAAM,IAAc;OAClB,GAAI,EAAK,cAAc,EAAY,aAAa,EAAE,WAAW,EAAK,aAAa,KAAA,GAAW;OAC1F,GAAI,EAAK,YAAY,EAAY,WAAW,EAAE,SAAS,EAAK,WAAW,KAAA,GAAW;OACnF;AACD,UAAI;AAgBF,OAfA,MAAM,EACJ,EAAc,EACZ,WAAW;QACT,IAAI,EAAQ;QACZ,OAAO;SACL,MAAM,EAAK,QAAQ,KAAA;SACnB,aAAa,EAAK,eAAe,KAAA;SACjC,aAAa,EAAK,eAAe,KAAA;SAEjC,GAAI,EAAK,WAAW,EAAY,UAAU,EAAE,QAAQ,EAAK,QAAQ;SACjE,GAAG;SACJ;QACF,EACF,CAAC,CACH,EACD,EAAkB,gCAAgC;eAC3C,GAAG;AACV,SAAa,aAAa,QAAQ,EAAE,UAAU,kCAAkC;;;KAqCvC,UAAU,KAAU;eAA3D,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAChC,IAAS,cAAc,eACjB;OACL;;GAEL,KACC,kBAAC,OAAD;IAAK,MAAK;IAAS,WAAU;cAC1B;IACG,CAAA;GAEP,KACC,kBAAC,OAAD;IAAK,MAAK;IAAQ,WAAU;cACzB;IACG,CAAA;GAGR,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,mBAA2B,CAAA,EAC3B,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cAAvB;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAsB;MAAoB,CAAA,EAC3D,kBAAC,GAAD;MACE,OAAO,EAAK;MACZ,WAAW,MAAM,EAAQ;OAAE,GAAG;OAAM,MAAM,EAAE,OAAO;OAAO,CAAC;MAC3D,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAsB;MAAmB,CAAA,EAC1D,kBAAC,YAAD;MACE,WAAU;MACV,OAAO,EAAK;MACZ,WAAW,MAAM,EAAQ;OAAE,GAAG;OAAM,aAAa,EAAE,OAAO;OAAO,CAAC;MAClE,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAsB;MAAmB,CAAA,EAC1D,kBAAC,UAAD;MACE,WAAU;MACV,OAAO,EAAK;MACZ,WAAW,MAAM,EAAQ;OAAE,GAAG;OAAM,aAAa,EAAE,OAAO;OAAO,CAAC;gBA/GxD;OAAC;OAAS;OAAU;OAAa;OAAU;OAAS;OAAS,CAiHxD,KAAK,MAClB,kBAAC,UAAD;OAAgB,OAAO;iBACpB,EAAE,aAAa;OACT,EAFI,EAEJ,CACT;MACK,CAAA,CACL,EAAA,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CAEE,kBAAC,SAAD;MAAO,SAAQ;MAAiB,WAAU;gBAAsB;MAExD,CAAA,EACR,kBAAC,UAAD;MACE,IAAG;MACH,WAAU;MACV,OAAO,EAAK;MACZ,WAAW,MAAM,EAAQ;OAAE,GAAG;OAAM,QAAQ,EAAE,OAAO;OAAO,CAAC;iBAE1D,EAAuC,SAAS,EAAK,OAAO,GAC3D,IACA,CAAC,EAAK,QAAQ,GAAG,EAAiB,EACpC,KAAK,MACL,kBAAC,UAAD;OAAgB,OAAO;iBACpB,EAAU,EAAE;OACN,EAFI,EAEJ,CACT;MACK,CAAA,CACL,EAAA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAgB,WAAU;iBAAsB;OAEvD,CAAA,EACR,kBAAC,GAAD;OACE,IAAG;OACH,MAAK;OACL,OAAO,EAAK;OACZ,KAAK,EAAK,WAAW,KAAA;OACrB,WAAW,MAAM,EAAQ;QAAE,GAAG;QAAM,WAAW,EAAE,OAAO;QAAO,CAAC;OAChE,WAAU;OACV,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAc,WAAU;iBAAsB;OAErD,CAAA,EACR,kBAAC,GAAD;OACE,IAAG;OACH,MAAK;OACL,OAAO,EAAK;OACZ,KAAK,EAAK,aAAa,KAAA;OACvB,WAAW,MAAM,EAAQ;QAAE,GAAG;QAAM,SAAS,EAAE,OAAO;QAAO,CAAC;OAC9D,gBAAc;OACd,WAAU;OACV,CAAA,CACE,EAAA,CAAA,CACF;;KACL,KACC,kBAAC,KAAD;MAAG,MAAK;MAAQ,WAAU;gBAA2B;MAEjD,CAAA;KAEM;MACT,EAAA,CAAA;GACH;MAhIa,kBAAC,OAAD;EAAK,WAAU;YAA4B;EAAwB,CAAA,GAZpF,kBAAC,OAAD;EAAK,WAAU;YAA4B;EAAkD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectsMilestoneDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsMilestoneDetailPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProjectsMilestoneDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsMilestoneDetailPagePage.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,+BAA+B,4CA+I9C"}
|
|
@@ -2,13 +2,14 @@ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
|
|
|
2
2
|
import { PersonName as t } from "../people/People.js";
|
|
3
3
|
import { detailPath as n } from "../utils/rowNavigation.js";
|
|
4
4
|
import { useEntityId as r } from "../hooks/useEntityId.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
5
|
+
import { MilestoneHeaderActions as i } from "../controls/MilestoneControls.js";
|
|
6
|
+
import { Calendar as a, FolderKanban as o, Target as s, User as c } from "lucide-react";
|
|
7
|
+
import { gql as l } from "@apollo/client";
|
|
8
|
+
import { useQuery as u } from "@apollo/client/react";
|
|
9
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
10
|
+
import { Badge as p, Card as m, CardContent as h, CardHeader as g, CardTitle as _ } from "@burdenoff/fe-libs/ui";
|
|
10
11
|
//#region src/planmagnet/pages/ProjectsMilestoneDetailPagePage.tsx
|
|
11
|
-
var
|
|
12
|
+
var v = l`
|
|
12
13
|
query GetMilestonesForDetail($id: ID!) {
|
|
13
14
|
planmagnetMilestone(id: $id) {
|
|
14
15
|
id
|
|
@@ -26,154 +27,145 @@ var _ = c`
|
|
|
26
27
|
completedAt
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
-
PENDING: "bg-gray-100 text-gray-800",
|
|
31
|
-
IN_PROGRESS: "bg-blue-100 text-blue-800",
|
|
32
|
-
COMPLETED: "bg-green-100 text-green-800",
|
|
33
|
-
MISSED: "bg-red-100 text-red-800",
|
|
34
|
-
CANCELLED: "bg-red-100 text-red-800"
|
|
35
|
-
};
|
|
30
|
+
`;
|
|
36
31
|
function y() {
|
|
37
|
-
let
|
|
38
|
-
variables: { id:
|
|
39
|
-
skip: !
|
|
32
|
+
let l = r("milestoneId"), y = e(), { data: b, loading: x, error: S } = u(v, {
|
|
33
|
+
variables: { id: l },
|
|
34
|
+
skip: !l
|
|
40
35
|
});
|
|
41
|
-
if (!
|
|
36
|
+
if (!l) return /* @__PURE__ */ d("div", {
|
|
42
37
|
className: "p-6 text-muted-foreground",
|
|
43
38
|
children: "No milestone selected. Open one from the list."
|
|
44
39
|
});
|
|
45
|
-
if (x && !b) return /* @__PURE__ */
|
|
40
|
+
if (x && !b) return /* @__PURE__ */ d("div", {
|
|
46
41
|
className: "flex items-center justify-center p-12",
|
|
47
|
-
children: /* @__PURE__ */
|
|
42
|
+
children: /* @__PURE__ */ d("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
48
43
|
});
|
|
49
|
-
if (S) return /* @__PURE__ */
|
|
44
|
+
if (S) return /* @__PURE__ */ f("div", {
|
|
50
45
|
className: "p-6 text-red-500",
|
|
51
46
|
children: ["Error loading milestone: ", S.message]
|
|
52
47
|
});
|
|
53
48
|
let C = b?.planmagnetMilestone;
|
|
54
|
-
if (!C) return /* @__PURE__ */
|
|
49
|
+
if (!C) return /* @__PURE__ */ d("div", {
|
|
55
50
|
className: "p-6 text-muted-foreground",
|
|
56
51
|
children: "Milestone not found."
|
|
57
52
|
});
|
|
58
53
|
let w = C.status === "COMPLETED";
|
|
59
|
-
return /* @__PURE__ */
|
|
54
|
+
return /* @__PURE__ */ f("div", {
|
|
60
55
|
className: "space-y-6 p-6",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
56
|
+
children: [/* @__PURE__ */ f("div", {
|
|
62
57
|
className: "flex items-center justify-between",
|
|
63
|
-
children: [/* @__PURE__ */
|
|
58
|
+
children: [/* @__PURE__ */ f("div", {
|
|
64
59
|
className: "flex items-center gap-3",
|
|
65
|
-
children: [/* @__PURE__ */
|
|
60
|
+
children: [/* @__PURE__ */ d(s, { className: "h-6 w-6 text-primary" }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
|
|
66
61
|
className: "text-2xl font-semibold",
|
|
67
62
|
children: C.name
|
|
68
|
-
}), /* @__PURE__ */
|
|
63
|
+
}), /* @__PURE__ */ f("p", {
|
|
69
64
|
className: "text-sm text-muted-foreground",
|
|
70
65
|
children: ["Project: ", C.project?.name ?? "not available"]
|
|
71
66
|
})] })]
|
|
72
|
-
}), /* @__PURE__ */
|
|
73
|
-
|
|
74
|
-
children: C.status.toLowerCase().replace("_", " ")
|
|
75
|
-
})]
|
|
76
|
-
}), /* @__PURE__ */ d("div", {
|
|
67
|
+
}), /* @__PURE__ */ d(i, { milestone: C })]
|
|
68
|
+
}), /* @__PURE__ */ f("div", {
|
|
77
69
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
78
|
-
children: [/* @__PURE__ */
|
|
70
|
+
children: [/* @__PURE__ */ f("div", {
|
|
79
71
|
className: "lg:col-span-2 space-y-6",
|
|
80
|
-
children: [/* @__PURE__ */
|
|
72
|
+
children: [/* @__PURE__ */ f(m, { children: [/* @__PURE__ */ d(g, { children: /* @__PURE__ */ d(_, { children: "Overview" }) }), /* @__PURE__ */ f(h, {
|
|
81
73
|
className: "space-y-4",
|
|
82
|
-
children: [/* @__PURE__ */
|
|
74
|
+
children: [/* @__PURE__ */ d("p", {
|
|
83
75
|
className: "text-sm",
|
|
84
76
|
children: C.description ?? "No description provided."
|
|
85
|
-
}), /* @__PURE__ */
|
|
77
|
+
}), /* @__PURE__ */ d("div", { children: /* @__PURE__ */ f("div", {
|
|
86
78
|
className: "flex justify-between text-sm mb-2",
|
|
87
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ d("span", {
|
|
88
80
|
className: "text-muted-foreground",
|
|
89
81
|
children: "Status"
|
|
90
|
-
}), /* @__PURE__ */
|
|
82
|
+
}), /* @__PURE__ */ d(p, {
|
|
91
83
|
variant: w ? "default" : "secondary",
|
|
92
84
|
className: "capitalize",
|
|
93
85
|
children: C.status.toLowerCase().replace("_", " ")
|
|
94
86
|
})]
|
|
95
87
|
}) })]
|
|
96
|
-
})] }), /* @__PURE__ */
|
|
88
|
+
})] }), /* @__PURE__ */ f(m, { children: [/* @__PURE__ */ d(g, { children: /* @__PURE__ */ d(_, { children: "Timeline" }) }), /* @__PURE__ */ d(h, { children: /* @__PURE__ */ f("div", {
|
|
97
89
|
className: "grid grid-cols-2 gap-4 text-center",
|
|
98
|
-
children: [/* @__PURE__ */
|
|
90
|
+
children: [/* @__PURE__ */ f("div", {
|
|
99
91
|
className: "p-4 bg-muted rounded-md",
|
|
100
|
-
children: [/* @__PURE__ */
|
|
92
|
+
children: [/* @__PURE__ */ d("p", {
|
|
101
93
|
className: "text-sm font-bold",
|
|
102
94
|
children: C.dueDate ? new Date(C.dueDate).toLocaleDateString() : "—"
|
|
103
|
-
}), /* @__PURE__ */
|
|
95
|
+
}), /* @__PURE__ */ d("p", {
|
|
104
96
|
className: "text-xs text-muted-foreground",
|
|
105
97
|
children: "Due Date"
|
|
106
98
|
})]
|
|
107
|
-
}), /* @__PURE__ */
|
|
99
|
+
}), /* @__PURE__ */ f("div", {
|
|
108
100
|
className: "p-4 bg-muted rounded-md",
|
|
109
|
-
children: [/* @__PURE__ */
|
|
101
|
+
children: [/* @__PURE__ */ d("p", {
|
|
110
102
|
className: "text-sm font-bold",
|
|
111
103
|
children: C.completedAt ? new Date(C.completedAt).toLocaleDateString() : "—"
|
|
112
|
-
}), /* @__PURE__ */
|
|
104
|
+
}), /* @__PURE__ */ d("p", {
|
|
113
105
|
className: "text-xs text-muted-foreground",
|
|
114
106
|
children: "Completed"
|
|
115
107
|
})]
|
|
116
108
|
})]
|
|
117
109
|
}) })] })]
|
|
118
|
-
}), /* @__PURE__ */
|
|
110
|
+
}), /* @__PURE__ */ f(m, { children: [/* @__PURE__ */ d(g, { children: /* @__PURE__ */ d(_, { children: "Details" }) }), /* @__PURE__ */ f(h, {
|
|
119
111
|
className: "space-y-3 text-sm",
|
|
120
112
|
children: [
|
|
121
|
-
/* @__PURE__ */
|
|
113
|
+
/* @__PURE__ */ f("div", {
|
|
122
114
|
className: "flex items-center gap-2",
|
|
123
115
|
children: [
|
|
124
|
-
/* @__PURE__ */
|
|
125
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ d(a, { className: "h-4 w-4 text-muted-foreground" }),
|
|
117
|
+
/* @__PURE__ */ d("span", {
|
|
126
118
|
className: "text-muted-foreground",
|
|
127
119
|
children: "Due:"
|
|
128
120
|
}),
|
|
129
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ d("span", {
|
|
130
122
|
className: "font-medium",
|
|
131
123
|
children: C.dueDate ? new Date(C.dueDate).toLocaleDateString() : "Not set"
|
|
132
124
|
})
|
|
133
125
|
]
|
|
134
126
|
}),
|
|
135
|
-
/* @__PURE__ */
|
|
127
|
+
/* @__PURE__ */ f("div", {
|
|
136
128
|
className: "flex items-center gap-2",
|
|
137
129
|
children: [
|
|
138
|
-
/* @__PURE__ */
|
|
139
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ d(o, { className: "h-4 w-4 text-muted-foreground" }),
|
|
131
|
+
/* @__PURE__ */ d("span", {
|
|
140
132
|
className: "text-muted-foreground",
|
|
141
133
|
children: "Project:"
|
|
142
134
|
}),
|
|
143
|
-
C.project ? /* @__PURE__ */
|
|
135
|
+
C.project ? /* @__PURE__ */ d("button", {
|
|
144
136
|
type: "button",
|
|
145
137
|
className: "font-medium text-primary hover:underline",
|
|
146
138
|
onClick: () => y(n("/projects/project-detail-page", C.project.id)),
|
|
147
139
|
children: C.project.name
|
|
148
|
-
}) : /* @__PURE__ */
|
|
140
|
+
}) : /* @__PURE__ */ d("span", {
|
|
149
141
|
className: "text-muted-foreground",
|
|
150
142
|
children: "not available"
|
|
151
143
|
})
|
|
152
144
|
]
|
|
153
145
|
}),
|
|
154
|
-
C.ownerId && /* @__PURE__ */
|
|
146
|
+
C.ownerId && /* @__PURE__ */ f("div", {
|
|
155
147
|
className: "flex items-center gap-2",
|
|
156
148
|
children: [
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ d(c, { className: "h-4 w-4 text-muted-foreground" }),
|
|
150
|
+
/* @__PURE__ */ d("span", {
|
|
159
151
|
className: "text-muted-foreground",
|
|
160
152
|
children: "Owner:"
|
|
161
153
|
}),
|
|
162
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ d("span", {
|
|
163
155
|
className: "font-medium",
|
|
164
|
-
children: /* @__PURE__ */
|
|
156
|
+
children: /* @__PURE__ */ d(t, { id: C.ownerId })
|
|
165
157
|
})
|
|
166
158
|
]
|
|
167
159
|
}),
|
|
168
|
-
/* @__PURE__ */
|
|
160
|
+
/* @__PURE__ */ f("div", {
|
|
169
161
|
className: "flex items-center gap-2",
|
|
170
162
|
children: [
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ d(a, { className: "h-4 w-4 text-muted-foreground" }),
|
|
164
|
+
/* @__PURE__ */ d("span", {
|
|
173
165
|
className: "text-muted-foreground",
|
|
174
166
|
children: "Created:"
|
|
175
167
|
}),
|
|
176
|
-
/* @__PURE__ */
|
|
168
|
+
/* @__PURE__ */ d("span", {
|
|
177
169
|
className: "font-medium",
|
|
178
170
|
children: C.createdAt ? new Date(C.createdAt).toLocaleDateString() : "—"
|
|
179
171
|
})
|