@evenicanpm/admin-integrate 1.2.2 → 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 (215) 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 +30 -0
  5. package/documents/Process/fragments.ts +22 -0
  6. package/documents/Process/get-process-details.ts +72 -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/ProcessExport/read.ts +108 -0
  15. package/documents/ProcessScheduleGroup/read.ts +43 -0
  16. package/documents/ProcessTask/fragments.ts +288 -0
  17. package/documents/ProcessTask/read.ts +12 -0
  18. package/documents/ProcessTemplate/fragments.ts +74 -0
  19. package/documents/ProcessTemplate/list.ts +67 -0
  20. package/documents/ProcessTemplate/read.ts +12 -0
  21. package/documents/RunProcess/run.ts +11 -0
  22. package/package.json +4 -3
  23. package/src/api/Integrations/queries/get-process.query.ts +12 -12
  24. package/src/api/Integrations/queries/get-process.server.ts +7 -2
  25. package/src/api/configuration/queries/configuration-export.query.ts +48 -0
  26. package/src/api/configuration/queries/configuration-export.server.ts +9 -0
  27. package/src/api/configuration/queries/index.ts +1 -0
  28. package/src/api/dashboard/queries/get-process-executions.query.ts +6 -3
  29. package/src/api/dashboard/queries/get-process-executions.server.ts +1 -1
  30. package/src/api/execution-details/queries/get-process-execution-details.query.ts +46 -0
  31. package/src/api/execution-details/queries/get-process-execution-details.server.ts +11 -0
  32. package/src/api/execution-details/queries/get-process-executions-by-process.query.ts +48 -0
  33. package/src/api/execution-details/queries/get-process-executions-by-process.server.ts +11 -0
  34. package/src/api/execution-details/queries/index.ts +2 -0
  35. package/src/api/process/mutations/copy-process.mutation.ts +45 -0
  36. package/src/api/process/mutations/copy-process.server.ts +14 -0
  37. package/src/api/process/mutations/index.ts +2 -0
  38. package/src/api/process/mutations/run-process.mutation.ts +41 -0
  39. package/src/api/process/mutations/run-process.server.ts +14 -0
  40. package/src/api/process/queries/get-process-by-id.query.ts +85 -0
  41. package/src/api/process/queries/get-process-by-id.server.ts +20 -0
  42. package/src/api/process/queries/index.ts +4 -0
  43. package/src/api/process-config/mutation/index.ts +2 -0
  44. package/src/api/process-config/mutation/process-config-import.mutation.ts +42 -0
  45. package/src/api/process-config/mutation/process-config-import.server.ts +14 -0
  46. package/src/api/process-config/mutation/process-config-merge.mutation.ts +33 -0
  47. package/src/api/process-config/mutation/process-config-merge.server.ts +14 -0
  48. package/src/api/process-task/queries/get-process-task-by-id.query.ts +46 -0
  49. package/src/api/process-task/queries/get-process-task-by-id.server.ts +9 -0
  50. package/src/api/process-task/queries/index.ts +1 -0
  51. package/src/api/scheduler/mutation/create-process-schedule-group-details.mutation.ts +47 -0
  52. package/src/api/scheduler/mutation/create-process-schedule-group-details.server.ts +14 -0
  53. package/src/api/scheduler/mutation/index.ts +2 -0
  54. package/src/api/scheduler/mutation/update-process-schedule-group-details.mutation.ts +47 -0
  55. package/src/api/scheduler/mutation/update-process-schedule-group-details.server.ts +14 -0
  56. package/src/api/scheduler/queries/get-non-scheduled-processes.query.ts +48 -0
  57. package/src/api/scheduler/queries/get-non-scheduled-processes.server.ts +11 -0
  58. package/src/api/scheduler/queries/get-process-schedule-group-details.query.ts +6 -3
  59. package/src/api/scheduler/queries/get-process-schedule-group-details.server.ts +3 -3
  60. package/src/api/scheduler/queries/get-process-schedule.query.ts +6 -3
  61. package/src/api/scheduler/queries/get-process-schedule.server.ts +3 -3
  62. package/src/api/scheduler/queries/get-scheduled-processes.query.ts +6 -3
  63. package/src/api/scheduler/queries/get-scheduled-processes.server.ts +1 -1
  64. package/src/api/scheduler/queries/index.ts +3 -2
  65. package/src/api/templates/queries/get-process-template-groups.query.ts +48 -0
  66. package/src/api/templates/queries/get-process-template-groups.server.ts +11 -0
  67. package/src/api/templates/queries/get-process-template-records.query.ts +48 -0
  68. package/src/api/templates/queries/get-process-template-records.server.ts +11 -0
  69. package/src/api/templates/queries/get-process-template.query.ts +48 -0
  70. package/src/api/templates/queries/get-process-template.server.ts +9 -0
  71. package/src/api/templates/queries/get-process-templates.query.ts +45 -0
  72. package/src/api/templates/queries/get-process-templates.server.ts +9 -0
  73. package/src/api/templates/queries/index.ts +5 -0
  74. package/src/api/templates/queries/template-input-search.query.ts +39 -0
  75. package/src/api/templates/queries/template-input-search.server.ts +42 -0
  76. package/src/api/templates/queries/types.ts +34 -0
  77. package/src/components/breadcrumbs/breadcrumbs.tsx +33 -6
  78. package/src/components/button/outlined-icon-button.tsx +2 -2
  79. package/src/components/core/date-time-popover.tsx +12 -5
  80. package/src/components/core/drawer-buttons.tsx +52 -0
  81. package/src/components/core/edited-typography.tsx +2 -2
  82. package/src/components/core/index.ts +4 -2
  83. package/src/components/core/loading.tsx +1 -1
  84. package/src/components/core/status-tag.tsx +97 -0
  85. package/src/components/core/title-edit.tsx +31 -22
  86. package/src/components/dashboard-list/dashboard-list-row.tsx +22 -29
  87. package/src/components/dashboard-list/dashboard-list.tsx +20 -16
  88. package/src/components/data-table/table-header.tsx +6 -8
  89. package/src/components/data-table/table-pagination.tsx +1 -1
  90. package/src/components/data-table/table-row.tsx +1 -1
  91. package/src/components/data-table/table-skeleton.tsx +10 -5
  92. package/src/components/execution/execution-filter.ts +1 -1
  93. package/src/components/execution/execution-status-icon.tsx +7 -7
  94. package/src/components/execution/execution-tag.tsx +12 -77
  95. package/src/components/execution/index.ts +1 -1
  96. package/src/components/execution-history-drawer/execution-history-drawer.tsx +202 -0
  97. package/src/components/execution-history-drawer/executions-card.tsx +85 -0
  98. package/src/components/execution-history-drawer/index.ts +1 -0
  99. package/src/components/footer/footer.tsx +10 -6
  100. package/src/components/header/dashboard-list-header.tsx +12 -7
  101. package/src/components/header/execution-details-header.tsx +35 -26
  102. package/src/components/header/header.tsx +10 -3
  103. package/src/components/header/index.ts +1 -1
  104. package/src/components/header/integration-details-header.tsx +108 -45
  105. package/src/components/integration-list/index.ts +2 -1
  106. package/src/components/integration-list/integration-filter.ts +1 -1
  107. package/src/components/integration-list/integration-status-icon.tsx +7 -8
  108. package/src/components/integration-list/integration-tag.tsx +6 -50
  109. package/src/components/integration-list/list/integration-list-row.tsx +161 -0
  110. package/src/components/integration-list/list/integration-list-table.tsx +62 -0
  111. package/src/{pages/integrations/integration-list → components/integration-list/list}/integration-list.tsx +47 -51
  112. package/src/components/integration-view/animated-svg.tsx +31 -0
  113. package/src/components/integration-view/edges/default-edge.tsx +2 -6
  114. package/src/components/integration-view/elk-layout-options.ts +2 -2
  115. package/src/components/integration-view/elk-types.ts +35 -6
  116. package/src/components/integration-view/flow-types.tsx +12 -0
  117. package/src/components/integration-view/integration-view.tsx +562 -56
  118. package/src/components/integration-view/nodes/add-node.tsx +20 -0
  119. package/src/components/integration-view/nodes/empty-node.tsx +65 -0
  120. package/src/components/integration-view/nodes/entry-node.tsx +98 -4
  121. package/src/components/integration-view/nodes/execution-entry-node.tsx +107 -0
  122. package/src/components/integration-view/nodes/execution-task-node.tsx +88 -0
  123. package/src/components/integration-view/nodes/group-node.tsx +33 -13
  124. package/src/components/integration-view/nodes/row-node.tsx +19 -0
  125. package/src/components/integration-view/nodes/task-node.tsx +50 -16
  126. package/src/components/integration-view/task-icon.tsx +193 -0
  127. package/src/components/integration-view/temp-data/initialElements.tsx +34 -32
  128. package/src/components/integration-view/types.ts +2 -2
  129. package/src/components/integration-view/utils/mapping.ts +404 -0
  130. package/src/components/layouts/main-layout.tsx +3 -4
  131. package/src/components/layouts/root-container.tsx +5 -11
  132. package/src/components/link-cards/link-card.tsx +15 -4
  133. package/src/components/link-cards/styles.ts +1 -1
  134. package/src/components/list-filter/date-filter.tsx +7 -4
  135. package/src/components/list-filter/date-range-filter.tsx +15 -7
  136. package/src/components/list-filter/index.ts +1 -1
  137. package/src/components/list-filter/list-filter.tsx +31 -26
  138. package/src/components/list-filter/multi-select-filter.tsx +11 -10
  139. package/src/components/list-filter/select-filter.tsx +23 -12
  140. package/src/components/scheduler/day-selector.tsx +29 -15
  141. package/src/components/scheduler/day-tag.tsx +14 -51
  142. package/src/components/scheduler/index.ts +2 -1
  143. package/src/components/scheduler/schedule-drawer/details-reducer.ts +217 -0
  144. package/src/components/scheduler/schedule-drawer/schedule-details-integrations.tsx +501 -0
  145. package/src/{pages → components}/scheduler/schedule-drawer/schedule-details-main.tsx +137 -100
  146. package/src/components/scheduler/schedule-drawer/schedule-details-name.tsx +94 -0
  147. package/src/{pages → components}/scheduler/schedule-drawer/schedule-details-skeleton.tsx +1 -2
  148. package/src/{pages → components}/scheduler/schedule-drawer/schedule-details.tsx +10 -14
  149. package/src/components/scheduler/schedule-drawer/schedule-drawer-group.tsx +214 -0
  150. package/src/{pages → components}/scheduler/schedule-drawer/schedule-drawer-legacy.tsx +7 -26
  151. package/src/components/scheduler/schedule-drawer/schedule-drawer.tsx +116 -0
  152. package/src/components/scheduler/schedule-drawer/sortable-integration-row.tsx +130 -0
  153. package/src/components/scheduler/schedule-filter.ts +1 -1
  154. package/src/components/scheduler/schedule-icon.tsx +5 -6
  155. package/src/components/scheduler/schedule-integration-icon.tsx +31 -0
  156. package/src/components/templates/index.ts +1 -0
  157. package/src/components/templates/inputs/index.tsx +1392 -0
  158. package/src/components/templates/template-filter.ts +5 -0
  159. package/src/components/templates/templates-list/index.ts +1 -0
  160. package/src/components/templates/templates-list/templates-list-row.tsx +55 -0
  161. package/src/components/templates/templates-list/templates-list-table.tsx +58 -0
  162. package/src/components/templates/templates-list/templates-list.tsx +253 -0
  163. package/src/components/templates/types.tsx +76 -0
  164. package/src/components/templates/wizard.tsx +737 -0
  165. package/src/hooks/use-breadcrumbs.ts +1 -1
  166. package/src/hooks/use-recurrence.tsx +1 -2
  167. package/src/pages/dashboard/dashboard-link-cards.tsx +8 -11
  168. package/src/pages/dashboard/dashboard-list-sections.tsx +8 -10
  169. package/src/pages/dashboard/dashboard.tsx +1 -2
  170. package/src/pages/execution-details/execution-details.tsx +212 -14
  171. package/src/pages/execution-details/task-execution-details.tsx +160 -0
  172. package/src/pages/execution-details/task-execution-drawer.tsx +54 -0
  173. package/src/pages/executions/executions-list/executions-list-row.tsx +21 -27
  174. package/src/pages/executions/executions-list/executions-list-table.tsx +29 -36
  175. package/src/pages/executions/executions-list/executions-list.tsx +24 -18
  176. package/src/pages/executions/executions.tsx +11 -15
  177. package/src/pages/integration-create/index.ts +1 -0
  178. package/src/pages/integration-create/integration-create.tsx +216 -0
  179. package/src/pages/integration-create/pre-creation-step.tsx +84 -0
  180. package/src/pages/integration-create/select-step.tsx +105 -0
  181. package/src/pages/integration-create/template-list-step.tsx +77 -0
  182. package/src/pages/integration-create/wizard-step.tsx +51 -0
  183. package/src/pages/integration-details/import-process/copy-tasks-list.tsx +265 -0
  184. package/src/pages/integration-details/import-process/copy-tasks-row.tsx +77 -0
  185. package/src/pages/integration-details/import-process/import-confirm.tsx +61 -0
  186. package/src/pages/integration-details/import-process/import-drawer.tsx +48 -0
  187. package/src/pages/integration-details/import-process/import-process-reducer.ts +90 -0
  188. package/src/pages/integration-details/import-process/import-process.tsx +149 -0
  189. package/src/pages/integration-details/index.ts +1 -0
  190. package/src/pages/integration-details/integration-details.tsx +468 -0
  191. package/src/pages/integration-details/task-drawer/add-task.tsx +172 -0
  192. package/src/pages/integration-details/task-drawer/edit-task.tsx +161 -0
  193. package/src/pages/integration-details/task-drawer/task-drawer.tsx +157 -0
  194. package/src/pages/integration-details/task-drawer/task-reducer.ts +103 -0
  195. package/src/pages/integrations/integrations.tsx +11 -14
  196. package/src/pages/scheduler/scheduler.tsx +12 -24
  197. package/src/pages/scheduler/schedules-list/schedules-list-row.tsx +27 -37
  198. package/src/pages/scheduler/schedules-list/schedules-list-table.tsx +28 -43
  199. package/src/pages/scheduler/schedules-list/schedules-list.tsx +48 -21
  200. package/src/utils/date-functions.ts +69 -0
  201. package/src/utils/slugify.ts +3 -0
  202. package/tsconfig.json +12 -4
  203. package/src/hooks/use-timestamp.tsx +0 -25
  204. package/src/pages/integrations/integration-list/integration-list-row.tsx +0 -147
  205. package/src/pages/integrations/integration-list/integration-list-table.tsx +0 -78
  206. package/src/pages/scheduler/schedule-drawer/schedule-details-integrations.tsx +0 -227
  207. package/src/pages/scheduler/schedule-drawer/schedule-details-name.tsx +0 -77
  208. package/src/pages/scheduler/schedule-drawer/schedule-drawer-buttons.tsx +0 -72
  209. package/src/pages/scheduler/schedule-drawer/schedule-drawer-group.tsx +0 -103
  210. package/src/pages/scheduler/schedule-drawer/schedule-drawer.tsx +0 -101
  211. package/src/pages/scheduler/schedule-drawer/sortable-integration-row.tsx +0 -93
  212. /package/src/{pages/integrations/integration-list → components/integration-list/list}/index.ts +0 -0
  213. /package/src/{pages → components}/scheduler/schedule-drawer/edited/edited-types.ts +0 -0
  214. /package/src/{pages → components}/scheduler/schedule-drawer/edited/index.ts +0 -0
  215. /package/src/{pages → components}/scheduler/schedule-drawer/index.ts +0 -0
@@ -0,0 +1,202 @@
1
+ "use client";
2
+ import type {
3
+ GetProcessExecutionsByProcessQuery,
4
+ ProcessExecutionInput,
5
+ } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
6
+ import { FlexBox } from "@evenicanpm/admin-core/components/flex-box";
7
+ import { TablePagination } from "@evenicanpm/admin-integrate/components/data-table";
8
+ import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
9
+ import {
10
+ Box,
11
+ Card,
12
+ Grid2 as Grid,
13
+ Stack,
14
+ type Theme,
15
+ Typography,
16
+ useTheme,
17
+ } from "@mui/material";
18
+ import IconButton from "@mui/material/IconButton";
19
+ import { useTranslations } from "next-intl";
20
+ import type React from "react";
21
+ import { useEffect, useState } from "react";
22
+ import ExecutionsCard from "./executions-card";
23
+
24
+ // Returned from processExecutionsByProcess query
25
+ export interface Item {
26
+ id: string;
27
+ name: string;
28
+ startDate: string;
29
+ executionStatus: {
30
+ id: string;
31
+ };
32
+ }
33
+
34
+ interface Props {
35
+ data: GetProcessExecutionsByProcessQuery;
36
+ loading: boolean;
37
+ input: ProcessExecutionInput;
38
+ setInput: (newInput: ProcessExecutionInput) => void;
39
+ drawerOpen?: boolean;
40
+ setDrawerOpen?: (open: boolean) => void;
41
+ }
42
+
43
+ const ExecutionHistoryDrawer: React.FC<Props> = (props: Props) => {
44
+ const t = useTranslations("Integrate.Executions");
45
+
46
+ const theme = useTheme();
47
+ const styles = getStyles(theme);
48
+
49
+ const [items, setItems] = useState<Item[]>([]);
50
+ const [fetched, setFetched] = useState<boolean>(false); // prevents "empty list" msg from showing for split second
51
+
52
+ useEffect(() => {
53
+ if (props.data?.processExecutionsByProcess?.nodes) {
54
+ setItems(props.data.processExecutionsByProcess.nodes as Item[]);
55
+ setFetched(true);
56
+ }
57
+ }, [props.data]);
58
+
59
+ const handleChangePage = (
60
+ event: React.ChangeEvent<unknown>,
61
+ value: number,
62
+ ) => {
63
+ const page = (props.input.skip || 0) / (props.input.top || 10) + 1;
64
+ if (page !== value && event) {
65
+ props.setInput({
66
+ ...props.input,
67
+ skip: (props.input.top || 10) * (value - 1),
68
+ });
69
+ setFetched(false);
70
+ }
71
+ };
72
+ // Toggle drawer open/close
73
+ const toggleDrawer = () => {
74
+ if (props.setDrawerOpen) props.setDrawerOpen(!props.drawerOpen);
75
+ };
76
+
77
+ return (
78
+ <Box
79
+ sx={{
80
+ width: props.drawerOpen ? 345 : 43,
81
+ //transition: "width 0.3s ease",
82
+ backgroundColor: theme.palette.background.default,
83
+ borderRight: `1px solid ${theme.palette.grey[400]}`,
84
+ display: "flex",
85
+ flexDirection: "column",
86
+ alignItems: "flex-start",
87
+ position: "relative",
88
+ overflow: "auto",
89
+ }}
90
+ >
91
+ <Box
92
+ sx={{
93
+ display: "flex",
94
+ alignItems: "center",
95
+ justifyContent: "center",
96
+ width: "100%",
97
+ p: 1,
98
+ borderBottom: `1px solid ${theme.palette.divider}`,
99
+ }}
100
+ >
101
+ {props.drawerOpen && (
102
+ <Typography
103
+ variant="subtitle1"
104
+ align="center"
105
+ sx={{
106
+ fontWeight: 600,
107
+ flex: 1,
108
+ padding: theme.spacing(0, 0, 0, 2),
109
+ }}
110
+ >
111
+ {t("ExecutionsDetail.history")}
112
+ </Typography>
113
+ )}
114
+ <IconButton
115
+ onClick={toggleDrawer}
116
+ size="small"
117
+ sx={{
118
+ transition: "transform 0.3s ease",
119
+ transform: props.drawerOpen ? "rotate(180deg)" : "rotate(0deg)",
120
+ }}
121
+ >
122
+ <KeyboardDoubleArrowRightIcon />
123
+ </IconButton>
124
+ </Box>
125
+ {props.drawerOpen &&
126
+ props?.data?.processExecutionsByProcess?.nodes?.map((item) => (
127
+ <ExecutionsCard key={item?.id as string} item={item as Item} />
128
+ ))}
129
+
130
+ {!props.loading && props.drawerOpen && fetched && items.length === 0 ? (
131
+ <Card
132
+ sx={{
133
+ background: "transparent",
134
+ textAlign: "center",
135
+ padding: theme.spacing(0, 2),
136
+ boxShadow: "none",
137
+ }}
138
+ >
139
+ <FlexBox
140
+ justifyContent="center"
141
+ alignItems="center"
142
+ sx={{
143
+ minHeight: "335px",
144
+ marginBottom: theme.spacing(2),
145
+ background: "transparent",
146
+ }}
147
+ >
148
+ <Stack spacing={1} justifyContent="center" alignItems="center">
149
+ <Typography variant="h6" color="info">
150
+ {t("ListEmpty.title")}
151
+ </Typography>
152
+ <Typography variant="body1">{t("ListEmpty.body")}</Typography>
153
+ </Stack>
154
+ </FlexBox>
155
+ </Card>
156
+ ) : null}
157
+
158
+ {!props.loading &&
159
+ props.data?.processExecutionsByProcess &&
160
+ fetched &&
161
+ props.drawerOpen &&
162
+ items.length > 0 ? (
163
+ <Grid container spacing={1} sx={styles.pagination}>
164
+ <Grid size={{ xs: 10.5 }}>
165
+ <FlexBox
166
+ justifyContent="center"
167
+ alignItems="center"
168
+ sx={styles.paginationBox}
169
+ >
170
+ <TablePagination
171
+ page={(props.input.skip || 0) / (props.input.top || 10) + 1}
172
+ onChange={handleChangePage}
173
+ count={Math.ceil(
174
+ (props.data.processExecutionsByProcess.recordCount || 10) /
175
+ (props.input.top || 10),
176
+ )}
177
+ />
178
+ </FlexBox>
179
+ </Grid>
180
+ </Grid>
181
+ ) : null}
182
+ </Box>
183
+ );
184
+ };
185
+
186
+ const getStyles = (theme: Theme) => {
187
+ return {
188
+ iconButton: {
189
+ borderRadius: 1,
190
+ },
191
+ pagination: {
192
+ marginTop: "auto",
193
+ width: "100%",
194
+ },
195
+ paginationBox: {
196
+ paddingLeft: theme.spacing(0),
197
+ width: "100%",
198
+ },
199
+ };
200
+ };
201
+
202
+ export default ExecutionHistoryDrawer;
@@ -0,0 +1,85 @@
1
+ import {
2
+ ExecutionStatusIcon,
3
+ ExecutionTag,
4
+ } from "@evenicanpm/admin-integrate/components/execution";
5
+ import { toShortDate } from "@evenicanpm/admin-integrate/utils/date-functions";
6
+ import { Box, Card, Typography, useTheme } from "@mui/material";
7
+ import { useParams, useRouter, useSearchParams } from "next/navigation";
8
+ import type React from "react";
9
+ import type { Item } from "./execution-history-drawer";
10
+
11
+ interface Props {
12
+ item: Item;
13
+ }
14
+
15
+ const ExecutionsCard: React.FC<Props> = (props: Props) => {
16
+ const { item } = props;
17
+ const theme = useTheme();
18
+ const router = useRouter();
19
+ const params = useParams();
20
+ const searchParams = useSearchParams();
21
+
22
+ const processId = params?.processId as string;
23
+ const selectedExecutionId = searchParams.get("ExecutionId");
24
+
25
+ const isSelected = item.id.toString() === selectedExecutionId;
26
+
27
+ const handleChangeExecutionId = (newId: string) => {
28
+ router.push(`/e4integrate/executions/${processId}?ExecutionId=${newId}`);
29
+ };
30
+
31
+ return (
32
+ <Box
33
+ sx={{
34
+ padding: theme.spacing(0.5, 2),
35
+ width: "100%",
36
+ }}
37
+ >
38
+ <Card
39
+ onClick={() => handleChangeExecutionId(item.id.toString())}
40
+ sx={{
41
+ backgroundColor: isSelected ? "#DBF0FE" /* primary[100] */ : "white",
42
+ border: `1px solid ${isSelected ? "#4E97FD" /*primary[500]*/ : theme.palette.grey[400]}`,
43
+ boxShadow: "none",
44
+ borderRadius: 2.5,
45
+ width: "100%",
46
+ p: 1,
47
+ cursor: "pointer",
48
+ transition: "all 0.2s ease-in-out",
49
+ "&:hover": { boxShadow: 4 },
50
+ }}
51
+ >
52
+ {/* Top Row: Icon, Name, and Status */}
53
+ <Box display="flex" alignItems="center" justifyContent="space-between">
54
+ <Box display="flex" alignItems="center" gap={1}>
55
+ <ExecutionStatusIcon executionStatusId={item.executionStatus.id} />
56
+ <Typography
57
+ variant="subtitle1"
58
+ title={item.name}
59
+ fontWeight={600}
60
+ sx={{
61
+ whiteSpace: "nowrap",
62
+ overflow: "hidden",
63
+ textOverflow: "ellipsis",
64
+ maxWidth: 100,
65
+ }}
66
+ >
67
+ {item.name}
68
+ </Typography>
69
+ </Box>
70
+
71
+ <ExecutionTag executionStatusId={item.executionStatus.id} />
72
+ </Box>
73
+
74
+ <Typography
75
+ variant="body2"
76
+ sx={{ color: theme.palette.grey[500], mt: 1, ml: 0 }}
77
+ >
78
+ {toShortDate(item.startDate)}
79
+ </Typography>
80
+ </Card>
81
+ </Box>
82
+ );
83
+ };
84
+
85
+ export default ExecutionsCard;
@@ -0,0 +1 @@
1
+ export { default as ExecutionHistoryDrawer } from "./execution-history-drawer";
@@ -1,11 +1,15 @@
1
- import React from "react";
2
- import { useTranslations } from "next-intl";
3
-
1
+ import { Copyright } from "@mui/icons-material";
4
2
  // MUI
5
- import { Theme, useTheme } from "@mui/material";
3
+ import {
4
+ Box,
5
+ Grid2 as Grid,
6
+ type Theme,
7
+ Typography,
8
+ useTheme,
9
+ } from "@mui/material";
6
10
  import styled from "@mui/material/styles/styled";
7
- import { Typography, Box, Grid2 as Grid } from "@mui/material";
8
- import { Copyright } from "@mui/icons-material";
11
+ import { useTranslations } from "next-intl";
12
+ import type React from "react";
9
13
 
10
14
  // Styled components
11
15
  const Footer = styled("footer")(() => ({
@@ -1,11 +1,16 @@
1
- import React from "react";
2
- import { redirect, RedirectType } from "next/navigation";
3
- import { useTranslations } from "next-intl";
4
-
5
- // MUI
6
- import { Theme, useTheme } from "@mui/material";
7
- import { Grid2 as Grid, Box, Typography, Button } from "@mui/material";
8
1
  import { Refresh, VisibilityOutlined } from "@mui/icons-material";
2
+ // MUI
3
+ import {
4
+ Box,
5
+ Button,
6
+ Grid2 as Grid,
7
+ type Theme,
8
+ Typography,
9
+ useTheme,
10
+ } from "@mui/material";
11
+ import { RedirectType, redirect } from "next/navigation";
12
+ import { useTranslations } from "next-intl";
13
+ import type React from "react";
9
14
 
10
15
  // Custom components
11
16
  import { OutlinedIconButton } from "../button";
@@ -1,17 +1,24 @@
1
- import React, { useState } from "react";
2
-
3
- // MUI
4
- import { Theme, useTheme } from "@mui/material";
5
- import { Grid2 as Grid, Typography, Stack } from "@mui/material";
6
-
7
- // Custom components
8
- import { ExecutionTag } from "@evenicanpm/admin-integrate/components/execution";
9
1
  import { DateTimePopover } from "@evenicanpm/admin-integrate/components/core";
2
+ import { ExecutionTag } from "@evenicanpm/admin-integrate/components/execution";
3
+ import {
4
+ toDurationDate,
5
+ toShortDate,
6
+ } from "@evenicanpm/admin-integrate/utils/date-functions";
7
+ import {
8
+ Grid2 as Grid,
9
+ Stack,
10
+ type Theme,
11
+ Typography,
12
+ useTheme,
13
+ } from "@mui/material";
14
+ import { useTranslations } from "next-intl";
15
+ import type React from "react";
16
+ import { useState } from "react";
10
17
 
11
- interface Execution {
18
+ export interface Execution {
12
19
  name: string;
13
20
  startDate: string;
14
- endDate: string;
21
+ endDate?: string;
15
22
  executionStatus: {
16
23
  id: string;
17
24
  };
@@ -23,13 +30,14 @@ interface Props {
23
30
  }
24
31
 
25
32
  const ExecutionDetailsHeader: React.FC<Props> = (props: Props) => {
33
+ const t = useTranslations("Integrate");
34
+
26
35
  const theme = useTheme();
27
36
  const styles = getStyles(theme);
28
37
 
29
- const startDate = new Date(props.execution.startDate);
30
- const endDate = new Date(props.execution.endDate);
31
- const localTime = startDate.toLocaleString();
32
- const duration = (endDate.getTime() - startDate.getTime()) / 1000;
38
+ const duration = props.execution.endDate
39
+ ? toDurationDate(props.execution.startDate, props.execution.endDate)
40
+ : "";
33
41
 
34
42
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
35
43
  const open = Boolean(anchorEl);
@@ -41,7 +49,6 @@ const ExecutionDetailsHeader: React.FC<Props> = (props: Props) => {
41
49
  const handlePopoverClose = () => {
42
50
  setAnchorEl(null);
43
51
  };
44
-
45
52
  return (
46
53
  <Grid container columnSpacing={1}>
47
54
  <Grid size={8}>
@@ -66,18 +73,20 @@ const ExecutionDetailsHeader: React.FC<Props> = (props: Props) => {
66
73
  </Stack>
67
74
  </Grid>
68
75
  <Grid size={12}>
69
- <Stack
70
- spacing={1}
71
- direction="row"
72
- onMouseEnter={handlePopoverOpen}
73
- onMouseLeave={handlePopoverClose}
74
- >
75
- <Typography color="grey" variant="caption">
76
- {localTime}
77
- </Typography>
78
- <Typography color="grey" variant="caption">
79
- Duration: {duration}s
76
+ <Stack spacing={1} direction="row">
77
+ <Typography
78
+ color="grey"
79
+ variant="caption"
80
+ onMouseEnter={handlePopoverOpen}
81
+ onMouseLeave={handlePopoverClose}
82
+ >
83
+ {toShortDate(props.execution.startDate)}
80
84
  </Typography>
85
+ {duration && (
86
+ <Typography color="grey" variant="caption">
87
+ {t("Executions.duration")}: {duration}
88
+ </Typography>
89
+ )}
81
90
  </Stack>
82
91
  </Grid>
83
92
  <DateTimePopover
@@ -1,6 +1,13 @@
1
- import React from "react";
2
- import { Box, Typography, AppBar, Toolbar, Stack } from "@mui/material";
3
- import { Theme, useTheme } from "@mui/material";
1
+ import {
2
+ AppBar,
3
+ Box,
4
+ Stack,
5
+ type Theme,
6
+ Toolbar,
7
+ Typography,
8
+ useTheme,
9
+ } from "@mui/material";
10
+ import type React from "react";
4
11
 
5
12
  interface Props {
6
13
  title: string; // e.g. Executions
@@ -1,4 +1,4 @@
1
- export { default as IntegrateHeader } from "./header";
2
1
  export { default as DashboardListHeader } from "./dashboard-list-header";
3
2
  export { default as ExecutionDetailsHeader } from "./execution-details-header";
3
+ export { default as IntegrateHeader } from "./header";
4
4
  export { default as IntegrationDetailsHeader } from "./integration-details-header";
@@ -1,29 +1,37 @@
1
- import React from "react";
2
- import { useTranslations } from "next-intl";
3
-
4
- // MUI
5
- import { Theme, useTheme } from "@mui/material";
6
- import { Grid2 as Grid, Stack, Divider, Button, Box } from "@mui/material";
7
1
  import {
8
- InfoOutlined,
2
+ StatusTag,
3
+ TitleEdit,
4
+ } from "@evenicanpm/admin-integrate/components/core";
5
+ import { IntegrationStatusIcon } from "@evenicanpm/admin-integrate/components/integration-list";
6
+ import {
7
+ AccessTime,
9
8
  Code,
10
9
  FileUploadOutlined,
11
10
  PlayArrowOutlined,
12
11
  } from "@mui/icons-material";
13
-
14
- // Custom components
15
- import { TitleEdit } from "@evenicanpm/admin-integrate/components/core";
16
-
17
- // TODO: when applying on page, change to use type of API query result
18
- type DetailsTemp = {
19
- name: string;
20
- processIcon: string;
21
- };
12
+ import {
13
+ Box,
14
+ Button,
15
+ Divider,
16
+ Grid2 as Grid,
17
+ Stack,
18
+ type SxProps,
19
+ type Theme,
20
+ useTheme,
21
+ } from "@mui/material";
22
+ import { useTranslations } from "next-intl";
22
23
 
23
24
  interface Props {
24
- details: DetailsTemp;
25
- setDetails: (newDetails: DetailsTemp) => void;
25
+ name: string;
26
+ setName: React.Dispatch<React.SetStateAction<string>>;
27
+ onImportClick?: React.MouseEventHandler<HTMLButtonElement>;
28
+ onScheduleClick?: React.MouseEventHandler<HTMLButtonElement>;
29
+ onExecutionsClick?: React.MouseEventHandler<HTMLButtonElement>;
30
+ icon?: string;
26
31
  children?: React.ReactNode; // buttons to go in header, e.g. save, cancel etc.
32
+ toolbar?: "enabled" | "disabled" | "hidden";
33
+ draft?: boolean;
34
+ untitled?: boolean;
27
35
  }
28
36
 
29
37
  const IntegrationDetailsHeader: React.FC<Props> = (props: Props) => {
@@ -33,24 +41,39 @@ const IntegrationDetailsHeader: React.FC<Props> = (props: Props) => {
33
41
  const styles = getStyles(theme);
34
42
 
35
43
  const onConfirm = (input: string) => {
36
- props.setDetails({ ...props.details, name: input });
44
+ props.setName(input);
37
45
  };
38
46
 
47
+ const toolbarStyles: SxProps =
48
+ props.toolbar === "disabled"
49
+ ? {
50
+ ...styles.controlsButton,
51
+ color: theme.palette.grey[100],
52
+ borderColor: theme.palette.grey[300],
53
+ }
54
+ : styles.controlsButton;
55
+
39
56
  return (
40
- <Grid container rowSpacing={1} columnSpacing={0}>
41
- <Grid size={{ xs: 12, sm: 8 }}>
57
+ <Grid container rowSpacing={1} columnSpacing={0} sx={styles.root}>
58
+ <Grid
59
+ size={{ xs: 12, sm: 8 }}
60
+ pl={2}
61
+ pt={1}
62
+ display="flex"
63
+ alignItems="center"
64
+ >
42
65
  <Stack spacing={1} direction="row" alignItems="center">
43
- {/* TODO: Apply Process icon component once that is merged. Using temp icon for now */}
44
- <InfoOutlined color="info" />
66
+ <IntegrationStatusIcon processIcon={props.icon || "noIcon"} />
45
67
 
46
- <TitleEdit
47
- title={props.details.name}
48
- onConfirm={onConfirm}
49
- variant="h5"
50
- />
68
+ <TitleEdit title={props.name} onConfirm={onConfirm} variant="h5" />
69
+
70
+ {props.untitled && <StatusTag type="warning" text={t("untitled")} />}
71
+ {props.draft && !props.untitled && (
72
+ <StatusTag type="info" text={t("draft")} />
73
+ )}
51
74
  </Stack>
52
75
  </Grid>
53
- <Grid size={{ xs: 12, sm: 4 }}>
76
+ <Grid size={{ xs: 12, sm: 4 }} pt={1} pr={2}>
54
77
  <Stack
55
78
  spacing={1}
56
79
  direction="row"
@@ -61,28 +84,68 @@ const IntegrationDetailsHeader: React.FC<Props> = (props: Props) => {
61
84
  {props.children}
62
85
  </Stack>
63
86
  </Grid>
64
- <Grid size={12}>
65
- <Divider sx={styles.divider} />
66
- </Grid>
67
- <Grid size={12}>
68
- <Stack direction="row">
69
- <Box sx={styles.controlsButton}>
70
- <Button startIcon={<Code />}>{t("codeView")}</Button>
71
- </Box>
72
- <Box sx={styles.controlsButton}>
73
- <Button startIcon={<FileUploadOutlined />}>{t("import")}</Button>
74
- </Box>
75
- <Box sx={{ ...styles.controlsButton, border: "none" }}>
76
- <Button startIcon={<PlayArrowOutlined />}>{t("executions")}</Button>
77
- </Box>
78
- </Stack>
79
- </Grid>
87
+
88
+ {(!props.toolbar || props.toolbar !== "hidden") && (
89
+ <>
90
+ <Grid size={12}>
91
+ <Divider sx={styles.divider} />
92
+ </Grid>
93
+ <Grid size={12} pb={1} pl={1} pr={1}>
94
+ <Stack direction="row">
95
+ <Box sx={toolbarStyles}>
96
+ <Button
97
+ startIcon={<Code />}
98
+ disabled={props.toolbar === "disabled"}
99
+ >
100
+ {t("codeView")}
101
+ </Button>
102
+ </Box>
103
+ <Box sx={toolbarStyles}>
104
+ <Button
105
+ startIcon={<FileUploadOutlined />}
106
+ disabled={props.toolbar === "disabled"}
107
+ onClick={(e) => {
108
+ if (props.onImportClick) props.onImportClick(e);
109
+ }}
110
+ >
111
+ {t("import")}
112
+ </Button>
113
+ </Box>
114
+ <Box sx={{ ...toolbarStyles }}>
115
+ <Button
116
+ startIcon={<AccessTime />}
117
+ disabled={props.toolbar === "disabled"}
118
+ onClick={(e) => {
119
+ if (props.onScheduleClick) props.onScheduleClick(e);
120
+ }}
121
+ >
122
+ {t("schedule")}
123
+ </Button>
124
+ </Box>
125
+ <Box sx={{ ...toolbarStyles, border: "none" }}>
126
+ <Button
127
+ startIcon={<PlayArrowOutlined />}
128
+ disabled={props.toolbar === "disabled"}
129
+ onClick={(e) => {
130
+ if (props.onExecutionsClick) props.onExecutionsClick(e);
131
+ }}
132
+ >
133
+ {t("executions")}
134
+ </Button>
135
+ </Box>
136
+ </Stack>
137
+ </Grid>
138
+ </>
139
+ )}
80
140
  </Grid>
81
141
  );
82
142
  };
83
143
 
84
144
  const getStyles = (theme: Theme) => {
85
145
  return {
146
+ root: {
147
+ backgroundColor: theme.palette.background.paper,
148
+ },
86
149
  divider: {
87
150
  border: `1px solid ${theme.palette.grey[500]}`,
88
151
  },
@@ -1,2 +1,3 @@
1
- export { default as IntegrationTag } from "./integration-tag";
2
1
  export { default as IntegrationStatusIcon } from "./integration-status-icon";
2
+ export { default as IntegrationTag } from "./integration-tag";
3
+ export { default as IntegrationList } from "./list";
@@ -1,4 +1,4 @@
1
- import {
1
+ import type {
2
2
  Filters,
3
3
  MultiSelectFilter,
4
4
  } from "@evenicanpm/admin-integrate/components/list-filter/list-filter-types";