@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
@@ -0,0 +1,221 @@
1
+ import type {
2
+ ConfigExport,
3
+ GetProcessByIdQuery,
4
+ Process,
5
+ } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
6
+ import { getProcessById } from "@evenicanpm/admin-integrate/api/process/queries";
7
+ import { buildProcessByIdQueryKey } from "@evenicanpm/admin-integrate/api/process/queries/get-process-by-id.query";
8
+ import {
9
+ type Crumb,
10
+ IntegrateBreadcrumbs,
11
+ } from "@evenicanpm/admin-integrate/components/breadcrumbs";
12
+ import { Loading } from "@evenicanpm/admin-integrate/components/core";
13
+ import { IntegrationDetailsHeader } from "@evenicanpm/admin-integrate/components/header";
14
+ import IntegrationView from "@evenicanpm/admin-integrate/components/integration-view/integration-view";
15
+ import type { DrawerOpen } from "@evenicanpm/admin-integrate/components/scheduler/schedule-drawer/schedule-drawer";
16
+ import ScheduleDrawer from "@evenicanpm/admin-integrate/components/scheduler/schedule-drawer/schedule-drawer";
17
+ import SaveIcon from "@mui/icons-material/Save";
18
+ import { Box, Button, useTheme } from "@mui/material";
19
+ import { useParams } from "next/navigation";
20
+ import { useTranslations } from "next-intl";
21
+ import { useEffect, useReducer, useState } from "react";
22
+ import ImportDrawer from "./import-process/import-drawer";
23
+ import {
24
+ ImportActionType,
25
+ importReducer,
26
+ } from "./import-process/import-process-reducer";
27
+ import TaskDrawer from "./task-drawer/task-drawer";
28
+ import {
29
+ type EditAction,
30
+ TaskActionType,
31
+ TaskMode,
32
+ taskReducer,
33
+ } from "./task-drawer/task-reducer";
34
+
35
+ export default function IntegrationDetails() {
36
+ const t = useTranslations("Integrate");
37
+ const params = useParams<{ processId: string }>();
38
+ const theme = useTheme();
39
+
40
+ const [breadcrumbs, setBreadcrumbs] = useState<Crumb[]>([
41
+ {
42
+ name: t("Header.dashboard"),
43
+ url: "/e4integrate",
44
+ },
45
+ {
46
+ name: t("Header.integrations"),
47
+ url: "/e4integrate/integrations",
48
+ },
49
+ ]);
50
+
51
+ const [taskState, dispatchTaskState] = useReducer(taskReducer, {
52
+ open: false,
53
+ mode: TaskMode.NONE,
54
+ step: null,
55
+ });
56
+
57
+ const [importState, dispatchImportState] = useReducer(importReducer, {
58
+ open: false,
59
+ step: null,
60
+ alert: null,
61
+ loading: false,
62
+ });
63
+
64
+ // TODO: initialize config w/ result of configurationExport query. Local edits done on this state.
65
+ const [config, setConfig] = useState<ConfigExport | null>(null);
66
+ console.log("config", config); // TODO: remove when config export implemented.
67
+
68
+ const handleUpdateConfig = (newConfig: ConfigExport) => {
69
+ // TODO: update config state with newConfig from configMerge
70
+
71
+ // when config export is implemented, change functionality to instead update the config state, rather than replace it
72
+ // this is so we can do things like change a single task's name, because doing an overwrite will replace the new name
73
+ // since config merge will generate names for the tasks automatically.
74
+ // also don't want to do things like overwrite parallel processing group, sort, Process name, etc.
75
+ setConfig(newConfig);
76
+ };
77
+
78
+ const { data, isLoading } = getProcessById.useData(
79
+ {
80
+ id: params.processId,
81
+ },
82
+ {
83
+ queryKey: buildProcessByIdQueryKey.byInput({ id: params.processId }),
84
+ refetchOnWindowFocus: false, // prevents refetching while user is in process of editing the integration
85
+ },
86
+ );
87
+ const details = data as GetProcessByIdQuery | undefined;
88
+
89
+ useEffect(() => {
90
+ const typedData = details as GetProcessByIdQuery;
91
+ if (typedData?.processById) {
92
+ if (breadcrumbs.length === 2) {
93
+ const newCrumbs: Crumb[] = JSON.parse(JSON.stringify(breadcrumbs));
94
+ newCrumbs.push({ name: typedData.processById.name as string });
95
+ setBreadcrumbs(newCrumbs);
96
+ }
97
+ }
98
+ }, [details]);
99
+
100
+ const [drawerOpen, setDrawerOpen] = useState<DrawerOpen | null>(null);
101
+ const [scheduleLoading, setScheduleLoading] = useState<boolean>(false);
102
+
103
+ const handleScheduleDrawerOpen = () => {
104
+ if (details?.processById) {
105
+ if (details.processById.processScheduleGroup) {
106
+ setDrawerOpen({
107
+ id: details.processById.processScheduleGroup.id,
108
+ group: true,
109
+ addMode: false,
110
+ });
111
+ } else {
112
+ setDrawerOpen({
113
+ id: "",
114
+ group: true,
115
+ addMode: true,
116
+ });
117
+ }
118
+ }
119
+ };
120
+
121
+ const [viewRefreshKey, setViewRefreshKey] = useState<number>(Date.now());
122
+ useEffect(() => {
123
+ const typedData = data as GetProcessByIdQuery;
124
+ if (typedData?.processById) {
125
+ setViewRefreshKey(Date.now());
126
+ }
127
+ }, [data]);
128
+
129
+ if (isLoading) {
130
+ return (
131
+ <Box sx={{ padding: theme.spacing(10, 3) }}>
132
+ <Loading />
133
+ </Box>
134
+ );
135
+ }
136
+
137
+ return (
138
+ <Box>
139
+ <IntegrateBreadcrumbs breadcrumbs={breadcrumbs} />
140
+ <IntegrationDetailsHeader
141
+ name={details?.processById?.name || "Untitled Integration"}
142
+ icon={details?.processById?.processIcon ?? ""}
143
+ setName={() => {}}
144
+ onImportClick={() =>
145
+ dispatchImportState({ type: ImportActionType.OPEN })
146
+ }
147
+ onScheduleClick={handleScheduleDrawerOpen}
148
+ >
149
+ <Button
150
+ variant="contained"
151
+ color="info"
152
+ startIcon={<SaveIcon />}
153
+ sx={{ padding: theme.spacing(1.3, 2) }}
154
+ >
155
+ {t("IntegrationDetails.save")}
156
+ </Button>
157
+ </IntegrationDetailsHeader>
158
+
159
+ <Box
160
+ sx={{
161
+ display: "flex",
162
+ height: "80vh",
163
+ width: "100%",
164
+ overflow: "hidden",
165
+ backgroundColor: theme.palette.background.default,
166
+ border: `1px solid ${theme.palette.grey[400]}`,
167
+ alignItems: scheduleLoading || importState.loading ? "center" : null,
168
+ justifyContent:
169
+ scheduleLoading || importState.loading ? "center" : null,
170
+ }}
171
+ >
172
+ <IntegrationView
173
+ key={viewRefreshKey}
174
+ data={(data as GetProcessByIdQuery)?.processById as Process}
175
+ variant="process"
176
+ onTaskClick={(id: string) =>
177
+ dispatchTaskState({
178
+ type: TaskActionType.OPEN_EDIT,
179
+ processTaskId: id,
180
+ } as EditAction)
181
+ }
182
+ drawerOpen={taskState.open}
183
+ processTaskId={
184
+ taskState.processTaskId ? taskState.processTaskId : undefined
185
+ }
186
+ />
187
+ <TaskDrawer
188
+ open={taskState.open}
189
+ onClose={() => dispatchTaskState({ type: TaskActionType.CLOSE })}
190
+ anchor="right"
191
+ taskState={taskState}
192
+ dispatch={dispatchTaskState}
193
+ handleUpdateConfig={handleUpdateConfig}
194
+ />
195
+ </Box>
196
+ <ScheduleDrawer
197
+ drawerOpen={drawerOpen}
198
+ setDrawerOpen={setDrawerOpen}
199
+ processData={data as GetProcessByIdQuery}
200
+ handleSave={(loading: boolean) => setScheduleLoading(loading)}
201
+ />
202
+
203
+ <ImportDrawer
204
+ open={importState.open}
205
+ onClose={() => dispatchImportState({ type: ImportActionType.CLOSE })}
206
+ anchor="right"
207
+ importState={importState}
208
+ dispatch={dispatchImportState}
209
+ />
210
+ {/* temporary ui below */}
211
+ <Button
212
+ variant="contained"
213
+ color="primary"
214
+ onClick={() => dispatchTaskState({ type: TaskActionType.OPEN_ADD })}
215
+ // sx={{ visibility: "hidden" }}
216
+ >
217
+ Add task
218
+ </Button>
219
+ </Box>
220
+ );
221
+ }
@@ -0,0 +1,120 @@
1
+ import type {
2
+ FilterQueryInput,
3
+ GetProcessTemplatesQuery,
4
+ } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
5
+ import { getProcessTemplates } from "@evenicanpm/admin-integrate/api/templates/queries";
6
+ import type { Head } from "@evenicanpm/admin-integrate/components/data-table/table-header";
7
+ import { Wizard } from "@evenicanpm/admin-integrate/components/templates";
8
+ import TemplatesList from "@evenicanpm/admin-integrate/components/templates/templates-list";
9
+ import type { ProcessConfigMerge } from "@evenicanpm/admin-integrate/components/templates/types";
10
+ import { Box, Typography, useTheme } from "@mui/material";
11
+ import { useTranslations } from "next-intl";
12
+ import { useState } from "react";
13
+ import {
14
+ type TaskAction,
15
+ TaskActionType,
16
+ type TaskState,
17
+ } from "./task-reducer";
18
+
19
+ interface Props {
20
+ taskState: TaskState;
21
+ dispatch: React.Dispatch<TaskAction>;
22
+ }
23
+
24
+ // steps:
25
+ // - 0: choose template from list
26
+ // - 1: wizard (finish --> update flowchart view with added task, close drawer)
27
+ export default function AddTask(props: Props) {
28
+ const t = useTranslations("Integrate");
29
+ const theme = useTheme();
30
+
31
+ const heading: Head[] = [
32
+ {
33
+ id: "name",
34
+ label: t("Templates.ListHeader.name"),
35
+ align: "left",
36
+ width: "95%",
37
+ sortable: true,
38
+ },
39
+ {
40
+ id: "view",
41
+ label: t("Templates.ListHeader.actions"),
42
+ align: "right",
43
+ width: "5%",
44
+ },
45
+ ];
46
+
47
+ const [processConfigMerge, setProcessConfigMerge] =
48
+ useState<ProcessConfigMerge | null>(null);
49
+ const [processTemplateId, setProcessTemplateId] = useState<string | null>(
50
+ null,
51
+ );
52
+
53
+ const [input, setInput] = useState<FilterQueryInput>({
54
+ sort: "name",
55
+ sortDesc: false,
56
+ top: 10,
57
+ skip: 0,
58
+ });
59
+
60
+ const { data, isLoading } = getProcessTemplates.useData({
61
+ input: input,
62
+ });
63
+
64
+ const handleNext = () => {
65
+ const action: TaskAction = { type: TaskActionType.INCREMENT_STEP };
66
+ props.dispatch(action);
67
+ };
68
+ const handleBack = () => {
69
+ const action: TaskAction = { type: TaskActionType.DECREMENT_STEP };
70
+ props.dispatch(action);
71
+ };
72
+
73
+ const handleRedirect = (id: string) => {
74
+ setProcessTemplateId(id);
75
+ handleNext();
76
+ };
77
+
78
+ return (
79
+ <>
80
+ {props.taskState.step === 0 && (
81
+ <Box sx={{ marginBottom: theme.spacing(3) }}>
82
+ <Typography variant="h6">
83
+ {t("IntegrationDetails.AddTask.title")}
84
+ </Typography>
85
+ <Typography variant="body1">
86
+ {t("IntegrationDetails.AddTask.descList")}
87
+ </Typography>
88
+ </Box>
89
+ )}
90
+ {props.taskState.step === 0 && (
91
+ <TemplatesList
92
+ heading={heading}
93
+ data={data as GetProcessTemplatesQuery}
94
+ loading={isLoading}
95
+ input={input}
96
+ setInput={setInput}
97
+ handleRedirect={handleRedirect}
98
+ />
99
+ )}
100
+ {props.taskState.step === 1 && processTemplateId && (
101
+ <Wizard
102
+ // todo: should be set to metadata returned from api query for integration details
103
+ metadata={{
104
+ name: "",
105
+ code: "",
106
+ parallelProcessingGroup: 1,
107
+ sort: 1,
108
+ }}
109
+ setProcessConfigMerge={setProcessConfigMerge}
110
+ processTemplateId={processTemplateId}
111
+ handleBack={handleBack}
112
+ handleFinish={handleNext}
113
+ />
114
+ )}
115
+ {props.taskState.step === 2 && (
116
+ <Typography>{JSON.stringify(processConfigMerge)}</Typography>
117
+ )}
118
+ </>
119
+ );
120
+ }
@@ -0,0 +1,175 @@
1
+ import type {
2
+ ConfigExport,
3
+ ConfigurationMergeMutation,
4
+ ConfigurationMergeMutationVariables,
5
+ GetProcessTaskByIdQuery,
6
+ } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
7
+ import { processConfigMerge } from "@evenicanpm/admin-integrate/api/process-config/mutation";
8
+ import { getProcessTaskById } from "@evenicanpm/admin-integrate/api/process-task/queries";
9
+ import {
10
+ Loading,
11
+ TitleEdit,
12
+ } from "@evenicanpm/admin-integrate/components/core";
13
+ import { Wizard } from "@evenicanpm/admin-integrate/components/templates";
14
+ import type {
15
+ Metadata,
16
+ ProcessConfigMerge,
17
+ } from "@evenicanpm/admin-integrate/components/templates/types";
18
+ import { removeTemplateConfig } from "@evenicanpm/admin-integrate/components/templates/wizard";
19
+ import ReportProblemIcon from "@mui/icons-material/ReportProblem";
20
+ import { Box, Stack, Typography, useTheme } from "@mui/material";
21
+ import { useEffect, useState } from "react";
22
+ import {
23
+ type TaskAction,
24
+ TaskActionType,
25
+ type TaskState,
26
+ } from "./task-reducer";
27
+
28
+ interface Props {
29
+ taskState: TaskState;
30
+ dispatch: React.Dispatch<TaskAction>;
31
+ handleUpdateConfig: (newConfig: ConfigExport) => void;
32
+ editable?: boolean;
33
+ }
34
+
35
+ export default function EditTask(props: Props) {
36
+ const theme = useTheme();
37
+
38
+ const processConfigMergeMutation = processConfigMerge();
39
+
40
+ const [processConfigMergeInput, setProcessConfigMergeInput] =
41
+ useState<ProcessConfigMerge | null>(null);
42
+
43
+ const handleFinish = () => {
44
+ const action: TaskAction = { type: TaskActionType.INCREMENT_STEP };
45
+ props.dispatch(action);
46
+ };
47
+ const handleBack = () => {
48
+ const action: TaskAction = { type: TaskActionType.DECREMENT_STEP };
49
+ props.dispatch(action);
50
+ };
51
+
52
+ const { data, isLoading } = getProcessTaskById.useData({
53
+ id: props.taskState.processTaskId as string,
54
+ });
55
+
56
+ const [metadata, setMetadata] = useState<Metadata | null>(null);
57
+ const [name, setName] = useState<string>("");
58
+ const [sharedCount, setSharedCount] = useState<number>();
59
+
60
+ useEffect(() => {
61
+ const typedData = data as GetProcessTaskByIdQuery;
62
+
63
+ if (typedData?.processTaskById) {
64
+ setMetadata({
65
+ name: "", // name/code of parent Process is not relevant when editing a single task.
66
+ code: "",
67
+ parallelProcessingGroup: typedData.processTaskById
68
+ .parallelProcessingGroup as number,
69
+ sort: typedData.processTaskById.sort as number,
70
+ });
71
+
72
+ setName(typedData?.processTaskById?.name as string);
73
+ }
74
+ }, [data]);
75
+
76
+ const handleNameEdit = (input: string) => {
77
+ setName(input);
78
+
79
+ // TODO: on name change confirm, update main config state in details pg w/ updated name/code for this task
80
+ // props.handleUpdateConfig(...)
81
+ };
82
+
83
+ useEffect(() => {
84
+ if (processConfigMergeInput) {
85
+ const input =
86
+ removeTemplateConfig(processConfigMergeInput?.input) ||
87
+ ({} as ConfigurationMergeMutationVariables);
88
+ processConfigMergeMutation.mutate(
89
+ {
90
+ input: input,
91
+ },
92
+ {
93
+ onSuccess: async (data: ConfigurationMergeMutation) => {
94
+ props.handleUpdateConfig(data?.configurationMerge as ConfigExport);
95
+ },
96
+ onError: (error) => {
97
+ console.error("Update failed:", error);
98
+ },
99
+ },
100
+ );
101
+ }
102
+ }, [processConfigMergeInput]);
103
+
104
+ if (isLoading) {
105
+ return (
106
+ <Box sx={{ padding: theme.spacing(10, 3) }}>
107
+ <Loading />
108
+ </Box>
109
+ );
110
+ }
111
+
112
+ const templateConfig = (data as GetProcessTaskByIdQuery)?.processTaskById
113
+ ?.endpoint?.templateConfig;
114
+
115
+ return (
116
+ <>
117
+ {props.taskState.step === 0 && metadata && (
118
+ <Box sx={{ marginBottom: theme.spacing(1) }}>
119
+ <Stack
120
+ direction="row"
121
+ spacing={1}
122
+ sx={{ minHeight: theme.spacing(7) }}
123
+ >
124
+ <TitleEdit
125
+ title={name}
126
+ onConfirm={handleNameEdit}
127
+ fullWidth
128
+ variant="h6"
129
+ readOnly={!props.editable}
130
+ />
131
+ </Stack>
132
+ {sharedCount !== undefined && sharedCount > 1 && props?.editable && (
133
+ <Typography
134
+ variant="body2"
135
+ color="error"
136
+ sx={{
137
+ display: "flex",
138
+ alignItems: "center",
139
+ gap: "5px",
140
+ fontSize: "12px",
141
+ }}
142
+ >
143
+ <ReportProblemIcon color="error" sx={{ fontSize: "18px" }} />{" "}
144
+ Changes to this integration tasks will affect other tasks sharing
145
+ the same <strong>Data Description</strong>
146
+ </Typography>
147
+ )}
148
+ </Box>
149
+ )}
150
+ {props.taskState.step === 0 &&
151
+ /*(data as GetProcessTaskByIdQuery).processTaskById?.endpoint
152
+ ?.templateConfig &&*/
153
+ metadata && (
154
+ <Wizard
155
+ metadata={metadata as Metadata}
156
+ setProcessConfigMerge={setProcessConfigMergeInput}
157
+ handleBack={handleBack}
158
+ handleFinish={handleFinish}
159
+ templateConfig={templateConfig}
160
+ processTemplateId={
161
+ (data as GetProcessTaskByIdQuery).processTaskById?.endpoint
162
+ ?.processTemplate?.id as string
163
+ }
164
+ isEditMode
165
+ disableBackToTemplates
166
+ readOnly={!props.editable}
167
+ sharedCount={(count: number) => setSharedCount(count)}
168
+ />
169
+ )}
170
+ {props.taskState.step === 1 && (
171
+ <Typography>{JSON.stringify(processConfigMergeInput)}</Typography>
172
+ )}
173
+ </>
174
+ );
175
+ }
@@ -0,0 +1,139 @@
1
+ import type { ConfigExport } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
2
+ import { DrawerButtons } from "@evenicanpm/admin-integrate/components/core";
3
+ import { EditOutlined } from "@mui/icons-material";
4
+ import {
5
+ Box,
6
+ Button,
7
+ type DrawerProps,
8
+ Drawer as MuiDrawer,
9
+ type Theme,
10
+ useTheme,
11
+ } from "@mui/material";
12
+ import { styled } from "@mui/material/styles";
13
+ import { usePathname, useRouter } from "next/navigation";
14
+ import { useTranslations } from "next-intl";
15
+ import { useEffect, useState } from "react";
16
+ import AddTask from "./add-task";
17
+ import EditTask from "./edit-task";
18
+ import {
19
+ type TaskAction,
20
+ TaskActionType,
21
+ TaskMode,
22
+ type TaskState,
23
+ } from "./task-reducer";
24
+
25
+ interface Props extends DrawerProps {
26
+ taskState: TaskState;
27
+ dispatch: React.Dispatch<TaskAction>;
28
+ handleUpdateConfig: (newConfig: ConfigExport) => void;
29
+ }
30
+
31
+ const Drawer = styled(MuiDrawer)({
32
+ position: "relative", //imp
33
+ //width: 625, //drawer width
34
+ "& .MuiDrawer-paper": {
35
+ width: 625, //drawer width
36
+ position: "absolute", //imp
37
+ transition: "none !important",
38
+ },
39
+ });
40
+
41
+ export default function TaskDrawer({
42
+ taskState,
43
+ dispatch,
44
+ handleUpdateConfig,
45
+ ...props
46
+ }: Props) {
47
+ const t = useTranslations("Integrate.IntegrationDetails.TaskDrawer");
48
+
49
+ const theme = useTheme();
50
+ const styles = getStyles(theme);
51
+
52
+ const router = useRouter();
53
+ const pathname = usePathname();
54
+
55
+ const [editable, setEditable] = useState<boolean>(false);
56
+ const [reloadKey, setReloadKey] = useState<number>(Date.now());
57
+
58
+ const confirmCancel = () => {
59
+ if (editable) {
60
+ return confirm(t("confirmTaskUpdateText"));
61
+ }
62
+ return true;
63
+ };
64
+
65
+ const handleClose = () => {
66
+ if (!confirmCancel()) return;
67
+
68
+ const action: TaskAction = { type: TaskActionType.CLOSE };
69
+ dispatch(action);
70
+ setEditable(false);
71
+ };
72
+
73
+ const handleEdit = () => {
74
+ if (!confirmCancel()) return;
75
+
76
+ if (editable) setReloadKey(Date.now());
77
+ setEditable(!editable);
78
+ };
79
+
80
+ useEffect(() => {
81
+ if (taskState.step === null || taskState.step === 0) {
82
+ router.replace(pathname);
83
+ }
84
+ }, [taskState.step]);
85
+
86
+ return (
87
+ <Drawer
88
+ {...props}
89
+ variant="persistent"
90
+ sx={{ padding: theme.spacing(2), width: taskState.open ? 525 : 0 }}
91
+ >
92
+ <DrawerButtons handleClose={handleClose}>
93
+ {taskState.mode === TaskMode.EDIT && (
94
+ <Button
95
+ variant={editable ? "outlined" : "contained"}
96
+ color={editable ? "error" : "info"}
97
+ onClick={handleEdit}
98
+ endIcon={<EditOutlined />}
99
+ >
100
+ {editable ? t("cancel") : t("edit")}
101
+ </Button>
102
+ )}
103
+ </DrawerButtons>
104
+ <Box sx={styles.main}>
105
+ {taskState.mode === TaskMode.ADD && (
106
+ <AddTask taskState={taskState} dispatch={dispatch} />
107
+ )}
108
+ {taskState.mode === TaskMode.EDIT && (
109
+ <EditTask
110
+ key={reloadKey}
111
+ taskState={taskState}
112
+ dispatch={dispatch}
113
+ editable={editable}
114
+ handleUpdateConfig={handleUpdateConfig}
115
+ />
116
+ )}
117
+ </Box>
118
+ </Drawer>
119
+ );
120
+ }
121
+
122
+ const getStyles = (theme: Theme) => {
123
+ return {
124
+ main: {
125
+ //width: 600,
126
+ padding: theme.spacing(2),
127
+ },
128
+ drawer: {
129
+ //width: 600,
130
+ },
131
+ enableEdit: {
132
+ backgroundColor: "info.main",
133
+ "&:hover": {
134
+ backgroundColor: "info.400",
135
+ },
136
+ color: "white",
137
+ },
138
+ };
139
+ };