@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,171 @@
1
+ import { usePlanMagnet 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 { ErrorLine as r } from "../controls/ConfirmButton.js";
5
+ import { AUTOMATION_RULE_QUERIES as i, AutomationRuleDeleteButton as a, AutomationRuleStatusSwitch as o, RunAutomationRuleDialog as s } from "../controls/AutomationRuleControls.js";
6
+ import { AutomationExecutionsPanel as c } from "../automation/AutomationExecutionsPanel.js";
7
+ import { actionsFromApi as l, actionsToApi as u, conditionsFromApi as d, conditionsToApi as f } from "../automation/automationRuleTypes.js";
8
+ import { AutomationRuleFields as p } from "../automation/AutomationRuleFields.js";
9
+ import { useState as m } from "react";
10
+ import { Bot as h, History as g, Save as _ } from "lucide-react";
11
+ import { gql as v } from "@apollo/client";
12
+ import { useMutation as y, useQuery as b } from "@apollo/client/react";
13
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
14
+ import { Button as C, Card as w, CardContent as T, CardHeader as E, CardTitle as D } from "@burdenoff/fe-libs/ui";
15
+ //#region src/planmagnet/pages/AutomationAutomationRuleDetailPagePage.tsx
16
+ var O = v`
17
+ query GetAutomationRule($id: ID!) {
18
+ planmagnetAutomationRule(id: $id) {
19
+ id
20
+ name
21
+ description
22
+ status
23
+ triggerType
24
+ conditions
25
+ actions
26
+ executionCount
27
+ lastExecutedAt
28
+ projectId
29
+ project {
30
+ id
31
+ name
32
+ }
33
+ }
34
+ }
35
+ `, k = v`
36
+ mutation UpdateAutomationRule($id: ID!, $input: PlanmagnetUpdateAutomationRuleInput!) {
37
+ planmagnetUpdateAutomationRule(id: $id, input: $input) {
38
+ id
39
+ name
40
+ description
41
+ triggerType
42
+ conditions
43
+ actions
44
+ }
45
+ }
46
+ `;
47
+ function A(e) {
48
+ return {
49
+ name: e.name,
50
+ description: e.description ?? "",
51
+ projectId: e.projectId ?? "",
52
+ triggerType: e.triggerType,
53
+ conditions: d(e.conditions),
54
+ actions: l(e.actions)
55
+ };
56
+ }
57
+ function j() {
58
+ let l = n(), { workspaceId: d } = e(), { data: v, loading: j, error: M } = b(O, {
59
+ variables: { id: l ?? "" },
60
+ skip: !l,
61
+ fetchPolicy: "cache-and-network"
62
+ }), [N, { loading: P }] = y(k, { refetchQueries: i }), [F, I] = m(null), [L, R] = m(!1), z = v?.planmagnetAutomationRule ?? null, [B, V] = m(null), [H, U] = m(null);
63
+ if (z && H !== z.id && (U(z.id), V(A(z))), !l) return /* @__PURE__ */ x("div", {
64
+ className: "p-6 text-muted-foreground",
65
+ children: "No rule selected. Open one from the list."
66
+ });
67
+ if (j && !v) return /* @__PURE__ */ x("div", {
68
+ className: "flex items-center justify-center p-12",
69
+ children: /* @__PURE__ */ x("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
70
+ });
71
+ if (M) return /* @__PURE__ */ S("div", {
72
+ className: "p-6 text-destructive",
73
+ children: ["Automation rule could not be loaded: ", M.message]
74
+ });
75
+ if (!z || !B) return /* @__PURE__ */ x("div", {
76
+ className: "p-6 text-muted-foreground",
77
+ children: "Automation rule not found."
78
+ });
79
+ let W = async () => {
80
+ I(null), R(!1);
81
+ let e = A(z), n = {};
82
+ B.name.trim() !== e.name && (n.name = B.name.trim()), B.description.trim() !== e.description.trim() && (n.description = B.description.trim() || null), B.triggerType !== e.triggerType && (n.triggerType = B.triggerType);
83
+ let r = f(B.conditions);
84
+ JSON.stringify(r ?? null) !== JSON.stringify(f(e.conditions) ?? null) && (n.conditions = r ?? null);
85
+ let i = u(B.actions);
86
+ if (JSON.stringify(i) !== JSON.stringify(u(e.actions)) && (n.actions = i), Object.keys(n).length === 0) {
87
+ R(!0);
88
+ return;
89
+ }
90
+ try {
91
+ await t(N({ variables: {
92
+ id: z.id,
93
+ input: n
94
+ } })), R(!0);
95
+ } catch (e) {
96
+ I(e instanceof Error ? e.message : "The rule could not be saved.");
97
+ }
98
+ };
99
+ return /* @__PURE__ */ S("div", {
100
+ className: "space-y-6 p-6 max-w-3xl",
101
+ children: [
102
+ /* @__PURE__ */ S("div", {
103
+ className: "flex flex-wrap items-start justify-between gap-3",
104
+ children: [/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("h1", {
105
+ className: "text-2xl font-semibold",
106
+ children: z.name
107
+ }), /* @__PURE__ */ x("p", {
108
+ className: "text-sm text-muted-foreground",
109
+ children: z.project?.name ?? "Unknown project"
110
+ })] }), /* @__PURE__ */ x("div", {
111
+ className: "flex flex-col items-end gap-2",
112
+ children: /* @__PURE__ */ S("div", {
113
+ className: "flex items-center gap-2",
114
+ children: [
115
+ /* @__PURE__ */ x(s, {
116
+ ruleId: z.id,
117
+ projectId: z.projectId ?? void 0
118
+ }),
119
+ /* @__PURE__ */ x(o, {
120
+ ruleId: z.id,
121
+ status: z.status
122
+ }),
123
+ /* @__PURE__ */ x(a, {
124
+ ruleId: z.id,
125
+ name: z.name
126
+ })
127
+ ]
128
+ })
129
+ })]
130
+ }),
131
+ F && /* @__PURE__ */ x(r, { message: F }),
132
+ L && !F && /* @__PURE__ */ x("p", {
133
+ className: "text-sm text-muted-foreground",
134
+ children: "Saved."
135
+ }),
136
+ /* @__PURE__ */ S(w, { children: [/* @__PURE__ */ x(E, { children: /* @__PURE__ */ S(D, {
137
+ className: "flex items-center gap-2",
138
+ children: [/* @__PURE__ */ x(h, { className: "h-4 w-4" }), "Rule details"]
139
+ }) }), /* @__PURE__ */ S(T, {
140
+ className: "space-y-4",
141
+ children: [/* @__PURE__ */ x(p, {
142
+ form: B,
143
+ onChange: (e) => {
144
+ V(e), R(!1);
145
+ },
146
+ projectLocked: !0
147
+ }), /* @__PURE__ */ x("div", {
148
+ className: "flex justify-end",
149
+ children: /* @__PURE__ */ S(C, {
150
+ size: "sm",
151
+ onClick: () => void W(),
152
+ disabled: P,
153
+ "data-testid": "automation-save",
154
+ children: [/* @__PURE__ */ x(_, { className: "mr-1 h-4 w-4" }), P ? "Saving…" : "Save changes"]
155
+ })
156
+ })]
157
+ })] }),
158
+ /* @__PURE__ */ S(w, { children: [/* @__PURE__ */ x(E, { children: /* @__PURE__ */ S(D, {
159
+ className: "flex items-center gap-2",
160
+ children: [/* @__PURE__ */ x(g, { className: "h-4 w-4" }), "Recent executions"]
161
+ }) }), /* @__PURE__ */ x(T, { children: /* @__PURE__ */ x(c, {
162
+ workspaceId: d,
163
+ ruleId: z.id
164
+ }) })] })
165
+ ]
166
+ });
167
+ }
168
+ //#endregion
169
+ export { j as AutomationAutomationRuleDetailPagePage };
170
+
171
+ //# sourceMappingURL=AutomationAutomationRuleDetailPagePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomationAutomationRuleDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/AutomationAutomationRuleDetailPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Bot, History, Save } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\nimport { throwOnError } from '../utils/mutationResult';\nimport { ErrorLine } from '../controls/ConfirmButton';\nimport {\n AUTOMATION_RULE_QUERIES,\n AutomationRuleDeleteButton,\n AutomationRuleStatusSwitch,\n RunAutomationRuleDialog,\n} from '../controls/AutomationRuleControls';\nimport { AutomationExecutionsPanel } from '../automation/AutomationExecutionsPanel';\nimport {\n AutomationRuleFields,\n type AutomationRuleFormState,\n} from '../automation/AutomationRuleFields';\nimport {\n actionsFromApi,\n actionsToApi,\n conditionsFromApi,\n conditionsToApi,\n type TriggerType,\n} from '../automation/automationRuleTypes';\n\nconst GET_RULE = gql`\n query GetAutomationRule($id: ID!) {\n planmagnetAutomationRule(id: $id) {\n id\n name\n description\n status\n triggerType\n conditions\n actions\n executionCount\n lastExecutedAt\n projectId\n project {\n id\n name\n }\n }\n }\n`;\n\nconst UPDATE = gql`\n mutation UpdateAutomationRule($id: ID!, $input: PlanmagnetUpdateAutomationRuleInput!) {\n planmagnetUpdateAutomationRule(id: $id, input: $input) {\n id\n name\n description\n triggerType\n conditions\n actions\n }\n }\n`;\n\ninterface RuleDetail {\n id: string;\n name: string;\n description: string | null;\n status: string;\n triggerType: string;\n conditions: unknown;\n actions: unknown;\n executionCount: number;\n lastExecutedAt: string | null;\n projectId: string | null;\n project: { id: string; name: string } | null;\n}\n\nfunction toForm(rule: RuleDetail): AutomationRuleFormState {\n return {\n name: rule.name,\n description: rule.description ?? '',\n projectId: rule.projectId ?? '',\n triggerType: rule.triggerType as TriggerType,\n conditions: conditionsFromApi(rule.conditions),\n actions: actionsFromApi(rule.actions),\n };\n}\n\nexport function AutomationAutomationRuleDetailPagePage() {\n const ruleId = useEntityId();\n const { workspaceId } = usePlanMagnet();\n const { data, loading, error } = useQuery<{ planmagnetAutomationRule: RuleDetail | null }>(\n GET_RULE,\n {\n variables: { id: ruleId ?? '' },\n skip: !ruleId,\n fetchPolicy: 'cache-and-network',\n }\n );\n const [update, { loading: saving }] = useMutation(UPDATE, {\n refetchQueries: AUTOMATION_RULE_QUERIES,\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const rule = data?.planmagnetAutomationRule ?? null;\n const [form, setForm] = useState<AutomationRuleFormState | null>(null);\n const [seededFor, setSeededFor] = useState<string | null>(null);\n\n // The form tracks the loaded rule; a later refetch (status toggle, run now) must not stomp in-progress edits,\n // so this only seeds the form the first time the rule arrives — adjusted during render (React's documented\n // pattern for deriving state from a prop/query change), not in an effect, so it takes effect on the very\n // render the rule shows up rather than one render late.\n if (rule && seededFor !== rule.id) {\n setSeededFor(rule.id);\n setForm(toForm(rule));\n }\n\n if (!ruleId)\n return (\n <div className=\"p-6 text-muted-foreground\">No rule selected. Open one from the list.</div>\n );\n if (loading && !data)\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n if (error)\n return (\n <div className=\"p-6 text-destructive\">\n Automation rule could not be loaded: {error.message}\n </div>\n );\n if (!rule || !form)\n return <div className=\"p-6 text-muted-foreground\">Automation rule not found.</div>;\n\n const handleSave = async () => {\n setSaveError(null);\n setSaved(false);\n const initial = toForm(rule);\n const input: Record<string, unknown> = {};\n if (form.name.trim() !== initial.name) input.name = form.name.trim();\n if (form.description.trim() !== initial.description.trim())\n input.description = form.description.trim() || null;\n if (form.triggerType !== initial.triggerType) input.triggerType = form.triggerType;\n const conditions = conditionsToApi(form.conditions);\n if (\n JSON.stringify(conditions ?? null) !==\n JSON.stringify(conditionsToApi(initial.conditions) ?? null)\n )\n input.conditions = conditions ?? null;\n const actions = actionsToApi(form.actions);\n if (JSON.stringify(actions) !== JSON.stringify(actionsToApi(initial.actions)))\n input.actions = actions;\n if (Object.keys(input).length === 0) {\n setSaved(true);\n return;\n }\n try {\n await throwOnError(update({ variables: { id: rule.id, input } }));\n setSaved(true);\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The rule could not be saved.');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-3xl\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{rule.name}</h1>\n <p className=\"text-sm text-muted-foreground\">{rule.project?.name ?? 'Unknown project'}</p>\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <div className=\"flex items-center gap-2\">\n <RunAutomationRuleDialog ruleId={rule.id} projectId={rule.projectId ?? undefined} />\n <AutomationRuleStatusSwitch ruleId={rule.id} status={rule.status} />\n <AutomationRuleDeleteButton ruleId={rule.id} name={rule.name} />\n </div>\n </div>\n </div>\n\n {saveError && <ErrorLine message={saveError} />}\n {saved && !saveError && <p className=\"text-sm text-muted-foreground\">Saved.</p>}\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Bot className=\"h-4 w-4\" />\n Rule details\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <AutomationRuleFields\n form={form}\n onChange={(next) => {\n setForm(next);\n setSaved(false);\n }}\n projectLocked\n />\n <div className=\"flex justify-end\">\n <Button\n size=\"sm\"\n onClick={() => void handleSave()}\n disabled={saving}\n data-testid=\"automation-save\"\n >\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving…' : 'Save changes'}\n </Button>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <History className=\"h-4 w-4\" />\n Recent executions\n </CardTitle>\n </CardHeader>\n <CardContent>\n <AutomationExecutionsPanel workspaceId={workspaceId} ruleId={rule.id} />\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function AutomationAutomationRulesPagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=AutomationAutomationRulesPagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomationAutomationRulesPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/AutomationAutomationRulesPagePage.tsx"],"names":[],"mappings":"AAkFA,wBAAgB,iCAAiC,4CAmMhD"}
@@ -0,0 +1,232 @@
1
+ import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
+ import { ProjectSelect as n } from "../controls/Pickers.js";
3
+ import { AutomationRuleDeleteButton as r, AutomationRuleStatusSwitch as i } from "../controls/AutomationRuleControls.js";
4
+ import { RULE_STATUSES as a, TRIGGER_TYPES as o, TRIGGER_TYPE_LABEL as s, triggerTypeLabel as c } from "../automation/automationRuleTypes.js";
5
+ import { ROW_LINK_CLASS as l, detailPath as u, rowLinkProps as d, stopRowActivation as f } from "../utils/rowNavigation.js";
6
+ import { useDeferredValue as p, useState as m } from "react";
7
+ import { Bot as h, Plus as g, Search as _ } from "lucide-react";
8
+ import { gql as v } from "@apollo/client";
9
+ import { useQuery as y } from "@apollo/client/react";
10
+ import { jsx as b, jsxs as x } from "react/jsx-runtime";
11
+ import { Badge as S, Button as C, EmptyState as w, Input as T } from "@burdenoff/fe-libs/ui";
12
+ //#region src/planmagnet/pages/AutomationAutomationRulesPagePage.tsx
13
+ var E = 50, D = v`
14
+ query AutomationRulesList(
15
+ $workspaceId: ID!
16
+ $filter: PlanmagnetAutomationRuleFilter
17
+ $pagination: PlanmagnetPaginationInput
18
+ ) {
19
+ planmagnetAutomationRules(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {
20
+ totalCount
21
+ pageInfo {
22
+ hasNextPage
23
+ endCursor
24
+ }
25
+ items {
26
+ id
27
+ name
28
+ description
29
+ status
30
+ triggerType
31
+ actions
32
+ executionCount
33
+ lastExecutedAt
34
+ projectId
35
+ project {
36
+ id
37
+ name
38
+ }
39
+ }
40
+ }
41
+ }
42
+ `, O = ["ALL", ...a];
43
+ function k(e) {
44
+ return Array.isArray(e) ? e.length : 0;
45
+ }
46
+ function A() {
47
+ let { workspaceId: a } = e(), v = t(), [A, j] = m(""), [M, N] = m("ALL"), [P, F] = m("ALL"), [I, L] = m(""), [R, z] = m(!1), B = p(A.trim()), V = {
48
+ ...B ? { search: B } : {},
49
+ ...M === "ALL" ? {} : { status: M },
50
+ ...P === "ALL" ? {} : { triggerType: P },
51
+ ...I ? { projectId: I } : {}
52
+ }, { data: H, loading: U, error: W, fetchMore: G } = y(D, {
53
+ variables: {
54
+ workspaceId: a ?? "",
55
+ filter: V,
56
+ pagination: { first: E }
57
+ },
58
+ skip: !a,
59
+ fetchPolicy: "cache-and-network"
60
+ }), K = H?.planmagnetAutomationRules, q = K?.items ?? [], J = async () => {
61
+ let e = K?.pageInfo.endCursor;
62
+ if (e) {
63
+ z(!0);
64
+ try {
65
+ await G({
66
+ variables: { pagination: {
67
+ first: E,
68
+ after: e
69
+ } },
70
+ updateQuery: (e, { fetchMoreResult: t }) => ({ planmagnetAutomationRules: {
71
+ ...t.planmagnetAutomationRules,
72
+ items: [...e.planmagnetAutomationRules.items, ...t.planmagnetAutomationRules.items]
73
+ } })
74
+ });
75
+ } finally {
76
+ z(!1);
77
+ }
78
+ }
79
+ };
80
+ return /* @__PURE__ */ x("div", {
81
+ className: "space-y-6 p-6",
82
+ "data-testid": "automation-rules-page",
83
+ children: [
84
+ /* @__PURE__ */ x("div", {
85
+ className: "flex flex-wrap items-center justify-between gap-3",
86
+ children: [/* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("h1", {
87
+ className: "text-2xl font-semibold",
88
+ children: "Automation rules"
89
+ }), /* @__PURE__ */ b("p", {
90
+ className: "text-sm text-muted-foreground",
91
+ children: K ? `${K.totalCount} rule${K.totalCount === 1 ? "" : "s"}` : "Trigger, condition and action rules that run against work items"
92
+ })] }), /* @__PURE__ */ x(C, {
93
+ size: "sm",
94
+ onClick: () => v("/automation/create-automation-rule-page"),
95
+ "data-testid": "automation-new",
96
+ children: [/* @__PURE__ */ b(g, { className: "mr-1 h-4 w-4" }), "New rule"]
97
+ })]
98
+ }),
99
+ /* @__PURE__ */ x("div", {
100
+ className: "flex flex-wrap items-center gap-3",
101
+ children: [
102
+ /* @__PURE__ */ x("div", {
103
+ className: "relative w-full max-w-sm",
104
+ children: [/* @__PURE__ */ b(_, { className: "absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" }), /* @__PURE__ */ b(T, {
105
+ "aria-label": "Search automation rules",
106
+ placeholder: "Search by name or description",
107
+ className: "pl-8",
108
+ value: A,
109
+ onChange: (e) => j(e.target.value)
110
+ })]
111
+ }),
112
+ /* @__PURE__ */ x("select", {
113
+ "aria-label": "Filter by trigger",
114
+ className: "rounded-md border border-input bg-background px-2 py-1.5 text-sm",
115
+ value: P,
116
+ onChange: (e) => F(e.target.value),
117
+ children: [/* @__PURE__ */ b("option", {
118
+ value: "ALL",
119
+ children: "Any trigger"
120
+ }), o.map((e) => /* @__PURE__ */ b("option", {
121
+ value: e,
122
+ children: s[e]
123
+ }, e))]
124
+ }),
125
+ /* @__PURE__ */ b("div", {
126
+ className: "w-48",
127
+ children: /* @__PURE__ */ b(n, {
128
+ id: "automation-filter-project",
129
+ value: I,
130
+ onChange: L,
131
+ noneLabel: "Any project"
132
+ })
133
+ })
134
+ ]
135
+ }),
136
+ /* @__PURE__ */ b("div", {
137
+ className: "flex gap-1",
138
+ role: "group",
139
+ "aria-label": "Filter by status",
140
+ children: O.map((e) => /* @__PURE__ */ b("button", {
141
+ type: "button",
142
+ "aria-pressed": M === e,
143
+ onClick: () => N(e),
144
+ className: `px-3 py-1.5 text-sm rounded-md capitalize ${M === e ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"}`,
145
+ children: e === "ALL" ? "All" : e.toLowerCase()
146
+ }, e))
147
+ }),
148
+ W && /* @__PURE__ */ x("p", {
149
+ role: "alert",
150
+ className: "text-sm text-destructive",
151
+ children: ["Automation rules could not be loaded: ", W.message]
152
+ }),
153
+ U && !H && /* @__PURE__ */ b("p", {
154
+ className: "text-sm text-muted-foreground",
155
+ children: "Loading automation rules…"
156
+ }),
157
+ K && q.length === 0 && /* @__PURE__ */ b(w, {
158
+ icon: /* @__PURE__ */ b(h, { className: "h-8 w-8 text-muted-foreground" }),
159
+ title: B || M !== "ALL" || P !== "ALL" || I ? "No rules match" : "No automation rules yet",
160
+ description: "Rules watch for an event on a project's work items and act automatically — assign, label, or move status.",
161
+ action: B || M !== "ALL" || P !== "ALL" || I ? void 0 : /* @__PURE__ */ x(C, {
162
+ size: "sm",
163
+ onClick: () => v("/automation/create-automation-rule-page"),
164
+ children: [/* @__PURE__ */ b(g, { className: "mr-1 h-4 w-4" }), "New rule"]
165
+ })
166
+ }),
167
+ /* @__PURE__ */ b("ul", {
168
+ className: "space-y-2",
169
+ children: q.map((e) => /* @__PURE__ */ b("li", { children: /* @__PURE__ */ x("div", {
170
+ ...d(() => v(u("/automation/automation-rule-detail-page", e.id)), e.name),
171
+ "data-testid": "automation-rule-row",
172
+ className: `flex flex-wrap items-center justify-between gap-3 rounded-md border p-3 ${l}`,
173
+ children: [/* @__PURE__ */ x("div", {
174
+ className: "min-w-0 flex-1",
175
+ children: [
176
+ /* @__PURE__ */ x("div", {
177
+ className: "flex flex-wrap items-center gap-2",
178
+ children: [/* @__PURE__ */ b("span", {
179
+ className: "truncate text-sm font-medium",
180
+ children: e.name
181
+ }), /* @__PURE__ */ b(S, {
182
+ variant: "outline",
183
+ children: c(e.triggerType)
184
+ })]
185
+ }),
186
+ /* @__PURE__ */ x("p", {
187
+ className: "mt-0.5 truncate text-xs text-muted-foreground",
188
+ children: [
189
+ e.project?.name ?? "Unknown project",
190
+ " · ",
191
+ k(e.actions),
192
+ " action",
193
+ k(e.actions) === 1 ? "" : "s",
194
+ " · run ",
195
+ e.executionCount,
196
+ " time",
197
+ e.executionCount === 1 ? "" : "s",
198
+ e.lastExecutedAt ? ` · last ${new Date(e.lastExecutedAt).toLocaleString()}` : ""
199
+ ]
200
+ }),
201
+ e.description && /* @__PURE__ */ b("p", {
202
+ className: "mt-0.5 truncate text-xs text-muted-foreground",
203
+ children: e.description
204
+ })
205
+ ]
206
+ }), /* @__PURE__ */ x("div", {
207
+ className: "flex items-center gap-3",
208
+ onClick: f,
209
+ children: [/* @__PURE__ */ b(i, {
210
+ ruleId: e.id,
211
+ status: e.status
212
+ }), /* @__PURE__ */ b(r, {
213
+ ruleId: e.id,
214
+ name: e.name
215
+ })]
216
+ })]
217
+ }) }, e.id))
218
+ }),
219
+ K?.pageInfo.hasNextPage && /* @__PURE__ */ b(C, {
220
+ size: "sm",
221
+ variant: "outline",
222
+ onClick: () => void J(),
223
+ disabled: R,
224
+ children: R ? "Loading…" : `Show more (${q.length} of ${K.totalCount})`
225
+ })
226
+ ]
227
+ });
228
+ }
229
+ //#endregion
230
+ export { A as AutomationAutomationRulesPagePage };
231
+
232
+ //# sourceMappingURL=AutomationAutomationRulesPagePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomationAutomationRulesPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/AutomationAutomationRulesPagePage.tsx"],"sourcesContent":["import { useDeferredValue, useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Badge, Button, EmptyState, Input } from '@burdenoff/fe-libs/ui';\nimport { Bot, Plus, Search } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ProjectSelect } from '../controls/Pickers';\nimport {\n AutomationRuleStatusSwitch,\n AutomationRuleDeleteButton,\n} from '../controls/AutomationRuleControls';\nimport {\n rowLinkProps,\n detailPath,\n stopRowActivation,\n ROW_LINK_CLASS,\n} from '../utils/rowNavigation';\nimport {\n RULE_STATUSES,\n TRIGGER_TYPES,\n TRIGGER_TYPE_LABEL,\n triggerTypeLabel,\n} from '../automation/automationRuleTypes';\n\n/**\n * Automation rules browse surface (BOFF-8047, capability register \"Automation rules\": model/API/authz were\n * already real and prod-verified — `planmagnetAutomationRules`/Create/Update/Delete/Toggle/Execute — gate 3\n * (UI) was the only gap; \"no UI anywhere\" until now.\n */\n\nconst PAGE = 50;\n\nconst RULES = gql`\n query AutomationRulesList(\n $workspaceId: ID!\n $filter: PlanmagnetAutomationRuleFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetAutomationRules(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n totalCount\n pageInfo {\n hasNextPage\n endCursor\n }\n items {\n id\n name\n description\n status\n triggerType\n actions\n executionCount\n lastExecutedAt\n projectId\n project {\n id\n name\n }\n }\n }\n }\n`;\n\ninterface RuleRow {\n id: string;\n name: string;\n description: string | null;\n status: string;\n triggerType: string;\n actions: unknown;\n executionCount: number;\n lastExecutedAt: string | null;\n projectId: string | null;\n project: { id: string; name: string } | null;\n}\n\nconst STATUS_FILTERS = ['ALL', ...RULE_STATUSES] as const;\n\nfunction actionCount(actions: unknown): number {\n return Array.isArray(actions) ? actions.length : 0;\n}\n\nexport function AutomationAutomationRulesPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [search, setSearch] = useState('');\n const [status, setStatus] = useState<(typeof STATUS_FILTERS)[number]>('ALL');\n const [triggerType, setTriggerType] = useState('ALL');\n const [projectId, setProjectId] = useState('');\n const [loadingMore, setLoadingMore] = useState(false);\n const term = useDeferredValue(search.trim());\n\n const filter = {\n ...(term ? { search: term } : {}),\n ...(status !== 'ALL' ? { status } : {}),\n ...(triggerType !== 'ALL' ? { triggerType } : {}),\n ...(projectId ? { projectId } : {}),\n };\n\n const { data, loading, error, fetchMore } = useQuery<{\n planmagnetAutomationRules: {\n totalCount: number;\n pageInfo: { hasNextPage: boolean; endCursor: string | null };\n items: RuleRow[];\n };\n }>(RULES, {\n variables: { workspaceId: workspaceId ?? '', filter, pagination: { first: PAGE } },\n skip: !workspaceId,\n fetchPolicy: 'cache-and-network',\n });\n\n const list = data?.planmagnetAutomationRules;\n const rules = list?.items ?? [];\n\n const loadMore = async () => {\n const after = list?.pageInfo.endCursor;\n if (!after) return;\n setLoadingMore(true);\n try {\n await fetchMore({\n variables: { pagination: { first: PAGE, after } },\n updateQuery: (prev, { fetchMoreResult }) => ({\n planmagnetAutomationRules: {\n ...fetchMoreResult.planmagnetAutomationRules,\n items: [\n ...prev.planmagnetAutomationRules.items,\n ...fetchMoreResult.planmagnetAutomationRules.items,\n ],\n },\n }),\n });\n } finally {\n setLoadingMore(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\" data-testid=\"automation-rules-page\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Automation rules</h1>\n <p className=\"text-sm text-muted-foreground\">\n {list\n ? `${list.totalCount} rule${list.totalCount === 1 ? '' : 's'}`\n : 'Trigger, condition and action rules that run against work items'}\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={() => navigate('/automation/create-automation-rule-page')}\n data-testid=\"automation-new\"\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n New rule\n </Button>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"relative w-full max-w-sm\">\n <Search className=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n aria-label=\"Search automation rules\"\n placeholder=\"Search by name or description\"\n className=\"pl-8\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n <select\n aria-label=\"Filter by trigger\"\n className=\"rounded-md border border-input bg-background px-2 py-1.5 text-sm\"\n value={triggerType}\n onChange={(e) => setTriggerType(e.target.value)}\n >\n <option value=\"ALL\">Any trigger</option>\n {TRIGGER_TYPES.map((t) => (\n <option key={t} value={t}>\n {TRIGGER_TYPE_LABEL[t]}\n </option>\n ))}\n </select>\n <div className=\"w-48\">\n <ProjectSelect\n id=\"automation-filter-project\"\n value={projectId}\n onChange={setProjectId}\n noneLabel=\"Any project\"\n />\n </div>\n </div>\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Filter by status\">\n {STATUS_FILTERS.map((s) => (\n <button\n key={s}\n type=\"button\"\n aria-pressed={status === s}\n onClick={() => setStatus(s)}\n className={`px-3 py-1.5 text-sm rounded-md capitalize ${status === s ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:bg-muted'}`}\n >\n {s === 'ALL' ? 'All' : s.toLowerCase()}\n </button>\n ))}\n </div>\n\n {error && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n Automation rules could not be loaded: {error.message}\n </p>\n )}\n {loading && !data && (\n <p className=\"text-sm text-muted-foreground\">Loading automation rules…</p>\n )}\n {list && rules.length === 0 && (\n <EmptyState\n icon={<Bot className=\"h-8 w-8 text-muted-foreground\" />}\n title={\n term || status !== 'ALL' || triggerType !== 'ALL' || projectId\n ? 'No rules match'\n : 'No automation rules yet'\n }\n description=\"Rules watch for an event on a project's work items and act automatically — assign, label, or move status.\"\n action={\n !(term || status !== 'ALL' || triggerType !== 'ALL' || projectId) ? (\n <Button size=\"sm\" onClick={() => navigate('/automation/create-automation-rule-page')}>\n <Plus className=\"mr-1 h-4 w-4\" />\n New rule\n </Button>\n ) : undefined\n }\n />\n )}\n\n <ul className=\"space-y-2\">\n {rules.map((rule) => (\n <li key={rule.id}>\n <div\n {...rowLinkProps(\n () => navigate(detailPath('/automation/automation-rule-detail-page', rule.id)),\n rule.name\n )}\n data-testid=\"automation-rule-row\"\n className={`flex flex-wrap items-center justify-between gap-3 rounded-md border p-3 ${ROW_LINK_CLASS}`}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-medium\">{rule.name}</span>\n <Badge variant=\"outline\">{triggerTypeLabel(rule.triggerType)}</Badge>\n </div>\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {rule.project?.name ?? 'Unknown project'} · {actionCount(rule.actions)} action\n {actionCount(rule.actions) === 1 ? '' : 's'} · run {rule.executionCount} time\n {rule.executionCount === 1 ? '' : 's'}\n {rule.lastExecutedAt\n ? ` · last ${new Date(rule.lastExecutedAt).toLocaleString()}`\n : ''}\n </p>\n {rule.description && (\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {rule.description}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-3\" onClick={stopRowActivation}>\n <AutomationRuleStatusSwitch ruleId={rule.id} status={rule.status} />\n <AutomationRuleDeleteButton ruleId={rule.id} name={rule.name} />\n </div>\n </div>\n </li>\n ))}\n </ul>\n {list?.pageInfo.hasNextPage && (\n <Button size=\"sm\" variant=\"outline\" onClick={() => void loadMore()} disabled={loadingMore}>\n {loadingMore ? 'Loading…' : `Show more (${rules.length} of ${list.totalCount})`}\n </Button>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function AutomationCreateAutomationRulePagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=AutomationCreateAutomationRulePagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomationCreateAutomationRulePagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/AutomationCreateAutomationRulePagePage.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,sCAAsC,4CA2FrD"}
@@ -0,0 +1,93 @@
1
+ import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
+ import { throwOnError as n } from "../utils/mutationResult.js";
3
+ import { AUTOMATION_RULE_QUERIES as r } from "../controls/AutomationRuleControls.js";
4
+ import { actionsToApi as i, conditionsToApi as a } from "../automation/automationRuleTypes.js";
5
+ import { AutomationRuleFields as o } from "../automation/AutomationRuleFields.js";
6
+ import { detailPath as s } from "../utils/rowNavigation.js";
7
+ import { useState as c } from "react";
8
+ import { Bot as l, Save as u, X as d } from "lucide-react";
9
+ import { gql as f } from "@apollo/client";
10
+ import { useMutation as p } from "@apollo/client/react";
11
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
12
+ import { Button as g, Card as _, CardContent as v, CardHeader as y, CardTitle as b } from "@burdenoff/fe-libs/ui";
13
+ //#region src/planmagnet/pages/AutomationCreateAutomationRulePagePage.tsx
14
+ var x = f`
15
+ mutation CreateAutomationRule($input: PlanmagnetCreateAutomationRuleInput!) {
16
+ planmagnetCreateAutomationRule(input: $input) {
17
+ id
18
+ }
19
+ }
20
+ `, S = {
21
+ name: "",
22
+ description: "",
23
+ projectId: "",
24
+ triggerType: "WORK_ITEM_CREATED",
25
+ conditions: [],
26
+ actions: []
27
+ };
28
+ function C() {
29
+ let { workspaceId: f } = e(), C = t(), [w, T] = c(S), [E, D] = c(null), [O, { loading: k }] = p(x, { refetchQueries: r }), A = w.name.trim() !== "" && w.projectId !== "" && !k, j = async () => {
30
+ if (!(!A || !f)) {
31
+ D(null);
32
+ try {
33
+ let e = (await n(O({ variables: { input: {
34
+ projectId: w.projectId,
35
+ name: w.name.trim(),
36
+ description: w.description.trim() || void 0,
37
+ triggerType: w.triggerType,
38
+ triggerConfig: {},
39
+ conditions: a(w.conditions),
40
+ actions: i(w.actions)
41
+ } } }))).data?.planmagnetCreateAutomationRule.id;
42
+ C(e ? s("/automation/automation-rule-detail-page", e) : "/automation/automation-rules-page");
43
+ } catch (e) {
44
+ D(e instanceof Error ? e.message : "The rule could not be created.");
45
+ }
46
+ }
47
+ };
48
+ return /* @__PURE__ */ h("div", {
49
+ className: "space-y-6 p-6 max-w-3xl",
50
+ children: [
51
+ /* @__PURE__ */ h("div", {
52
+ className: "flex items-center justify-between",
53
+ children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h1", {
54
+ className: "text-2xl font-semibold",
55
+ children: "New automation rule"
56
+ }), /* @__PURE__ */ m("p", {
57
+ className: "text-sm text-muted-foreground",
58
+ children: "Runs its actions when the trigger fires and every condition matches."
59
+ })] }), /* @__PURE__ */ h("div", {
60
+ className: "flex gap-2",
61
+ children: [/* @__PURE__ */ h(g, {
62
+ variant: "outline",
63
+ size: "sm",
64
+ onClick: () => C("/automation/automation-rules-page"),
65
+ children: [/* @__PURE__ */ m(d, { className: "mr-1 h-4 w-4" }), "Cancel"]
66
+ }), /* @__PURE__ */ h(g, {
67
+ size: "sm",
68
+ onClick: () => void j(),
69
+ disabled: !A,
70
+ "data-testid": "automation-create-submit",
71
+ children: [/* @__PURE__ */ m(u, { className: "mr-1 h-4 w-4" }), k ? "Creating…" : "Create rule"]
72
+ })]
73
+ })]
74
+ }),
75
+ E && /* @__PURE__ */ m("div", {
76
+ role: "alert",
77
+ className: "p-3 bg-destructive/10 text-destructive rounded-md text-sm",
78
+ children: E
79
+ }),
80
+ /* @__PURE__ */ h(_, { children: [/* @__PURE__ */ m(y, { children: /* @__PURE__ */ h(b, {
81
+ className: "flex items-center gap-2",
82
+ children: [/* @__PURE__ */ m(l, { className: "h-4 w-4" }), "Rule details"]
83
+ }) }), /* @__PURE__ */ m(v, { children: /* @__PURE__ */ m(o, {
84
+ form: w,
85
+ onChange: T
86
+ }) })] })
87
+ ]
88
+ });
89
+ }
90
+ //#endregion
91
+ export { C as AutomationCreateAutomationRulePagePage };
92
+
93
+ //# sourceMappingURL=AutomationCreateAutomationRulePagePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomationCreateAutomationRulePagePage.js","names":[],"sources":["../../../src/planmagnet/pages/AutomationCreateAutomationRulePagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Bot, Save, X } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { throwOnError } from '../utils/mutationResult';\nimport { detailPath } from '../utils/rowNavigation';\nimport {\n AutomationRuleFields,\n type AutomationRuleFormState,\n} from '../automation/AutomationRuleFields';\nimport { actionsToApi, conditionsToApi } from '../automation/automationRuleTypes';\nimport { AUTOMATION_RULE_QUERIES } from '../controls/AutomationRuleControls';\n\nconst CREATE = gql`\n mutation CreateAutomationRule($input: PlanmagnetCreateAutomationRuleInput!) {\n planmagnetCreateAutomationRule(input: $input) {\n id\n }\n }\n`;\n\nconst EMPTY: AutomationRuleFormState = {\n name: '',\n description: '',\n projectId: '',\n triggerType: 'WORK_ITEM_CREATED',\n conditions: [],\n actions: [],\n};\n\nexport function AutomationCreateAutomationRulePagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [form, setForm] = useState<AutomationRuleFormState>(EMPTY);\n const [error, setError] = useState<string | null>(null);\n const [create, { loading }] = useMutation<{ planmagnetCreateAutomationRule: { id: string } }>(\n CREATE,\n {\n refetchQueries: AUTOMATION_RULE_QUERIES,\n }\n );\n\n const canSubmit = form.name.trim() !== '' && form.projectId !== '' && !loading;\n\n const handleCreate = async () => {\n if (!canSubmit || !workspaceId) return;\n setError(null);\n try {\n const result = await throwOnError(\n create({\n variables: {\n input: {\n projectId: form.projectId,\n name: form.name.trim(),\n description: form.description.trim() || undefined,\n triggerType: form.triggerType,\n triggerConfig: {},\n conditions: conditionsToApi(form.conditions),\n actions: actionsToApi(form.actions),\n },\n },\n })\n );\n const id = result.data?.planmagnetCreateAutomationRule.id;\n navigate(\n id\n ? detailPath('/automation/automation-rule-detail-page', id)\n : '/automation/automation-rules-page'\n );\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The rule could not be created.');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-3xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">New automation rule</h1>\n <p className=\"text-sm text-muted-foreground\">\n Runs its actions when the trigger fires and every condition matches.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate('/automation/automation-rules-page')}\n >\n <X className=\"mr-1 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void handleCreate()}\n disabled={!canSubmit}\n data-testid=\"automation-create-submit\"\n >\n <Save className=\"mr-1 h-4 w-4\" />\n {loading ? 'Creating…' : 'Create rule'}\n </Button>\n </div>\n </div>\n {error && (\n <div role=\"alert\" className=\"p-3 bg-destructive/10 text-destructive rounded-md text-sm\">\n {error}\n </div>\n )}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Bot className=\"h-4 w-4\" />\n Rule details\n </CardTitle>\n </CardHeader>\n <CardContent>\n <AutomationRuleFields form={form} onChange={setForm} />\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,IAAM,IAAS,CAAG;;;;;;GAQZ,IAAiC;CACrC,MAAM;CACN,aAAa;CACb,WAAW;CACX,aAAa;CACb,YAAY,EAAE;CACd,SAAS,EAAE;CACZ;AAED,SAAgB,IAAyC;CACvD,IAAM,EAAE,mBAAgB,GAAe,EACjC,IAAW,GAAuB,EAClC,CAAC,GAAM,KAAW,EAAkC,EAAM,EAC1D,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAQ,EAAE,gBAAa,EAC5B,GACA,EACE,gBAAgB,GACjB,CACF,EAEK,IAAY,EAAK,KAAK,MAAM,KAAK,MAAM,EAAK,cAAc,MAAM,CAAC,GAEjE,IAAe,YAAY;AAC3B,SAAC,KAAa,CAAC,IACnB;KAAS,KAAK;AACd,OAAI;IAgBF,IAAM,KAfS,MAAM,EACnB,EAAO,EACL,WAAW,EACT,OAAO;KACL,WAAW,EAAK;KAChB,MAAM,EAAK,KAAK,MAAM;KACtB,aAAa,EAAK,YAAY,MAAM,IAAI,KAAA;KACxC,aAAa,EAAK;KAClB,eAAe,EAAE;KACjB,YAAY,EAAgB,EAAK,WAAW;KAC5C,SAAS,EAAa,EAAK,QAAQ;KACpC,EACF,EACF,CAAC,CACH,EACiB,MAAM,+BAA+B;AACvD,MACE,IACI,EAAW,2CAA2C,EAAG,GACzD,oCACL;YACM,GAAG;AACV,MAAS,aAAa,QAAQ,EAAE,UAAU,iCAAiC;;;;AAI/E,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eAAyB;KAAwB,CAAA,EAC/D,kBAAC,KAAD;KAAG,WAAU;eAAgC;KAEzC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,SAAQ;MACR,MAAK;MACL,eAAe,EAAS,oCAAoC;gBAH9D,CAKE,kBAAC,GAAD,EAAG,WAAU,gBAAiB,CAAA,EAAA,SAEvB;SACT,kBAAC,GAAD;MACE,MAAK;MACL,eAAe,KAAK,GAAc;MAClC,UAAU,CAAC;MACX,eAAY;gBAJd,CAME,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAChC,IAAU,cAAc,cAClB;QACL;OACF;;GACL,KACC,kBAAC,OAAD;IAAK,MAAK;IAAQ,WAAU;cACzB;IACG,CAAA;GAER,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAW,WAAU;cAArB,CACE,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA,EAAA,eAEjB;OACD,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAA4B;IAAM,UAAU;IAAW,CAAA,EAC3C,CAAA,CACT,EAAA,CAAA;GACH"}
@@ -0,0 +1,2 @@
1
+ export declare function CompetitorsCompetitorDetailPagePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=CompetitorsCompetitorDetailPagePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompetitorsCompetitorDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/CompetitorsCompetitorDetailPagePage.tsx"],"names":[],"mappings":"AAoCA,wBAAgB,mCAAmC,4CA0HlD"}