@evenicanpm/admin-integrate 1.3.0 → 1.4.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 (79) hide show
  1. package/documents/Endpoint/list.ts +8 -0
  2. package/documents/Process/get-process-details.ts +0 -1
  3. package/documents/ProcessConfig/fragments.ts +1 -1
  4. package/documents/ProcessExport/read.ts +108 -0
  5. package/documents/ProcessTask/fragments.ts +4 -1
  6. package/documents/ProcessTemplate/fragments.ts +6 -1
  7. package/package.json +2 -2
  8. package/src/api/configuration/queries/configuration-export.query.ts +48 -0
  9. package/src/api/configuration/queries/configuration-export.server.ts +9 -0
  10. package/src/api/configuration/queries/index.ts +1 -0
  11. package/src/api/process/mutations/copy-process.mutation.ts +2 -5
  12. package/src/api/process-config/mutation/process-config-import.mutation.ts +9 -0
  13. package/src/api/process-task/queries/get-process-task-by-id.query.ts +1 -0
  14. package/src/api/scheduler/mutation/create-process-schedule-group-details.mutation.ts +2 -2
  15. package/src/api/scheduler/mutation/update-process-schedule-group-details.mutation.ts +2 -2
  16. package/src/api/templates/queries/template-input-search.query.ts +5 -0
  17. package/src/api/templates/queries/template-input-search.server.ts +8 -1
  18. package/src/api/templates/queries/types.ts +9 -3
  19. package/src/components/breadcrumbs/breadcrumbs.tsx +1 -1
  20. package/src/components/core/date-time-popover.tsx +1 -1
  21. package/src/components/core/drawer-buttons.tsx +1 -1
  22. package/src/components/core/edited-typography.tsx +1 -1
  23. package/src/components/core/title-edit.tsx +13 -11
  24. package/src/components/dashboard-list/dashboard-list.tsx +1 -1
  25. package/src/components/data-table/table-header.tsx +1 -1
  26. package/src/components/data-table/table-skeleton.tsx +1 -1
  27. package/src/components/execution-history-drawer/execution-history-drawer.tsx +1 -2
  28. package/src/components/header/integration-details-header.tsx +4 -0
  29. package/src/components/integration-list/list/integration-list-row.tsx +2 -2
  30. package/src/components/integration-list/list/integration-list-table.tsx +3 -3
  31. package/src/components/integration-list/list/integration-list.tsx +3 -3
  32. package/src/components/integration-view/edges/default-edge.tsx +1 -5
  33. package/src/components/integration-view/flow-types.tsx +2 -0
  34. package/src/components/integration-view/integration-view.tsx +148 -577
  35. package/src/components/integration-view/nodes/add-node.tsx +20 -0
  36. package/src/components/integration-view/nodes/group-node.tsx +15 -1
  37. package/src/components/integration-view/nodes/task-node.tsx +38 -10
  38. package/src/components/integration-view/temp-data/initialElements.tsx +0 -2
  39. package/src/components/integration-view/utils/mapping.ts +404 -0
  40. package/src/components/layouts/main-layout.tsx +1 -1
  41. package/src/components/layouts/root-container.tsx +2 -5
  42. package/src/components/link-cards/link-card.tsx +1 -1
  43. package/src/components/list-filter/date-filter.tsx +3 -1
  44. package/src/components/list-filter/date-range-filter.tsx +4 -2
  45. package/src/components/list-filter/list-filter.tsx +1 -1
  46. package/src/components/list-filter/select-filter.tsx +10 -4
  47. package/src/components/scheduler/schedule-drawer/schedule-details-integrations.tsx +6 -8
  48. package/src/components/scheduler/schedule-drawer/schedule-details-main.tsx +1 -1
  49. package/src/components/scheduler/schedule-drawer/schedule-details-name.tsx +1 -1
  50. package/src/components/scheduler/schedule-drawer/schedule-details.tsx +1 -1
  51. package/src/components/scheduler/schedule-drawer/schedule-drawer-group.tsx +4 -8
  52. package/src/components/scheduler/schedule-drawer/schedule-drawer-legacy.tsx +1 -1
  53. package/src/components/scheduler/schedule-drawer/schedule-drawer.tsx +2 -2
  54. package/src/components/scheduler/schedule-drawer/sortable-integration-row.tsx +1 -1
  55. package/src/components/templates/inputs/index.tsx +162 -121
  56. package/src/components/templates/templates-list/templates-list-table.tsx +2 -2
  57. package/src/components/templates/templates-list/templates-list.tsx +1 -1
  58. package/src/components/templates/types.tsx +1 -0
  59. package/src/components/templates/wizard.tsx +98 -50
  60. package/src/pages/dashboard/dashboard-list-sections.tsx +2 -2
  61. package/src/pages/execution-details/execution-details.tsx +4 -3
  62. package/src/pages/execution-details/task-execution-details.tsx +1 -1
  63. package/src/pages/execution-details/task-execution-drawer.tsx +1 -1
  64. package/src/pages/executions/executions-list/executions-list-table.tsx +1 -1
  65. package/src/pages/integration-create/integration-create.tsx +87 -45
  66. package/src/pages/integration-create/pre-creation-step.tsx +77 -5
  67. package/src/pages/integration-create/select-step.tsx +1 -1
  68. package/src/pages/integration-create/wizard-step.tsx +2 -1
  69. package/src/pages/integration-details/import-process/copy-tasks-list.tsx +2 -2
  70. package/src/pages/integration-details/import-process/copy-tasks-row.tsx +1 -1
  71. package/src/pages/integration-details/import-process/import-confirm.tsx +1 -1
  72. package/src/pages/integration-details/import-process/import-drawer.tsx +1 -1
  73. package/src/pages/integration-details/import-process/import-process.tsx +1 -1
  74. package/src/pages/integration-details/integration-details.tsx +290 -43
  75. package/src/pages/integration-details/task-drawer/add-task.tsx +65 -13
  76. package/src/pages/integration-details/task-drawer/edit-task.tsx +69 -83
  77. package/src/pages/integration-details/task-drawer/task-drawer.tsx +22 -4
  78. package/src/pages/integration-details/task-drawer/task-reducer.ts +32 -2
  79. package/src/pages/scheduler/schedules-list/schedules-list-table.tsx +1 -1
@@ -1,12 +1,84 @@
1
- //import type { ProcessConfigMerge } from "@evenicanpm/admin-integrate/components/templates/types";
2
- import { Box } from "@mui/material";
1
+ import { Box, useTheme } from "@mui/material";
2
+ import { useReducer } from "react";
3
+ import type {
4
+ ConfigExport,
5
+ EndpointExport,
6
+ } from "../../../../admin-core/src/api/e4/graphqlRequestSdk";
7
+ import { IntegrationView } from "../../components/integration-view";
8
+ import {
9
+ type EditAction,
10
+ TaskActionType,
11
+ TaskMode,
12
+ taskReducer,
13
+ } from "../integration-details/task-drawer/task-reducer";
3
14
 
4
15
  interface Props {
5
16
  processConfig: any | null;
6
17
  }
7
18
 
8
- export default function PreCreationStep(props: Props) {
19
+ export default function PreCreationStep(props: Readonly<Props>) {
20
+ const theme = useTheme();
21
+
22
+ const [_taskState, dispatchTaskState] = useReducer(taskReducer, {
23
+ open: false,
24
+ mode: TaskMode.NONE,
25
+ step: null,
26
+ });
27
+
9
28
  // TODO: render integration
10
- console.log("processConfigMerge payload:", props.processConfig);
11
- return <Box></Box>;
29
+ return (
30
+ <Box
31
+ sx={{
32
+ display: "flex",
33
+ height: "80vh",
34
+ width: "100%",
35
+ overflow: "hidden",
36
+ backgroundColor: theme.palette.background.default,
37
+ border: `1px solid ${theme.palette.grey[400]}`,
38
+ alignItems: null,
39
+ justifyContent: null,
40
+ }}
41
+ className="integration-view-container"
42
+ >
43
+ <IntegrationView
44
+ canEdit={false}
45
+ //key={viewRefreshKey}
46
+ //data={(data as GetProcessByIdQuery)?.processById as Process}
47
+ config={props.processConfig as ConfigExport}
48
+ variant="process"
49
+ drawerOpen={false}
50
+ processTaskId={undefined}
51
+ onTaskClick={(processTask: any) => {
52
+ const endpoint = props.processConfig?.Endpoints.find(
53
+ (ep: EndpointExport) => ep.Name === processTask.endpoint,
54
+ );
55
+
56
+ let templateConfig: any;
57
+
58
+ if (typeof endpoint.TemplateConfig === "string") {
59
+ templateConfig = endpoint.TemplateConfig;
60
+ } else if (typeof endpoint.TemplateConfig === "object") {
61
+ templateConfig = JSON.stringify(endpoint.TemplateConfig);
62
+ }
63
+
64
+ dispatchTaskState({
65
+ type: TaskActionType.OPEN_EDIT,
66
+ processTaskId: processTask.id,
67
+ templateConfig: templateConfig,
68
+ sort: processTask.sort,
69
+ parallelProcessingGroup: processTask.parallelProcessingGroup,
70
+ processTemplateId: endpoint?.ProcessTemplateId,
71
+ } as EditAction);
72
+ }}
73
+ />
74
+ {/* <TaskDrawer
75
+ open={taskState.open}
76
+ onClose={() => dispatchTaskState({ type: TaskActionType.CLOSE })}
77
+ anchor="right"
78
+ taskState={taskState}
79
+ dispatch={dispatchTaskState}
80
+ //handleUpdateConfig={handleUpdateConfig}
81
+ /> */}
82
+ </Box>
83
+ );
12
84
  }
@@ -20,7 +20,7 @@ interface Props {
20
20
  setStep: React.Dispatch<React.SetStateAction<number>>;
21
21
  }
22
22
 
23
- export default function SelectStep(props: Props) {
23
+ export default function SelectStep(props: Readonly<Props>) {
24
24
  const t = useTranslations("Integrate.Templates");
25
25
 
26
26
  const theme = useTheme();
@@ -21,7 +21,7 @@ interface Props {
21
21
  >;
22
22
  }
23
23
 
24
- export default function WizardStep(props: Props) {
24
+ export default function WizardStep(props: Readonly<Props>) {
25
25
  const router = useRouter();
26
26
  const pathname = usePathname();
27
27
  const searchParams = useSearchParams();
@@ -44,6 +44,7 @@ export default function WizardStep(props: Props) {
44
44
  handleBack={handleBack}
45
45
  handleFinish={handleFinish}
46
46
  setProcessConfigMerge={props.setProcessConfigMerge}
47
+ isCreateMode
47
48
  />
48
49
  </Box>
49
50
  );
@@ -42,7 +42,7 @@ interface Props {
42
42
  dispatch: React.Dispatch<ImportAction>;
43
43
  }
44
44
 
45
- export default function CopyTasksList(props: Props) {
45
+ export default function CopyTasksList(props: Readonly<Props>) {
46
46
  const t = useTranslations("Integrate.IntegrationDetails.ImportProcess");
47
47
 
48
48
  const params = useParams<{ processId: string }>();
@@ -74,7 +74,7 @@ export default function CopyTasksList(props: Props) {
74
74
  null,
75
75
  );
76
76
  const anyChecked =
77
- checked === null ? false : Object.values(checked).some((value) => value);
77
+ checked === null ? false : Object.values(checked).some(Boolean);
78
78
  const disableConfirm =
79
79
  props.loading || !!props.importState.alert || !anyChecked;
80
80
 
@@ -22,7 +22,7 @@ interface Props {
22
22
  sx?: SxProps;
23
23
  }
24
24
 
25
- export default function CopyTasksRow(props: Props) {
25
+ export default function CopyTasksRow(props: Readonly<Props>) {
26
26
  const headings = {
27
27
  actions: props.heading.find((h) => h.id === "actions"),
28
28
  name: props.heading.find((h) => h.id === "name"),
@@ -17,7 +17,7 @@ interface Props {
17
17
  dispatch: React.Dispatch<ImportAction>;
18
18
  }
19
19
 
20
- export default function ImportConfirm(props: Props) {
20
+ export default function ImportConfirm(props: Readonly<Props>) {
21
21
  const t = useTranslations("Integrate.IntegrationDetails.ImportProcess");
22
22
  const params = useParams<{ processId: string }>();
23
23
 
@@ -22,7 +22,7 @@ export default function ImportDrawer({
22
22
  importState,
23
23
  dispatch,
24
24
  ...props
25
- }: Props) {
25
+ }: Readonly<Props>) {
26
26
  const theme = useTheme();
27
27
  const styles = getStyles(theme);
28
28
 
@@ -25,7 +25,7 @@ interface Props {
25
25
  dispatch: React.Dispatch<ImportAction>;
26
26
  }
27
27
 
28
- export default function ImportProcess(props: Props) {
28
+ export default function ImportProcess(props: Readonly<Props>) {
29
29
  const t = useTranslations("Integrate.IntegrationDetails.ImportProcess");
30
30
  const l = useTranslations("Integrate.IntegrationList.ListHeader");
31
31
 
@@ -1,7 +1,8 @@
1
1
  import type {
2
2
  ConfigExport,
3
+ ConfigImport,
4
+ ConfigurationExportQuery,
3
5
  GetProcessByIdQuery,
4
- Process,
5
6
  } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
6
7
  import { getProcessById } from "@evenicanpm/admin-integrate/api/process/queries";
7
8
  import { buildProcessByIdQueryKey } from "@evenicanpm/admin-integrate/api/process/queries/get-process-by-id.query";
@@ -14,11 +15,15 @@ import { IntegrationDetailsHeader } from "@evenicanpm/admin-integrate/components
14
15
  import IntegrationView from "@evenicanpm/admin-integrate/components/integration-view/integration-view";
15
16
  import type { DrawerOpen } from "@evenicanpm/admin-integrate/components/scheduler/schedule-drawer/schedule-drawer";
16
17
  import ScheduleDrawer from "@evenicanpm/admin-integrate/components/scheduler/schedule-drawer/schedule-drawer";
18
+ import CancelIcon from "@mui/icons-material/Cancel";
17
19
  import SaveIcon from "@mui/icons-material/Save";
18
- import { Box, Button, useTheme } from "@mui/material";
19
- import { useParams } from "next/navigation";
20
+ import { Box, Button, CircularProgress, useTheme } from "@mui/material";
21
+ import { useParams, useRouter } from "next/navigation";
20
22
  import { useTranslations } from "next-intl";
21
23
  import { useEffect, useReducer, useState } from "react";
24
+ import { configurationExport } from "../../api/configuration/queries";
25
+ import { buildConfigurationExportQueryKey } from "../../api/configuration/queries/configuration-export.query";
26
+ import { processConfigImport } from "../../api/process-config/mutation";
22
27
  import ImportDrawer from "./import-process/import-drawer";
23
28
  import {
24
29
  ImportActionType,
@@ -32,10 +37,76 @@ import {
32
37
  taskReducer,
33
38
  } from "./task-drawer/task-reducer";
34
39
 
40
+ function mergeByKey(
41
+ keyFields: string | string[],
42
+ arr1: any[] = [],
43
+ arr2: any[] = [],
44
+ ) {
45
+ const keys = Array.isArray(keyFields) ? keyFields : [keyFields];
46
+
47
+ // Build lookup maps for each key -> value => baseItem (from arr1)
48
+ const lookupByKey: Record<string, Map<any, any>> = {};
49
+ for (const k of keys) {
50
+ lookupByKey[k] = new Map();
51
+ }
52
+
53
+ for (const item of arr1) {
54
+ for (const key of keys) {
55
+ const val = item?.[key];
56
+ if (val !== undefined && val !== null) {
57
+ lookupByKey[key].set(val, item);
58
+ }
59
+ }
60
+ }
61
+
62
+ // Use a Set to preserve insertion order and ensure uniqueness
63
+ const resultSet = new Set<any>(arr1);
64
+
65
+ for (const item of arr2) {
66
+ let matchedBase: any = null;
67
+
68
+ // Try keys in order of priority
69
+ for (const key of keys) {
70
+ const val = item?.[key];
71
+ if (val !== undefined && val !== null) {
72
+ const candidate = lookupByKey[key].get(val);
73
+ if (candidate) {
74
+ matchedBase = candidate;
75
+ break;
76
+ }
77
+ }
78
+ }
79
+
80
+ if (matchedBase) {
81
+ // Merge properties from item into matched base (respecting exclusions)
82
+ for (const prop of Object.keys(item)) {
83
+ if (prop !== "Sort" && prop !== "ParallelProcessingGroup") {
84
+ matchedBase[prop] = item[prop];
85
+ }
86
+ }
87
+ } else {
88
+ // No match found by any tiered key -> add as new
89
+ resultSet.add(item);
90
+ // Register the newly added item in lookups so subsequent arr2 items can match it
91
+ for (const key of keys) {
92
+ const val = item?.[key];
93
+ if (val !== undefined && val !== null) {
94
+ lookupByKey[key].set(val, item);
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ return Array.from(resultSet);
101
+ }
102
+
35
103
  export default function IntegrationDetails() {
36
104
  const t = useTranslations("Integrate");
37
105
  const params = useParams<{ processId: string }>();
38
106
  const theme = useTheme();
107
+ const router = useRouter();
108
+
109
+ const [config, setConfig] = useState<ConfigExport | null>(null);
39
110
 
40
111
  const [breadcrumbs, setBreadcrumbs] = useState<Crumb[]>([
41
112
  {
@@ -61,36 +132,123 @@ export default function IntegrationDetails() {
61
132
  loading: false,
62
133
  });
63
134
 
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.
135
+ const { data, isLoading } = getProcessById.useData(
136
+ {
137
+ id: params.processId,
138
+ },
139
+ {
140
+ queryKey: buildProcessByIdQueryKey.byInput({ id: params.processId }),
141
+ refetchOnWindowFocus: false, // prevents refetching while user is in process of editing the integration
142
+ },
143
+ );
144
+
145
+ const {
146
+ data: configFromApi,
147
+ isLoading: configLoading,
148
+ refetch,
149
+ } = configurationExport.useData(
150
+ {
151
+ processId: params.processId,
152
+ includeIds: true,
153
+ useSourceEndpoint: true,
154
+ },
155
+ {
156
+ queryKey: buildConfigurationExportQueryKey.byInput({
157
+ processId: params.processId,
158
+ includeIds: true,
159
+ useSourceEndpoint: true,
160
+ }),
161
+ refetchOnWindowFocus: false, // prevents refetching while user is in process of editing the integration
162
+ },
163
+ );
67
164
 
68
165
  const handleUpdateConfig = (newConfig: ConfigExport) => {
166
+ dispatchTaskState({
167
+ type: TaskActionType.CLOSE,
168
+ });
69
169
  // TODO: update config state with newConfig from configMerge
70
170
 
71
171
  // when config export is implemented, change functionality to instead update the config state, rather than replace it
72
172
  // this is so we can do things like change a single task's name, because doing an overwrite will replace the new name
73
173
  // since config merge will generate names for the tasks automatically.
74
174
  // also don't want to do things like overwrite parallel processing group, sort, Process name, etc.
75
- setConfig(newConfig);
175
+ //setConfig(newConfig);
176
+
177
+ const configData: ConfigExport =
178
+ config ?? (configFromApi as any)?.configurationExport;
179
+
180
+ configData.DepotGroups = mergeByKey(
181
+ "DepotGroup",
182
+ configData.DepotGroups || [],
183
+ newConfig.DepotGroups || [],
184
+ );
185
+
186
+ configData.Depots = mergeByKey(
187
+ "Depot",
188
+ configData.Depots || [],
189
+ newConfig.Depots || [],
190
+ );
191
+
192
+ configData.Endpoints = mergeByKey(
193
+ "Endpoint",
194
+ configData.Endpoints || [],
195
+ newConfig.Endpoints || [],
196
+ );
197
+
198
+ configData.Entities = mergeByKey(
199
+ "Entity",
200
+ configData.Entities || [],
201
+ newConfig.Entities || [],
202
+ );
203
+
204
+ if (newConfig?.Processes?.[0])
205
+ newConfig.Processes[0].ProcessTasks =
206
+ newConfig?.Processes[0]?.ProcessTasks?.map((newTask) => {
207
+ if (newTask)
208
+ newTask.Name =
209
+ newTask?.Name || newTask?.ProcessTask?.replaceAll("_", " ");
210
+
211
+ return newTask;
212
+ });
213
+
214
+ if (configData?.Processes?.[0])
215
+ configData.Processes[0].ProcessTasks = mergeByKey(
216
+ ["ProcessTaskId", "ProcessTask"],
217
+ configData.Processes?.[0]?.ProcessTasks || [],
218
+ newConfig.Processes?.[0]?.ProcessTasks || [],
219
+ );
220
+
221
+ setConfig(configData);
222
+ };
223
+
224
+ const processConfigImportMutation = processConfigImport();
225
+
226
+ const handleProcessConfigImport = () => {
227
+ if (config) {
228
+ processConfigImportMutation.mutate(
229
+ {
230
+ config: config as ConfigImport,
231
+ reRoutedFromMerge: true,
232
+ },
233
+ {
234
+ onSuccess: () => {
235
+ setConfig(null);
236
+ },
237
+ onError: (error) => {
238
+ console.error("Update failed:", error);
239
+ },
240
+ },
241
+ );
242
+ }
76
243
  };
77
244
 
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
245
  const details = data as GetProcessByIdQuery | undefined;
88
246
 
89
247
  useEffect(() => {
90
248
  const typedData = details as GetProcessByIdQuery;
91
249
  if (typedData?.processById) {
92
250
  if (breadcrumbs.length === 2) {
93
- const newCrumbs: Crumb[] = JSON.parse(JSON.stringify(breadcrumbs));
251
+ const newCrumbs: Crumb[] = structuredClone(breadcrumbs);
94
252
  newCrumbs.push({ name: typedData.processById.name as string });
95
253
  setBreadcrumbs(newCrumbs);
96
254
  }
@@ -120,13 +278,30 @@ export default function IntegrationDetails() {
120
278
 
121
279
  const [viewRefreshKey, setViewRefreshKey] = useState<number>(Date.now());
122
280
  useEffect(() => {
123
- const typedData = data as GetProcessByIdQuery;
124
- if (typedData?.processById) {
281
+ setViewRefreshKey(Date.now());
282
+ }, [data, config]);
283
+
284
+ useEffect(() => {
285
+ if (!scheduleLoading) {
125
286
  setViewRefreshKey(Date.now());
126
287
  }
127
- }, [data]);
288
+ }, [scheduleLoading]);
128
289
 
129
- if (isLoading) {
290
+ const onAdd = (data: any) => {
291
+ dispatchTaskState({
292
+ type: TaskActionType.OPEN_ADD,
293
+ sort: data.sort,
294
+ parallelProcessingGroup: data.paralellelProcessingGroup,
295
+ } as EditAction);
296
+ };
297
+
298
+ useEffect(() => {
299
+ const handler = (e: CustomEvent) => onAdd(e.detail);
300
+
301
+ document.addEventListener("addItem", handler as EventListener);
302
+ }, []);
303
+
304
+ if (isLoading || configLoading) {
130
305
  return (
131
306
  <Box sx={{ padding: theme.spacing(10, 3) }}>
132
307
  <Loading />
@@ -138,19 +313,53 @@ export default function IntegrationDetails() {
138
313
  <Box>
139
314
  <IntegrateBreadcrumbs breadcrumbs={breadcrumbs} />
140
315
  <IntegrationDetailsHeader
141
- name={details?.processById?.name || "Untitled Integration"}
316
+ name={
317
+ (config || (configFromApi as any)?.configurationExport)?.Processes[0]
318
+ ?.Name || "Untitled Integration"
319
+ }
142
320
  icon={details?.processById?.processIcon ?? ""}
143
- setName={() => {}}
144
- onImportClick={() =>
145
- dispatchImportState({ type: ImportActionType.OPEN })
321
+ setName={(name) => {
322
+ const configData =
323
+ config || (configFromApi as any)?.configurationExport;
324
+ configData.Processes[0].Name = name;
325
+ setConfig(configData);
326
+ }}
327
+ onImportClick={() => {
328
+ if (!config) {
329
+ dispatchImportState({ type: ImportActionType.OPEN });
330
+ }
331
+ }}
332
+ onScheduleClick={() => {
333
+ if (!config) {
334
+ handleScheduleDrawerOpen();
335
+ }
336
+ }}
337
+ onExecutionsClick={() =>
338
+ router.push(`/e4integrate/executions/${params.processId}`)
146
339
  }
147
- onScheduleClick={handleScheduleDrawerOpen}
148
340
  >
341
+ {config ? (
342
+ <Button
343
+ variant="contained"
344
+ color="error"
345
+ startIcon={<CancelIcon />}
346
+ sx={{ padding: theme.spacing(1.3, 2) }}
347
+ onClick={() => {
348
+ refetch().then(() => {
349
+ setConfig(null);
350
+ });
351
+ }}
352
+ >
353
+ Cancel
354
+ </Button>
355
+ ) : null}
149
356
  <Button
150
357
  variant="contained"
151
358
  color="info"
152
359
  startIcon={<SaveIcon />}
153
360
  sx={{ padding: theme.spacing(1.3, 2) }}
361
+ onClick={handleProcessConfigImport}
362
+ disabled={!config}
154
363
  >
155
364
  {t("IntegrationDetails.save")}
156
365
  </Button>
@@ -169,28 +378,66 @@ export default function IntegrationDetails() {
169
378
  scheduleLoading || importState.loading ? "center" : null,
170
379
  }}
171
380
  >
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
- />
381
+ {!scheduleLoading &&
382
+ !importState.loading &&
383
+ (config || configFromApi) ? (
384
+ <IntegrationView
385
+ canEdit
386
+ key={viewRefreshKey}
387
+ //data={(data as GetProcessByIdQuery)?.processById as Process}
388
+ config={
389
+ config ||
390
+ ((configFromApi as ConfigurationExportQuery)
391
+ .configurationExport as ConfigExport)
392
+ }
393
+ variant="process"
394
+ onTaskClick={(processTask: any) => {
395
+ const endpoint = (
396
+ config ??
397
+ (configFromApi as ConfigurationExportQuery).configurationExport
398
+ )?.Endpoints?.find(
399
+ (ep) => !!ep && ep.Name === processTask.endpoint,
400
+ );
401
+
402
+ let templateConfig: any;
403
+
404
+ if (endpoint) {
405
+ if (typeof endpoint.TemplateConfig === "string") {
406
+ templateConfig = endpoint.TemplateConfig;
407
+ } else if (typeof endpoint.TemplateConfig === "object") {
408
+ templateConfig = JSON.stringify(endpoint.TemplateConfig);
409
+ }
410
+ }
411
+
412
+ dispatchTaskState({
413
+ type: TaskActionType.OPEN_EDIT,
414
+ processTaskId: processTask.id,
415
+ templateConfig: templateConfig,
416
+ sort: processTask.sort,
417
+ parallelProcessingGroup: processTask.parallelProcessingGroup,
418
+ processTemplateId: endpoint?.ProcessTemplateId,
419
+ name: processTask.name,
420
+ } as EditAction);
421
+ }}
422
+ drawerOpen={taskState.open}
423
+ processTaskId={
424
+ taskState.processTaskId ? taskState.processTaskId : undefined
425
+ }
426
+ onConfigChange={setConfig}
427
+ onAdd={() => {}}
428
+ />
429
+ ) : (
430
+ <CircularProgress />
431
+ )}
187
432
  <TaskDrawer
188
433
  open={taskState.open}
189
434
  onClose={() => dispatchTaskState({ type: TaskActionType.CLOSE })}
190
435
  anchor="right"
191
436
  taskState={taskState}
437
+ renderKey={taskState.processTaskId}
192
438
  dispatch={dispatchTaskState}
193
439
  handleUpdateConfig={handleUpdateConfig}
440
+ config={config ?? (configFromApi as any)?.configurationExport}
194
441
  />
195
442
  </Box>
196
443
  <ScheduleDrawer
@@ -208,14 +455,14 @@ export default function IntegrationDetails() {
208
455
  dispatch={dispatchImportState}
209
456
  />
210
457
  {/* temporary ui below */}
211
- <Button
458
+ {/* <Button
212
459
  variant="contained"
213
460
  color="primary"
214
461
  onClick={() => dispatchTaskState({ type: TaskActionType.OPEN_ADD })}
215
462
  // sx={{ visibility: "hidden" }}
216
463
  >
217
464
  Add task
218
- </Button>
465
+ </Button> */}
219
466
  </Box>
220
467
  );
221
468
  }