@burdenoff/microfe-planmagnet 2026.928.3 → 2026.928.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoot.js +126 -84
  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 +192 -64
  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.d.ts +20 -0
  47. package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -0
  48. package/dist/planmagnet/controls/CompetitorControls.js +172 -0
  49. package/dist/planmagnet/controls/CompetitorControls.js.map +1 -0
  50. package/dist/planmagnet/controls/CustomFieldControls.d.ts +42 -0
  51. package/dist/planmagnet/controls/CustomFieldControls.d.ts.map +1 -0
  52. package/dist/planmagnet/controls/CustomFieldControls.js +84 -0
  53. package/dist/planmagnet/controls/CustomFieldControls.js.map +1 -0
  54. package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts +8 -0
  55. package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts.map +1 -0
  56. package/dist/planmagnet/controls/CustomFieldValuesPanel.js +315 -0
  57. package/dist/planmagnet/controls/CustomFieldValuesPanel.js.map +1 -0
  58. package/dist/planmagnet/controls/FeatureControls.js +53 -53
  59. package/dist/planmagnet/controls/FeatureTriage.js +11 -11
  60. package/dist/planmagnet/controls/ObjectiveControls.js +37 -37
  61. package/dist/planmagnet/controls/Pickers.d.ts +17 -2
  62. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  63. package/dist/planmagnet/controls/Pickers.js +100 -9
  64. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  65. package/dist/planmagnet/controls/PortfolioControls.d.ts +13 -0
  66. package/dist/planmagnet/controls/PortfolioControls.d.ts.map +1 -0
  67. package/dist/planmagnet/controls/PortfolioControls.js +114 -0
  68. package/dist/planmagnet/controls/PortfolioControls.js.map +1 -0
  69. package/dist/planmagnet/controls/ProgramControls.d.ts +25 -0
  70. package/dist/planmagnet/controls/ProgramControls.d.ts.map +1 -0
  71. package/dist/planmagnet/controls/ProgramControls.js +187 -0
  72. package/dist/planmagnet/controls/ProgramControls.js.map +1 -0
  73. package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -1
  74. package/dist/planmagnet/controls/ProjectControls.js +54 -47
  75. package/dist/planmagnet/controls/ProjectControls.js.map +1 -1
  76. package/dist/planmagnet/controls/ReleaseControls.js +7 -7
  77. package/dist/planmagnet/controls/RiskControls.d.ts +27 -0
  78. package/dist/planmagnet/controls/RiskControls.d.ts.map +1 -0
  79. package/dist/planmagnet/controls/RiskControls.js +346 -0
  80. package/dist/planmagnet/controls/RiskControls.js.map +1 -0
  81. package/dist/planmagnet/controls/TemplateControls.d.ts +15 -0
  82. package/dist/planmagnet/controls/TemplateControls.d.ts.map +1 -0
  83. package/dist/planmagnet/controls/TemplateControls.js +55 -0
  84. package/dist/planmagnet/controls/TemplateControls.js.map +1 -0
  85. package/dist/planmagnet/controls/WorkItemControls.js +1 -1
  86. package/dist/planmagnet/create/CreateDialogs.d.ts +20 -0
  87. package/dist/planmagnet/create/CreateDialogs.d.ts.map +1 -1
  88. package/dist/planmagnet/create/CreateDialogs.js +455 -116
  89. package/dist/planmagnet/create/CreateDialogs.js.map +1 -1
  90. package/dist/planmagnet/dependency/DependencyPanel.d.ts +6 -0
  91. package/dist/planmagnet/dependency/DependencyPanel.d.ts.map +1 -0
  92. package/dist/planmagnet/dependency/DependencyPanel.js +310 -0
  93. package/dist/planmagnet/dependency/DependencyPanel.js.map +1 -0
  94. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts +2 -0
  95. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts.map +1 -0
  96. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +171 -0
  97. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js.map +1 -0
  98. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts +2 -0
  99. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts.map +1 -0
  100. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js +232 -0
  101. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js.map +1 -0
  102. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts +2 -0
  103. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts.map +1 -0
  104. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +93 -0
  105. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js.map +1 -0
  106. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts +2 -0
  107. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -0
  108. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +127 -0
  109. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -0
  110. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts +2 -0
  111. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -0
  112. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +129 -0
  113. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -0
  114. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts +2 -0
  115. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -0
  116. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +132 -0
  117. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -0
  118. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts +2 -0
  119. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -0
  120. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +181 -0
  121. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -0
  122. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts +2 -0
  123. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts.map +1 -0
  124. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js +242 -0
  125. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js.map +1 -0
  126. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts +2 -0
  127. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts.map +1 -0
  128. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +302 -0
  129. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js.map +1 -0
  130. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts +2 -0
  131. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -0
  132. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +335 -0
  133. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -0
  134. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts +2 -0
  135. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts.map +1 -0
  136. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +154 -0
  137. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js.map +1 -0
  138. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  139. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +124 -138
  140. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  141. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts +2 -0
  142. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts.map +1 -0
  143. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +221 -0
  144. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js.map +1 -0
  145. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts +2 -0
  146. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts.map +1 -0
  147. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +279 -0
  148. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js.map +1 -0
  149. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts +2 -0
  150. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts.map +1 -0
  151. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js +178 -0
  152. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js.map +1 -0
  153. package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts +2 -0
  154. package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts.map +1 -0
  155. package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +157 -0
  156. package/dist/planmagnet/pages/ProgramsProgramsPagePage.js.map +1 -0
  157. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts +2 -0
  158. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts.map +1 -0
  159. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js +315 -0
  160. package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js.map +1 -0
  161. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts +2 -0
  162. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts.map +1 -0
  163. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +186 -0
  164. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js.map +1 -0
  165. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts +2 -0
  166. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts.map +1 -0
  167. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js +164 -0
  168. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js.map +1 -0
  169. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts +2 -0
  170. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts.map +1 -0
  171. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js +348 -0
  172. package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js.map +1 -0
  173. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  174. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +130 -103
  175. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  176. package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +4 -4
  177. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +4 -4
  178. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +6 -6
  179. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  180. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +325 -189
  181. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  182. package/dist/planmagnet/pages/ProjectsProjectsPagePage.d.ts.map +1 -1
  183. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +81 -72
  184. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js.map +1 -1
  185. package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts +2 -0
  186. package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts.map +1 -0
  187. package/dist/planmagnet/pages/RisksRiskDetailPagePage.js +278 -0
  188. package/dist/planmagnet/pages/RisksRiskDetailPagePage.js.map +1 -0
  189. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts +2 -0
  190. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts.map +1 -0
  191. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js +191 -0
  192. package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js.map +1 -0
  193. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +5 -5
  194. package/dist/planmagnet/pages/TasksEditTaskPagePage.js +4 -4
  195. package/dist/planmagnet/pages/TasksImportPagePage.js +5 -5
  196. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  197. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +161 -137
  198. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  199. package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
  200. package/dist/planmagnet/pages/TasksTasksPagePage.js +124 -113
  201. package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
  202. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts +2 -0
  203. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts.map +1 -0
  204. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +263 -0
  205. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js.map +1 -0
  206. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts +2 -0
  207. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts.map +1 -0
  208. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js +254 -0
  209. package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js.map +1 -0
  210. package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts +2 -0
  211. package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts.map +1 -0
  212. package/dist/planmagnet/pages/TasksTimesheetsPagePage.js +165 -0
  213. package/dist/planmagnet/pages/TasksTimesheetsPagePage.js.map +1 -0
  214. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts +2 -0
  215. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts.map +1 -0
  216. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js +316 -0
  217. package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js.map +1 -0
  218. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts +2 -0
  219. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts.map +1 -0
  220. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js +208 -0
  221. package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js.map +1 -0
  222. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts +0 -5
  223. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts.map +1 -1
  224. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +47 -89
  225. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js.map +1 -1
  226. package/dist/planmagnet/roadmaps/RoadmapControls.js +24 -24
  227. package/dist/planmagnet/time/TaskTimePanel.d.ts +7 -0
  228. package/dist/planmagnet/time/TaskTimePanel.d.ts.map +1 -0
  229. package/dist/planmagnet/time/TaskTimePanel.js +104 -0
  230. package/dist/planmagnet/time/TaskTimePanel.js.map +1 -0
  231. package/dist/planmagnet/time/TimeEntryControls.d.ts +37 -0
  232. package/dist/planmagnet/time/TimeEntryControls.d.ts.map +1 -0
  233. package/dist/planmagnet/time/TimeEntryControls.js +338 -0
  234. package/dist/planmagnet/time/TimeEntryControls.js.map +1 -0
  235. package/dist/planmagnet/time/TimesheetControls.d.ts +18 -0
  236. package/dist/planmagnet/time/TimesheetControls.d.ts.map +1 -0
  237. package/dist/planmagnet/time/TimesheetControls.js +244 -0
  238. package/dist/planmagnet/time/TimesheetControls.js.map +1 -0
  239. package/dist/planmagnet/time/timeShared.d.ts +29 -0
  240. package/dist/planmagnet/time/timeShared.d.ts.map +1 -0
  241. package/dist/planmagnet/time/timeShared.js +34 -0
  242. package/dist/planmagnet/time/timeShared.js.map +1 -0
  243. package/dist/planmagnet/utils/rowNavigation.js +5 -2
  244. package/dist/planmagnet/utils/rowNavigation.js.map +1 -1
  245. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompetitorsEditCompetitorPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/CompetitorsEditCompetitorPagePage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery, useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft, Loader2 } from 'lucide-react';\nimport { useParams } from 'react-router';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\n\nconst GET_COMPETITOR = gql`\n query GetCompetitorForEdit($id: ID!) {\n planmagnetCompetitor(id: $id) {\n id\n name\n website\n description\n tags\n }\n }\n`;\n\nconst UPDATE_COMPETITOR = gql`\n mutation UpdateCompetitor($id: ID!, $input: PlanmagnetUpdateCompetitorInput!) {\n planmagnetUpdateCompetitor(id: $id, input: $input) {\n id\n name\n website\n description\n tags\n updatedAt\n }\n }\n`;\n\nexport function CompetitorsEditCompetitorPagePage() {\n const navigate = usePlanMagnetNavigate();\n const params = useParams<{ id: string }>();\n const competitorId = params.id ?? '';\n\n const { data, loading, error } = useQuery<{\n planmagnetCompetitor: {\n id: string;\n name: string;\n website: string | null;\n description: string | null;\n tags: string[];\n } | null;\n }>(GET_COMPETITOR, { variables: { id: competitorId }, skip: !competitorId });\n\n const [updateCompetitor, { loading: saving }] = useMutation(UPDATE_COMPETITOR, {\n refetchQueries: [\n 'ListCompetitors',\n 'GetCompetitorForEdit',\n 'GetCompetitor',\n 'PickerCompetitors',\n ],\n awaitRefetchQueries: true,\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const competitor = data?.planmagnetCompetitor;\n\n const defaultForm = useMemo(\n () => ({\n name: competitor?.name ?? '',\n website: competitor?.website ?? '',\n description: competitor?.description ?? '',\n tags: competitor?.tags?.join(', ') ?? '',\n }),\n [competitor]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (val: Record<string, string>) => setFormOverrides(val);\n\n const handleSave = async () => {\n if (!competitor || !form.name.trim()) return;\n const tagList = (v: string) =>\n v\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n const next: Record<string, unknown> = {\n name: form.name.trim(),\n website: form.website.trim() || null,\n description: form.description.trim() || null,\n tags: tagList(form.tags),\n };\n const before: Record<string, unknown> = {\n name: defaultForm.name,\n website: defaultForm.website.trim() || null,\n description: defaultForm.description.trim() || null,\n tags: tagList(defaultForm.tags),\n };\n const input = Object.fromEntries(\n Object.entries(next).filter(([k, v]) => JSON.stringify(v) !== JSON.stringify(before[k]))\n );\n setSaveError(null);\n setSaved(false);\n if (Object.keys(input).length === 0) {\n setSaved(true);\n return;\n }\n try {\n await throwOnError(updateCompetitor({ variables: { id: competitorId, input } }));\n setSaved(true);\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The competitor could not be saved.');\n }\n };\n\n // Only before the first load: a refetch must not blank the page (it unmounts every component on it and\n // loses their state).\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load competitor: {error.message}</div>;\n }\n\n if (!competitor) return <div className=\"p-6 text-muted-foreground\">Competitor not found.</div>;\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Back to the competitor\"\n onClick={() => navigate(detailPath('/products/competitor-detail-page', competitorId))}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Competitor</h1>\n <p className=\"text-sm text-muted-foreground\">{competitor.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || !form.name.trim()}>\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Save Changes\n </Button>\n </div>\n\n {saved && (\n <div role=\"status\" className=\"p-3 bg-muted text-status-success-text rounded-md text-sm\">\n Changes saved.\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Competitor Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Website</label>\n <Input\n value={form.website}\n onChange={(e) => setForm({ ...form, website: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description / Notes</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Tags (comma-separated)</label>\n <Input\n value={form.tags}\n onChange={(e) => setForm({ ...form, tags: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function PortfoliosCreatePortfolioPagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=PortfoliosCreatePortfolioPagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PortfoliosCreatePortfolioPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/PortfoliosCreatePortfolioPagePage.tsx"],"names":[],"mappings":"AAmBA,wBAAgB,iCAAiC,4CAyOhD"}
@@ -0,0 +1,242 @@
1
+ import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
+ import { throwOnError as n } from "../utils/mutationResult.js";
3
+ import { enumLabel as r } from "../controls/WorkItemControls.js";
4
+ import { PORTFOLIO_STATUSES as i, STRATEGIC_ALIGNMENTS as a } from "../controls/PortfolioControls.js";
5
+ import { useState as o } from "react";
6
+ import { Briefcase as s, Loader2 as c, Save as l, X as u } from "lucide-react";
7
+ import { gql as d } from "@apollo/client";
8
+ import { useMutation as f } from "@apollo/client/react";
9
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
10
+ import { Button as h, Card as g, CardContent as _, CardHeader as v, CardTitle as y, Input as b } from "@burdenoff/fe-libs/ui";
11
+ //#region src/planmagnet/pages/PortfoliosCreatePortfolioPagePage.tsx
12
+ var x = d`
13
+ mutation CreatePortfolio($input: PlanmagnetCreatePortfolioInput!) {
14
+ planmagnetCreatePortfolio(input: $input) {
15
+ id
16
+ name
17
+ }
18
+ }
19
+ `;
20
+ function S() {
21
+ let { currentUser: d } = e(), S = t(), [C, w] = o({
22
+ name: "",
23
+ description: "",
24
+ status: "ACTIVE",
25
+ alignment: "",
26
+ alignmentLabel: "",
27
+ budgetTotal: "",
28
+ currency: "",
29
+ fiscalPeriod: "",
30
+ tags: ""
31
+ }), [T, E] = o(null), [D, { loading: O }] = f(x, { refetchQueries: ["ListPortfolios"] }), k = C.alignment === "CUSTOM" && !C.alignmentLabel.trim(), A = C.budgetTotal !== "" && Number(C.budgetTotal) < 0;
32
+ return /* @__PURE__ */ m("div", {
33
+ className: "space-y-6 p-6 max-w-4xl",
34
+ children: [
35
+ /* @__PURE__ */ m("div", {
36
+ className: "flex items-center justify-between",
37
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
38
+ className: "text-2xl font-semibold",
39
+ children: "Create Portfolio"
40
+ }), /* @__PURE__ */ p("p", {
41
+ className: "text-sm text-muted-foreground",
42
+ children: "Group programs and projects for executive-level oversight and alignment tracking."
43
+ })] }), /* @__PURE__ */ m("div", {
44
+ className: "flex gap-2",
45
+ children: [/* @__PURE__ */ m(h, {
46
+ variant: "outline",
47
+ size: "sm",
48
+ onClick: () => S("/products/portfolios-page"),
49
+ children: [/* @__PURE__ */ p(u, { className: "mr-1 h-4 w-4" }), "Cancel"]
50
+ }), /* @__PURE__ */ m(h, {
51
+ size: "sm",
52
+ onClick: async () => {
53
+ if (!(!C.name.trim() || k || A)) {
54
+ E(null);
55
+ try {
56
+ await n(D({ variables: { input: {
57
+ name: C.name.trim(),
58
+ description: C.description.trim() || void 0,
59
+ status: C.status,
60
+ ownerId: d?.id ?? "",
61
+ ...C.alignment ? { alignment: C.alignment } : {},
62
+ ...C.alignment === "CUSTOM" ? { alignmentLabel: C.alignmentLabel.trim() } : {},
63
+ ...C.budgetTotal === "" ? {} : { budgetTotal: Number(C.budgetTotal) },
64
+ currency: C.currency.trim() || void 0,
65
+ fiscalPeriod: C.fiscalPeriod.trim() || void 0,
66
+ tags: C.tags.split(",").map((e) => e.trim()).filter(Boolean)
67
+ } } })), S("/products/portfolios-page");
68
+ } catch (e) {
69
+ E(e instanceof Error ? e.message : "The portfolio could not be created.");
70
+ }
71
+ }
72
+ },
73
+ disabled: O || !C.name.trim() || k || A,
74
+ children: [O ? /* @__PURE__ */ p(c, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ p(l, { className: "mr-1 h-4 w-4" }), "Create Portfolio"]
75
+ })]
76
+ })]
77
+ }),
78
+ T && /* @__PURE__ */ m("div", {
79
+ role: "alert",
80
+ className: "p-3 rounded-md bg-destructive/10 text-destructive text-sm",
81
+ children: ["Failed to create portfolio: ", T]
82
+ }),
83
+ /* @__PURE__ */ m(g, { children: [/* @__PURE__ */ p(v, { children: /* @__PURE__ */ m(y, {
84
+ className: "flex items-center gap-2",
85
+ children: [/* @__PURE__ */ p(s, { className: "h-4 w-4" }), "Portfolio Details"]
86
+ }) }), /* @__PURE__ */ m(_, {
87
+ className: "space-y-4",
88
+ children: [
89
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
90
+ className: "text-sm font-medium",
91
+ children: "Name"
92
+ }), /* @__PURE__ */ p(b, {
93
+ value: C.name,
94
+ onChange: (e) => w({
95
+ ...C,
96
+ name: e.target.value
97
+ }),
98
+ className: "mt-1",
99
+ placeholder: "e.g. 2026 Platform Investments"
100
+ })] }),
101
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
102
+ className: "text-sm font-medium",
103
+ children: "Description"
104
+ }), /* @__PURE__ */ p("textarea", {
105
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]",
106
+ value: C.description,
107
+ onChange: (e) => w({
108
+ ...C,
109
+ description: e.target.value
110
+ }),
111
+ placeholder: "Describe what this portfolio covers…"
112
+ })] }),
113
+ /* @__PURE__ */ m("div", {
114
+ className: "grid grid-cols-2 gap-4",
115
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
116
+ htmlFor: "portfolio-status",
117
+ className: "text-sm font-medium",
118
+ children: "Status"
119
+ }), /* @__PURE__ */ p("select", {
120
+ id: "portfolio-status",
121
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
122
+ value: C.status,
123
+ onChange: (e) => w({
124
+ ...C,
125
+ status: e.target.value
126
+ }),
127
+ children: i.map((e) => /* @__PURE__ */ p("option", {
128
+ value: e,
129
+ children: r(e)
130
+ }, e))
131
+ })] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
132
+ htmlFor: "portfolio-alignment",
133
+ className: "text-sm font-medium",
134
+ children: "Strategic Alignment"
135
+ }), /* @__PURE__ */ m("select", {
136
+ id: "portfolio-alignment",
137
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
138
+ value: C.alignment,
139
+ onChange: (e) => w({
140
+ ...C,
141
+ alignment: e.target.value
142
+ }),
143
+ children: [/* @__PURE__ */ p("option", {
144
+ value: "",
145
+ children: "Not set"
146
+ }), a.map((e) => /* @__PURE__ */ p("option", {
147
+ value: e,
148
+ children: e === "CUSTOM" ? "Custom…" : r(e)
149
+ }, e))]
150
+ })] })]
151
+ }),
152
+ C.alignment === "CUSTOM" && /* @__PURE__ */ m("div", { children: [
153
+ /* @__PURE__ */ p("label", {
154
+ className: "text-sm font-medium",
155
+ children: "Custom Alignment Label"
156
+ }),
157
+ /* @__PURE__ */ p(b, {
158
+ value: C.alignmentLabel,
159
+ onChange: (e) => w({
160
+ ...C,
161
+ alignmentLabel: e.target.value
162
+ }),
163
+ className: "mt-1",
164
+ placeholder: "Name this strategic theme",
165
+ "aria-invalid": k
166
+ }),
167
+ k && /* @__PURE__ */ p("p", {
168
+ role: "alert",
169
+ className: "text-sm text-destructive mt-1",
170
+ children: "A custom alignment needs a label."
171
+ })
172
+ ] }),
173
+ /* @__PURE__ */ m("div", {
174
+ className: "grid grid-cols-3 gap-4",
175
+ children: [
176
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
177
+ className: "text-sm font-medium",
178
+ children: "Total Budget"
179
+ }), /* @__PURE__ */ p(b, {
180
+ type: "number",
181
+ min: "0",
182
+ value: C.budgetTotal,
183
+ onChange: (e) => w({
184
+ ...C,
185
+ budgetTotal: e.target.value
186
+ }),
187
+ className: "mt-1",
188
+ "aria-invalid": A,
189
+ placeholder: "0"
190
+ })] }),
191
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
192
+ className: "text-sm font-medium",
193
+ children: "Currency"
194
+ }), /* @__PURE__ */ p(b, {
195
+ value: C.currency,
196
+ onChange: (e) => w({
197
+ ...C,
198
+ currency: e.target.value
199
+ }),
200
+ className: "mt-1",
201
+ placeholder: "USD"
202
+ })] }),
203
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
204
+ className: "text-sm font-medium",
205
+ children: "Fiscal Period"
206
+ }), /* @__PURE__ */ p(b, {
207
+ value: C.fiscalPeriod,
208
+ onChange: (e) => w({
209
+ ...C,
210
+ fiscalPeriod: e.target.value
211
+ }),
212
+ className: "mt-1",
213
+ placeholder: "e.g. FY2026"
214
+ })] })
215
+ ]
216
+ }),
217
+ A && /* @__PURE__ */ p("p", {
218
+ role: "alert",
219
+ className: "text-sm text-destructive",
220
+ children: "The budget cannot be negative."
221
+ }),
222
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
223
+ className: "text-sm font-medium",
224
+ children: "Tags (comma-separated)"
225
+ }), /* @__PURE__ */ p(b, {
226
+ value: C.tags,
227
+ onChange: (e) => w({
228
+ ...C,
229
+ tags: e.target.value
230
+ }),
231
+ className: "mt-1",
232
+ placeholder: "e.g. strategic, core, growth"
233
+ })] })
234
+ ]
235
+ })] })
236
+ ]
237
+ });
238
+ }
239
+ //#endregion
240
+ export { S as PortfoliosCreatePortfolioPagePage };
241
+
242
+ //# sourceMappingURL=PortfoliosCreatePortfolioPagePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PortfoliosCreatePortfolioPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/PortfoliosCreatePortfolioPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, X, Briefcase, Loader2 } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { throwOnError } from '../utils/mutationResult';\nimport { enumLabel } from '../controls/WorkItemControls';\nimport { PORTFOLIO_STATUSES, STRATEGIC_ALIGNMENTS } from '../controls/PortfolioControls';\n\nconst CREATE_PORTFOLIO = gql`\n mutation CreatePortfolio($input: PlanmagnetCreatePortfolioInput!) {\n planmagnetCreatePortfolio(input: $input) {\n id\n name\n }\n }\n`;\n\nexport function PortfoliosCreatePortfolioPagePage() {\n const { currentUser } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const [form, setForm] = useState({\n name: '',\n description: '',\n status: 'ACTIVE' as (typeof PORTFOLIO_STATUSES)[number],\n alignment: '' as '' | (typeof STRATEGIC_ALIGNMENTS)[number],\n alignmentLabel: '',\n budgetTotal: '',\n currency: '',\n fiscalPeriod: '',\n tags: '',\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [createPortfolio, { loading: saving }] = useMutation(CREATE_PORTFOLIO, {\n refetchQueries: ['ListPortfolios'],\n });\n\n // The service refuses CUSTOM without a label (BOFF-7934) — checked here too so the reason shows before a\n // round trip, not only after one.\n const needsLabel = form.alignment === 'CUSTOM' && !form.alignmentLabel.trim();\n const invalidBudget = form.budgetTotal !== '' && Number(form.budgetTotal) < 0;\n\n const handleCreate = async () => {\n if (!form.name.trim() || needsLabel || invalidBudget) return;\n setSaveError(null);\n try {\n await throwOnError(\n createPortfolio({\n variables: {\n input: {\n name: form.name.trim(),\n description: form.description.trim() || undefined,\n status: form.status,\n ownerId: currentUser?.id ?? '',\n ...(form.alignment ? { alignment: form.alignment } : {}),\n ...(form.alignment === 'CUSTOM'\n ? { alignmentLabel: form.alignmentLabel.trim() }\n : {}),\n ...(form.budgetTotal !== '' ? { budgetTotal: Number(form.budgetTotal) } : {}),\n currency: form.currency.trim() || undefined,\n fiscalPeriod: form.fiscalPeriod.trim() || undefined,\n tags: form.tags\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean),\n },\n },\n })\n );\n navigate('/products/portfolios-page');\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The portfolio could not be created.');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Create Portfolio</h1>\n <p className=\"text-sm text-muted-foreground\">\n Group programs and projects for executive-level oversight and alignment tracking.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/products/portfolios-page')}>\n <X className=\"mr-1 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleCreate}\n disabled={saving || !form.name.trim() || needsLabel || invalidBudget}\n >\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Create Portfolio\n </Button>\n </div>\n </div>\n\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n Failed to create portfolio: {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Briefcase className=\"h-4 w-4\" />\n Portfolio Details\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. 2026 Platform Investments\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n placeholder=\"Describe what this portfolio covers…\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"portfolio-status\" className=\"text-sm font-medium\">\n Status\n </label>\n <select\n id=\"portfolio-status\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.status}\n onChange={(e) =>\n setForm({\n ...form,\n status: e.target.value as (typeof PORTFOLIO_STATUSES)[number],\n })\n }\n >\n {PORTFOLIO_STATUSES.map((s) => (\n <option key={s} value={s}>\n {enumLabel(s)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"portfolio-alignment\" className=\"text-sm font-medium\">\n Strategic Alignment\n </label>\n <select\n id=\"portfolio-alignment\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.alignment}\n onChange={(e) =>\n setForm({\n ...form,\n alignment: e.target.value as typeof form.alignment,\n })\n }\n >\n <option value=\"\">Not set</option>\n {STRATEGIC_ALIGNMENTS.map((a) => (\n <option key={a} value={a}>\n {a === 'CUSTOM' ? 'Custom…' : enumLabel(a)}\n </option>\n ))}\n </select>\n </div>\n </div>\n {form.alignment === 'CUSTOM' && (\n <div>\n <label className=\"text-sm font-medium\">Custom Alignment Label</label>\n <Input\n value={form.alignmentLabel}\n onChange={(e) => setForm({ ...form, alignmentLabel: e.target.value })}\n className=\"mt-1\"\n placeholder=\"Name this strategic theme\"\n aria-invalid={needsLabel}\n />\n {needsLabel && (\n <p role=\"alert\" className=\"text-sm text-destructive mt-1\">\n A custom alignment needs a label.\n </p>\n )}\n </div>\n )}\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Total Budget</label>\n <Input\n type=\"number\"\n min=\"0\"\n value={form.budgetTotal}\n onChange={(e) => setForm({ ...form, budgetTotal: e.target.value })}\n className=\"mt-1\"\n aria-invalid={invalidBudget}\n placeholder=\"0\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Currency</label>\n <Input\n value={form.currency}\n onChange={(e) => setForm({ ...form, currency: e.target.value })}\n className=\"mt-1\"\n placeholder=\"USD\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Fiscal Period</label>\n <Input\n value={form.fiscalPeriod}\n onChange={(e) => setForm({ ...form, fiscalPeriod: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. FY2026\"\n />\n </div>\n </div>\n {invalidBudget && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n The budget cannot be negative.\n </p>\n )}\n <div>\n <label className=\"text-sm font-medium\">Tags (comma-separated)</label>\n <Input\n value={form.tags}\n onChange={(e) => setForm({ ...form, tags: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. strategic, core, growth\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function PortfoliosEditPortfolioPagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=PortfoliosEditPortfolioPagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PortfoliosEditPortfolioPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/PortfoliosEditPortfolioPagePage.tsx"],"names":[],"mappings":"AA+CA,wBAAgB,+BAA+B,4CAuR9C"}
@@ -0,0 +1,302 @@
1
+ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
+ import { throwOnError as t } from "../utils/mutationResult.js";
3
+ import { enumLabel as n } from "../controls/WorkItemControls.js";
4
+ import { detailPath as r } from "../utils/rowNavigation.js";
5
+ import { PORTFOLIO_STATUSES as i, STRATEGIC_ALIGNMENTS as a } from "../controls/PortfolioControls.js";
6
+ import { useMemo as o, useState as s } from "react";
7
+ import { ArrowLeft as c, Loader2 as l, Save as u } from "lucide-react";
8
+ import { useParams as d } from "react-router";
9
+ import { gql as f } from "@apollo/client";
10
+ import { useMutation as p, useQuery as m } from "@apollo/client/react";
11
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
12
+ import { Button as _, Card as v, CardContent as y, CardHeader as b, CardTitle as x, Input as S } from "@burdenoff/fe-libs/ui";
13
+ //#region src/planmagnet/pages/PortfoliosEditPortfolioPagePage.tsx
14
+ var C = f`
15
+ query GetPortfolioForEdit($id: ID!) {
16
+ planmagnetPortfolio(id: $id) {
17
+ id
18
+ name
19
+ description
20
+ status
21
+ alignment
22
+ alignmentLabel
23
+ budgetTotal
24
+ currency
25
+ fiscalPeriod
26
+ tags
27
+ }
28
+ }
29
+ `, w = f`
30
+ mutation UpdatePortfolio($id: ID!, $input: PlanmagnetUpdatePortfolioInput!) {
31
+ planmagnetUpdatePortfolio(id: $id, input: $input) {
32
+ id
33
+ name
34
+ description
35
+ status
36
+ alignment
37
+ alignmentLabel
38
+ budgetTotal
39
+ currency
40
+ fiscalPeriod
41
+ tags
42
+ updatedAt
43
+ }
44
+ }
45
+ `;
46
+ function T() {
47
+ let f = e(), T = d().id ?? "", { data: E, loading: D, error: O } = m(C, {
48
+ variables: { id: T },
49
+ skip: !T
50
+ }), [k, { loading: A }] = p(w, {
51
+ refetchQueries: [
52
+ "ListPortfolios",
53
+ "GetPortfolioForEdit",
54
+ "GetPortfolio",
55
+ "GetPortfolioOverview"
56
+ ],
57
+ awaitRefetchQueries: !0
58
+ }), [j, M] = s(null), [N, P] = s(!1), F = E?.planmagnetPortfolio, I = o(() => ({
59
+ name: F?.name ?? "",
60
+ description: F?.description ?? "",
61
+ status: F?.status ?? "ACTIVE",
62
+ alignment: F?.alignment ?? "",
63
+ alignmentLabel: F?.alignmentLabel ?? "",
64
+ budgetTotal: F?.budgetTotal == null ? "" : String(F.budgetTotal),
65
+ currency: F?.currency ?? "",
66
+ fiscalPeriod: F?.fiscalPeriod ?? "",
67
+ tags: F?.tags?.join(", ") ?? ""
68
+ }), [F]), [L, R] = s({}), z = {
69
+ ...I,
70
+ ...L
71
+ }, B = (e) => R(e), V = i.includes(z.status) ? i : [z.status, ...i], H = z.alignment === "CUSTOM" && !z.alignmentLabel.trim(), U = z.budgetTotal !== "" && Number(z.budgetTotal) < 0;
72
+ return D && !E ? /* @__PURE__ */ h("div", {
73
+ className: "flex items-center justify-center p-12",
74
+ children: /* @__PURE__ */ h(l, { className: "h-8 w-8 animate-spin text-muted-foreground" })
75
+ }) : O ? /* @__PURE__ */ g("div", {
76
+ className: "p-6 text-destructive",
77
+ children: ["Failed to load portfolio: ", O.message]
78
+ }) : F ? /* @__PURE__ */ g("div", {
79
+ className: "space-y-6 p-6 max-w-4xl",
80
+ children: [
81
+ /* @__PURE__ */ g("div", {
82
+ className: "flex items-center justify-between",
83
+ children: [/* @__PURE__ */ g("div", {
84
+ className: "flex items-center gap-3",
85
+ children: [/* @__PURE__ */ h(_, {
86
+ variant: "ghost",
87
+ size: "sm",
88
+ "aria-label": "Back to the portfolio",
89
+ onClick: () => f(r("/products/portfolio-detail-page", T)),
90
+ children: /* @__PURE__ */ h(c, { className: "h-4 w-4" })
91
+ }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("h1", {
92
+ className: "text-2xl font-semibold",
93
+ children: "Edit Portfolio"
94
+ }), /* @__PURE__ */ h("p", {
95
+ className: "text-sm text-muted-foreground",
96
+ children: F.name
97
+ })] })]
98
+ }), /* @__PURE__ */ g(_, {
99
+ size: "sm",
100
+ onClick: async () => {
101
+ if (!F || !z.name.trim() || H || U) return;
102
+ let e = (e) => e.split(",").map((e) => e.trim()).filter(Boolean), n = {
103
+ name: z.name.trim(),
104
+ description: z.description.trim() || null,
105
+ status: z.status,
106
+ alignment: z.alignment || null,
107
+ alignmentLabel: z.alignment === "CUSTOM" ? z.alignmentLabel.trim() : null,
108
+ budgetTotal: z.budgetTotal === "" ? null : Number(z.budgetTotal),
109
+ currency: z.currency.trim() || null,
110
+ fiscalPeriod: z.fiscalPeriod.trim() || null,
111
+ tags: e(z.tags)
112
+ }, r = {
113
+ name: I.name,
114
+ description: I.description.trim() || null,
115
+ status: I.status,
116
+ alignment: I.alignment || null,
117
+ alignmentLabel: I.alignment === "CUSTOM" ? I.alignmentLabel.trim() : null,
118
+ budgetTotal: I.budgetTotal === "" ? null : Number(I.budgetTotal),
119
+ currency: I.currency.trim() || null,
120
+ fiscalPeriod: I.fiscalPeriod.trim() || null,
121
+ tags: e(I.tags)
122
+ }, i = Object.fromEntries(Object.entries(n).filter(([e, t]) => JSON.stringify(t) !== JSON.stringify(r[e])));
123
+ if (M(null), P(!1), Object.keys(i).length === 0) {
124
+ P(!0);
125
+ return;
126
+ }
127
+ try {
128
+ await t(k({ variables: {
129
+ id: T,
130
+ input: i
131
+ } })), P(!0);
132
+ } catch (e) {
133
+ M(e instanceof Error ? e.message : "The portfolio could not be saved.");
134
+ }
135
+ },
136
+ disabled: A || H || U,
137
+ children: [A ? /* @__PURE__ */ h(l, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ h(u, { className: "mr-1 h-4 w-4" }), "Save Changes"]
138
+ })]
139
+ }),
140
+ N && /* @__PURE__ */ h("div", {
141
+ role: "status",
142
+ className: "p-3 bg-muted text-status-success-text rounded-md text-sm",
143
+ children: "Changes saved."
144
+ }),
145
+ j && /* @__PURE__ */ h("div", {
146
+ role: "alert",
147
+ className: "p-3 rounded-md bg-destructive/10 text-destructive text-sm",
148
+ children: j
149
+ }),
150
+ /* @__PURE__ */ g(v, { children: [/* @__PURE__ */ h(b, { children: /* @__PURE__ */ h(x, { children: "Portfolio Details" }) }), /* @__PURE__ */ g(y, {
151
+ className: "space-y-4",
152
+ children: [
153
+ /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
154
+ className: "text-sm font-medium",
155
+ children: "Name"
156
+ }), /* @__PURE__ */ h(S, {
157
+ value: z.name,
158
+ onChange: (e) => B({
159
+ ...z,
160
+ name: e.target.value
161
+ }),
162
+ className: "mt-1"
163
+ })] }),
164
+ /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
165
+ className: "text-sm font-medium",
166
+ children: "Description"
167
+ }), /* @__PURE__ */ h("textarea", {
168
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]",
169
+ value: z.description,
170
+ onChange: (e) => B({
171
+ ...z,
172
+ description: e.target.value
173
+ })
174
+ })] }),
175
+ /* @__PURE__ */ g("div", {
176
+ className: "grid grid-cols-2 gap-4",
177
+ children: [/* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
178
+ htmlFor: "portfolio-edit-status",
179
+ className: "text-sm font-medium",
180
+ children: "Status"
181
+ }), /* @__PURE__ */ h("select", {
182
+ id: "portfolio-edit-status",
183
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
184
+ value: z.status,
185
+ onChange: (e) => B({
186
+ ...z,
187
+ status: e.target.value
188
+ }),
189
+ children: V.map((e) => /* @__PURE__ */ h("option", {
190
+ value: e,
191
+ children: n(e)
192
+ }, e))
193
+ })] }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
194
+ htmlFor: "portfolio-edit-alignment",
195
+ className: "text-sm font-medium",
196
+ children: "Strategic Alignment"
197
+ }), /* @__PURE__ */ g("select", {
198
+ id: "portfolio-edit-alignment",
199
+ className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
200
+ value: z.alignment,
201
+ onChange: (e) => B({
202
+ ...z,
203
+ alignment: e.target.value
204
+ }),
205
+ children: [/* @__PURE__ */ h("option", {
206
+ value: "",
207
+ children: "Not set"
208
+ }), a.map((e) => /* @__PURE__ */ h("option", {
209
+ value: e,
210
+ children: e === "CUSTOM" ? "Custom…" : n(e)
211
+ }, e))]
212
+ })] })]
213
+ }),
214
+ z.alignment === "CUSTOM" && /* @__PURE__ */ g("div", { children: [
215
+ /* @__PURE__ */ h("label", {
216
+ className: "text-sm font-medium",
217
+ children: "Custom Alignment Label"
218
+ }),
219
+ /* @__PURE__ */ h(S, {
220
+ value: z.alignmentLabel,
221
+ onChange: (e) => B({
222
+ ...z,
223
+ alignmentLabel: e.target.value
224
+ }),
225
+ className: "mt-1",
226
+ "aria-invalid": H
227
+ }),
228
+ H && /* @__PURE__ */ h("p", {
229
+ role: "alert",
230
+ className: "text-sm text-destructive mt-1",
231
+ children: "A custom alignment needs a label."
232
+ })
233
+ ] }),
234
+ /* @__PURE__ */ g("div", {
235
+ className: "grid grid-cols-3 gap-4",
236
+ children: [
237
+ /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
238
+ className: "text-sm font-medium",
239
+ children: "Total Budget"
240
+ }), /* @__PURE__ */ h(S, {
241
+ type: "number",
242
+ min: "0",
243
+ value: z.budgetTotal,
244
+ onChange: (e) => B({
245
+ ...z,
246
+ budgetTotal: e.target.value
247
+ }),
248
+ className: "mt-1",
249
+ "aria-invalid": U
250
+ })] }),
251
+ /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
252
+ className: "text-sm font-medium",
253
+ children: "Currency"
254
+ }), /* @__PURE__ */ h(S, {
255
+ value: z.currency,
256
+ onChange: (e) => B({
257
+ ...z,
258
+ currency: e.target.value
259
+ }),
260
+ className: "mt-1"
261
+ })] }),
262
+ /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
263
+ className: "text-sm font-medium",
264
+ children: "Fiscal Period"
265
+ }), /* @__PURE__ */ h(S, {
266
+ value: z.fiscalPeriod,
267
+ onChange: (e) => B({
268
+ ...z,
269
+ fiscalPeriod: e.target.value
270
+ }),
271
+ className: "mt-1"
272
+ })] })
273
+ ]
274
+ }),
275
+ U && /* @__PURE__ */ h("p", {
276
+ role: "alert",
277
+ className: "text-sm text-destructive",
278
+ children: "The budget cannot be negative."
279
+ }),
280
+ /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
281
+ className: "text-sm font-medium",
282
+ children: "Tags (comma-separated)"
283
+ }), /* @__PURE__ */ h(S, {
284
+ value: z.tags,
285
+ onChange: (e) => B({
286
+ ...z,
287
+ tags: e.target.value
288
+ }),
289
+ className: "mt-1"
290
+ })] })
291
+ ]
292
+ })] })
293
+ ]
294
+ }) : /* @__PURE__ */ h("div", {
295
+ className: "p-6 text-muted-foreground",
296
+ children: "Portfolio not found."
297
+ });
298
+ }
299
+ //#endregion
300
+ export { T as PortfoliosEditPortfolioPagePage };
301
+
302
+ //# sourceMappingURL=PortfoliosEditPortfolioPagePage.js.map