@evenicanpm/admin-integrate 1.2.2 → 1.3.0

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 (209) hide show
  1. package/documents/ConfigImport/configuration-import.ts +54 -0
  2. package/documents/CopyProcess/copy.ts +25 -0
  3. package/documents/Endpoint/fragments.ts +9 -0
  4. package/documents/Endpoint/list.ts +22 -0
  5. package/documents/Process/fragments.ts +22 -0
  6. package/documents/Process/get-process-details.ts +73 -0
  7. package/documents/Process/list.ts +24 -0
  8. package/documents/ProcessConfig/fragments.ts +116 -0
  9. package/documents/ProcessConfig/read.ts +35 -0
  10. package/documents/ProcessExecution/fragments.ts +12 -0
  11. package/documents/ProcessExecution/list.ts +30 -1
  12. package/documents/ProcessExecutionDetails/fragments.ts +96 -0
  13. package/documents/ProcessExecutionDetails/read.ts +12 -0
  14. package/documents/ProcessScheduleGroup/read.ts +43 -0
  15. package/documents/ProcessTask/fragments.ts +285 -0
  16. package/documents/ProcessTask/read.ts +12 -0
  17. package/documents/ProcessTemplate/fragments.ts +69 -0
  18. package/documents/ProcessTemplate/list.ts +67 -0
  19. package/documents/ProcessTemplate/read.ts +12 -0
  20. package/documents/RunProcess/run.ts +11 -0
  21. package/package.json +4 -3
  22. package/src/api/Integrations/queries/get-process.query.ts +12 -12
  23. package/src/api/Integrations/queries/get-process.server.ts +7 -2
  24. package/src/api/dashboard/queries/get-process-executions.query.ts +6 -3
  25. package/src/api/dashboard/queries/get-process-executions.server.ts +1 -1
  26. package/src/api/execution-details/queries/get-process-execution-details.query.ts +46 -0
  27. package/src/api/execution-details/queries/get-process-execution-details.server.ts +11 -0
  28. package/src/api/execution-details/queries/get-process-executions-by-process.query.ts +48 -0
  29. package/src/api/execution-details/queries/get-process-executions-by-process.server.ts +11 -0
  30. package/src/api/execution-details/queries/index.ts +2 -0
  31. package/src/api/process/mutations/copy-process.mutation.ts +48 -0
  32. package/src/api/process/mutations/copy-process.server.ts +14 -0
  33. package/src/api/process/mutations/index.ts +2 -0
  34. package/src/api/process/mutations/run-process.mutation.ts +41 -0
  35. package/src/api/process/mutations/run-process.server.ts +14 -0
  36. package/src/api/process/queries/get-process-by-id.query.ts +85 -0
  37. package/src/api/process/queries/get-process-by-id.server.ts +20 -0
  38. package/src/api/process/queries/index.ts +4 -0
  39. package/src/api/process-config/mutation/index.ts +2 -0
  40. package/src/api/process-config/mutation/process-config-import.mutation.ts +33 -0
  41. package/src/api/process-config/mutation/process-config-import.server.ts +14 -0
  42. package/src/api/process-config/mutation/process-config-merge.mutation.ts +33 -0
  43. package/src/api/process-config/mutation/process-config-merge.server.ts +14 -0
  44. package/src/api/process-task/queries/get-process-task-by-id.query.ts +45 -0
  45. package/src/api/process-task/queries/get-process-task-by-id.server.ts +9 -0
  46. package/src/api/process-task/queries/index.ts +1 -0
  47. package/src/api/scheduler/mutation/create-process-schedule-group-details.mutation.ts +47 -0
  48. package/src/api/scheduler/mutation/create-process-schedule-group-details.server.ts +14 -0
  49. package/src/api/scheduler/mutation/index.ts +2 -0
  50. package/src/api/scheduler/mutation/update-process-schedule-group-details.mutation.ts +47 -0
  51. package/src/api/scheduler/mutation/update-process-schedule-group-details.server.ts +14 -0
  52. package/src/api/scheduler/queries/get-non-scheduled-processes.query.ts +48 -0
  53. package/src/api/scheduler/queries/get-non-scheduled-processes.server.ts +11 -0
  54. package/src/api/scheduler/queries/get-process-schedule-group-details.query.ts +6 -3
  55. package/src/api/scheduler/queries/get-process-schedule-group-details.server.ts +3 -3
  56. package/src/api/scheduler/queries/get-process-schedule.query.ts +6 -3
  57. package/src/api/scheduler/queries/get-process-schedule.server.ts +3 -3
  58. package/src/api/scheduler/queries/get-scheduled-processes.query.ts +6 -3
  59. package/src/api/scheduler/queries/get-scheduled-processes.server.ts +1 -1
  60. package/src/api/scheduler/queries/index.ts +3 -2
  61. package/src/api/templates/queries/get-process-template-groups.query.ts +48 -0
  62. package/src/api/templates/queries/get-process-template-groups.server.ts +11 -0
  63. package/src/api/templates/queries/get-process-template-records.query.ts +48 -0
  64. package/src/api/templates/queries/get-process-template-records.server.ts +11 -0
  65. package/src/api/templates/queries/get-process-template.query.ts +48 -0
  66. package/src/api/templates/queries/get-process-template.server.ts +9 -0
  67. package/src/api/templates/queries/get-process-templates.query.ts +45 -0
  68. package/src/api/templates/queries/get-process-templates.server.ts +9 -0
  69. package/src/api/templates/queries/index.ts +5 -0
  70. package/src/api/templates/queries/template-input-search.query.ts +34 -0
  71. package/src/api/templates/queries/template-input-search.server.ts +35 -0
  72. package/src/api/templates/queries/types.ts +28 -0
  73. package/src/components/breadcrumbs/breadcrumbs.tsx +32 -5
  74. package/src/components/button/outlined-icon-button.tsx +2 -2
  75. package/src/components/core/date-time-popover.tsx +11 -4
  76. package/src/components/core/drawer-buttons.tsx +52 -0
  77. package/src/components/core/edited-typography.tsx +1 -1
  78. package/src/components/core/index.ts +4 -2
  79. package/src/components/core/loading.tsx +1 -1
  80. package/src/components/core/status-tag.tsx +97 -0
  81. package/src/components/core/title-edit.tsx +18 -11
  82. package/src/components/dashboard-list/dashboard-list-row.tsx +22 -29
  83. package/src/components/dashboard-list/dashboard-list.tsx +19 -15
  84. package/src/components/data-table/table-header.tsx +5 -7
  85. package/src/components/data-table/table-pagination.tsx +1 -1
  86. package/src/components/data-table/table-row.tsx +1 -1
  87. package/src/components/data-table/table-skeleton.tsx +9 -4
  88. package/src/components/execution/execution-filter.ts +1 -1
  89. package/src/components/execution/execution-status-icon.tsx +7 -7
  90. package/src/components/execution/execution-tag.tsx +12 -77
  91. package/src/components/execution/index.ts +1 -1
  92. package/src/components/execution-history-drawer/execution-history-drawer.tsx +203 -0
  93. package/src/components/execution-history-drawer/executions-card.tsx +85 -0
  94. package/src/components/execution-history-drawer/index.ts +1 -0
  95. package/src/components/footer/footer.tsx +10 -6
  96. package/src/components/header/dashboard-list-header.tsx +12 -7
  97. package/src/components/header/execution-details-header.tsx +35 -26
  98. package/src/components/header/header.tsx +10 -3
  99. package/src/components/header/index.ts +1 -1
  100. package/src/components/header/integration-details-header.tsx +104 -45
  101. package/src/components/integration-list/index.ts +2 -1
  102. package/src/components/integration-list/integration-filter.ts +1 -1
  103. package/src/components/integration-list/integration-status-icon.tsx +7 -8
  104. package/src/components/integration-list/integration-tag.tsx +6 -50
  105. package/src/components/integration-list/list/integration-list-row.tsx +161 -0
  106. package/src/components/integration-list/list/integration-list-table.tsx +62 -0
  107. package/src/{pages/integrations/integration-list → components/integration-list/list}/integration-list.tsx +47 -51
  108. package/src/components/integration-view/animated-svg.tsx +31 -0
  109. package/src/components/integration-view/edges/default-edge.tsx +1 -1
  110. package/src/components/integration-view/elk-layout-options.ts +2 -2
  111. package/src/components/integration-view/elk-types.ts +35 -6
  112. package/src/components/integration-view/flow-types.tsx +10 -0
  113. package/src/components/integration-view/integration-view.tsx +990 -55
  114. package/src/components/integration-view/nodes/empty-node.tsx +65 -0
  115. package/src/components/integration-view/nodes/entry-node.tsx +98 -4
  116. package/src/components/integration-view/nodes/execution-entry-node.tsx +107 -0
  117. package/src/components/integration-view/nodes/execution-task-node.tsx +88 -0
  118. package/src/components/integration-view/nodes/group-node.tsx +19 -13
  119. package/src/components/integration-view/nodes/row-node.tsx +19 -0
  120. package/src/components/integration-view/nodes/task-node.tsx +14 -8
  121. package/src/components/integration-view/task-icon.tsx +193 -0
  122. package/src/components/integration-view/temp-data/initialElements.tsx +36 -32
  123. package/src/components/integration-view/types.ts +2 -2
  124. package/src/components/layouts/main-layout.tsx +2 -3
  125. package/src/components/layouts/root-container.tsx +3 -6
  126. package/src/components/link-cards/link-card.tsx +15 -4
  127. package/src/components/link-cards/styles.ts +1 -1
  128. package/src/components/list-filter/date-filter.tsx +4 -3
  129. package/src/components/list-filter/date-range-filter.tsx +11 -5
  130. package/src/components/list-filter/index.ts +1 -1
  131. package/src/components/list-filter/list-filter.tsx +30 -25
  132. package/src/components/list-filter/multi-select-filter.tsx +11 -10
  133. package/src/components/list-filter/select-filter.tsx +13 -8
  134. package/src/components/scheduler/day-selector.tsx +29 -15
  135. package/src/components/scheduler/day-tag.tsx +14 -51
  136. package/src/components/scheduler/index.ts +2 -1
  137. package/src/components/scheduler/schedule-drawer/details-reducer.ts +217 -0
  138. package/src/components/scheduler/schedule-drawer/schedule-details-integrations.tsx +503 -0
  139. package/src/{pages → components}/scheduler/schedule-drawer/schedule-details-main.tsx +136 -99
  140. package/src/components/scheduler/schedule-drawer/schedule-details-name.tsx +94 -0
  141. package/src/{pages → components}/scheduler/schedule-drawer/schedule-details-skeleton.tsx +1 -2
  142. package/src/{pages → components}/scheduler/schedule-drawer/schedule-details.tsx +9 -13
  143. package/src/components/scheduler/schedule-drawer/schedule-drawer-group.tsx +218 -0
  144. package/src/{pages → components}/scheduler/schedule-drawer/schedule-drawer-legacy.tsx +6 -25
  145. package/src/components/scheduler/schedule-drawer/schedule-drawer.tsx +116 -0
  146. package/src/components/scheduler/schedule-drawer/sortable-integration-row.tsx +130 -0
  147. package/src/components/scheduler/schedule-filter.ts +1 -1
  148. package/src/components/scheduler/schedule-icon.tsx +5 -6
  149. package/src/components/scheduler/schedule-integration-icon.tsx +31 -0
  150. package/src/components/templates/index.ts +1 -0
  151. package/src/components/templates/inputs/index.tsx +1351 -0
  152. package/src/components/templates/template-filter.ts +5 -0
  153. package/src/components/templates/templates-list/index.ts +1 -0
  154. package/src/components/templates/templates-list/templates-list-row.tsx +55 -0
  155. package/src/components/templates/templates-list/templates-list-table.tsx +58 -0
  156. package/src/components/templates/templates-list/templates-list.tsx +253 -0
  157. package/src/components/templates/types.tsx +75 -0
  158. package/src/components/templates/wizard.tsx +689 -0
  159. package/src/hooks/use-breadcrumbs.ts +1 -1
  160. package/src/hooks/use-recurrence.tsx +1 -2
  161. package/src/pages/dashboard/dashboard-link-cards.tsx +8 -11
  162. package/src/pages/dashboard/dashboard-list-sections.tsx +7 -9
  163. package/src/pages/dashboard/dashboard.tsx +1 -2
  164. package/src/pages/execution-details/execution-details.tsx +211 -14
  165. package/src/pages/execution-details/task-execution-details.tsx +160 -0
  166. package/src/pages/execution-details/task-execution-drawer.tsx +54 -0
  167. package/src/pages/executions/executions-list/executions-list-row.tsx +21 -27
  168. package/src/pages/executions/executions-list/executions-list-table.tsx +28 -35
  169. package/src/pages/executions/executions-list/executions-list.tsx +24 -18
  170. package/src/pages/executions/executions.tsx +11 -15
  171. package/src/pages/integration-create/index.ts +1 -0
  172. package/src/pages/integration-create/integration-create.tsx +174 -0
  173. package/src/pages/integration-create/pre-creation-step.tsx +12 -0
  174. package/src/pages/integration-create/select-step.tsx +105 -0
  175. package/src/pages/integration-create/template-list-step.tsx +77 -0
  176. package/src/pages/integration-create/wizard-step.tsx +50 -0
  177. package/src/pages/integration-details/import-process/copy-tasks-list.tsx +265 -0
  178. package/src/pages/integration-details/import-process/copy-tasks-row.tsx +77 -0
  179. package/src/pages/integration-details/import-process/import-confirm.tsx +61 -0
  180. package/src/pages/integration-details/import-process/import-drawer.tsx +48 -0
  181. package/src/pages/integration-details/import-process/import-process-reducer.ts +90 -0
  182. package/src/pages/integration-details/import-process/import-process.tsx +149 -0
  183. package/src/pages/integration-details/index.ts +1 -0
  184. package/src/pages/integration-details/integration-details.tsx +221 -0
  185. package/src/pages/integration-details/task-drawer/add-task.tsx +120 -0
  186. package/src/pages/integration-details/task-drawer/edit-task.tsx +175 -0
  187. package/src/pages/integration-details/task-drawer/task-drawer.tsx +139 -0
  188. package/src/pages/integration-details/task-drawer/task-reducer.ts +73 -0
  189. package/src/pages/integrations/integrations.tsx +11 -14
  190. package/src/pages/scheduler/scheduler.tsx +12 -24
  191. package/src/pages/scheduler/schedules-list/schedules-list-row.tsx +27 -37
  192. package/src/pages/scheduler/schedules-list/schedules-list-table.tsx +27 -42
  193. package/src/pages/scheduler/schedules-list/schedules-list.tsx +48 -21
  194. package/src/utils/date-functions.ts +69 -0
  195. package/src/utils/slugify.ts +3 -0
  196. package/tsconfig.json +12 -4
  197. package/src/hooks/use-timestamp.tsx +0 -25
  198. package/src/pages/integrations/integration-list/integration-list-row.tsx +0 -147
  199. package/src/pages/integrations/integration-list/integration-list-table.tsx +0 -78
  200. package/src/pages/scheduler/schedule-drawer/schedule-details-integrations.tsx +0 -227
  201. package/src/pages/scheduler/schedule-drawer/schedule-details-name.tsx +0 -77
  202. package/src/pages/scheduler/schedule-drawer/schedule-drawer-buttons.tsx +0 -72
  203. package/src/pages/scheduler/schedule-drawer/schedule-drawer-group.tsx +0 -103
  204. package/src/pages/scheduler/schedule-drawer/schedule-drawer.tsx +0 -101
  205. package/src/pages/scheduler/schedule-drawer/sortable-integration-row.tsx +0 -93
  206. /package/src/{pages/integrations/integration-list → components/integration-list/list}/index.ts +0 -0
  207. /package/src/{pages → components}/scheduler/schedule-drawer/edited/edited-types.ts +0 -0
  208. /package/src/{pages → components}/scheduler/schedule-drawer/edited/index.ts +0 -0
  209. /package/src/{pages → components}/scheduler/schedule-drawer/index.ts +0 -0
@@ -1,38 +1,43 @@
1
- import { useTranslations } from "next-intl";
2
- import { useState } from "react";
3
-
4
- // Api
5
- import { ProcessScheduleGroupDetailsUpdate } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
6
-
7
- // MUI
8
- import { Theme, useTheme } from "@mui/material";
1
+ import type { ProcessScheduleGroupDetailsUpdate } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
2
+ import {
3
+ DateTimePopover,
4
+ EditedTypography,
5
+ } from "@evenicanpm/admin-integrate/components/core";
6
+ import {
7
+ DaySelector,
8
+ type IsDay,
9
+ } from "@evenicanpm/admin-integrate/components/scheduler";
10
+ import { InfoOutlined } from "@mui/icons-material";
9
11
  import {
10
12
  Box,
13
+ MenuItem,
14
+ Select,
15
+ type SelectChangeEvent,
11
16
  Stack,
12
- Typography,
13
17
  Switch,
14
18
  TextField,
15
- Select,
16
- MenuItem,
17
- SelectChangeEvent,
19
+ type Theme,
20
+ Typography,
21
+ useTheme,
18
22
  } from "@mui/material";
19
23
  import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker";
20
- import { InfoOutlined } from "@mui/icons-material";
21
-
22
- // Custom components
23
- import { DaySelector } from "@evenicanpm/admin-integrate/components/scheduler";
24
+ import { useTranslations } from "next-intl";
25
+ import { useState } from "react";
24
26
  import {
25
- DateTimePopover,
26
- EditedTypography,
27
- } from "@evenicanpm/admin-integrate/components/core";
28
-
29
- // Types
30
- import { Edited } from "./edited";
31
- import { IsDay } from "@evenicanpm/admin-integrate/components/scheduler";
27
+ type DetailsAction,
28
+ DetailsActionType,
29
+ type EditDaysAction,
30
+ type EditRecurrenceAction,
31
+ type EditStartDateAction,
32
+ type ErrorsState,
33
+ type SetErrorsAction,
34
+ } from "./details-reducer";
35
+ import type { Edited } from "./edited";
32
36
 
33
37
  interface Props {
34
38
  details: ProcessScheduleGroupDetailsUpdate;
35
- setDetails: (newDetails: ProcessScheduleGroupDetailsUpdate) => void;
39
+ errors?: ErrorsState;
40
+ dispatchDetails?: (value: DetailsAction) => void;
36
41
  edited: Edited;
37
42
  setEdited: (newEdited: Edited) => void;
38
43
  readOnly?: boolean;
@@ -44,13 +49,6 @@ export default function ScheduleDetailsMain(props: Props) {
44
49
  const theme = useTheme();
45
50
  const styles = getStyles(theme);
46
51
 
47
- const [dateError, setDateError] = useState<string | null>(null);
48
-
49
- const [interval, setInterval] = useState<string>(
50
- props.details.interval?.toString() || "1",
51
- );
52
- const [intervalError, setIntervalError] = useState<string | null>(null);
53
-
54
52
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
55
53
  const open = Boolean(anchorEl);
56
54
 
@@ -63,89 +61,128 @@ export default function ScheduleDetailsMain(props: Props) {
63
61
  };
64
62
 
65
63
  const handleEnabledChange = () => {
66
- props.setDetails({
67
- ...props.details,
68
- isDisabled: !props.details.isDisabled,
69
- });
70
- if (!props.edited.enabled) {
71
- props.setEdited({
72
- ...props.edited,
73
- enabled: true,
74
- });
64
+ if (props.dispatchDetails) {
65
+ props.dispatchDetails({ type: DetailsActionType.TOGGLE_ENABLED });
66
+
67
+ if (!props.edited.enabled) {
68
+ props.setEdited({
69
+ ...props.edited,
70
+ enabled: true,
71
+ });
72
+ }
75
73
  }
76
74
  };
77
75
 
78
76
  const handleDayChange = (newDays: IsDay) => {
79
- props.setDetails({
80
- ...props.details,
81
- ...newDays,
82
- });
83
- if (!props.edited.days) {
84
- props.setEdited({
85
- ...props.edited,
86
- days: true,
87
- });
77
+ if (props.dispatchDetails) {
78
+ const action: EditDaysAction = {
79
+ type: DetailsActionType.EDIT_DAYS,
80
+ isDay: newDays,
81
+ };
82
+ props.dispatchDetails(action);
83
+
84
+ if (!props.edited.days) {
85
+ props.setEdited({
86
+ ...props.edited,
87
+ days: true,
88
+ });
89
+ }
88
90
  }
89
91
  };
90
92
 
91
93
  const handleStartDateChange = (newStartDate: string | null) => {
92
- if (newStartDate) {
93
- try {
94
- const date = new Date(newStartDate);
95
- props.setDetails({
96
- ...props.details,
97
- startDate: date.toISOString(),
98
- });
99
- setDateError(null);
100
- if (!props.edited.startDate) {
101
- props.setEdited({
102
- ...props.edited,
103
- startDate: true,
104
- });
94
+ if (props.dispatchDetails) {
95
+ const setErrorAction: SetErrorsAction = {
96
+ type: DetailsActionType.SET_ERRORS,
97
+ errors: { startDate: true },
98
+ };
99
+
100
+ if (newStartDate) {
101
+ try {
102
+ const date = new Date(newStartDate);
103
+ const dateAction: EditStartDateAction = {
104
+ type: DetailsActionType.EDIT_START_DATE,
105
+ startDate: date.toISOString(),
106
+ };
107
+ props.dispatchDetails(dateAction);
108
+
109
+ const clearErrorAction: SetErrorsAction = {
110
+ type: DetailsActionType.SET_ERRORS,
111
+ errors: { startDate: false },
112
+ };
113
+ props.dispatchDetails(clearErrorAction);
114
+
115
+ if (!props.edited.startDate) {
116
+ props.setEdited({
117
+ ...props.edited,
118
+ startDate: true,
119
+ });
120
+ }
121
+ } catch {
122
+ props.dispatchDetails(setErrorAction);
105
123
  }
106
- } catch {
107
- setDateError(t("invalidDate"));
124
+ } else {
125
+ props.dispatchDetails(setErrorAction);
108
126
  }
109
- } else {
110
- setDateError(t("invalidDate"));
111
127
  }
112
128
  };
113
129
 
114
130
  const handleStartDateError = (newError: string | null) => {
115
- setDateError(newError ? t("invalidDate") : null);
131
+ if (newError && props.dispatchDetails) {
132
+ const action: SetErrorsAction = {
133
+ type: DetailsActionType.SET_ERRORS,
134
+ errors: { startDate: true },
135
+ };
136
+ props.dispatchDetails(action);
137
+ }
116
138
  };
117
139
 
118
140
  const handleIntervalChange = (event: React.ChangeEvent<HTMLInputElement>) => {
119
- setInterval(event.target.value);
120
- const newInterval = Number(event.target.value);
141
+ if (props.dispatchDetails) {
142
+ const newInterval = Number(event.target.value);
121
143
 
122
- if (!isNaN(newInterval)) {
123
- props.setDetails({
124
- ...props.details,
125
- interval: newInterval,
126
- });
144
+ if (!Number.isNaN(newInterval) && newInterval > 0) {
145
+ const intervalAction: EditRecurrenceAction = {
146
+ type: DetailsActionType.EDIT_RECURRENCE,
147
+ interval: newInterval,
148
+ };
149
+ props.dispatchDetails(intervalAction);
150
+
151
+ const clearErrorAction: SetErrorsAction = {
152
+ type: DetailsActionType.SET_ERRORS,
153
+ errors: { interval: false },
154
+ };
155
+ props.dispatchDetails(clearErrorAction);
156
+
157
+ if (!props.edited.recurrence) {
158
+ props.setEdited({
159
+ ...props.edited,
160
+ recurrence: true,
161
+ });
162
+ }
163
+ } else {
164
+ const setErrorAction: SetErrorsAction = {
165
+ type: DetailsActionType.SET_ERRORS,
166
+ errors: { interval: true },
167
+ };
168
+ props.dispatchDetails(setErrorAction);
169
+ }
170
+ }
171
+ };
172
+
173
+ const handleIntervalUnitChange = (event: SelectChangeEvent) => {
174
+ if (props.dispatchDetails) {
175
+ const action: EditRecurrenceAction = {
176
+ type: DetailsActionType.EDIT_RECURRENCE,
177
+ intervalUnitId: event.target.value,
178
+ };
179
+ props.dispatchDetails(action);
127
180
  if (!props.edited.recurrence) {
128
181
  props.setEdited({
129
182
  ...props.edited,
130
183
  recurrence: true,
131
184
  });
132
185
  }
133
- setIntervalError(null);
134
- } else {
135
- setIntervalError(t("invalidInterval"));
136
- }
137
- };
138
-
139
- const handleIntervalUnitChange = (event: SelectChangeEvent) => {
140
- props.setDetails({
141
- ...props.details,
142
- intervalUnitId: event.target.value,
143
- });
144
- if (!props.edited.recurrence) {
145
- props.setEdited({
146
- ...props.edited,
147
- recurrence: true,
148
- });
149
186
  }
150
187
  };
151
188
 
@@ -156,13 +193,13 @@ export default function ScheduleDetailsMain(props: Props) {
156
193
  <Box>
157
194
  <Stack direction="row" spacing={1} alignItems="flex-end">
158
195
  <Typography variant="body1">
159
- {props.details.isDisabled ? t("disabled") : t("enabled")}
196
+ {props.details?.isDisabled ? t("disabled") : t("enabled")}
160
197
  </Typography>
161
198
  <EditedTypography edited={props.edited.enabled} />
162
199
  </Stack>
163
200
  <Switch
164
201
  color="info"
165
- checked={!props.details.isDisabled}
202
+ checked={!props.details?.isDisabled}
166
203
  onChange={handleEnabledChange}
167
204
  disabled={props.readOnly}
168
205
  />
@@ -201,19 +238,19 @@ export default function ScheduleDetailsMain(props: Props) {
201
238
  </Stack>
202
239
  <DateTimePicker
203
240
  sx={styles.startDatePicker}
204
- value={props.details.startDate}
241
+ value={props.details?.startDate}
205
242
  onChange={handleStartDateChange}
206
243
  onError={handleStartDateError}
207
244
  views={["year", "month", "day", "hours", "minutes", "seconds"]}
208
245
  slotProps={{
209
246
  textField: {
210
- helperText: dateError || "",
247
+ helperText: props.errors?.startDate ? t("invalidDate") : "",
211
248
  },
212
249
  }}
213
250
  disabled={props.readOnly}
214
251
  />
215
252
  <DateTimePopover
216
- dateIsoString={props.details.startDate}
253
+ dateIsoString={props.details?.startDate}
217
254
  sx={{ pointerEvents: "none" }}
218
255
  open={open}
219
256
  anchorEl={anchorEl}
@@ -238,10 +275,10 @@ export default function ScheduleDetailsMain(props: Props) {
238
275
  </Stack>
239
276
  <Stack direction="row" spacing={1} alignItems="flex-start">
240
277
  <TextField
241
- value={interval}
278
+ value={props.details?.interval as number}
242
279
  onChange={handleIntervalChange}
243
- error={intervalError !== null}
244
- helperText={intervalError || ""}
280
+ error={props.errors?.interval}
281
+ helperText={props.errors?.interval ? t("invalidInterval") : ""}
245
282
  slotProps={{
246
283
  htmlInput: {
247
284
  sx: {
@@ -253,7 +290,7 @@ export default function ScheduleDetailsMain(props: Props) {
253
290
  disabled={props.readOnly}
254
291
  />
255
292
  <Select
256
- value={props.details.intervalUnitId || "1"}
293
+ value={props.details?.intervalUnitId as string}
257
294
  onChange={handleIntervalUnitChange}
258
295
  sx={styles.recurrenceUnit}
259
296
  disabled={props.readOnly}
@@ -0,0 +1,94 @@
1
+ import type { ProcessScheduleGroupDetailsUpdate } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
2
+ import {
3
+ EditedTypography,
4
+ TitleEdit,
5
+ } from "@evenicanpm/admin-integrate/components/core";
6
+ import { ScheduleIcon } from "@evenicanpm/admin-integrate/components/scheduler";
7
+ import { Box, Stack, type Theme, Typography, useTheme } from "@mui/material";
8
+ import { useTranslations } from "next-intl";
9
+ import {
10
+ type DetailsAction,
11
+ DetailsActionType,
12
+ type EditNameAction,
13
+ type ErrorsState,
14
+ type SetErrorsAction,
15
+ } from "./details-reducer";
16
+ import type { Edited } from "./edited";
17
+
18
+ interface Props {
19
+ details: ProcessScheduleGroupDetailsUpdate;
20
+ errors?: ErrorsState;
21
+ dispatchDetails?: (value: DetailsAction) => void;
22
+ edited: Edited;
23
+ setEdited: (newEdited: Edited) => void;
24
+ readOnly?: boolean;
25
+ }
26
+
27
+ export default function ScheduleDetailsName(props: Props) {
28
+ const t = useTranslations("Integrate.Scheduler");
29
+
30
+ const theme = useTheme();
31
+ const styles = getStyles(theme);
32
+
33
+ const onConfirm = (input: string) => {
34
+ if (props.dispatchDetails && input !== props.details?.name) {
35
+ const nameAction: EditNameAction = {
36
+ type: DetailsActionType.EDIT_NAME,
37
+ name: input,
38
+ };
39
+ props.dispatchDetails(nameAction);
40
+
41
+ const clearErrorAction: SetErrorsAction = {
42
+ type: DetailsActionType.SET_ERRORS,
43
+ errors: { name: false },
44
+ };
45
+ props.dispatchDetails(clearErrorAction);
46
+
47
+ if (!props.edited.name) {
48
+ props.setEdited({
49
+ ...props.edited,
50
+ name: true,
51
+ });
52
+ }
53
+ }
54
+ };
55
+
56
+ return (
57
+ <Box sx={styles.main}>
58
+ <Stack direction="row" spacing={1} sx={styles.stack}>
59
+ <Box display="flex" justifyContent="center" alignItems="center">
60
+ <ScheduleIcon
61
+ isDisabled={props.details?.isDisabled || false}
62
+ isLegacy={props.readOnly || false}
63
+ enablePopover
64
+ />
65
+ </Box>
66
+ <TitleEdit
67
+ title={props.details?.name || t("untitled")}
68
+ onConfirm={onConfirm}
69
+ readOnly={props.readOnly}
70
+ fullWidth
71
+ />
72
+ </Stack>
73
+ <Typography
74
+ variant="caption"
75
+ color="error"
76
+ display={props.errors?.name ? "block" : "none"}
77
+ >
78
+ {t("emptyName")}
79
+ </Typography>
80
+ <EditedTypography edited={props.edited.name} />
81
+ </Box>
82
+ );
83
+ }
84
+
85
+ const getStyles = (theme: Theme) => {
86
+ return {
87
+ main: {
88
+ marginBottom: theme.spacing(2),
89
+ },
90
+ stack: {
91
+ minHeight: theme.spacing(7),
92
+ },
93
+ };
94
+ };
@@ -1,6 +1,5 @@
1
1
  // MUI
2
- import { Theme, useTheme } from "@mui/material";
3
- import { Skeleton, Stack, Box } from "@mui/material";
2
+ import { Box, Skeleton, Stack, type Theme, useTheme } from "@mui/material";
4
3
 
5
4
  export default function ScheduleDetailsSkeleton() {
6
5
  const theme = useTheme();
@@ -1,24 +1,20 @@
1
- // Api
2
- import { ProcessScheduleGroupDetailsUpdate } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
3
-
4
- // MUI
5
- import { Theme, useTheme } from "@mui/material";
6
- import { Box } from "@mui/material";
7
-
8
- // Local components
9
- import ScheduleDetailsName from "./schedule-details-name";
1
+ import type { ProcessScheduleGroupDetailsUpdate } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
2
+ import { Box, type Theme, useTheme } from "@mui/material";
3
+ import type { DetailsAction, ErrorsState } from "./details-reducer";
4
+ import type { Edited } from "./edited";
10
5
  import ScheduleDetailsMain from "./schedule-details-main";
11
-
12
- // Types
13
- import { Edited } from "./edited";
6
+ import ScheduleDetailsName from "./schedule-details-name";
7
+ import type { DrawerOpen } from "./schedule-drawer";
14
8
 
15
9
  interface Props {
16
10
  id: string;
17
11
  details: ProcessScheduleGroupDetailsUpdate;
18
- setDetails: (newDetails: ProcessScheduleGroupDetailsUpdate) => void;
12
+ errors?: ErrorsState;
13
+ dispatchDetails?: (value: DetailsAction) => void;
19
14
  edited: Edited;
20
15
  setEdited: (newEdited: Edited) => void;
21
16
  readOnly?: boolean;
17
+ drawerOpen?: DrawerOpen;
22
18
  }
23
19
 
24
20
  export default function ScheduleDetails(props: Props) {
@@ -0,0 +1,218 @@
1
+ import type {
2
+ GetProcessScheduleGroupDetailsQuery,
3
+ ProcessScheduleGroupDetailsCreate,
4
+ ProcessScheduleGroupDetailsUpdate,
5
+ } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
6
+ import {
7
+ createProcessScheduleGroupDetails,
8
+ updateProcessScheduleGroupDetails,
9
+ } from "@evenicanpm/admin-integrate/api/scheduler/mutation";
10
+ import { getProcessScheduleGroupDetails } from "@evenicanpm/admin-integrate/api/scheduler/queries";
11
+ import { DrawerButtons } from "@evenicanpm/admin-integrate/components/core";
12
+ import { Add, Save } from "@mui/icons-material";
13
+ import { Button, Divider, type Theme, useTheme } from "@mui/material";
14
+ import { useEffect } from "react";
15
+ import {
16
+ type DetailsAction,
17
+ DetailsActionType,
18
+ type DetailsState,
19
+ type InitAction,
20
+ } from "./details-reducer";
21
+ import type { Edited } from "./edited";
22
+ import ScheduleDetails from "./schedule-details";
23
+ import ScheduleDetailsIntegrations from "./schedule-details-integrations";
24
+ import ScheduleDetailsSkeleton from "./schedule-details-skeleton";
25
+ import type { DrawerOpen } from "./schedule-drawer";
26
+
27
+ interface Props {
28
+ drawerOpen: DrawerOpen;
29
+ detailsState: DetailsState;
30
+ dispatchDetails: (value: DetailsAction) => void;
31
+ edited: Edited;
32
+ setEdited: (newEdited: Edited) => void;
33
+ handleClose: (isUpdate?: boolean) => void;
34
+ handleSave?: (loading: boolean) => void;
35
+ }
36
+
37
+ export default function ScheduleDrawerGroup(props: Props) {
38
+ const theme = useTheme();
39
+ const styles = getStyles(theme);
40
+
41
+ const { data, refetch, isRefetching } =
42
+ getProcessScheduleGroupDetails.useData({
43
+ id: props.drawerOpen.id,
44
+ });
45
+
46
+ useEffect(() => {
47
+ if (data && !props.drawerOpen.addMode) {
48
+ const typedData = data as GetProcessScheduleGroupDetailsQuery;
49
+ if (typedData.processScheduleGroupDetails) {
50
+ const fetchedDetails = typedData.processScheduleGroupDetails;
51
+ const processes = fetchedDetails.processSchedule?.processes || [];
52
+ const newDetails = {
53
+ ...fetchedDetails,
54
+ processes,
55
+ };
56
+ delete newDetails.processSchedule;
57
+
58
+ const action: InitAction = {
59
+ type: DetailsActionType.INIT,
60
+ details: newDetails as ProcessScheduleGroupDetailsUpdate,
61
+ };
62
+ props.dispatchDetails(action);
63
+ }
64
+ }
65
+ }, [data]);
66
+
67
+ useEffect(() => {
68
+ refetch();
69
+ }, [props.drawerOpen]);
70
+
71
+ useEffect(() => {
72
+ if (
73
+ props.drawerOpen.addMode &&
74
+ props.detailsState &&
75
+ props.detailsState.details === null
76
+ ) {
77
+ props.dispatchDetails({ type: DetailsActionType.INIT_BLANK });
78
+ }
79
+ }, []);
80
+
81
+ const updateMutation = updateProcessScheduleGroupDetails();
82
+ const createMutation = createProcessScheduleGroupDetails();
83
+
84
+ const handleSave = () => {
85
+ if (props.detailsState?.details?.processes) {
86
+ // Look into moving sort updates into reducer action. State update using dispatch and api call for update should be sync calls
87
+ const input = {
88
+ ...props.detailsState.details,
89
+ processes: props.detailsState.details.processes.map(
90
+ ({ id }, index) => ({
91
+ id,
92
+ sort: index + 1,
93
+ }),
94
+ ),
95
+ };
96
+
97
+ if (props.handleSave) {
98
+ props.handleSave(true);
99
+ }
100
+
101
+ updateMutation.mutate(
102
+ {
103
+ input: input as ProcessScheduleGroupDetailsUpdate,
104
+ },
105
+ {
106
+ onSuccess: async () => {
107
+ props.handleClose(false);
108
+ if (props.handleSave) {
109
+ props.handleSave(false);
110
+ }
111
+ },
112
+ onError: (error) => {
113
+ console.error("Update failed:", error);
114
+ if (props.handleSave) {
115
+ props.handleSave(false);
116
+ }
117
+ },
118
+ },
119
+ );
120
+ }
121
+ };
122
+
123
+ const handleAdd = () => {
124
+ if (props.detailsState?.details?.processes) {
125
+ // Look into moving sort updates into reducer action. State update using dispatch and api call for update should be sync calls
126
+ const input = {
127
+ ...props.detailsState.details,
128
+ processes: props.detailsState.details.processes.map(
129
+ ({ id }, index) => ({
130
+ id,
131
+ sort: index + 1,
132
+ }),
133
+ ),
134
+ };
135
+
136
+ createMutation.mutate(
137
+ {
138
+ input: input as ProcessScheduleGroupDetailsCreate,
139
+ },
140
+ {
141
+ onSuccess: async () => {
142
+ props.handleClose(false);
143
+ },
144
+ onError: (error) => {
145
+ console.error("Create failed:", error);
146
+ },
147
+ },
148
+ );
149
+ }
150
+ };
151
+
152
+ const isEdited = Object.values(props.edited).some((value) => value);
153
+ const isError = props.detailsState?.errors
154
+ ? Object.values(props.detailsState.errors).some((value) => value)
155
+ : false;
156
+
157
+ return (
158
+ <>
159
+ <DrawerButtons handleClose={() => props.handleClose(true)}>
160
+ {!props.drawerOpen?.addMode && (
161
+ <Button
162
+ variant="contained"
163
+ color="info"
164
+ onClick={handleSave}
165
+ disabled={!isEdited || isError}
166
+ sx={{ padding: theme.spacing(0.6, 1.3) }}
167
+ >
168
+ <Save />
169
+ </Button>
170
+ )}
171
+ {props.drawerOpen?.addMode && (
172
+ <Button
173
+ variant="contained"
174
+ color="info"
175
+ onClick={handleAdd}
176
+ disabled={isError}
177
+ sx={{ padding: theme.spacing(0.6, 1.3) }}
178
+ >
179
+ <Add />
180
+ </Button>
181
+ )}
182
+ </DrawerButtons>
183
+ {props.detailsState?.details && !isRefetching ? (
184
+ <>
185
+ <ScheduleDetails
186
+ id={props.drawerOpen.id}
187
+ details={props.detailsState.details}
188
+ errors={props.detailsState.errors}
189
+ dispatchDetails={props.dispatchDetails}
190
+ edited={props.edited}
191
+ setEdited={props.setEdited}
192
+ drawerOpen={props.drawerOpen}
193
+ />
194
+ <Divider sx={styles.divider} />
195
+ <ScheduleDetailsIntegrations
196
+ data={data as GetProcessScheduleGroupDetailsQuery}
197
+ details={props.detailsState.details}
198
+ errors={props.detailsState.errors}
199
+ dispatchDetails={props.dispatchDetails}
200
+ edited={props.edited}
201
+ setEdited={props.setEdited}
202
+ defaultScheduledProcess={props.detailsState.defaultScheduledProcess}
203
+ />
204
+ </>
205
+ ) : (
206
+ <ScheduleDetailsSkeleton />
207
+ )}
208
+ </>
209
+ );
210
+ }
211
+
212
+ const getStyles = (_theme: Theme) => {
213
+ return {
214
+ divider: {
215
+ borderColor: "grey.400",
216
+ },
217
+ };
218
+ };