@evenicanpm/admin-integrate 1.3.0 → 1.6.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.
- package/documents/Endpoint/list.ts +8 -0
- package/documents/Process/get-process-details.ts +0 -1
- package/documents/ProcessConfig/fragments.ts +1 -1
- package/documents/ProcessExport/read.ts +108 -0
- package/documents/ProcessTask/fragments.ts +4 -1
- package/documents/ProcessTemplate/fragments.ts +6 -1
- package/package.json +2 -2
- package/src/api/configuration/queries/configuration-export.query.ts +48 -0
- package/src/api/configuration/queries/configuration-export.server.ts +9 -0
- package/src/api/configuration/queries/index.ts +1 -0
- package/src/api/process/mutations/copy-process.mutation.ts +2 -5
- package/src/api/process-config/mutation/process-config-import.mutation.ts +9 -0
- package/src/api/process-task/queries/get-process-task-by-id.query.ts +1 -0
- package/src/api/scheduler/mutation/create-process-schedule-group-details.mutation.ts +2 -2
- package/src/api/scheduler/mutation/update-process-schedule-group-details.mutation.ts +2 -2
- package/src/api/templates/queries/template-input-search.query.ts +5 -0
- package/src/api/templates/queries/template-input-search.server.ts +8 -1
- package/src/api/templates/queries/types.ts +9 -3
- package/src/components/breadcrumbs/breadcrumbs.tsx +1 -1
- package/src/components/core/date-time-popover.tsx +1 -1
- package/src/components/core/drawer-buttons.tsx +1 -1
- package/src/components/core/edited-typography.tsx +1 -1
- package/src/components/core/title-edit.tsx +13 -11
- package/src/components/dashboard-list/dashboard-list.tsx +1 -1
- package/src/components/data-table/table-header.tsx +1 -1
- package/src/components/data-table/table-skeleton.tsx +1 -1
- package/src/components/execution-history-drawer/execution-history-drawer.tsx +1 -2
- package/src/components/header/integration-details-header.tsx +4 -0
- package/src/components/integration-list/list/integration-list-row.tsx +2 -2
- package/src/components/integration-list/list/integration-list-table.tsx +3 -3
- package/src/components/integration-list/list/integration-list.tsx +3 -3
- package/src/components/integration-view/edges/default-edge.tsx +1 -5
- package/src/components/integration-view/flow-types.tsx +2 -0
- package/src/components/integration-view/integration-view.tsx +148 -577
- package/src/components/integration-view/nodes/add-node.tsx +20 -0
- package/src/components/integration-view/nodes/group-node.tsx +15 -1
- package/src/components/integration-view/nodes/task-node.tsx +38 -10
- package/src/components/integration-view/temp-data/initialElements.tsx +0 -2
- package/src/components/integration-view/utils/mapping.ts +404 -0
- package/src/components/layouts/main-layout.tsx +1 -1
- package/src/components/layouts/root-container.tsx +2 -5
- package/src/components/link-cards/link-card.tsx +1 -1
- package/src/components/list-filter/date-filter.tsx +3 -1
- package/src/components/list-filter/date-range-filter.tsx +4 -2
- package/src/components/list-filter/list-filter.tsx +1 -1
- package/src/components/list-filter/select-filter.tsx +10 -4
- package/src/components/scheduler/schedule-drawer/schedule-details-integrations.tsx +6 -8
- package/src/components/scheduler/schedule-drawer/schedule-details-main.tsx +1 -1
- package/src/components/scheduler/schedule-drawer/schedule-details-name.tsx +1 -1
- package/src/components/scheduler/schedule-drawer/schedule-details.tsx +1 -1
- package/src/components/scheduler/schedule-drawer/schedule-drawer-group.tsx +4 -8
- package/src/components/scheduler/schedule-drawer/schedule-drawer-legacy.tsx +1 -1
- package/src/components/scheduler/schedule-drawer/schedule-drawer.tsx +2 -2
- package/src/components/scheduler/schedule-drawer/sortable-integration-row.tsx +1 -1
- package/src/components/templates/inputs/index.tsx +162 -121
- package/src/components/templates/templates-list/templates-list-table.tsx +2 -2
- package/src/components/templates/templates-list/templates-list.tsx +1 -1
- package/src/components/templates/types.tsx +1 -0
- package/src/components/templates/wizard.tsx +98 -50
- package/src/pages/dashboard/dashboard-list-sections.tsx +2 -2
- package/src/pages/execution-details/execution-details.tsx +4 -3
- package/src/pages/execution-details/task-execution-details.tsx +1 -1
- package/src/pages/execution-details/task-execution-drawer.tsx +1 -1
- package/src/pages/executions/executions-list/executions-list-table.tsx +1 -1
- package/src/pages/integration-create/integration-create.tsx +87 -45
- package/src/pages/integration-create/pre-creation-step.tsx +77 -5
- package/src/pages/integration-create/select-step.tsx +1 -1
- package/src/pages/integration-create/wizard-step.tsx +2 -1
- package/src/pages/integration-details/import-process/copy-tasks-list.tsx +2 -2
- package/src/pages/integration-details/import-process/copy-tasks-row.tsx +1 -1
- package/src/pages/integration-details/import-process/import-confirm.tsx +1 -1
- package/src/pages/integration-details/import-process/import-drawer.tsx +1 -1
- package/src/pages/integration-details/import-process/import-process.tsx +1 -1
- package/src/pages/integration-details/integration-details.tsx +290 -43
- package/src/pages/integration-details/task-drawer/add-task.tsx +65 -13
- package/src/pages/integration-details/task-drawer/edit-task.tsx +69 -83
- package/src/pages/integration-details/task-drawer/task-drawer.tsx +22 -4
- package/src/pages/integration-details/task-drawer/task-reducer.ts +32 -2
- package/src/pages/scheduler/schedules-list/schedules-list-table.tsx +1 -1
|
@@ -1,12 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
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
|
-
|
|
11
|
-
|
|
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(
|
|
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
|
|
|
@@ -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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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[] =
|
|
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
|
-
|
|
124
|
-
|
|
281
|
+
setViewRefreshKey(Date.now());
|
|
282
|
+
}, [data, config]);
|
|
283
|
+
|
|
284
|
+
useEffect(() => {
|
|
285
|
+
if (!scheduleLoading) {
|
|
125
286
|
setViewRefreshKey(Date.now());
|
|
126
287
|
}
|
|
127
|
-
}, [
|
|
288
|
+
}, [scheduleLoading]);
|
|
128
289
|
|
|
129
|
-
|
|
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={
|
|
316
|
+
name={
|
|
317
|
+
(config || (configFromApi as any)?.configurationExport)?.Processes[0]
|
|
318
|
+
?.Name || "Untitled Integration"
|
|
319
|
+
}
|
|
142
320
|
icon={details?.processById?.processIcon ?? ""}
|
|
143
|
-
setName={() => {
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
}
|