@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.
- package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.js +126 -84
- package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +192 -64
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts +5 -0
- package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts.map +1 -0
- package/dist/planmagnet/automation/AutomationExecutionsPanel.js +107 -0
- package/dist/planmagnet/automation/AutomationExecutionsPanel.js.map +1 -0
- package/dist/planmagnet/automation/AutomationRuleFields.d.ts +29 -0
- package/dist/planmagnet/automation/AutomationRuleFields.d.ts.map +1 -0
- package/dist/planmagnet/automation/AutomationRuleFields.js +308 -0
- package/dist/planmagnet/automation/AutomationRuleFields.js.map +1 -0
- package/dist/planmagnet/automation/automationRuleTypes.d.ts +60 -0
- package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -0
- package/dist/planmagnet/automation/automationRuleTypes.js +113 -0
- package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -0
- package/dist/planmagnet/board/BulkActions.d.ts +11 -0
- package/dist/planmagnet/board/BulkActions.d.ts.map +1 -0
- package/dist/planmagnet/board/BulkActions.js +182 -0
- package/dist/planmagnet/board/BulkActions.js.map +1 -0
- package/dist/planmagnet/board/ProjectBoard.d.ts.map +1 -1
- package/dist/planmagnet/board/ProjectBoard.js +289 -254
- package/dist/planmagnet/board/ProjectBoard.js.map +1 -1
- package/dist/planmagnet/budgets/BudgetControls.d.ts +30 -0
- package/dist/planmagnet/budgets/BudgetControls.d.ts.map +1 -0
- package/dist/planmagnet/budgets/BudgetControls.js +470 -0
- package/dist/planmagnet/budgets/BudgetControls.js.map +1 -0
- package/dist/planmagnet/budgets/ExpenseControls.d.ts +27 -0
- package/dist/planmagnet/budgets/ExpenseControls.d.ts.map +1 -0
- package/dist/planmagnet/budgets/ExpenseControls.js +366 -0
- package/dist/planmagnet/budgets/ExpenseControls.js.map +1 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts +5 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts.map +1 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.js +112 -0
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.js.map +1 -0
- package/dist/planmagnet/budgets/budgetMath.d.ts +26 -0
- package/dist/planmagnet/budgets/budgetMath.d.ts.map +1 -0
- package/dist/planmagnet/budgets/budgetMath.js +49 -0
- package/dist/planmagnet/budgets/budgetMath.js.map +1 -0
- package/dist/planmagnet/controls/AutomationRuleControls.d.ts +23 -0
- package/dist/planmagnet/controls/AutomationRuleControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/AutomationRuleControls.js +172 -0
- package/dist/planmagnet/controls/AutomationRuleControls.js.map +1 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts +20 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/CompetitorControls.js +172 -0
- package/dist/planmagnet/controls/CompetitorControls.js.map +1 -0
- package/dist/planmagnet/controls/CustomFieldControls.d.ts +42 -0
- package/dist/planmagnet/controls/CustomFieldControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/CustomFieldControls.js +84 -0
- package/dist/planmagnet/controls/CustomFieldControls.js.map +1 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts +8 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts.map +1 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.js +315 -0
- package/dist/planmagnet/controls/CustomFieldValuesPanel.js.map +1 -0
- package/dist/planmagnet/controls/FeatureControls.js +53 -53
- package/dist/planmagnet/controls/FeatureTriage.js +11 -11
- package/dist/planmagnet/controls/ObjectiveControls.js +37 -37
- package/dist/planmagnet/controls/Pickers.d.ts +17 -2
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +100 -9
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/controls/PortfolioControls.d.ts +13 -0
- package/dist/planmagnet/controls/PortfolioControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/PortfolioControls.js +114 -0
- package/dist/planmagnet/controls/PortfolioControls.js.map +1 -0
- package/dist/planmagnet/controls/ProgramControls.d.ts +25 -0
- package/dist/planmagnet/controls/ProgramControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ProgramControls.js +187 -0
- package/dist/planmagnet/controls/ProgramControls.js.map +1 -0
- package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/ProjectControls.js +54 -47
- package/dist/planmagnet/controls/ProjectControls.js.map +1 -1
- package/dist/planmagnet/controls/ReleaseControls.js +7 -7
- package/dist/planmagnet/controls/RiskControls.d.ts +27 -0
- package/dist/planmagnet/controls/RiskControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/RiskControls.js +346 -0
- package/dist/planmagnet/controls/RiskControls.js.map +1 -0
- package/dist/planmagnet/controls/TemplateControls.d.ts +15 -0
- package/dist/planmagnet/controls/TemplateControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/TemplateControls.js +55 -0
- package/dist/planmagnet/controls/TemplateControls.js.map +1 -0
- package/dist/planmagnet/controls/WorkItemControls.js +1 -1
- package/dist/planmagnet/create/CreateDialogs.d.ts +20 -0
- package/dist/planmagnet/create/CreateDialogs.d.ts.map +1 -1
- package/dist/planmagnet/create/CreateDialogs.js +455 -116
- package/dist/planmagnet/create/CreateDialogs.js.map +1 -1
- package/dist/planmagnet/dependency/DependencyPanel.d.ts +6 -0
- package/dist/planmagnet/dependency/DependencyPanel.d.ts.map +1 -0
- package/dist/planmagnet/dependency/DependencyPanel.js +310 -0
- package/dist/planmagnet/dependency/DependencyPanel.js.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +171 -0
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js +232 -0
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js.map +1 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts +2 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +93 -0
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +127 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +129 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +132 -0
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +181 -0
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js +242 -0
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +302 -0
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +335 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +154 -0
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +124 -138
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +221 -0
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +279 -0
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js +178 -0
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +157 -0
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js +315 -0
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +186 -0
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js +164 -0
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js +348 -0
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +130 -103
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +4 -4
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +4 -4
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +6 -6
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +325 -189
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +81 -72
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.js +278 -0
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js +191 -0
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +5 -5
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js +4 -4
- package/dist/planmagnet/pages/TasksImportPagePage.js +5 -5
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +161 -137
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.js +124 -113
- package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +263 -0
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js +254 -0
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.js +165 -0
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js +316 -0
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js.map +1 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js +208 -0
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js.map +1 -0
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts +0 -5
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts.map +1 -1
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +47 -89
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.js +24 -24
- package/dist/planmagnet/time/TaskTimePanel.d.ts +7 -0
- package/dist/planmagnet/time/TaskTimePanel.d.ts.map +1 -0
- package/dist/planmagnet/time/TaskTimePanel.js +104 -0
- package/dist/planmagnet/time/TaskTimePanel.js.map +1 -0
- package/dist/planmagnet/time/TimeEntryControls.d.ts +37 -0
- package/dist/planmagnet/time/TimeEntryControls.d.ts.map +1 -0
- package/dist/planmagnet/time/TimeEntryControls.js +338 -0
- package/dist/planmagnet/time/TimeEntryControls.js.map +1 -0
- package/dist/planmagnet/time/TimesheetControls.d.ts +18 -0
- package/dist/planmagnet/time/TimesheetControls.d.ts.map +1 -0
- package/dist/planmagnet/time/TimesheetControls.js +244 -0
- package/dist/planmagnet/time/TimesheetControls.js.map +1 -0
- package/dist/planmagnet/time/timeShared.d.ts +29 -0
- package/dist/planmagnet/time/timeShared.d.ts.map +1 -0
- package/dist/planmagnet/time/timeShared.js +34 -0
- package/dist/planmagnet/time/timeShared.js.map +1 -0
- package/dist/planmagnet/utils/rowNavigation.js +5 -2
- package/dist/planmagnet/utils/rowNavigation.js.map +1 -1
- 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":";;;;;;;;;;;;;;;AA4BA,IAAM,IAAW,CAAG;;;;;;;;;;;;;;;;;;;GAqBd,IAAS,CAAG;;;;;;;;;;;;AA2BlB,SAAS,EAAO,GAA2C;AACzD,QAAO;EACL,MAAM,EAAK;EACX,aAAa,EAAK,eAAe;EACjC,WAAW,EAAK,aAAa;EAC7B,aAAa,EAAK;EAClB,YAAY,EAAkB,EAAK,WAAW;EAC9C,SAAS,EAAe,EAAK,QAAQ;EACtC;;AAGH,SAAgB,IAAyC;CACvD,IAAM,IAAS,GAAa,EACtB,EAAE,mBAAgB,GAAe,EACjC,EAAE,SAAM,YAAS,aAAU,EAC/B,GACA;EACE,WAAW,EAAE,IAAI,KAAU,IAAI;EAC/B,MAAM,CAAC;EACP,aAAa;EACd,CACF,EACK,CAAC,GAAQ,EAAE,SAAS,OAAY,EAAY,GAAQ,EACxD,gBAAgB,GACjB,CAAC,EACI,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAO,KAAY,EAAS,GAAM,EAEnC,IAAO,GAAM,4BAA4B,MACzC,CAAC,GAAM,KAAW,EAAyC,KAAK,EAChE,CAAC,GAAW,KAAgB,EAAwB,KAAK;AAW/D,KALI,KAAQ,MAAc,EAAK,OAC7B,EAAa,EAAK,GAAG,EACrB,EAAQ,EAAO,EAAK,CAAC,GAGnB,CAAC,EACH,QACE,kBAAC,OAAD;EAAK,WAAU;YAA4B;EAA+C,CAAA;AAE9F,KAAI,KAAW,CAAC,EACd,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAK,WAAU,kFAAmF,CAAA;EAC9F,CAAA;AAEV,KAAI,EACF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAAsC,yCACE,EAAM,QACxC;;AAEV,KAAI,CAAC,KAAQ,CAAC,EACZ,QAAO,kBAAC,OAAD;EAAK,WAAU;YAA4B;EAAgC,CAAA;CAEpF,IAAM,IAAa,YAAY;AAE7B,EADA,EAAa,KAAK,EAClB,EAAS,GAAM;EACf,IAAM,IAAU,EAAO,EAAK,EACtB,IAAiC,EAAE;AAIzC,EAHI,EAAK,KAAK,MAAM,KAAK,EAAQ,SAAM,EAAM,OAAO,EAAK,KAAK,MAAM,GAChE,EAAK,YAAY,MAAM,KAAK,EAAQ,YAAY,MAAM,KACxD,EAAM,cAAc,EAAK,YAAY,MAAM,IAAI,OAC7C,EAAK,gBAAgB,EAAQ,gBAAa,EAAM,cAAc,EAAK;EACvE,IAAM,IAAa,EAAgB,EAAK,WAAW;AACnD,EACE,KAAK,UAAU,KAAc,KAAK,KAClC,KAAK,UAAU,EAAgB,EAAQ,WAAW,IAAI,KAAK,KAE3D,EAAM,aAAa,KAAc;EACnC,IAAM,IAAU,EAAa,EAAK,QAAQ;AAG1C,MAFI,KAAK,UAAU,EAAQ,KAAK,KAAK,UAAU,EAAa,EAAQ,QAAQ,CAAC,KAC3E,EAAM,UAAU,IACd,OAAO,KAAK,EAAM,CAAC,WAAW,GAAG;AACnC,KAAS,GAAK;AACd;;AAEF,MAAI;AAEF,GADA,MAAM,EAAa,EAAO,EAAE,WAAW;IAAE,IAAI,EAAK;IAAI;IAAO,EAAE,CAAC,CAAC,EACjE,EAAS,GAAK;WACP,GAAG;AACV,KAAa,aAAa,QAAQ,EAAE,UAAU,+BAA+B;;;AAIjF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eAA0B,EAAK;KAAU,CAAA,EACvD,kBAAC,KAAD;KAAG,WAAU;eAAiC,EAAK,SAAS,QAAQ;KAAsB,CAAA,CACtF,EAAA,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QAAyB,QAAQ,EAAK;QAAI,WAAW,EAAK,aAAa,KAAA;QAAa,CAAA;OACpF,kBAAC,GAAD;QAA4B,QAAQ,EAAK;QAAI,QAAQ,EAAK;QAAU,CAAA;OACpE,kBAAC,GAAD;QAA4B,QAAQ,EAAK;QAAI,MAAM,EAAK;QAAQ,CAAA;OAC5D;;KACF,CAAA,CACF;;GAEL,KAAa,kBAAC,GAAD,EAAW,SAAS,GAAa,CAAA;GAC9C,KAAS,CAAC,KAAa,kBAAC,KAAD;IAAG,WAAU;cAAgC;IAAU,CAAA;GAE/E,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;IAAa,WAAU;cAAvB,CACE,kBAAC,GAAD;KACQ;KACN,WAAW,MAAS;AAElB,MADA,EAAQ,EAAK,EACb,EAAS,GAAM;;KAEjB,eAAA;KACA,CAAA,EACF,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MACE,MAAK;MACL,eAAe,KAAK,GAAY;MAChC,UAAU;MACV,eAAY;gBAJd,CAME,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAChC,IAAS,YAAY,eACf;;KACL,CAAA,CACM;MACT,EAAA,CAAA;GAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAW,WAAU;cAArB,CACE,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA,EAAA,oBAErB;OACD,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAwC;IAAa,QAAQ,EAAK;IAAM,CAAA,EAC5D,CAAA,CACT,EAAA,CAAA;GACH"}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"CompetitorsCompetitorDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/CompetitorsCompetitorDetailPagePage.tsx"],"names":[],"mappings":"AAoCA,wBAAgB,mCAAmC,4CA0HlD"}
|