@evenicanpm/admin-integrate 1.1.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/README.md +29 -0
- package/documents/ProcessExecution/fragments.ts +16 -0
- package/documents/ProcessExecution/list.ts +31 -0
- package/package.json +19 -0
- package/src/api/dashboard/queries/get-process-executions.query.ts +48 -0
- package/src/api/dashboard/queries/get-process-executions.server.ts +11 -0
- package/src/api/dashboard/queries/index.ts +1 -0
- package/src/auth/.keep +0 -0
- package/src/auth/types/.keep +0 -0
- package/src/components/breadcrumbs/breadcrumbs.tsx +42 -0
- package/src/components/breadcrumbs/index.ts +2 -0
- package/src/components/button/index.ts +1 -0
- package/src/components/button/outlined-icon-button.tsx +47 -0
- package/src/components/core/index.ts +1 -0
- package/src/components/core/loading.tsx +15 -0
- package/src/components/dashboard-list/dashboard-list-row.tsx +145 -0
- package/src/components/dashboard-list/dashboard-list.tsx +157 -0
- package/src/components/dashboard-list/index.ts +1 -0
- package/src/components/data-table/index.ts +3 -0
- package/src/components/data-table/table-header.tsx +109 -0
- package/src/components/data-table/table-pagination.tsx +36 -0
- package/src/components/data-table/table-row.tsx +27 -0
- package/src/components/data-table/table-skeleton.tsx +45 -0
- package/src/components/execution/execution-filter.ts +30 -0
- package/src/components/execution/execution-status-icon.tsx +30 -0
- package/src/components/execution/execution-tag.tsx +100 -0
- package/src/components/execution/index.ts +2 -0
- package/src/components/footer/footer.tsx +55 -0
- package/src/components/footer/index.ts +1 -0
- package/src/components/header/dashboard-list-header.tsx +88 -0
- package/src/components/header/execution-details-header.tsx +154 -0
- package/src/components/header/header.tsx +42 -0
- package/src/components/header/index.ts +3 -0
- package/src/components/icons/up-down.tsx +21 -0
- package/src/components/integration-view/edges/default-edge.tsx +23 -0
- package/src/components/integration-view/elk-layout-options.ts +39 -0
- package/src/components/integration-view/elk-types.ts +19 -0
- package/src/components/integration-view/flow-types.tsx +16 -0
- package/src/components/integration-view/index.ts +1 -0
- package/src/components/integration-view/integration-view.tsx +159 -0
- package/src/components/integration-view/nodes/connection-node.tsx +10 -0
- package/src/components/integration-view/nodes/entry-node.tsx +10 -0
- package/src/components/integration-view/nodes/group-node.tsx +10 -0
- package/src/components/integration-view/nodes/task-node.tsx +17 -0
- package/src/components/integration-view/temp-data/initialElements.ts +238 -0
- package/src/components/integration-view/types.ts +12 -0
- package/src/components/layouts/index.ts +2 -0
- package/src/components/layouts/main-layout.tsx +28 -0
- package/src/components/layouts/root-container.tsx +43 -0
- package/src/components/link-cards/index.ts +1 -0
- package/src/components/link-cards/link-card.tsx +36 -0
- package/src/components/link-cards/styles.ts +29 -0
- package/src/components/list-filter/date-filter.tsx +55 -0
- package/src/components/list-filter/date-range-filter.tsx +101 -0
- package/src/components/list-filter/index.ts +6 -0
- package/src/components/list-filter/list-filter-types.ts +70 -0
- package/src/components/list-filter/list-filter.tsx +409 -0
- package/src/components/list-filter/multi-select-filter.tsx +117 -0
- package/src/components/list-filter/select-filter.tsx +82 -0
- package/src/hooks/use-breadcrumbs.ts +45 -0
- package/src/hooks/use-timestamp.tsx +25 -0
- package/src/lib/.keep +0 -0
- package/src/pages/dashboard/dashboard-link-cards.tsx +122 -0
- package/src/pages/dashboard/dashboard-list-sections.tsx +149 -0
- package/src/pages/dashboard/dashboard.tsx +14 -0
- package/src/pages/dashboard/index.ts +1 -0
- package/src/pages/execution-details/execution-details.tsx +43 -0
- package/src/pages/execution-details/index.ts +1 -0
- package/src/pages/executions/executions-list/executions-list-row.tsx +142 -0
- package/src/pages/executions/executions-list/executions-list-table.tsx +78 -0
- package/src/pages/executions/executions-list/executions-list.tsx +265 -0
- package/src/pages/executions/executions-list/index.ts +1 -0
- package/src/pages/executions/executions.tsx +98 -0
- package/src/pages/executions/index.ts +1 -0
- package/src/pages/integrations/index.ts +1 -0
- package/src/pages/integrations/integrations.tsx +39 -0
- package/src/pages/scheduler/index.ts +1 -0
- package/src/pages/scheduler/scheduler.tsx +39 -0
- package/tsconfig.json +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @evenicanpm/admin-core
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
- this package should contain the internals of the admin
|
|
6
|
+
- the admin should be a shell that implements all of the code in this package
|
|
7
|
+
- there should be an exstensibility layer on the key components
|
|
8
|
+
- api
|
|
9
|
+
- components
|
|
10
|
+
- etc
|
|
11
|
+
|
|
12
|
+
## Build and Dependencies
|
|
13
|
+
|
|
14
|
+
- this package is consumed and built by webpack as part of admin build
|
|
15
|
+
- it does not have it's own compile/build step
|
|
16
|
+
- must have this package listed under `transpilePackages` in the admin next.config.mjs
|
|
17
|
+
- using `transpilePackages` keeps the @evenicanpm packages very lightweight and portable
|
|
18
|
+
- during product dev this package is installed via local file url (symlink)
|
|
19
|
+
- this means this packages dependencies are NOT installed, everything should be a peerDep
|
|
20
|
+
and then added to the admin package.json as a dependency
|
|
21
|
+
- there is a step in the `init.sh` script that will symlink the admin node_modules to
|
|
22
|
+
the top-level of client packages - this ensures that the same versions of packages are used
|
|
23
|
+
- this is required for packages such as `@tanstack/react-query` that require the same package
|
|
24
|
+
location to be used across the entire codebase
|
|
25
|
+
|
|
26
|
+
## Misc
|
|
27
|
+
|
|
28
|
+
- if at some point we want to start installing packages in this repo we will have to run an npm
|
|
29
|
+
install step in the `init.sh` of admin
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { gql } from "graphql-request";
|
|
2
|
+
|
|
3
|
+
export const PROCESS_EXECUTION_FRAGMENT_SM = gql`
|
|
4
|
+
fragment e4ProcessExecutionFragmentSM on ProcessExecution {
|
|
5
|
+
id
|
|
6
|
+
name
|
|
7
|
+
startDate
|
|
8
|
+
executionStatus {
|
|
9
|
+
id
|
|
10
|
+
}
|
|
11
|
+
process {
|
|
12
|
+
id
|
|
13
|
+
}
|
|
14
|
+
modified
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { gql } from "graphql-request";
|
|
2
|
+
|
|
3
|
+
import { PROCESS_EXECUTION_FRAGMENT_SM } from "./fragments";
|
|
4
|
+
|
|
5
|
+
const GET_PROCESS_EXECUTIONS = gql`
|
|
6
|
+
${PROCESS_EXECUTION_FRAGMENT_SM}
|
|
7
|
+
query GetProcessExecutions($input: ProcessExecutionInput) {
|
|
8
|
+
processExecutions(input: $input) {
|
|
9
|
+
nodes {
|
|
10
|
+
...e4ProcessExecutionFragmentSM
|
|
11
|
+
}
|
|
12
|
+
pageInfo {
|
|
13
|
+
resultsReturned
|
|
14
|
+
currentPage
|
|
15
|
+
hasNextPage
|
|
16
|
+
hasPreviousPage
|
|
17
|
+
skip
|
|
18
|
+
top
|
|
19
|
+
sort
|
|
20
|
+
sortDesc
|
|
21
|
+
search
|
|
22
|
+
executionStatusIds
|
|
23
|
+
dateRange {
|
|
24
|
+
startDate
|
|
25
|
+
endDate
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
recordCount
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`;
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@evenicanpm/admin-integrate",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "e4Integrate Admin Panel",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./index.js",
|
|
10
|
+
"./*": "./*"
|
|
11
|
+
},
|
|
12
|
+
"author": "Evenica",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"@xyflow/react": "^12.8.4",
|
|
16
|
+
"elkjs": "^0.10.0"
|
|
17
|
+
},
|
|
18
|
+
"gitHead": "0c9180f24435b0361dfc05ccba4a1f0e7ad19a7a"
|
|
19
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useQuery, QueryClient, UseQueryOptions } from "@tanstack/react-query";
|
|
2
|
+
import { queryFn } from "./get-process-executions.server";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
GetProcessExecutionsQuery,
|
|
6
|
+
GetProcessExecutionsQueryVariables,
|
|
7
|
+
} from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
|
|
8
|
+
|
|
9
|
+
export const buildProcessExecutionsQueryKey = {
|
|
10
|
+
all: () => ["getProcessExecutions"] as const,
|
|
11
|
+
byInput: (variables?: GetProcessExecutionsQueryVariables) => [
|
|
12
|
+
"getProcessExecutions",
|
|
13
|
+
variables,
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const getProcessExecutions = {
|
|
18
|
+
queryKey: buildProcessExecutionsQueryKey.all(),
|
|
19
|
+
|
|
20
|
+
prefetch: (
|
|
21
|
+
queryClient: QueryClient,
|
|
22
|
+
variables?: GetProcessExecutionsQueryVariables,
|
|
23
|
+
) =>
|
|
24
|
+
queryClient.prefetchQuery({
|
|
25
|
+
queryKey: buildProcessExecutionsQueryKey.byInput(variables),
|
|
26
|
+
queryFn: () => queryFn(variables),
|
|
27
|
+
}),
|
|
28
|
+
|
|
29
|
+
fetchData: async (
|
|
30
|
+
queryClient: QueryClient,
|
|
31
|
+
variables?: GetProcessExecutionsQueryVariables,
|
|
32
|
+
) => {
|
|
33
|
+
return await queryClient.fetchQuery({
|
|
34
|
+
queryKey: buildProcessExecutionsQueryKey.byInput(variables),
|
|
35
|
+
queryFn: () => queryFn(variables),
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
useData: (
|
|
40
|
+
variables?: GetProcessExecutionsQueryVariables,
|
|
41
|
+
options?: UseQueryOptions,
|
|
42
|
+
) =>
|
|
43
|
+
useQuery<GetProcessExecutionsQuery>({
|
|
44
|
+
queryKey: buildProcessExecutionsQueryKey.byInput(variables),
|
|
45
|
+
queryFn: () => queryFn(variables),
|
|
46
|
+
...options,
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import createGraphqlclient from "@evenicanpm/admin-core/api/sdk/graphqlClient.client";
|
|
3
|
+
import { GetProcessExecutionsQueryVariables } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
|
|
4
|
+
|
|
5
|
+
export const queryFn = async (
|
|
6
|
+
variables?: GetProcessExecutionsQueryVariables,
|
|
7
|
+
) => {
|
|
8
|
+
const sdk = await createGraphqlclient();
|
|
9
|
+
const { data } = await sdk.GetProcessExecutions(variables);
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getProcessExecutions } from "./get-process-executions.query";
|
package/src/auth/.keep
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
|
|
4
|
+
// MUI
|
|
5
|
+
import styled from "@mui/material/styles/styled";
|
|
6
|
+
import { Breadcrumbs, Typography } from "@mui/material";
|
|
7
|
+
|
|
8
|
+
// STYLED COMPONENTS
|
|
9
|
+
export const Wrapper = styled("div")(({ theme }) => ({
|
|
10
|
+
padding: theme.spacing(0, 1, 3),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
export interface Crumb {
|
|
14
|
+
name: string;
|
|
15
|
+
url?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
breadcrumbs: Crumb[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default function IntegrateBreadcrumbs({ breadcrumbs }: Props) {
|
|
23
|
+
return (
|
|
24
|
+
<Wrapper>
|
|
25
|
+
<Breadcrumbs>
|
|
26
|
+
{breadcrumbs.map((bc) =>
|
|
27
|
+
bc.url ? (
|
|
28
|
+
<Link href={bc.url} key={bc.name}>
|
|
29
|
+
<Typography variant="body1" color="info.main">
|
|
30
|
+
{bc.name}
|
|
31
|
+
</Typography>
|
|
32
|
+
</Link>
|
|
33
|
+
) : (
|
|
34
|
+
<Typography variant="body1" key={bc.name} color="info.main">
|
|
35
|
+
{bc.name}
|
|
36
|
+
</Typography>
|
|
37
|
+
),
|
|
38
|
+
)}
|
|
39
|
+
</Breadcrumbs>
|
|
40
|
+
</Wrapper>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as OutlinedIconButton } from "./outlined-icon-button";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { IconButton, SxProps } from "@mui/material";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
color?:
|
|
6
|
+
| "inherit"
|
|
7
|
+
| "default"
|
|
8
|
+
| "primary"
|
|
9
|
+
| "secondary"
|
|
10
|
+
| "error"
|
|
11
|
+
| "info"
|
|
12
|
+
| "success"
|
|
13
|
+
| "warning";
|
|
14
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
sx?: SxProps;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const OutlinedIconButton: React.FC<Props> = (props: Props) => {
|
|
20
|
+
const sx = {
|
|
21
|
+
// Default style
|
|
22
|
+
borderWidth: "2px",
|
|
23
|
+
borderStyle: "solid",
|
|
24
|
+
borderColor: `${props.color}.light`,
|
|
25
|
+
"&:hover": {
|
|
26
|
+
backgroundColor: "action.hover",
|
|
27
|
+
borderColor: `${props.color}.main`,
|
|
28
|
+
},
|
|
29
|
+
borderRadius: "8px",
|
|
30
|
+
|
|
31
|
+
// Override style
|
|
32
|
+
...props.sx,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<IconButton
|
|
37
|
+
centerRipple={false}
|
|
38
|
+
color={props.color || "inherit"}
|
|
39
|
+
sx={sx}
|
|
40
|
+
onClick={props.onClick}
|
|
41
|
+
>
|
|
42
|
+
{props.children}
|
|
43
|
+
</IconButton>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default OutlinedIconButton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Loading } from "./loading";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
2
|
+
import FlexRowCenter from "@evenicanpm/admin-core/components/flex-box/flex-row-center";
|
|
3
|
+
import { useTheme } from "@mui/material";
|
|
4
|
+
|
|
5
|
+
const Loading = () => {
|
|
6
|
+
const theme = useTheme();
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<FlexRowCenter sx={{ margin: theme.spacing(1) }}>
|
|
10
|
+
<CircularProgress color="info" />
|
|
11
|
+
</FlexRowCenter>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default Loading;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { redirect, RedirectType } from "next/navigation";
|
|
3
|
+
|
|
4
|
+
// MUI
|
|
5
|
+
import { Theme, useTheme } from "@mui/material";
|
|
6
|
+
import { Box, Stack, Typography, Popover } from "@mui/material";
|
|
7
|
+
import { RemoveRedEye } from "@mui/icons-material";
|
|
8
|
+
|
|
9
|
+
// Custom components
|
|
10
|
+
import {
|
|
11
|
+
StyledTableCell,
|
|
12
|
+
StyledTableRow,
|
|
13
|
+
StyledIconButton,
|
|
14
|
+
} from "@evenicanpm/admin-integrate/components/data-table/table-row";
|
|
15
|
+
import { ExecutionStatusIcon } from "@evenicanpm/admin-integrate/components/execution";
|
|
16
|
+
|
|
17
|
+
// Hooks
|
|
18
|
+
import useTimestamp from "@evenicanpm/admin-integrate/hooks/use-timestamp";
|
|
19
|
+
|
|
20
|
+
// Types
|
|
21
|
+
import { Item } from "./dashboard-list";
|
|
22
|
+
import { Head } from "../data-table/table-header";
|
|
23
|
+
import { TableCellProps } from "@mui/material";
|
|
24
|
+
|
|
25
|
+
interface Props {
|
|
26
|
+
item: Item;
|
|
27
|
+
heading: Head[]; // for alignment
|
|
28
|
+
enableBgColor?: boolean;
|
|
29
|
+
sx?: SxProps;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const DashboardListRow: React.FC<Props> = (props: Props) => {
|
|
33
|
+
const theme = useTheme();
|
|
34
|
+
const styles = getStyles(theme);
|
|
35
|
+
|
|
36
|
+
// e.g. "xx days ago"
|
|
37
|
+
const time = useTimestamp(props.item.startDate);
|
|
38
|
+
const localTime = new Date(props.item.startDate).toString();
|
|
39
|
+
|
|
40
|
+
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
|
|
41
|
+
const open = Boolean(anchorEl);
|
|
42
|
+
|
|
43
|
+
const handlePopoverOpen = (event: React.MouseEvent<HTMLElement>) => {
|
|
44
|
+
setAnchorEl(event.currentTarget);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handlePopoverClose = () => {
|
|
48
|
+
setAnchorEl(null);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const handleRedirect = () => {
|
|
52
|
+
//Temporarily commented out until executions detail page is implemented
|
|
53
|
+
// redirect(
|
|
54
|
+
// `/e4integrate/executions/${props.item.process.id}?ExecutionId=${props.item.id}`,
|
|
55
|
+
// RedirectType.push,
|
|
56
|
+
// );
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// only relevant for execution status 450 & 500 (i.e. Notifications list)
|
|
60
|
+
let bgColor = "";
|
|
61
|
+
if (props.enableBgColor) {
|
|
62
|
+
switch (props.item.executionStatus.id) {
|
|
63
|
+
case "450":
|
|
64
|
+
bgColor = "warning.100";
|
|
65
|
+
break;
|
|
66
|
+
case "500":
|
|
67
|
+
bgColor = "error.100";
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const sx = props.sx || {};
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<StyledTableRow sx={{ ...sx, backgroundColor: bgColor }}>
|
|
76
|
+
<StyledTableCell
|
|
77
|
+
align={props.heading[0].align as TableCellProps["align"]}
|
|
78
|
+
width={props.heading[0].width}
|
|
79
|
+
>
|
|
80
|
+
<Stack spacing={1} direction="row">
|
|
81
|
+
<Box display="flex" justifyContent="flex-end" alignItems="center">
|
|
82
|
+
<ExecutionStatusIcon
|
|
83
|
+
executionStatusId={props.item.executionStatus.id}
|
|
84
|
+
/>
|
|
85
|
+
</Box>
|
|
86
|
+
<Box display="flex" justifyContent="flex-end" alignItems="center">
|
|
87
|
+
<Typography>{props.item.name}</Typography>
|
|
88
|
+
</Box>
|
|
89
|
+
</Stack>
|
|
90
|
+
</StyledTableCell>
|
|
91
|
+
<StyledTableCell
|
|
92
|
+
align={props.heading[1].align as TableCellProps["align"]}
|
|
93
|
+
width={props.heading[1].width}
|
|
94
|
+
sx={styles.timeCell}
|
|
95
|
+
>
|
|
96
|
+
<Typography
|
|
97
|
+
onMouseEnter={handlePopoverOpen}
|
|
98
|
+
onMouseLeave={handlePopoverClose}
|
|
99
|
+
>
|
|
100
|
+
{time}
|
|
101
|
+
</Typography>
|
|
102
|
+
<Popover
|
|
103
|
+
sx={{ pointerEvents: "none" }}
|
|
104
|
+
open={open}
|
|
105
|
+
anchorEl={anchorEl}
|
|
106
|
+
anchorOrigin={{
|
|
107
|
+
vertical: "bottom",
|
|
108
|
+
horizontal: "center",
|
|
109
|
+
}}
|
|
110
|
+
transformOrigin={{
|
|
111
|
+
vertical: "top",
|
|
112
|
+
horizontal: "center",
|
|
113
|
+
}}
|
|
114
|
+
onClose={handlePopoverClose}
|
|
115
|
+
disableRestoreFocus
|
|
116
|
+
>
|
|
117
|
+
<Box sx={styles.popover}>
|
|
118
|
+
<Typography>{localTime}</Typography>
|
|
119
|
+
</Box>
|
|
120
|
+
</Popover>
|
|
121
|
+
</StyledTableCell>
|
|
122
|
+
<StyledTableCell
|
|
123
|
+
align={props.heading[2].align as TableCellProps["align"]}
|
|
124
|
+
width={props.heading[2].width}
|
|
125
|
+
>
|
|
126
|
+
<StyledIconButton onClick={handleRedirect}>
|
|
127
|
+
<RemoveRedEye />
|
|
128
|
+
</StyledIconButton>
|
|
129
|
+
</StyledTableCell>
|
|
130
|
+
</StyledTableRow>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const getStyles = (theme: Theme) => {
|
|
135
|
+
return {
|
|
136
|
+
timeCell: {
|
|
137
|
+
cursor: "default",
|
|
138
|
+
},
|
|
139
|
+
popover: {
|
|
140
|
+
padding: theme.spacing(1),
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export default DashboardListRow;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
import { useTranslations } from "next-intl";
|
|
3
|
+
|
|
4
|
+
// API
|
|
5
|
+
import { GetProcessExecutionsQuery } from "@evenicanpm/admin-core/api/e4/graphqlRequestSdk";
|
|
6
|
+
|
|
7
|
+
// MUI
|
|
8
|
+
import { Card, Table, TableContainer, TableBody, Box } from "@mui/material";
|
|
9
|
+
import { Theme, useTheme } from "@mui/material";
|
|
10
|
+
|
|
11
|
+
// Custom components
|
|
12
|
+
import { FlexBox } from "@evenicanpm/admin-core/components/flex-box";
|
|
13
|
+
|
|
14
|
+
import { TableHeader, TableSkeleton } from "../data-table";
|
|
15
|
+
import DashboardListRow from "./dashboard-list-row";
|
|
16
|
+
import { DashboardListHeader } from "../header/";
|
|
17
|
+
|
|
18
|
+
// Types
|
|
19
|
+
import { Head } from "../data-table/table-header";
|
|
20
|
+
import { Typography, Stack } from "@mui/material";
|
|
21
|
+
|
|
22
|
+
// Returned from processExecutions query
|
|
23
|
+
export interface Item {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
startDate: string;
|
|
27
|
+
executionStatus: {
|
|
28
|
+
id: string;
|
|
29
|
+
};
|
|
30
|
+
process: {
|
|
31
|
+
id: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Props {
|
|
36
|
+
title: string;
|
|
37
|
+
heading: Head[];
|
|
38
|
+
data: GetProcessExecutionsQuery;
|
|
39
|
+
loading: boolean;
|
|
40
|
+
url: string;
|
|
41
|
+
handleRefresh?: () => void;
|
|
42
|
+
enableBgColor?: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Row height in terms of multiples of theme.spacing(1) (e.g. theme.spacing(7.5 & rows per page))
|
|
46
|
+
const rowHeight = 7.5;
|
|
47
|
+
|
|
48
|
+
const DashboardList: React.FC<Props> = (props: Props) => {
|
|
49
|
+
const t = useTranslations("Integrate.Dashboard");
|
|
50
|
+
|
|
51
|
+
const theme = useTheme();
|
|
52
|
+
const styles = getStyles(theme);
|
|
53
|
+
|
|
54
|
+
const [items, setItems] = useState<Item[]>([]);
|
|
55
|
+
const [fetched, setFetched] = useState<boolean>(false); // prevents "empty list" msg from showing for split second
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (props.data) {
|
|
59
|
+
setItems(props.data.processExecutions.nodes as Item[]);
|
|
60
|
+
setFetched(true);
|
|
61
|
+
}
|
|
62
|
+
}, [props.data]);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Card sx={styles.card}>
|
|
66
|
+
<Box mr={2} ml={2}>
|
|
67
|
+
<DashboardListHeader
|
|
68
|
+
title={props.title}
|
|
69
|
+
url={props.url}
|
|
70
|
+
handleRefresh={props.handleRefresh}
|
|
71
|
+
/>
|
|
72
|
+
</Box>
|
|
73
|
+
|
|
74
|
+
{props.loading && (
|
|
75
|
+
<TableSkeleton
|
|
76
|
+
heading={props.heading}
|
|
77
|
+
perPage={5}
|
|
78
|
+
rowSx={styles.rowSx}
|
|
79
|
+
sx={styles.tableContainer}
|
|
80
|
+
/>
|
|
81
|
+
)}
|
|
82
|
+
|
|
83
|
+
{!props.loading && props.data && fetched && items.length > 0 ? (
|
|
84
|
+
<TableContainer sx={styles.tableContainer}>
|
|
85
|
+
<Table>
|
|
86
|
+
<TableHeader
|
|
87
|
+
heading={props.heading}
|
|
88
|
+
orderBy={"startDate"}
|
|
89
|
+
order={"desc"}
|
|
90
|
+
/>
|
|
91
|
+
<TableBody>
|
|
92
|
+
{items.map((item, index) => (
|
|
93
|
+
<DashboardListRow
|
|
94
|
+
key={index}
|
|
95
|
+
item={item}
|
|
96
|
+
heading={props.heading}
|
|
97
|
+
enableBgColor={props.enableBgColor}
|
|
98
|
+
sx={styles.rowSx}
|
|
99
|
+
/>
|
|
100
|
+
))}
|
|
101
|
+
</TableBody>
|
|
102
|
+
</Table>
|
|
103
|
+
</TableContainer>
|
|
104
|
+
) : null}
|
|
105
|
+
|
|
106
|
+
{!props.loading && !(props.data && fetched && items.length > 0) ? (
|
|
107
|
+
<FlexBox
|
|
108
|
+
justifyContent="center"
|
|
109
|
+
alignItems="center"
|
|
110
|
+
sx={{
|
|
111
|
+
minHeight: "335px",
|
|
112
|
+
marginBottom: theme.spacing(2),
|
|
113
|
+
}}
|
|
114
|
+
>
|
|
115
|
+
<Stack spacing={1} justifyContent="center" alignItems="center">
|
|
116
|
+
<Typography variant="h6" color="info">
|
|
117
|
+
{t("ListEmpty.title")}
|
|
118
|
+
</Typography>
|
|
119
|
+
<Typography variant="body1">{t("ListEmpty.body")}</Typography>
|
|
120
|
+
</Stack>
|
|
121
|
+
</FlexBox>
|
|
122
|
+
) : null}
|
|
123
|
+
</Card>
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const getStyles = (theme: Theme) => {
|
|
128
|
+
return {
|
|
129
|
+
card: {
|
|
130
|
+
paddingTop: theme.spacing(2),
|
|
131
|
+
},
|
|
132
|
+
title: {
|
|
133
|
+
display: "flex",
|
|
134
|
+
alignItems: "center",
|
|
135
|
+
height: "100%",
|
|
136
|
+
},
|
|
137
|
+
typography: {
|
|
138
|
+
fontWeight: "medium",
|
|
139
|
+
},
|
|
140
|
+
button: {
|
|
141
|
+
borderWidth: 2,
|
|
142
|
+
borderRadius: 1,
|
|
143
|
+
marginRight: theme.spacing(1),
|
|
144
|
+
},
|
|
145
|
+
iconButton: {
|
|
146
|
+
borderRadius: 1,
|
|
147
|
+
},
|
|
148
|
+
tableContainer: {
|
|
149
|
+
paddingTop: theme.spacing(2),
|
|
150
|
+
},
|
|
151
|
+
rowSx: {
|
|
152
|
+
height: theme.spacing(rowHeight),
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export default DashboardList;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./dashboard-list";
|