@burdenoff/microfe-planmagnet 2026.928.4 → 2026.928.6

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 (226) hide show
  1. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoot.js +130 -97
  3. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  4. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  5. package/dist/planmagnet/PlanMagnetRoutes.js +256 -156
  6. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  7. package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts +5 -0
  8. package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts.map +1 -0
  9. package/dist/planmagnet/automation/AutomationExecutionsPanel.js +107 -0
  10. package/dist/planmagnet/automation/AutomationExecutionsPanel.js.map +1 -0
  11. package/dist/planmagnet/automation/AutomationRuleFields.d.ts +29 -0
  12. package/dist/planmagnet/automation/AutomationRuleFields.d.ts.map +1 -0
  13. package/dist/planmagnet/automation/AutomationRuleFields.js +308 -0
  14. package/dist/planmagnet/automation/AutomationRuleFields.js.map +1 -0
  15. package/dist/planmagnet/automation/automationRuleTypes.d.ts +60 -0
  16. package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -0
  17. package/dist/planmagnet/automation/automationRuleTypes.js +113 -0
  18. package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -0
  19. package/dist/planmagnet/board/BulkActions.d.ts +11 -0
  20. package/dist/planmagnet/board/BulkActions.d.ts.map +1 -0
  21. package/dist/planmagnet/board/BulkActions.js +182 -0
  22. package/dist/planmagnet/board/BulkActions.js.map +1 -0
  23. package/dist/planmagnet/board/ProjectBoard.d.ts.map +1 -1
  24. package/dist/planmagnet/board/ProjectBoard.js +289 -254
  25. package/dist/planmagnet/board/ProjectBoard.js.map +1 -1
  26. package/dist/planmagnet/budgets/BudgetControls.d.ts +30 -0
  27. package/dist/planmagnet/budgets/BudgetControls.d.ts.map +1 -0
  28. package/dist/planmagnet/budgets/BudgetControls.js +470 -0
  29. package/dist/planmagnet/budgets/BudgetControls.js.map +1 -0
  30. package/dist/planmagnet/budgets/ExpenseControls.d.ts +27 -0
  31. package/dist/planmagnet/budgets/ExpenseControls.d.ts.map +1 -0
  32. package/dist/planmagnet/budgets/ExpenseControls.js +366 -0
  33. package/dist/planmagnet/budgets/ExpenseControls.js.map +1 -0
  34. package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts +5 -0
  35. package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts.map +1 -0
  36. package/dist/planmagnet/budgets/ProjectBudgetsSummary.js +112 -0
  37. package/dist/planmagnet/budgets/ProjectBudgetsSummary.js.map +1 -0
  38. package/dist/planmagnet/budgets/budgetMath.d.ts +26 -0
  39. package/dist/planmagnet/budgets/budgetMath.d.ts.map +1 -0
  40. package/dist/planmagnet/budgets/budgetMath.js +49 -0
  41. package/dist/planmagnet/budgets/budgetMath.js.map +1 -0
  42. package/dist/planmagnet/controls/AutomationRuleControls.d.ts +23 -0
  43. package/dist/planmagnet/controls/AutomationRuleControls.d.ts.map +1 -0
  44. package/dist/planmagnet/controls/AutomationRuleControls.js +172 -0
  45. package/dist/planmagnet/controls/AutomationRuleControls.js.map +1 -0
  46. package/dist/planmagnet/controls/CompetitorControls.js +15 -15
  47. package/dist/planmagnet/controls/CustomFieldControls.d.ts +42 -0
  48. package/dist/planmagnet/controls/CustomFieldControls.d.ts.map +1 -0
  49. package/dist/planmagnet/controls/CustomFieldControls.js +84 -0
  50. package/dist/planmagnet/controls/CustomFieldControls.js.map +1 -0
  51. package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts +8 -0
  52. package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts.map +1 -0
  53. package/dist/planmagnet/controls/CustomFieldValuesPanel.js +315 -0
  54. package/dist/planmagnet/controls/CustomFieldValuesPanel.js.map +1 -0
  55. package/dist/planmagnet/controls/FeatureControls.js +54 -54
  56. package/dist/planmagnet/controls/ObjectiveControls.js +15 -15
  57. package/dist/planmagnet/controls/Pickers.d.ts +7 -0
  58. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  59. package/dist/planmagnet/controls/Pickers.js +58 -20
  60. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  61. package/dist/planmagnet/controls/PortfolioControls.js +7 -7
  62. package/dist/planmagnet/controls/ProgramControls.js +19 -19
  63. package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -1
  64. package/dist/planmagnet/controls/ProjectControls.js +54 -47
  65. package/dist/planmagnet/controls/ProjectControls.js.map +1 -1
  66. package/dist/planmagnet/controls/ReleaseControls.js +7 -7
  67. package/dist/planmagnet/controls/RiskControls.d.ts +27 -0
  68. package/dist/planmagnet/controls/RiskControls.d.ts.map +1 -0
  69. package/dist/planmagnet/controls/RiskControls.js +346 -0
  70. package/dist/planmagnet/controls/RiskControls.js.map +1 -0
  71. package/dist/planmagnet/controls/TemplateControls.d.ts +15 -0
  72. package/dist/planmagnet/controls/TemplateControls.d.ts.map +1 -0
  73. package/dist/planmagnet/controls/TemplateControls.js +55 -0
  74. package/dist/planmagnet/controls/TemplateControls.js.map +1 -0
  75. package/dist/planmagnet/controls/WorkItemControls.d.ts +6 -2
  76. package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -1
  77. package/dist/planmagnet/controls/WorkItemControls.js +9 -9
  78. package/dist/planmagnet/controls/WorkItemControls.js.map +1 -1
  79. package/dist/planmagnet/create/CreateDialogs.d.ts +20 -0
  80. package/dist/planmagnet/create/CreateDialogs.d.ts.map +1 -1
  81. package/dist/planmagnet/create/CreateDialogs.js +455 -116
  82. package/dist/planmagnet/create/CreateDialogs.js.map +1 -1
  83. package/dist/planmagnet/dependency/DependencyPanel.d.ts +6 -0
  84. package/dist/planmagnet/dependency/DependencyPanel.d.ts.map +1 -0
  85. package/dist/planmagnet/dependency/DependencyPanel.js +310 -0
  86. package/dist/planmagnet/dependency/DependencyPanel.js.map +1 -0
  87. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts +2 -0
  88. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts.map +1 -0
  89. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +171 -0
  90. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js.map +1 -0
  91. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts +2 -0
  92. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts.map +1 -0
  93. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js +232 -0
  94. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js.map +1 -0
  95. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts +2 -0
  96. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts.map +1 -0
  97. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +93 -0
  98. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js.map +1 -0
  99. package/dist/planmagnet/pages/DashboardDashboardPagePage.d.ts.map +1 -1
  100. package/dist/planmagnet/pages/DashboardDashboardPagePage.js +11 -3
  101. package/dist/planmagnet/pages/DashboardDashboardPagePage.js.map +1 -1
  102. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +5 -5
  103. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +9 -9
  104. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +6 -6
  105. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +4 -4
  106. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +6 -6
  107. package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +5 -5
  108. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts +2 -0
  109. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts.map +1 -0
  110. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js +315 -0
  111. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js.map +1 -0
  112. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts +2 -0
  113. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts.map +1 -0
  114. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +186 -0
  115. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js.map +1 -0
  116. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts +2 -0
  117. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts.map +1 -0
  118. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js +164 -0
  119. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js.map +1 -0
  120. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts +2 -0
  121. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts.map +1 -0
  122. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js +348 -0
  123. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js.map +1 -0
  124. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +10 -10
  125. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +4 -4
  126. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
  127. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +20 -10
  128. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
  129. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.d.ts.map +1 -1
  130. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +13 -8
  131. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js.map +1 -1
  132. package/dist/planmagnet/pages/ProjectsPlanningPagePage.d.ts.map +1 -1
  133. package/dist/planmagnet/pages/ProjectsPlanningPagePage.js +76 -56
  134. package/dist/planmagnet/pages/ProjectsPlanningPagePage.js.map +1 -1
  135. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  136. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +372 -203
  137. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  138. package/dist/planmagnet/pages/ProjectsProjectsPagePage.d.ts.map +1 -1
  139. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +81 -72
  140. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js.map +1 -1
  141. package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts +2 -0
  142. package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts.map +1 -0
  143. package/dist/planmagnet/pages/RisksRiskDetailPagePage.js +278 -0
  144. package/dist/planmagnet/pages/RisksRiskDetailPagePage.js.map +1 -0
  145. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts +2 -0
  146. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts.map +1 -0
  147. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js +191 -0
  148. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js.map +1 -0
  149. package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
  150. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +168 -122
  151. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
  152. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +5 -5
  153. package/dist/planmagnet/pages/TasksEditTaskPagePage.js +4 -4
  154. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  155. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +161 -137
  156. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  157. package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
  158. package/dist/planmagnet/pages/TasksTasksPagePage.js +124 -113
  159. package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
  160. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts +2 -0
  161. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts.map +1 -0
  162. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +263 -0
  163. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js.map +1 -0
  164. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts +2 -0
  165. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts.map +1 -0
  166. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js +254 -0
  167. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js.map +1 -0
  168. package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts +2 -0
  169. package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts.map +1 -0
  170. package/dist/planmagnet/pages/TasksTimesheetsPagePage.js +165 -0
  171. package/dist/planmagnet/pages/TasksTimesheetsPagePage.js.map +1 -0
  172. package/dist/planmagnet/pages/TeamCreateTeamPagePage.d.ts.map +1 -1
  173. package/dist/planmagnet/pages/TeamCreateTeamPagePage.js +288 -91
  174. package/dist/planmagnet/pages/TeamCreateTeamPagePage.js.map +1 -1
  175. package/dist/planmagnet/pages/TeamTeamDetailPagePage.d.ts +2 -0
  176. package/dist/planmagnet/pages/TeamTeamDetailPagePage.d.ts.map +1 -0
  177. package/dist/planmagnet/pages/TeamTeamDetailPagePage.js +217 -0
  178. package/dist/planmagnet/pages/TeamTeamDetailPagePage.js.map +1 -0
  179. package/dist/planmagnet/pages/TeamTeamEditPagePage.d.ts +2 -0
  180. package/dist/planmagnet/pages/TeamTeamEditPagePage.d.ts.map +1 -0
  181. package/dist/planmagnet/pages/TeamTeamEditPagePage.js +211 -0
  182. package/dist/planmagnet/pages/TeamTeamEditPagePage.js.map +1 -0
  183. package/dist/planmagnet/pages/TeamTeamsListPagePage.d.ts +2 -0
  184. package/dist/planmagnet/pages/TeamTeamsListPagePage.d.ts.map +1 -0
  185. package/dist/planmagnet/pages/TeamTeamsListPagePage.js +118 -0
  186. package/dist/planmagnet/pages/TeamTeamsListPagePage.js.map +1 -0
  187. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts +2 -0
  188. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts.map +1 -0
  189. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js +316 -0
  190. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js.map +1 -0
  191. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts +2 -0
  192. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts.map +1 -0
  193. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js +208 -0
  194. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js.map +1 -0
  195. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts +0 -5
  196. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts.map +1 -1
  197. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +47 -89
  198. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js.map +1 -1
  199. package/dist/planmagnet/roadmaps/RoadmapControls.js +24 -24
  200. package/dist/planmagnet/sprints/SprintControls.d.ts +15 -3
  201. package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
  202. package/dist/planmagnet/sprints/SprintControls.js +293 -190
  203. package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
  204. package/dist/planmagnet/team/TeamControls.d.ts +31 -0
  205. package/dist/planmagnet/team/TeamControls.d.ts.map +1 -0
  206. package/dist/planmagnet/team/TeamControls.js +407 -0
  207. package/dist/planmagnet/team/TeamControls.js.map +1 -0
  208. package/dist/planmagnet/time/TaskTimePanel.d.ts +7 -0
  209. package/dist/planmagnet/time/TaskTimePanel.d.ts.map +1 -0
  210. package/dist/planmagnet/time/TaskTimePanel.js +104 -0
  211. package/dist/planmagnet/time/TaskTimePanel.js.map +1 -0
  212. package/dist/planmagnet/time/TimeEntryControls.d.ts +37 -0
  213. package/dist/planmagnet/time/TimeEntryControls.d.ts.map +1 -0
  214. package/dist/planmagnet/time/TimeEntryControls.js +338 -0
  215. package/dist/planmagnet/time/TimeEntryControls.js.map +1 -0
  216. package/dist/planmagnet/time/TimesheetControls.d.ts +18 -0
  217. package/dist/planmagnet/time/TimesheetControls.d.ts.map +1 -0
  218. package/dist/planmagnet/time/TimesheetControls.js +244 -0
  219. package/dist/planmagnet/time/TimesheetControls.js.map +1 -0
  220. package/dist/planmagnet/time/timeShared.d.ts +29 -0
  221. package/dist/planmagnet/time/timeShared.d.ts.map +1 -0
  222. package/dist/planmagnet/time/timeShared.js +34 -0
  223. package/dist/planmagnet/time/timeShared.js.map +1 -0
  224. package/dist/planmagnet/utils/rowNavigation.js +5 -2
  225. package/dist/planmagnet/utils/rowNavigation.js.map +1 -1
  226. package/package.json +1 -1
@@ -0,0 +1,217 @@
1
+ import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
+ import { PersonName as n } from "../people/People.js";
3
+ import { useEntityId as r } from "../hooks/useEntityId.js";
4
+ import { ROW_LINK_CLASS as i, detailPath as a, rowLinkProps as o } from "../utils/rowNavigation.js";
5
+ import { PlanMagnetNotFoundPage as s } from "./NotFoundPage.js";
6
+ import { NewSprintDialog as c } from "../sprints/SprintControls.js";
7
+ import { TeamHeaderActions as l, TeamMembersPanel as u, TeamProjectsPanel as d } from "../team/TeamControls.js";
8
+ import { Gauge as f, UserRound as p, Users as m, Zap as h } from "lucide-react";
9
+ import { gql as g } from "@apollo/client";
10
+ import { useQuery as _ } from "@apollo/client/react";
11
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
12
+ import { Badge as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w } from "@burdenoff/fe-libs/ui";
13
+ //#region src/planmagnet/pages/TeamTeamDetailPagePage.tsx
14
+ var T = g`
15
+ query GetTeamDetail($id: ID!) {
16
+ planmagnetTeam(id: $id) {
17
+ id
18
+ name
19
+ description
20
+ leadId
21
+ capacity
22
+ createdAt
23
+ members {
24
+ id
25
+ actorId
26
+ }
27
+ projects {
28
+ id
29
+ name
30
+ key
31
+ }
32
+ }
33
+ }
34
+ `, E = g`
35
+ query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {
36
+ planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {
37
+ items {
38
+ id
39
+ name
40
+ status
41
+ goal
42
+ velocity
43
+ startDate
44
+ endDate
45
+ workItems {
46
+ id
47
+ status
48
+ storyPoints
49
+ }
50
+ }
51
+ totalCount
52
+ }
53
+ }
54
+ `, D = {
55
+ PLANNING: "bg-blue-100 text-blue-800",
56
+ ACTIVE: "bg-green-100 text-green-800",
57
+ REVIEW: "bg-purple-100 text-purple-800",
58
+ COMPLETED: "bg-gray-100 text-gray-800",
59
+ CANCELLED: "bg-red-100 text-red-800"
60
+ };
61
+ function O() {
62
+ let g = r("teamId"), { workspaceId: O } = e(), k = t(), { data: A, loading: j, error: M } = _(T, {
63
+ variables: { id: g },
64
+ skip: !g
65
+ }), { data: N, loading: P } = _(E, {
66
+ variables: {
67
+ workspaceId: O ?? "",
68
+ filter: { teamId: g }
69
+ },
70
+ skip: !g || !O
71
+ });
72
+ if (!g) return /* @__PURE__ */ v("div", {
73
+ className: "p-6 text-muted-foreground",
74
+ children: "No team selected. Open one from the list."
75
+ });
76
+ if (j && !A) return /* @__PURE__ */ v("div", {
77
+ className: "flex items-center justify-center p-12",
78
+ children: /* @__PURE__ */ v("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
79
+ });
80
+ if (M) return /* @__PURE__ */ y("div", {
81
+ className: "p-6 text-destructive",
82
+ children: ["Error loading team: ", M.message]
83
+ });
84
+ let F = A?.planmagnetTeam;
85
+ if (!F) return /* @__PURE__ */ v(s, {});
86
+ let I = N?.planmagnetSprints.items ?? [];
87
+ return /* @__PURE__ */ y("div", {
88
+ className: "space-y-6 p-6",
89
+ children: [
90
+ /* @__PURE__ */ y("div", {
91
+ className: "flex items-start justify-between gap-4",
92
+ children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ y("div", {
93
+ className: "flex items-center gap-2",
94
+ children: [/* @__PURE__ */ v(m, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ v("h1", {
95
+ className: "text-2xl font-semibold",
96
+ children: F.name
97
+ })]
98
+ }), /* @__PURE__ */ v("p", {
99
+ className: "text-sm text-muted-foreground mt-1",
100
+ children: F.description ?? "No description"
101
+ })] }), /* @__PURE__ */ v(l, {
102
+ teamId: F.id,
103
+ name: F.name
104
+ })]
105
+ }),
106
+ /* @__PURE__ */ y("div", {
107
+ className: "grid grid-cols-2 md:grid-cols-4 gap-4",
108
+ children: [
109
+ /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
110
+ className: "pt-4",
111
+ children: [/* @__PURE__ */ y("div", {
112
+ className: "flex items-center gap-2 text-muted-foreground text-xs",
113
+ children: [/* @__PURE__ */ v(p, { className: "h-4 w-4" }), "Lead"]
114
+ }), /* @__PURE__ */ v("p", {
115
+ className: "text-sm font-bold mt-1 truncate",
116
+ children: F.leadId ? /* @__PURE__ */ v(n, { id: F.leadId }) : "No lead"
117
+ })]
118
+ }) }),
119
+ /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
120
+ className: "pt-4",
121
+ children: [/* @__PURE__ */ y("div", {
122
+ className: "flex items-center gap-2 text-muted-foreground text-xs",
123
+ children: [/* @__PURE__ */ v(f, { className: "h-4 w-4" }), "Capacity"]
124
+ }), /* @__PURE__ */ v("p", {
125
+ className: "text-xl font-bold mt-1",
126
+ children: F.capacity ?? "—"
127
+ })]
128
+ }) }),
129
+ /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
130
+ className: "pt-4",
131
+ children: [/* @__PURE__ */ y("div", {
132
+ className: "flex items-center gap-2 text-muted-foreground text-xs",
133
+ children: [/* @__PURE__ */ v(m, { className: "h-4 w-4" }), "Members"]
134
+ }), /* @__PURE__ */ v("p", {
135
+ className: "text-xl font-bold mt-1",
136
+ children: F.members.length
137
+ })]
138
+ }) }),
139
+ /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
140
+ className: "pt-4",
141
+ children: [/* @__PURE__ */ y("div", {
142
+ className: "flex items-center gap-2 text-muted-foreground text-xs",
143
+ children: [/* @__PURE__ */ v(h, { className: "h-4 w-4" }), "Team sprints"]
144
+ }), /* @__PURE__ */ v("p", {
145
+ className: "text-xl font-bold mt-1",
146
+ children: N?.planmagnetSprints.totalCount ?? (P ? "—" : I.length)
147
+ })]
148
+ }) })
149
+ ]
150
+ }),
151
+ /* @__PURE__ */ y("div", {
152
+ className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
153
+ children: [/* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(w, { children: "Members" }) }), /* @__PURE__ */ v(S, { children: /* @__PURE__ */ v(u, {
154
+ teamId: F.id,
155
+ members: F.members
156
+ }) })] }), /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(w, { children: "Projects" }) }), /* @__PURE__ */ v(S, { children: /* @__PURE__ */ v(d, {
157
+ teamId: F.id,
158
+ projects: F.projects
159
+ }) })] })]
160
+ }),
161
+ /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ y(C, {
162
+ className: "flex flex-row items-center justify-between space-y-0",
163
+ children: [/* @__PURE__ */ v(w, { children: "Sprints" }), /* @__PURE__ */ v(c, {
164
+ initialScope: "team",
165
+ initialTeamId: F.id,
166
+ onCreated: (e) => k(a("/projects/planning-detail-page", e))
167
+ })]
168
+ }), /* @__PURE__ */ y(S, {
169
+ className: "space-y-2",
170
+ children: [
171
+ P && I.length === 0 && /* @__PURE__ */ v("p", {
172
+ className: "text-sm text-muted-foreground text-center py-4",
173
+ children: "Loading sprints…"
174
+ }),
175
+ !P && I.length === 0 && /* @__PURE__ */ v("p", {
176
+ className: "text-sm text-muted-foreground text-center py-4",
177
+ children: "No sprints yet. A team sprint can only include work items from this team's projects."
178
+ }),
179
+ I.map((e) => {
180
+ let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), n = e.workItems.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0);
181
+ return /* @__PURE__ */ y("div", {
182
+ ...o(() => k(a("/projects/planning-detail-page", e.id)), e.name),
183
+ className: `flex items-center justify-between border rounded-md p-2.5 ${i}`,
184
+ children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
185
+ className: "text-sm font-medium",
186
+ children: e.name
187
+ }), e.goal && /* @__PURE__ */ v("p", {
188
+ className: "text-xs text-muted-foreground",
189
+ children: e.goal
190
+ })] }), /* @__PURE__ */ y("div", {
191
+ className: "flex items-center gap-2",
192
+ children: [/* @__PURE__ */ v("span", {
193
+ className: "text-xs text-muted-foreground",
194
+ children: e.status === "COMPLETED" && e.velocity != null ? `${e.velocity} pts velocity` : `${n}/${t} pts`
195
+ }), /* @__PURE__ */ v("span", {
196
+ className: `text-xs px-2 py-0.5 rounded-full capitalize ${D[e.status] ?? "bg-gray-100"}`,
197
+ children: e.status.toLowerCase().replace("_", " ")
198
+ })]
199
+ })]
200
+ }, e.id);
201
+ })
202
+ ]
203
+ })] }),
204
+ /* @__PURE__ */ y("p", {
205
+ className: "text-xs text-muted-foreground",
206
+ children: ["Created ", /* @__PURE__ */ v(b, {
207
+ variant: "outline",
208
+ children: new Date(F.createdAt).toLocaleDateString()
209
+ })]
210
+ })
211
+ ]
212
+ });
213
+ }
214
+ //#endregion
215
+ export { O as TeamTeamDetailPagePage };
216
+
217
+ //# sourceMappingURL=TeamTeamDetailPagePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamTeamDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TeamTeamDetailPagePage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Badge, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Users, UserRound, Gauge, Zap } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ROW_LINK_CLASS, detailPath, rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { TeamHeaderActions, TeamMembersPanel, TeamProjectsPanel } from '../team/TeamControls';\nimport { NewSprintDialog } from '../sprints/SprintControls';\nimport { PlanMagnetNotFoundPage } from './NotFoundPage';\n\n/**\n * Team detail (BOFF-8044): members, lead, capacity, projects, and the team's own sprints\n * (sprints whose scope is this team, never a project — sprint scope is PROJECT xor TEAM).\n */\n\nconst GET_TEAM_DETAIL = gql`\n query GetTeamDetail($id: ID!) {\n planmagnetTeam(id: $id) {\n id\n name\n description\n leadId\n capacity\n createdAt\n members {\n id\n actorId\n }\n projects {\n id\n name\n key\n }\n }\n }\n`;\n\nconst GET_TEAM_SPRINTS = gql`\n query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {\n planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {\n items {\n id\n name\n status\n goal\n velocity\n startDate\n endDate\n workItems {\n id\n status\n storyPoints\n }\n }\n totalCount\n }\n }\n`;\n\ninterface TeamDetail {\n id: string;\n name: string;\n description: string | null;\n leadId: string | null;\n capacity: number | null;\n createdAt: string;\n members: { id: string; actorId: string }[];\n projects: { id: string; name: string; key: string }[];\n}\n\ninterface TeamSprintNode {\n id: string;\n name: string;\n status: string;\n goal: string | null;\n velocity: number | null;\n startDate: string | null;\n endDate: string | null;\n workItems: { id: string; status: string; storyPoints: number | null }[];\n}\n\nconst statusColor: Record<string, string> = {\n PLANNING: 'bg-blue-100 text-blue-800',\n ACTIVE: 'bg-green-100 text-green-800',\n REVIEW: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-gray-100 text-gray-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function TeamTeamDetailPagePage() {\n const teamId = useEntityId('teamId');\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{ planmagnetTeam: TeamDetail | null }>(\n GET_TEAM_DETAIL,\n { variables: { id: teamId }, skip: !teamId }\n );\n const { data: sprintData, loading: sprintsLoading } = useQuery<{\n planmagnetSprints: { items: TeamSprintNode[]; totalCount: number };\n }>(GET_TEAM_SPRINTS, {\n variables: { workspaceId: workspaceId ?? '', filter: { teamId } },\n skip: !teamId || !workspaceId,\n });\n\n if (!teamId) {\n return (\n <div className=\"p-6 text-muted-foreground\">No team selected. Open one from the list.</div>\n );\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 }\n if (error) {\n return <div className=\"p-6 text-destructive\">Error loading team: {error.message}</div>;\n }\n\n const team = data?.planmagnetTeam;\n // Deleted, unauthorized or an unknown id all read back the same way (no cross-tenant existence\n // leak) — the real 404 page, not an inline message and not a same-URL redirect (H5).\n if (!team) return <PlanMagnetNotFoundPage />;\n\n const sprints = sprintData?.planmagnetSprints.items ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <div className=\"flex items-center gap-2\">\n <Users className=\"h-5 w-5 text-primary\" />\n <h1 className=\"text-2xl font-semibold\">{team.name}</h1>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {team.description ?? 'No description'}\n </p>\n </div>\n <TeamHeaderActions teamId={team.id} name={team.name} />\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <UserRound className=\"h-4 w-4\" />\n Lead\n </div>\n <p className=\"text-sm font-bold mt-1 truncate\">\n {team.leadId ? <PersonName id={team.leadId} /> : 'No lead'}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Gauge className=\"h-4 w-4\" />\n Capacity\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.capacity ?? '—'}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Users className=\"h-4 w-4\" />\n Members\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.members.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Zap className=\"h-4 w-4\" />\n Team sprints\n </div>\n <p className=\"text-xl font-bold mt-1\">\n {sprintData?.planmagnetSprints.totalCount ?? (sprintsLoading ? '—' : sprints.length)}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Members</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamMembersPanel teamId={team.id} members={team.members} />\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Projects</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamProjectsPanel teamId={team.id} projects={team.projects} />\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Sprints</CardTitle>\n <NewSprintDialog\n initialScope=\"team\"\n initialTeamId={team.id}\n onCreated={(id) => navigate(detailPath('/projects/planning-detail-page', id))}\n />\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">Loading sprints…</p>\n )}\n {!sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No sprints yet. A team sprint can only include work items from this team&apos;s\n projects.\n </p>\n )}\n {sprints.map((sprint) => {\n const totalPoints = sprint.workItems.reduce(\n (sum, wi) => sum + (wi.storyPoints ?? 0),\n 0\n );\n const donePoints = sprint.workItems\n .filter((wi) => wi.status === 'DONE')\n .reduce((sum, wi) => sum + (wi.storyPoints ?? 0), 0);\n return (\n <div\n key={sprint.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/planning-detail-page', sprint.id)),\n sprint.name\n )}\n className={`flex items-center justify-between border rounded-md p-2.5 ${ROW_LINK_CLASS}`}\n >\n <div>\n <p className=\"text-sm font-medium\">{sprint.name}</p>\n {sprint.goal && <p className=\"text-xs text-muted-foreground\">{sprint.goal}</p>}\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {sprint.status === 'COMPLETED' && sprint.velocity != null\n ? `${sprint.velocity} pts velocity`\n : `${donePoints}/${totalPoints} pts`}\n </span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[sprint.status] ?? 'bg-gray-100'}`}\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <p className=\"text-xs text-muted-foreground\">\n Created <Badge variant=\"outline\">{new Date(team.createdAt).toLocaleDateString()}</Badge>\n </p>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function TeamTeamEditPagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=TeamTeamEditPagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamTeamEditPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TeamTeamEditPagePage.tsx"],"names":[],"mappings":"AA+CA,wBAAgB,oBAAoB,4CA8LnC"}
@@ -0,0 +1,211 @@
1
+ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
+ import { throwOnError as t } from "../utils/mutationResult.js";
3
+ import { useEntityId as n } from "../hooks/useEntityId.js";
4
+ import { AssigneeSelect as r } from "../controls/WorkItemControls.js";
5
+ import { detailPath as i } from "../utils/rowNavigation.js";
6
+ import { parseIntField as a } from "../utils/formValidation.js";
7
+ import { PlanMagnetNotFoundPage as o } from "./NotFoundPage.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";
14
+ //#region src/planmagnet/pages/TeamTeamEditPagePage.tsx
15
+ var S = d`
16
+ query GetTeamForEdit($id: ID!) {
17
+ planmagnetTeam(id: $id) {
18
+ id
19
+ name
20
+ description
21
+ leadId
22
+ capacity
23
+ }
24
+ }
25
+ `, C = d`
26
+ mutation UpdateTeam($id: ID!, $input: PlanmagnetUpdateTeamInput!) {
27
+ planmagnetUpdateTeam(id: $id, input: $input) {
28
+ id
29
+ name
30
+ description
31
+ leadId
32
+ capacity
33
+ }
34
+ }
35
+ `;
36
+ function w() {
37
+ let d = n("teamId"), w = e(), { data: T, loading: E, error: D } = p(S, {
38
+ variables: { id: d },
39
+ skip: !d
40
+ }), O = T?.planmagnetTeam, k = s(() => ({
41
+ name: O?.name ?? "",
42
+ description: O?.description ?? "",
43
+ leadId: O?.leadId ?? "",
44
+ capacity: O?.capacity?.toString() ?? ""
45
+ }), [O]), [A, j] = c({}), M = {
46
+ ...k,
47
+ ...A
48
+ }, N = (e) => j((t) => {
49
+ let n = { ...t };
50
+ for (let [t, r] of Object.entries(e)) r !== M[t] && (n[t] = r);
51
+ return n;
52
+ }), [P, F] = c(null), [I, L] = c(null), R = a(M.capacity, { min: 0 }), z = M.name.trim() === "", [B, { loading: V }] = f(C, { refetchQueries: [
53
+ "GetTeams",
54
+ "GetTeamDetail",
55
+ "GetTeamForEdit"
56
+ ] });
57
+ return d ? E && !T ? /* @__PURE__ */ m("div", {
58
+ className: "flex items-center justify-center p-12",
59
+ children: /* @__PURE__ */ m("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
60
+ }) : D ? /* @__PURE__ */ h("div", {
61
+ className: "p-6 text-destructive",
62
+ children: ["Error loading team: ", D.message]
63
+ }) : O ? /* @__PURE__ */ h("div", {
64
+ className: "space-y-6 p-6 max-w-4xl",
65
+ children: [
66
+ /* @__PURE__ */ h("div", {
67
+ className: "flex items-center justify-between",
68
+ children: [/* @__PURE__ */ h("div", {
69
+ className: "flex items-center gap-3",
70
+ children: [/* @__PURE__ */ m(g, {
71
+ variant: "ghost",
72
+ size: "sm",
73
+ "aria-label": "Back to the team",
74
+ onClick: () => w(i("/team/team-detail-page", d)),
75
+ children: /* @__PURE__ */ m(l, { className: "h-4 w-4" })
76
+ }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h1", {
77
+ className: "text-2xl font-semibold",
78
+ children: "Edit Team"
79
+ }), /* @__PURE__ */ m("p", {
80
+ className: "text-sm text-muted-foreground",
81
+ children: O.name
82
+ })] })]
83
+ }), /* @__PURE__ */ h(g, {
84
+ size: "sm",
85
+ onClick: async () => {
86
+ if (!(!O || z || R.invalid)) {
87
+ F(null), L(null);
88
+ try {
89
+ await t(B({ variables: {
90
+ id: O.id,
91
+ input: {
92
+ name: M.name.trim(),
93
+ description: M.description.trim() || void 0,
94
+ leadId: M.leadId || void 0,
95
+ capacity: R.value
96
+ }
97
+ } })), L("Team updated successfully."), j({});
98
+ } catch (e) {
99
+ F(e instanceof Error ? e.message : "The team could not be saved.");
100
+ }
101
+ }
102
+ },
103
+ disabled: V || z || R.invalid,
104
+ children: [/* @__PURE__ */ m(u, { className: "mr-1 h-4 w-4" }), V ? "Saving..." : "Save Changes"]
105
+ })]
106
+ }),
107
+ I && /* @__PURE__ */ m("div", {
108
+ role: "status",
109
+ className: "p-3 rounded-md text-sm bg-muted text-status-success-text",
110
+ children: I
111
+ }),
112
+ P && /* @__PURE__ */ h("div", {
113
+ role: "alert",
114
+ className: "p-3 rounded-md text-sm bg-destructive/10 text-destructive",
115
+ children: ["Error: ", P]
116
+ }),
117
+ /* @__PURE__ */ h(_, { children: [/* @__PURE__ */ m(y, { children: /* @__PURE__ */ m(b, { children: "Team Details" }) }), /* @__PURE__ */ h(v, {
118
+ className: "space-y-4",
119
+ children: [
120
+ /* @__PURE__ */ h("div", { children: [
121
+ /* @__PURE__ */ m("label", {
122
+ htmlFor: "team-name",
123
+ className: "text-sm font-medium",
124
+ children: "Team Name"
125
+ }),
126
+ /* @__PURE__ */ m(x, {
127
+ id: "team-name",
128
+ value: M.name,
129
+ onChange: (e) => N({
130
+ ...M,
131
+ name: e.target.value
132
+ }),
133
+ "aria-invalid": z,
134
+ className: "mt-1"
135
+ }),
136
+ z && /* @__PURE__ */ m("p", {
137
+ role: "alert",
138
+ className: "mt-1 text-xs text-destructive",
139
+ children: "Choose a name for the team."
140
+ })
141
+ ] }),
142
+ /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
143
+ htmlFor: "team-description",
144
+ className: "text-sm font-medium",
145
+ children: "Description"
146
+ }), /* @__PURE__ */ m("textarea", {
147
+ id: "team-description",
148
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]",
149
+ value: M.description,
150
+ onChange: (e) => N({
151
+ ...M,
152
+ description: e.target.value
153
+ }),
154
+ placeholder: "Describe the team's mission and responsibilities..."
155
+ })] }),
156
+ /* @__PURE__ */ h("div", {
157
+ className: "grid grid-cols-2 gap-4",
158
+ children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
159
+ htmlFor: "team-lead",
160
+ className: "text-sm font-medium",
161
+ children: "Team Lead"
162
+ }), /* @__PURE__ */ m("div", {
163
+ className: "mt-1",
164
+ children: /* @__PURE__ */ m(r, {
165
+ id: "team-lead",
166
+ value: M.leadId,
167
+ onChange: (e) => N({
168
+ ...M,
169
+ leadId: e
170
+ }),
171
+ noneLabel: "No lead"
172
+ })
173
+ })] }), /* @__PURE__ */ h("div", { children: [
174
+ /* @__PURE__ */ m("label", {
175
+ htmlFor: "team-capacity",
176
+ className: "text-sm font-medium",
177
+ children: "Capacity (story points)"
178
+ }),
179
+ /* @__PURE__ */ m(x, {
180
+ id: "team-capacity",
181
+ type: "number",
182
+ min: 0,
183
+ step: 1,
184
+ value: M.capacity,
185
+ onChange: (e) => N({
186
+ ...M,
187
+ capacity: e.target.value
188
+ }),
189
+ "aria-invalid": R.invalid,
190
+ className: "mt-1",
191
+ placeholder: "e.g. 60"
192
+ }),
193
+ R.invalid && /* @__PURE__ */ m("p", {
194
+ role: "alert",
195
+ className: "mt-1 text-xs text-destructive",
196
+ children: "Capacity must be a whole number, 0 or more."
197
+ })
198
+ ] })]
199
+ })
200
+ ]
201
+ })] })
202
+ ]
203
+ }) : /* @__PURE__ */ m(o, {}) : /* @__PURE__ */ m("div", {
204
+ className: "p-6 text-muted-foreground",
205
+ children: "No team selected. Open one from the list."
206
+ });
207
+ }
208
+ //#endregion
209
+ export { w as TeamTeamEditPagePage };
210
+
211
+ //# sourceMappingURL=TeamTeamEditPagePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamTeamEditPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TeamTeamEditPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } 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 { parseIntField } from '../utils/formValidation';\nimport { AssigneeSelect } from '../controls/WorkItemControls';\nimport { PlanMagnetNotFoundPage } from './NotFoundPage';\n\n/** Edit a team's own fields (BOFF-8044). Members and projects are managed from the detail page. */\n\nconst GET_TEAM_FOR_EDIT = gql`\n query GetTeamForEdit($id: ID!) {\n planmagnetTeam(id: $id) {\n id\n name\n description\n leadId\n capacity\n }\n }\n`;\n\nconst UPDATE_TEAM = gql`\n mutation UpdateTeam($id: ID!, $input: PlanmagnetUpdateTeamInput!) {\n planmagnetUpdateTeam(id: $id, input: $input) {\n id\n name\n description\n leadId\n capacity\n }\n }\n`;\n\ninterface TeamForEdit {\n id: string;\n name: string;\n description: string | null;\n leadId: string | null;\n capacity: number | null;\n}\n\nexport function TeamTeamEditPagePage() {\n const teamId = useEntityId('teamId');\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{ planmagnetTeam: TeamForEdit | null }>(\n GET_TEAM_FOR_EDIT,\n { variables: { id: teamId }, skip: !teamId }\n );\n const team = data?.planmagnetTeam;\n\n const defaultForm = useMemo(\n () => ({\n name: team?.name ?? '',\n description: team?.description ?? '',\n leadId: team?.leadId ?? '',\n capacity: team?.capacity?.toString() ?? '',\n }),\n [team]\n );\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (updates: Record<string, string>) =>\n setFormOverrides((prev) => {\n const next = { ...prev };\n for (const [key, value] of Object.entries(updates)) {\n if (value !== form[key as keyof typeof form]) next[key] = value;\n }\n return next;\n });\n\n const [saveError, setSaveError] = useState<string | null>(null);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const capacity = parseIntField(form.capacity, { min: 0 });\n const nameInvalid = form.name.trim() === '';\n const [updateTeam, { loading: saving }] = useMutation(UPDATE_TEAM, {\n refetchQueries: ['GetTeams', 'GetTeamDetail', 'GetTeamForEdit'],\n });\n\n const handleSave = async () => {\n if (!team || nameInvalid || capacity.invalid) return;\n setSaveError(null);\n setSuccessMessage(null);\n try {\n await throwOnError(\n updateTeam({\n variables: {\n id: team.id,\n input: {\n name: form.name.trim(),\n description: form.description.trim() || undefined,\n leadId: form.leadId || undefined,\n capacity: capacity.value,\n },\n },\n })\n );\n setSuccessMessage('Team updated successfully.');\n setFormOverrides({});\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The team could not be saved.');\n }\n };\n\n if (!teamId) {\n return (\n <div className=\"p-6 text-muted-foreground\">No team selected. Open one from the list.</div>\n );\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 }\n if (error) {\n return <div className=\"p-6 text-destructive\">Error loading team: {error.message}</div>;\n }\n if (!team) return <PlanMagnetNotFoundPage />;\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 team\"\n onClick={() => navigate(detailPath('/team/team-detail-page', teamId))}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Team</h1>\n <p className=\"text-sm text-muted-foreground\">{team.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || nameInvalid || capacity.invalid}>\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 rounded-md text-sm bg-muted text-status-success-text\">\n {successMessage}\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md text-sm bg-destructive/10 text-destructive\">\n Error: {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Team Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label htmlFor=\"team-name\" className=\"text-sm font-medium\">\n Team Name\n </label>\n <Input\n id=\"team-name\"\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n aria-invalid={nameInvalid}\n className=\"mt-1\"\n />\n {nameInvalid && (\n <p role=\"alert\" className=\"mt-1 text-xs text-destructive\">\n Choose a name for the team.\n </p>\n )}\n </div>\n <div>\n <label htmlFor=\"team-description\" className=\"text-sm font-medium\">\n Description\n </label>\n <textarea\n id=\"team-description\"\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 placeholder=\"Describe the team's mission and responsibilities...\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"team-lead\" className=\"text-sm font-medium\">\n Team Lead\n </label>\n <div className=\"mt-1\">\n <AssigneeSelect\n id=\"team-lead\"\n value={form.leadId}\n onChange={(next) => setForm({ ...form, leadId: next })}\n noneLabel=\"No lead\"\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"team-capacity\" className=\"text-sm font-medium\">\n Capacity (story points)\n </label>\n <Input\n id=\"team-capacity\"\n type=\"number\"\n min={0}\n step={1}\n value={form.capacity}\n onChange={(e) => setForm({ ...form, capacity: e.target.value })}\n aria-invalid={capacity.invalid}\n className=\"mt-1\"\n placeholder=\"e.g. 60\"\n />\n {capacity.invalid && (\n <p role=\"alert\" className=\"mt-1 text-xs text-destructive\">\n Capacity must be a whole number, 0 or more.\n </p>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function TeamTeamsListPagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=TeamTeamsListPagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamTeamsListPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TeamTeamsListPagePage.tsx"],"names":[],"mappings":"AA6CA,wBAAgB,qBAAqB,4CA4FpC"}
@@ -0,0 +1,118 @@
1
+ import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
+ import { PersonName as n } from "../people/People.js";
3
+ import { detailPath as r, rowLinkProps as i } from "../utils/rowNavigation.js";
4
+ import { FolderKanban as a, Plus as o, UserRound as s, Users as c } from "lucide-react";
5
+ import { gql as l } from "@apollo/client";
6
+ import { useQuery as u } from "@apollo/client/react";
7
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ import { Button as p, Card as m, CardContent as h, CardHeader as g, CardTitle as _ } from "@burdenoff/fe-libs/ui";
9
+ //#region src/planmagnet/pages/TeamTeamsListPagePage.tsx
10
+ var v = l`
11
+ query GetTeams($workspaceId: ID!, $pagination: PlanmagnetPaginationInput) {
12
+ planmagnetTeams(workspaceId: $workspaceId, pagination: $pagination) {
13
+ items {
14
+ id
15
+ name
16
+ description
17
+ leadId
18
+ capacity
19
+ members {
20
+ id
21
+ }
22
+ projects {
23
+ id
24
+ }
25
+ }
26
+ totalCount
27
+ }
28
+ }
29
+ `;
30
+ function y() {
31
+ let { workspaceId: l } = e(), y = t(), { data: b, loading: x, error: S } = u(v, {
32
+ variables: {
33
+ workspaceId: l ?? "",
34
+ pagination: { first: 100 }
35
+ },
36
+ skip: !l
37
+ }), C = b?.planmagnetTeams.items ?? [];
38
+ return x && !b ? /* @__PURE__ */ d("div", {
39
+ className: "flex items-center justify-center p-12",
40
+ children: /* @__PURE__ */ d("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
41
+ }) : S ? /* @__PURE__ */ f("div", {
42
+ className: "p-6 text-destructive",
43
+ children: ["Error loading teams: ", S.message]
44
+ }) : /* @__PURE__ */ f("div", {
45
+ className: "space-y-6 p-6",
46
+ children: [/* @__PURE__ */ f("div", {
47
+ className: "flex items-center justify-between",
48
+ children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
49
+ className: "text-2xl font-semibold",
50
+ children: "Teams"
51
+ }), /* @__PURE__ */ f("p", {
52
+ className: "text-sm text-muted-foreground",
53
+ children: [
54
+ b?.planmagnetTeams.totalCount ?? C.length,
55
+ " team",
56
+ (b?.planmagnetTeams.totalCount ?? C.length) === 1 ? "" : "s"
57
+ ]
58
+ })] }), /* @__PURE__ */ f(p, {
59
+ size: "sm",
60
+ "data-testid": "team-create",
61
+ onClick: () => y("/team/create-team-page"),
62
+ children: [/* @__PURE__ */ d(o, { className: "mr-1 h-4 w-4" }), "New team"]
63
+ })]
64
+ }), C.length === 0 ? /* @__PURE__ */ d("p", {
65
+ className: "text-sm text-muted-foreground text-center py-12",
66
+ children: "No teams yet — create one to group projects and track cross-project sprints."
67
+ }) : /* @__PURE__ */ d("div", {
68
+ className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
69
+ children: C.map((e) => /* @__PURE__ */ f(m, {
70
+ "data-testid": "team-row",
71
+ ...i(() => y(r("/team/team-detail-page", e.id)), e.name),
72
+ children: [/* @__PURE__ */ d(g, {
73
+ className: "pb-2",
74
+ children: /* @__PURE__ */ f(_, {
75
+ className: "text-base flex items-center gap-2",
76
+ children: [/* @__PURE__ */ d(c, { className: "h-4 w-4 text-primary" }), e.name]
77
+ })
78
+ }), /* @__PURE__ */ f(h, {
79
+ className: "space-y-2",
80
+ children: [/* @__PURE__ */ d("p", {
81
+ className: "text-sm text-muted-foreground line-clamp-2",
82
+ children: e.description ?? "No description"
83
+ }), /* @__PURE__ */ f("div", {
84
+ className: "flex items-center gap-4 text-xs text-muted-foreground",
85
+ children: [
86
+ /* @__PURE__ */ f("span", {
87
+ className: "flex items-center gap-1",
88
+ children: [/* @__PURE__ */ d(s, { className: "h-3 w-3" }), e.leadId ? /* @__PURE__ */ d(n, { id: e.leadId }) : "No lead"]
89
+ }),
90
+ /* @__PURE__ */ f("span", {
91
+ className: "flex items-center gap-1",
92
+ children: [
93
+ /* @__PURE__ */ d(c, { className: "h-3 w-3" }),
94
+ e.members.length,
95
+ " member",
96
+ e.members.length === 1 ? "" : "s"
97
+ ]
98
+ }),
99
+ /* @__PURE__ */ f("span", {
100
+ className: "flex items-center gap-1",
101
+ children: [
102
+ /* @__PURE__ */ d(a, { className: "h-3 w-3" }),
103
+ e.projects.length,
104
+ " project",
105
+ e.projects.length === 1 ? "" : "s"
106
+ ]
107
+ })
108
+ ]
109
+ })]
110
+ })]
111
+ }, e.id))
112
+ })]
113
+ });
114
+ }
115
+ //#endregion
116
+ export { y as TeamTeamsListPagePage };
117
+
118
+ //# sourceMappingURL=TeamTeamsListPagePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamTeamsListPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TeamTeamsListPagePage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Plus, Users, FolderKanban, UserRound } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps, detailPath } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\n\n/**\n * Teams list (BOFF-8044). A Team is a first-class, cross-project entity — members, a lead, capacity, and the\n * projects it can draw team-sprint work from. This replaces the old mislabelled \"Team\" nav entry, which was\n * really the workspace roster (kept, relabelled \"Members\" — see PlanMagnetRoot.tsx).\n */\n\nconst GET_TEAMS = gql`\n query GetTeams($workspaceId: ID!, $pagination: PlanmagnetPaginationInput) {\n planmagnetTeams(workspaceId: $workspaceId, pagination: $pagination) {\n items {\n id\n name\n description\n leadId\n capacity\n members {\n id\n }\n projects {\n id\n }\n }\n totalCount\n }\n }\n`;\n\ninterface TeamListItem {\n id: string;\n name: string;\n description: string | null;\n leadId: string | null;\n capacity: number | null;\n members: { id: string }[];\n projects: { id: string }[];\n}\n\nexport function TeamTeamsListPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{\n planmagnetTeams: { items: TeamListItem[]; totalCount: number };\n }>(GET_TEAMS, {\n variables: { workspaceId: workspaceId ?? '', pagination: { first: 100 } },\n skip: !workspaceId,\n });\n\n const teams = data?.planmagnetTeams.items ?? [];\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 }\n if (error) {\n return <div className=\"p-6 text-destructive\">Error loading teams: {error.message}</div>;\n }\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\">Teams</h1>\n <p className=\"text-sm text-muted-foreground\">\n {data?.planmagnetTeams.totalCount ?? teams.length} team\n {(data?.planmagnetTeams.totalCount ?? teams.length) === 1 ? '' : 's'}\n </p>\n </div>\n <Button\n size=\"sm\"\n data-testid=\"team-create\"\n onClick={() => navigate('/team/create-team-page')}\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n New team\n </Button>\n </div>\n\n {teams.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-12\">\n No teams yet — create one to group projects and track cross-project sprints.\n </p>\n ) : (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {teams.map((team) => (\n <Card\n key={team.id}\n data-testid=\"team-row\"\n {...rowLinkProps(\n () => navigate(detailPath('/team/team-detail-page', team.id)),\n team.name\n )}\n >\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Users className=\"h-4 w-4 text-primary\" />\n {team.name}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground line-clamp-2\">\n {team.description ?? 'No description'}\n </p>\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <UserRound className=\"h-3 w-3\" />\n {team.leadId ? <PersonName id={team.leadId} /> : 'No lead'}\n </span>\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3 w-3\" />\n {team.members.length} member{team.members.length === 1 ? '' : 's'}\n </span>\n <span className=\"flex items-center gap-1\">\n <FolderKanban className=\"h-3 w-3\" />\n {team.projects.length} project{team.projects.length === 1 ? '' : 's'}\n </span>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAcA,IAAM,IAAY,CAAG;;;;;;;;;;;;;;;;;;;;AA+BrB,SAAgB,IAAwB;CACtC,IAAM,EAAE,mBAAgB,GAAe,EACjC,IAAW,GAAuB,EAElC,EAAE,SAAM,YAAS,aAAU,EAE9B,GAAW;EACZ,WAAW;GAAE,aAAa,KAAe;GAAI,YAAY,EAAE,OAAO,KAAK;GAAE;EACzE,MAAM,CAAC;EACR,CAAC,EAEI,IAAQ,GAAM,gBAAgB,SAAS,EAAE;AAe/C,QAXI,KAAW,CAAC,IAEZ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAK,WAAU,kFAAmF,CAAA;EAC9F,CAAA,GAGN,IACK,kBAAC,OAAD;EAAK,WAAU;YAAf,CAAsC,yBAAsB,EAAM,QAAc;MAIvF,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAyB;IAAU,CAAA,EACjD,kBAAC,KAAD;IAAG,WAAU;cAAb;KACG,GAAM,gBAAgB,cAAc,EAAM;KAAO;MAChD,GAAM,gBAAgB,cAAc,EAAM,YAAY,IAAI,KAAK;KAC/D;MACA,EAAA,CAAA,EACN,kBAAC,GAAD;IACE,MAAK;IACL,eAAY;IACZ,eAAe,EAAS,yBAAyB;cAHnD,CAKE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,WAE1B;MACL;MAEL,EAAM,WAAW,IAChB,kBAAC,KAAD;GAAG,WAAU;aAAkD;GAE3D,CAAA,GAEJ,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAM,KAAK,MACV,kBAAC,GAAD;IAEE,eAAY;IACZ,GAAI,QACI,EAAS,EAAW,0BAA0B,EAAK,GAAG,CAAC,EAC7D,EAAK,KACN;cANH,CAQE,kBAAC,GAAD;KAAY,WAAU;eACpB,kBAAC,GAAD;MAAW,WAAU;gBAArB,CACE,kBAAC,GAAD,EAAO,WAAU,wBAAyB,CAAA,EACzC,EAAK,KACI;;KACD,CAAA,EACb,kBAAC,GAAD;KAAa,WAAU;eAAvB,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAK,eAAe;MACnB,CAAA,EACJ,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAChC,EAAK,SAAS,kBAAC,GAAD,EAAY,IAAI,EAAK,QAAU,CAAA,GAAG,UAC5C;;OACP,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;SAC5B,EAAK,QAAQ;SAAO;SAAQ,EAAK,QAAQ,WAAW,IAAI,KAAK;SACzD;;OACP,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACE,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;SACnC,EAAK,SAAS;SAAO;SAAS,EAAK,SAAS,WAAW,IAAI,KAAK;SAC5D;;OACH;QACM;OACT;MAhCA,EAAK,GAgCL,CACP;GACE,CAAA,CAEJ"}
@@ -0,0 +1,2 @@
1
+ export declare function TemplatesEditTemplatePagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=TemplatesEditTemplatePagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplatesEditTemplatePagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TemplatesEditTemplatePagePage.tsx"],"names":[],"mappings":"AAoHA,wBAAgB,6BAA6B,4CAmQ5C"}