@burdenoff/microfe-planmagnet 2026.926.2 → 2026.927.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/planmagnet/pages/DashboardDashboardPagePage.d.ts.map +1 -1
  2. package/dist/planmagnet/pages/DashboardDashboardPagePage.js +14 -4
  3. package/dist/planmagnet/pages/DashboardDashboardPagePage.js.map +1 -1
  4. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  5. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +102 -100
  6. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  7. package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
  8. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +95 -94
  9. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
  10. package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
  11. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +1 -1
  12. package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
  13. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  14. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +97 -93
  15. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  16. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.d.ts.map +1 -1
  17. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +84 -73
  18. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js.map +1 -1
  19. package/dist/planmagnet/pages/ProjectsMilestonesPagePage.d.ts.map +1 -1
  20. package/dist/planmagnet/pages/ProjectsMilestonesPagePage.js +13 -8
  21. package/dist/planmagnet/pages/ProjectsMilestonesPagePage.js.map +1 -1
  22. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
  23. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +129 -125
  24. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
  25. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.d.ts.map +1 -1
  26. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +112 -109
  27. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js.map +1 -1
  28. package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts.map +1 -1
  29. package/dist/planmagnet/pages/ReportsReportsPagePage.js +72 -83
  30. package/dist/planmagnet/pages/ReportsReportsPagePage.js.map +1 -1
  31. package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
  32. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +103 -103
  33. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
  34. package/dist/planmagnet/pages/TasksEditTaskPagePage.d.ts.map +1 -1
  35. package/dist/planmagnet/pages/TasksEditTaskPagePage.js +101 -99
  36. package/dist/planmagnet/pages/TasksEditTaskPagePage.js.map +1 -1
  37. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  38. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +127 -125
  39. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  40. package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
  41. package/dist/planmagnet/pages/TasksTasksPagePage.js +8 -11
  42. package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
  43. package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
  44. package/dist/planmagnet/pages/TeamTeamPagePage.js +67 -68
  45. package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
  46. package/dist/planmagnet/pages/WorkspaceCreateWorkspacePagePage.d.ts.map +1 -1
  47. package/dist/planmagnet/pages/WorkspaceCreateWorkspacePagePage.js +1 -5
  48. package/dist/planmagnet/pages/WorkspaceCreateWorkspacePagePage.js.map +1 -1
  49. package/dist/planmagnet/people/People.d.ts +18 -0
  50. package/dist/planmagnet/people/People.d.ts.map +1 -1
  51. package/dist/planmagnet/people/People.js +26 -12
  52. package/dist/planmagnet/people/People.js.map +1 -1
  53. package/package.json +1 -1
@@ -1,18 +1,24 @@
1
- import { PersonName as e } from "../people/People.js";
2
- import { useEntityId as t } from "../hooks/useEntityId.js";
3
- import { Calendar as n, FolderKanban as r, Target as i, User as a } from "lucide-react";
4
- import { gql as o } from "@apollo/client";
5
- import { useQuery as s } from "@apollo/client/react";
6
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
- import { Badge as u, Card as d, CardContent as f, CardHeader as p, CardTitle as m } from "@burdenoff/fe-libs/ui";
1
+ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
+ import { PersonName as t } from "../people/People.js";
3
+ import { detailPath as n } from "../utils/rowNavigation.js";
4
+ import { useEntityId as r } from "../hooks/useEntityId.js";
5
+ import { Calendar as i, FolderKanban as a, Target as o, User as s } from "lucide-react";
6
+ import { gql as c } from "@apollo/client";
7
+ import { useQuery as l } from "@apollo/client/react";
8
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
+ import { Badge as f, Card as p, CardContent as m, CardHeader as h, CardTitle as g } from "@burdenoff/fe-libs/ui";
8
10
  //#region src/planmagnet/pages/ProjectsMilestoneDetailPagePage.tsx
9
- var h = o`
11
+ var _ = c`
10
12
  query GetMilestonesForDetail($id: ID!) {
11
13
  planmagnetMilestone(id: $id) {
12
14
  id
13
15
  name
14
16
  description
15
17
  projectId
18
+ project {
19
+ id
20
+ name
21
+ }
16
22
  status
17
23
  dueDate
18
24
  ownerId
@@ -20,151 +26,156 @@ var h = o`
20
26
  completedAt
21
27
  }
22
28
  }
23
- `, g = {
29
+ `, v = {
24
30
  PENDING: "bg-gray-100 text-gray-800",
25
31
  IN_PROGRESS: "bg-blue-100 text-blue-800",
26
32
  COMPLETED: "bg-green-100 text-green-800",
27
33
  MISSED: "bg-red-100 text-red-800",
28
34
  CANCELLED: "bg-red-100 text-red-800"
29
35
  };
30
- function _() {
31
- let o = t("milestoneId"), { data: _, loading: v, error: y } = s(h, {
32
- variables: { id: o },
33
- skip: !o
36
+ function y() {
37
+ let c = r("milestoneId"), y = e(), { data: b, loading: x, error: S } = l(_, {
38
+ variables: { id: c },
39
+ skip: !c
34
40
  });
35
- if (!o) return /* @__PURE__ */ c("div", {
41
+ if (!c) return /* @__PURE__ */ u("div", {
36
42
  className: "p-6 text-muted-foreground",
37
43
  children: "No milestone selected. Open one from the list."
38
44
  });
39
- if (v && !_) return /* @__PURE__ */ c("div", {
45
+ if (x && !b) return /* @__PURE__ */ u("div", {
40
46
  className: "flex items-center justify-center p-12",
41
- children: /* @__PURE__ */ c("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
47
+ children: /* @__PURE__ */ u("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
42
48
  });
43
- if (y) return /* @__PURE__ */ l("div", {
49
+ if (S) return /* @__PURE__ */ d("div", {
44
50
  className: "p-6 text-red-500",
45
- children: ["Error loading milestone: ", y.message]
51
+ children: ["Error loading milestone: ", S.message]
46
52
  });
47
- let b = _?.planmagnetMilestone;
48
- if (!b) return /* @__PURE__ */ c("div", {
53
+ let C = b?.planmagnetMilestone;
54
+ if (!C) return /* @__PURE__ */ u("div", {
49
55
  className: "p-6 text-muted-foreground",
50
56
  children: "Milestone not found."
51
57
  });
52
- let x = b.status === "COMPLETED";
53
- return /* @__PURE__ */ l("div", {
58
+ let w = C.status === "COMPLETED";
59
+ return /* @__PURE__ */ d("div", {
54
60
  className: "space-y-6 p-6",
55
- children: [/* @__PURE__ */ l("div", {
61
+ children: [/* @__PURE__ */ d("div", {
56
62
  className: "flex items-center justify-between",
57
- children: [/* @__PURE__ */ l("div", {
63
+ children: [/* @__PURE__ */ d("div", {
58
64
  className: "flex items-center gap-3",
59
- children: [/* @__PURE__ */ c(i, { className: "h-6 w-6 text-primary" }), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
65
+ children: [/* @__PURE__ */ u(o, { className: "h-6 w-6 text-primary" }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
60
66
  className: "text-2xl font-semibold",
61
- children: b.name
62
- }), /* @__PURE__ */ l("p", {
67
+ children: C.name
68
+ }), /* @__PURE__ */ d("p", {
63
69
  className: "text-sm text-muted-foreground",
64
- children: ["Project: ", b.projectId]
70
+ children: ["Project: ", C.project?.name ?? "not available"]
65
71
  })] })]
66
- }), /* @__PURE__ */ c("span", {
67
- className: `text-xs px-3 py-1 rounded-full capitalize ${g[b.status] ?? "bg-gray-100"}`,
68
- children: b.status.toLowerCase().replace("_", " ")
72
+ }), /* @__PURE__ */ u("span", {
73
+ className: `text-xs px-3 py-1 rounded-full capitalize ${v[C.status] ?? "bg-gray-100"}`,
74
+ children: C.status.toLowerCase().replace("_", " ")
69
75
  })]
70
- }), /* @__PURE__ */ l("div", {
76
+ }), /* @__PURE__ */ d("div", {
71
77
  className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
72
- children: [/* @__PURE__ */ l("div", {
78
+ children: [/* @__PURE__ */ d("div", {
73
79
  className: "lg:col-span-2 space-y-6",
74
- children: [/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ c(p, { children: /* @__PURE__ */ c(m, { children: "Overview" }) }), /* @__PURE__ */ l(f, {
80
+ children: [/* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Overview" }) }), /* @__PURE__ */ d(m, {
75
81
  className: "space-y-4",
76
- children: [/* @__PURE__ */ c("p", {
82
+ children: [/* @__PURE__ */ u("p", {
77
83
  className: "text-sm",
78
- children: b.description ?? "No description provided."
79
- }), /* @__PURE__ */ c("div", { children: /* @__PURE__ */ l("div", {
84
+ children: C.description ?? "No description provided."
85
+ }), /* @__PURE__ */ u("div", { children: /* @__PURE__ */ d("div", {
80
86
  className: "flex justify-between text-sm mb-2",
81
- children: [/* @__PURE__ */ c("span", {
87
+ children: [/* @__PURE__ */ u("span", {
82
88
  className: "text-muted-foreground",
83
89
  children: "Status"
84
- }), /* @__PURE__ */ c(u, {
85
- variant: x ? "default" : "secondary",
90
+ }), /* @__PURE__ */ u(f, {
91
+ variant: w ? "default" : "secondary",
86
92
  className: "capitalize",
87
- children: b.status.toLowerCase().replace("_", " ")
93
+ children: C.status.toLowerCase().replace("_", " ")
88
94
  })]
89
95
  }) })]
90
- })] }), /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ c(p, { children: /* @__PURE__ */ c(m, { children: "Timeline" }) }), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ l("div", {
96
+ })] }), /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Timeline" }) }), /* @__PURE__ */ u(m, { children: /* @__PURE__ */ d("div", {
91
97
  className: "grid grid-cols-2 gap-4 text-center",
92
- children: [/* @__PURE__ */ l("div", {
98
+ children: [/* @__PURE__ */ d("div", {
93
99
  className: "p-4 bg-muted rounded-md",
94
- children: [/* @__PURE__ */ c("p", {
100
+ children: [/* @__PURE__ */ u("p", {
95
101
  className: "text-sm font-bold",
96
- children: b.dueDate ? new Date(b.dueDate).toLocaleDateString() : "—"
97
- }), /* @__PURE__ */ c("p", {
102
+ children: C.dueDate ? new Date(C.dueDate).toLocaleDateString() : "—"
103
+ }), /* @__PURE__ */ u("p", {
98
104
  className: "text-xs text-muted-foreground",
99
105
  children: "Due Date"
100
106
  })]
101
- }), /* @__PURE__ */ l("div", {
107
+ }), /* @__PURE__ */ d("div", {
102
108
  className: "p-4 bg-muted rounded-md",
103
- children: [/* @__PURE__ */ c("p", {
109
+ children: [/* @__PURE__ */ u("p", {
104
110
  className: "text-sm font-bold",
105
- children: b.completedAt ? new Date(b.completedAt).toLocaleDateString() : "—"
106
- }), /* @__PURE__ */ c("p", {
111
+ children: C.completedAt ? new Date(C.completedAt).toLocaleDateString() : "—"
112
+ }), /* @__PURE__ */ u("p", {
107
113
  className: "text-xs text-muted-foreground",
108
114
  children: "Completed"
109
115
  })]
110
116
  })]
111
117
  }) })] })]
112
- }), /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ c(p, { children: /* @__PURE__ */ c(m, { children: "Details" }) }), /* @__PURE__ */ l(f, {
118
+ }), /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g, { children: "Details" }) }), /* @__PURE__ */ d(m, {
113
119
  className: "space-y-3 text-sm",
114
120
  children: [
115
- /* @__PURE__ */ l("div", {
121
+ /* @__PURE__ */ d("div", {
116
122
  className: "flex items-center gap-2",
117
123
  children: [
118
- /* @__PURE__ */ c(n, { className: "h-4 w-4 text-muted-foreground" }),
119
- /* @__PURE__ */ c("span", {
124
+ /* @__PURE__ */ u(i, { className: "h-4 w-4 text-muted-foreground" }),
125
+ /* @__PURE__ */ u("span", {
120
126
  className: "text-muted-foreground",
121
127
  children: "Due:"
122
128
  }),
123
- /* @__PURE__ */ c("span", {
129
+ /* @__PURE__ */ u("span", {
124
130
  className: "font-medium",
125
- children: b.dueDate ? new Date(b.dueDate).toLocaleDateString() : "Not set"
131
+ children: C.dueDate ? new Date(C.dueDate).toLocaleDateString() : "Not set"
126
132
  })
127
133
  ]
128
134
  }),
129
- /* @__PURE__ */ l("div", {
135
+ /* @__PURE__ */ d("div", {
130
136
  className: "flex items-center gap-2",
131
137
  children: [
132
- /* @__PURE__ */ c(r, { className: "h-4 w-4 text-muted-foreground" }),
133
- /* @__PURE__ */ c("span", {
138
+ /* @__PURE__ */ u(a, { className: "h-4 w-4 text-muted-foreground" }),
139
+ /* @__PURE__ */ u("span", {
134
140
  className: "text-muted-foreground",
135
141
  children: "Project:"
136
142
  }),
137
- /* @__PURE__ */ c("span", {
138
- className: "font-medium",
139
- children: b.projectId
143
+ C.project ? /* @__PURE__ */ u("button", {
144
+ type: "button",
145
+ className: "font-medium text-primary hover:underline",
146
+ onClick: () => y(n("/projects/project-detail-page", C.project.id)),
147
+ children: C.project.name
148
+ }) : /* @__PURE__ */ u("span", {
149
+ className: "text-muted-foreground",
150
+ children: "not available"
140
151
  })
141
152
  ]
142
153
  }),
143
- b.ownerId && /* @__PURE__ */ l("div", {
154
+ C.ownerId && /* @__PURE__ */ d("div", {
144
155
  className: "flex items-center gap-2",
145
156
  children: [
146
- /* @__PURE__ */ c(a, { className: "h-4 w-4 text-muted-foreground" }),
147
- /* @__PURE__ */ c("span", {
157
+ /* @__PURE__ */ u(s, { className: "h-4 w-4 text-muted-foreground" }),
158
+ /* @__PURE__ */ u("span", {
148
159
  className: "text-muted-foreground",
149
160
  children: "Owner:"
150
161
  }),
151
- /* @__PURE__ */ c("span", {
162
+ /* @__PURE__ */ u("span", {
152
163
  className: "font-medium",
153
- children: /* @__PURE__ */ c(e, { id: b.ownerId })
164
+ children: /* @__PURE__ */ u(t, { id: C.ownerId })
154
165
  })
155
166
  ]
156
167
  }),
157
- /* @__PURE__ */ l("div", {
168
+ /* @__PURE__ */ d("div", {
158
169
  className: "flex items-center gap-2",
159
170
  children: [
160
- /* @__PURE__ */ c(n, { className: "h-4 w-4 text-muted-foreground" }),
161
- /* @__PURE__ */ c("span", {
171
+ /* @__PURE__ */ u(i, { className: "h-4 w-4 text-muted-foreground" }),
172
+ /* @__PURE__ */ u("span", {
162
173
  className: "text-muted-foreground",
163
174
  children: "Created:"
164
175
  }),
165
- /* @__PURE__ */ c("span", {
176
+ /* @__PURE__ */ u("span", {
166
177
  className: "font-medium",
167
- children: b.createdAt ? new Date(b.createdAt).toLocaleDateString() : "—"
178
+ children: C.createdAt ? new Date(C.createdAt).toLocaleDateString() : "—"
168
179
  })
169
180
  ]
170
181
  })
@@ -174,6 +185,6 @@ function _() {
174
185
  });
175
186
  }
176
187
  //#endregion
177
- export { _ as ProjectsMilestoneDetailPagePage };
188
+ export { y as ProjectsMilestoneDetailPagePage };
178
189
 
179
190
  //# sourceMappingURL=ProjectsMilestoneDetailPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsMilestoneDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsMilestoneDetailPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Target, Calendar, FolderKanban, User } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { PersonName } from '../people/People';\n\nconst GET_MILESTONES_FOR_DETAIL = gql`\n query GetMilestonesForDetail($id: ID!) {\n planmagnetMilestone(id: $id) {\n id\n name\n description\n projectId\n status\n dueDate\n ownerId\n createdAt\n completedAt\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n PENDING: 'bg-gray-100 text-gray-800',\n IN_PROGRESS: 'bg-blue-100 text-blue-800',\n COMPLETED: 'bg-green-100 text-green-800',\n MISSED: 'bg-red-100 text-red-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function ProjectsMilestoneDetailPagePage() {\n const milestoneId = useEntityId('milestoneId');\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_MILESTONES_FOR_DETAIL, {\n variables: { id: milestoneId },\n skip: !milestoneId,\n });\n\n if (!milestoneId)\n return (\n <div className=\"p-6 text-muted-foreground\">\n No milestone selected. Open one from the list.\n </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-red-500\">Error loading milestone: {error.message}</div>;\n\n const ms = data?.planmagnetMilestone;\n if (!ms) return <div className=\"p-6 text-muted-foreground\">Milestone not found.</div>;\n\n const isCompleted = ms.status === 'COMPLETED';\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Target className=\"h-6 w-6 text-primary\" />\n <div>\n <h1 className=\"text-2xl font-semibold\">{ms.name}</h1>\n <p className=\"text-sm text-muted-foreground\">Project: {ms.projectId}</p>\n </div>\n </div>\n <span\n className={`text-xs px-3 py-1 rounded-full capitalize ${statusColor[ms.status] ?? 'bg-gray-100'}`}\n >\n {ms.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Overview</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm\">{ms.description ?? 'No description provided.'}</p>\n <div>\n <div className=\"flex justify-between text-sm mb-2\">\n <span className=\"text-muted-foreground\">Status</span>\n <Badge variant={isCompleted ? 'default' : 'secondary'} className=\"capitalize\">\n {ms.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Timeline</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 gap-4 text-center\">\n <div className=\"p-4 bg-muted rounded-md\">\n <p className=\"text-sm font-bold\">\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : '—'}\n </p>\n <p className=\"text-xs text-muted-foreground\">Due Date</p>\n </div>\n <div className=\"p-4 bg-muted rounded-md\">\n <p className=\"text-sm font-bold\">\n {ms.completedAt ? new Date(ms.completedAt).toLocaleDateString() : '—'}\n </p>\n <p className=\"text-xs text-muted-foreground\">Completed</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Due:</span>\n <span className=\"font-medium\">\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : 'Not set'}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <FolderKanban className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Project:</span>\n <span className=\"font-medium\">{ms.projectId}</span>\n </div>\n {ms.ownerId && (\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Owner:</span>\n <span className=\"font-medium\">\n <PersonName id={ms.ownerId} />\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Created:</span>\n <span className=\"font-medium\">\n {ms.createdAt ? new Date(ms.createdAt).toLocaleDateString() : '—'}\n </span>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectsMilestoneDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsMilestoneDetailPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Target, Calendar, FolderKanban, User } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { PersonName } from '../people/People';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\n\nconst GET_MILESTONES_FOR_DETAIL = gql`\n query GetMilestonesForDetail($id: ID!) {\n planmagnetMilestone(id: $id) {\n id\n name\n description\n projectId\n project {\n id\n name\n }\n status\n dueDate\n ownerId\n createdAt\n completedAt\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n PENDING: 'bg-gray-100 text-gray-800',\n IN_PROGRESS: 'bg-blue-100 text-blue-800',\n COMPLETED: 'bg-green-100 text-green-800',\n MISSED: 'bg-red-100 text-red-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function ProjectsMilestoneDetailPagePage() {\n const milestoneId = useEntityId('milestoneId');\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_MILESTONES_FOR_DETAIL, {\n variables: { id: milestoneId },\n skip: !milestoneId,\n });\n\n if (!milestoneId)\n return (\n <div className=\"p-6 text-muted-foreground\">\n No milestone selected. Open one from the list.\n </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-red-500\">Error loading milestone: {error.message}</div>;\n\n const ms = data?.planmagnetMilestone;\n if (!ms) return <div className=\"p-6 text-muted-foreground\">Milestone not found.</div>;\n\n const isCompleted = ms.status === 'COMPLETED';\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Target className=\"h-6 w-6 text-primary\" />\n <div>\n <h1 className=\"text-2xl font-semibold\">{ms.name}</h1>\n <p className=\"text-sm text-muted-foreground\">\n Project: {ms.project?.name ?? 'not available'}\n </p>\n </div>\n </div>\n <span\n className={`text-xs px-3 py-1 rounded-full capitalize ${statusColor[ms.status] ?? 'bg-gray-100'}`}\n >\n {ms.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Overview</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm\">{ms.description ?? 'No description provided.'}</p>\n <div>\n <div className=\"flex justify-between text-sm mb-2\">\n <span className=\"text-muted-foreground\">Status</span>\n <Badge variant={isCompleted ? 'default' : 'secondary'} className=\"capitalize\">\n {ms.status.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Timeline</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 gap-4 text-center\">\n <div className=\"p-4 bg-muted rounded-md\">\n <p className=\"text-sm font-bold\">\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : '—'}\n </p>\n <p className=\"text-xs text-muted-foreground\">Due Date</p>\n </div>\n <div className=\"p-4 bg-muted rounded-md\">\n <p className=\"text-sm font-bold\">\n {ms.completedAt ? new Date(ms.completedAt).toLocaleDateString() : '—'}\n </p>\n <p className=\"text-xs text-muted-foreground\">Completed</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n <Card>\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Due:</span>\n <span className=\"font-medium\">\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : 'Not set'}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <FolderKanban className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Project:</span>\n {/* The project's name, linked — this printed the raw project UUID (BOFF-7949). */}\n {ms.project ? (\n <button\n type=\"button\"\n className=\"font-medium text-primary hover:underline\"\n onClick={() =>\n navigate(detailPath('/projects/project-detail-page', ms.project.id))\n }\n >\n {ms.project.name}\n </button>\n ) : (\n <span className=\"text-muted-foreground\">not available</span>\n )}\n </div>\n {ms.ownerId && (\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Owner:</span>\n <span className=\"font-medium\">\n <PersonName id={ms.ownerId} />\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-muted-foreground\">Created:</span>\n <span className=\"font-medium\">\n {ms.createdAt ? new Date(ms.createdAt).toLocaleDateString() : '—'}\n </span>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsMilestonesPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsMilestonesPagePage.tsx"],"names":[],"mappings":"AA+CA,wBAAgB,0BAA0B,4CAiHzC"}
1
+ {"version":3,"file":"ProjectsMilestonesPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsMilestonesPagePage.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,0BAA0B,4CA+HzC"}
@@ -17,6 +17,10 @@ var v = u`
17
17
  name
18
18
  description
19
19
  projectId
20
+ project {
21
+ id
22
+ name
23
+ }
20
24
  status
21
25
  dueDate
22
26
  ownerId
@@ -48,10 +52,6 @@ function x() {
48
52
  className: "flex items-center justify-center p-12",
49
53
  children: /* @__PURE__ */ f("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
50
54
  });
51
- if (E) return /* @__PURE__ */ p("div", {
52
- className: "p-6 text-red-500",
53
- children: ["Error loading milestones: ", E.message]
54
- });
55
55
  let D = w?.planmagnetMilestones?.items ?? [], O = w?.planmagnetMilestones?.totalCount ?? 0;
56
56
  return /* @__PURE__ */ p("div", {
57
57
  className: "space-y-6 p-6",
@@ -61,9 +61,9 @@ function x() {
61
61
  children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
62
62
  className: "text-2xl font-semibold",
63
63
  children: "Milestones"
64
- }), /* @__PURE__ */ p("p", {
64
+ }), /* @__PURE__ */ f("p", {
65
65
  className: "text-sm text-muted-foreground",
66
- children: [O, " milestones across all projects"]
66
+ children: S === "all" ? `${O} milestones across all projects` : `${O} ${S.toLowerCase().replace("_", " ")} milestones`
67
67
  })] }), /* @__PURE__ */ f(a, { onCreated: (e) => x(r("/projects/milestone-detail-page", e)) })]
68
68
  }),
69
69
  /* @__PURE__ */ f("div", {
@@ -74,6 +74,11 @@ function x() {
74
74
  children: e === "all" ? "All" : e.toLowerCase().replace("_", " ")
75
75
  }, e))
76
76
  }),
77
+ E && /* @__PURE__ */ p("div", {
78
+ role: "alert",
79
+ className: "rounded-md border border-destructive/40 p-4 text-sm text-destructive",
80
+ children: ["Milestones could not be loaded: ", E.message]
81
+ }),
77
82
  /* @__PURE__ */ f("div", {
78
83
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
79
84
  children: D.map((e) => /* @__PURE__ */ p(m, {
@@ -109,13 +114,13 @@ function x() {
109
114
  }),
110
115
  /* @__PURE__ */ p("div", {
111
116
  className: "text-xs text-muted-foreground",
112
- children: ["Project: ", e.projectId]
117
+ children: ["Project: ", e.project?.name ?? "not available"]
113
118
  })
114
119
  ]
115
120
  })]
116
121
  }, e.id))
117
122
  }),
118
- D.length === 0 && /* @__PURE__ */ f("p", {
123
+ !E && D.length === 0 && /* @__PURE__ */ f("p", {
119
124
  className: "text-center text-muted-foreground py-8",
120
125
  children: "No milestones found."
121
126
  })
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsMilestonesPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsMilestonesPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Target, Calendar, User } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps, detailPath } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { NewMilestoneDialog } from '../create/CreateDialogs';\n\nconst GET_MILESTONES = gql`\n query GetMilestones($workspaceId: ID!, $filter: PlanmagnetMilestoneFilter) {\n planmagnetMilestones(workspaceId: $workspaceId, filter: $filter, pagination: { first: 100 }) {\n items {\n id\n name\n description\n projectId\n status\n dueDate\n ownerId\n createdAt\n }\n totalCount\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n PENDING: 'bg-gray-100 text-gray-800',\n IN_PROGRESS: 'bg-blue-100 text-blue-800',\n COMPLETED: 'bg-green-100 text-green-800',\n MISSED: 'bg-red-100 text-red-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nconst milestoneStatuses = [\n 'all',\n 'PENDING',\n 'IN_PROGRESS',\n 'COMPLETED',\n 'MISSED',\n 'CANCELLED',\n] as const;\n\nexport function ProjectsMilestonesPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [filter, setFilter] = useState<string>('all');\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_MILESTONES, {\n variables: {\n workspaceId: workspaceId ?? 'default',\n filter: filter !== 'all' ? { status: filter } : undefined,\n },\n });\n\n // Only before the first load: a refetch after a create must not blank the page.\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-red-500\">Error loading milestones: {error.message}</div>;\n\n const milestones = data?.planmagnetMilestones?.items ?? [];\n const totalCount = data?.planmagnetMilestones?.totalCount ?? 0;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Milestones</h1>\n <p className=\"text-sm text-muted-foreground\">\n {totalCount} milestones across all projects\n </p>\n </div>\n <NewMilestoneDialog\n onCreated={(id) => navigate(detailPath('/projects/milestone-detail-page', id))}\n />\n </div>\n <div className=\"flex gap-1\">\n {milestoneStatuses.map((s) => (\n <button\n key={s}\n onClick={() => setFilter(s)}\n className={`px-3 py-1.5 text-sm rounded-md capitalize ${filter === s ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:bg-muted'}`}\n >\n {s === 'all' ? 'All' : s.toLowerCase().replace('_', ' ')}\n </button>\n ))}\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {milestones.map(\n (ms: {\n id: string;\n name: string;\n description: string | null;\n projectId: string;\n status: string;\n dueDate: string | null;\n ownerId: string | null;\n }) => (\n <Card\n key={ms.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/milestone-detail-page', ms.id)),\n ms.name\n )}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Target className=\"h-4 w-4 text-primary\" />\n {ms.name}\n </CardTitle>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[ms.status] ?? 'bg-gray-100'}`}\n >\n {ms.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {ms.description ?? 'No description'}\n </p>\n <div className=\"flex gap-3 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : 'No due date'}\n </span>\n {ms.ownerId && (\n <span className=\"flex items-center gap-1\">\n <User className=\"h-3 w-3\" />\n <PersonName id={ms.ownerId} />\n </span>\n )}\n </div>\n <div className=\"text-xs text-muted-foreground\">Project: {ms.projectId}</div>\n </CardContent>\n </Card>\n )\n )}\n </div>\n {milestones.length === 0 && (\n <p className=\"text-center text-muted-foreground py-8\">No milestones found.</p>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectsMilestonesPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsMilestonesPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Target, Calendar, User } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps, detailPath } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { NewMilestoneDialog } from '../create/CreateDialogs';\n\nconst GET_MILESTONES = gql`\n query GetMilestones($workspaceId: ID!, $filter: PlanmagnetMilestoneFilter) {\n planmagnetMilestones(workspaceId: $workspaceId, filter: $filter, pagination: { first: 100 }) {\n items {\n id\n name\n description\n projectId\n project {\n id\n name\n }\n status\n dueDate\n ownerId\n createdAt\n }\n totalCount\n }\n }\n`;\n\nconst statusColor: Record<string, string> = {\n PENDING: 'bg-gray-100 text-gray-800',\n IN_PROGRESS: 'bg-blue-100 text-blue-800',\n COMPLETED: 'bg-green-100 text-green-800',\n MISSED: 'bg-red-100 text-red-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nconst milestoneStatuses = [\n 'all',\n 'PENDING',\n 'IN_PROGRESS',\n 'COMPLETED',\n 'MISSED',\n 'CANCELLED',\n] as const;\n\nexport function ProjectsMilestonesPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [filter, setFilter] = useState<string>('all');\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_MILESTONES, {\n variables: {\n workspaceId: workspaceId ?? 'default',\n filter: filter !== 'all' ? { status: filter } : undefined,\n },\n });\n\n // Only before the first load: a refetch after a create must not blank the page.\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 // A failed load is shown INSIDE the list area: an early return here replaced the whole page, so the status tabs\n // and New Milestone vanished and a failing tab could not be left (BOFF-7942).\n\n const milestones = data?.planmagnetMilestones?.items ?? [];\n const totalCount = data?.planmagnetMilestones?.totalCount ?? 0;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Milestones</h1>\n <p className=\"text-sm text-muted-foreground\">\n {/* The count follows the tab: it is the filtered total, so do not call it \"all\". */}\n {filter === 'all'\n ? `${totalCount} milestones across all projects`\n : `${totalCount} ${filter.toLowerCase().replace('_', ' ')} milestones`}\n </p>\n </div>\n <NewMilestoneDialog\n onCreated={(id) => navigate(detailPath('/projects/milestone-detail-page', id))}\n />\n </div>\n <div className=\"flex gap-1\">\n {milestoneStatuses.map((s) => (\n <button\n key={s}\n onClick={() => setFilter(s)}\n className={`px-3 py-1.5 text-sm rounded-md capitalize ${filter === s ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:bg-muted'}`}\n >\n {s === 'all' ? 'All' : s.toLowerCase().replace('_', ' ')}\n </button>\n ))}\n </div>\n {error && (\n <div\n role=\"alert\"\n className=\"rounded-md border border-destructive/40 p-4 text-sm text-destructive\"\n >\n Milestones could not be loaded: {error.message}\n </div>\n )}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {milestones.map(\n (ms: {\n id: string;\n name: string;\n description: string | null;\n projectId: string;\n project: { id: string; name: string } | null;\n status: string;\n dueDate: string | null;\n ownerId: string | null;\n }) => (\n <Card\n key={ms.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/milestone-detail-page', ms.id)),\n ms.name\n )}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Target className=\"h-4 w-4 text-primary\" />\n {ms.name}\n </CardTitle>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[ms.status] ?? 'bg-gray-100'}`}\n >\n {ms.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {ms.description ?? 'No description'}\n </p>\n <div className=\"flex gap-3 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n {ms.dueDate ? new Date(ms.dueDate).toLocaleDateString() : 'No due date'}\n </span>\n {ms.ownerId && (\n <span className=\"flex items-center gap-1\">\n <User className=\"h-3 w-3\" />\n <PersonName id={ms.ownerId} />\n </span>\n )}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n Project: {ms.project?.name ?? 'not available'}\n </div>\n </CardContent>\n </Card>\n )\n )}\n </div>\n {!error && milestones.length === 0 && (\n <p className=\"text-center text-muted-foreground py-8\">No milestones found.</p>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsPlanningDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsPlanningDetailPagePage.tsx"],"names":[],"mappings":"AA8EA,wBAAgB,8BAA8B,4CAmQ7C"}
1
+ {"version":3,"file":"ProjectsPlanningDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProjectsPlanningDetailPagePage.tsx"],"names":[],"mappings":"AA8EA,wBAAgB,8BAA8B,4CA8Q7C"}