@orchestrator-ui/orchestrator-ui-components 0.3.1 → 0.5.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/.turbo/turbo-build.log +5 -5
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +11 -9
- package/CHANGELOG.md +19 -0
- package/dist/index.d.ts +332 -58
- package/dist/index.js +8487 -2415
- package/package.json +8 -9
- package/src/components/WfoBadges/WfoEngineStatusBadge/WfoEngineStatusBadge.tsx +8 -5
- package/src/components/WfoBadges/WfoEnvironmentBadge/WfoEnvironmentBadge.tsx +2 -1
- package/src/components/WfoForms/formFields/OrganisationField.tsx +11 -11
- package/src/components/WfoForms/formFields/SplitPrefix.tsx +11 -4
- package/src/components/WfoForms/formFields/SubscriptionField.tsx +1 -1
- package/src/components/WfoPageTemplate/WfoSidebar/WfoCopyright.tsx +22 -0
- package/src/components/WfoPageTemplate/WfoSidebar/WfoSidebar.tsx +10 -6
- package/src/components/WfoPageTemplate/WfoSidebar/styles.ts +17 -0
- package/src/components/WfoProcessList/WfoProcessesList.tsx +59 -25
- package/src/components/WfoProcessList/processListObjectMappers.ts +45 -1
- package/src/components/WfoSettings/WfoEngineStatusButton.tsx +11 -13
- package/src/components/WfoSettings/WfoFlushSettings.tsx +23 -35
- package/src/components/WfoSettings/WfoModifySettings.tsx +3 -16
- package/src/components/WfoSettings/WfoStatus.tsx +4 -9
- package/src/components/WfoSettings/index.ts +4 -1
- package/src/components/WfoSubscription/WfoSubscription.tsx +5 -2
- package/src/components/WfoSubscription/WfoSubscriptionDetailTree.tsx +1 -0
- package/src/components/WfoSubscription/WfoSubscriptionGeneral.tsx +1 -1
- package/src/components/WfoSubscription/subscriptionDetailTabs.tsx +36 -6
- package/src/components/WfoSubscriptionsList/WfoSubscriptionsList.tsx +42 -11
- package/src/components/WfoSubscriptionsList/index.ts +1 -1
- package/src/components/WfoSubscriptionsList/subscriptionListTabs.ts +1 -1
- package/src/components/WfoSubscriptionsList/{mapGraphQlSubscriptionsResultToSubscriptionListItems.ts → subscriptionResultMappers.ts} +6 -0
- package/src/components/WfoTable/WfoTableWithFilter/WfoTableWithFilter.tsx +12 -0
- package/src/components/WfoToastsList/WfoToastsList.tsx +11 -11
- package/src/components/WfoTree/WfoTreeNode.tsx +2 -0
- package/src/configuration/constants.ts +1 -0
- package/src/contexts/OrchestratorConfigContext.tsx +2 -4
- package/src/contexts/index.ts +0 -1
- package/src/graphqlQueries/index.ts +1 -1
- package/src/graphqlQueries/processListQuery.ts +29 -29
- package/src/graphqlQueries/subscriptionDetailQuery.ts +1 -1
- package/src/graphqlQueries/subscriptionsDropdownOptionsQuery.ts +1 -1
- package/src/hooks/index.ts +1 -2
- package/src/hooks/useCheckEngineStatus.ts +10 -9
- package/src/hooks/useOrchestratorConfig.ts +1 -16
- package/src/hooks/useQueryWithGraphql.ts +22 -0
- package/src/hooks/useShowToastMessage.ts +43 -0
- package/src/hooks/useStoredTableConfig.ts +5 -4
- package/src/icons/WfoCogFill.tsx +23 -25
- package/src/icons/WfoCubeSolid.tsx +33 -0
- package/src/icons/WfoPlayCircle.tsx +35 -0
- package/src/icons/WfoShare.tsx +35 -0
- package/src/icons/index.ts +3 -0
- package/src/index.ts +1 -0
- package/src/messages/en-GB.json +9 -5
- package/src/messages/nl-NL.json +8 -4
- package/src/pages/metadata/WfoProductBlocksPage.tsx +40 -6
- package/src/pages/metadata/WfoProductsPage.tsx +38 -9
- package/src/pages/metadata/WfoResourceTypesPage.tsx +36 -5
- package/src/pages/metadata/WfoWorkflowsPage.tsx +40 -9
- package/src/pages/settings/WfoSettingsPage.tsx +14 -23
- package/src/rtk/api.ts +40 -0
- package/src/rtk/endpoints/customers.ts +27 -0
- package/src/rtk/endpoints/index.ts +3 -0
- package/src/rtk/endpoints/processList.ts +89 -0
- package/src/rtk/endpoints/settings.ts +72 -0
- package/src/rtk/hooks.ts +7 -0
- package/src/rtk/index.ts +5 -0
- package/src/rtk/slices/index.ts +1 -0
- package/src/rtk/slices/orchestratorConfig.ts +16 -0
- package/src/rtk/slices/toastMessages.ts +56 -0
- package/src/rtk/store.ts +40 -0
- package/src/rtk/storeProvider.tsx +26 -0
- package/src/types/types.ts +33 -2
- package/src/utils/csvDownload.ts +83 -0
- package/src/utils/getDefaultTableConfig.ts +1 -3
- package/src/utils/getQueryVariablesForExport.spec.ts +19 -0
- package/src/utils/getQueryVariablesForExport.ts +11 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/sortObjectKeys.spec.ts +34 -0
- package/src/utils/sortObjectKeys.ts +33 -0
- package/src/components/WfoSettings/WfoSettings.tsx +0 -40
- package/src/contexts/ToastContext.tsx +0 -136
- package/src/graphqlQueries/customersQuery.ts +0 -20
- package/src/hooks/useEngineStatusQuery.ts +0 -64
- package/src/hooks/useToastMessage.ts +0 -5
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { useEngineStatusMutation, useEngineStatusQuery } from '@/hooks';
|
|
5
|
-
import { EngineStatus } from '@/types';
|
|
3
|
+
import { EuiHorizontalRule, EuiPageHeader, EuiSpacer } from '@elastic/eui';
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
const { data: engineStatus } = useEngineStatusQuery();
|
|
9
|
-
const { mutate, data: newEngineStatus } = useEngineStatusMutation();
|
|
10
|
-
|
|
11
|
-
const isRunning =
|
|
12
|
-
newEngineStatus?.global_status === EngineStatus.RUNNING ||
|
|
13
|
-
engineStatus?.global_status === EngineStatus.RUNNING;
|
|
14
|
-
const currentEngineStatus =
|
|
15
|
-
newEngineStatus?.global_status || engineStatus?.global_status;
|
|
16
|
-
const currentRunningProcesses =
|
|
17
|
-
newEngineStatus?.running_processes || engineStatus?.running_processes;
|
|
18
|
-
|
|
19
|
-
const changeEngineStatus = () => {
|
|
20
|
-
mutate({ global_lock: isRunning });
|
|
21
|
-
};
|
|
5
|
+
import { WfoFlushSettings, WfoModifySettings, WfoStatus } from '@/components';
|
|
22
6
|
|
|
7
|
+
export const WfoSettingsPage = () => {
|
|
23
8
|
return (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
9
|
+
<>
|
|
10
|
+
<EuiSpacer />
|
|
11
|
+
|
|
12
|
+
<EuiPageHeader pageTitle="Settings" />
|
|
13
|
+
<EuiHorizontalRule />
|
|
14
|
+
<WfoFlushSettings />
|
|
15
|
+
<EuiSpacer />
|
|
16
|
+
<WfoModifySettings />
|
|
17
|
+
<EuiSpacer />
|
|
18
|
+
<WfoStatus />
|
|
19
|
+
</>
|
|
29
20
|
);
|
|
30
21
|
};
|
package/src/rtk/api.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
|
2
|
+
import { graphqlRequestBaseQuery } from '@rtk-query/graphql-request-base-query';
|
|
3
|
+
|
|
4
|
+
import type { RootState } from './store';
|
|
5
|
+
|
|
6
|
+
export enum BaseQueryTypes {
|
|
7
|
+
fetch = 'fetch',
|
|
8
|
+
graphql = 'graphql',
|
|
9
|
+
custom = 'custom',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type ExtraOptions = {
|
|
13
|
+
baseQueryType?: BaseQueryTypes;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const orchestratorApi = createApi({
|
|
17
|
+
reducerPath: 'orchestratorApi',
|
|
18
|
+
baseQuery: (args, api, extraOptions: ExtraOptions) => {
|
|
19
|
+
const { baseQueryType } = extraOptions || {};
|
|
20
|
+
|
|
21
|
+
const state = api.getState() as RootState;
|
|
22
|
+
const { orchestratorApiBaseUrl, graphqlEndpointCore } =
|
|
23
|
+
state.orchestratorConfig;
|
|
24
|
+
|
|
25
|
+
switch (baseQueryType) {
|
|
26
|
+
case BaseQueryTypes.fetch:
|
|
27
|
+
const fetchFn = fetchBaseQuery({
|
|
28
|
+
baseUrl: orchestratorApiBaseUrl,
|
|
29
|
+
});
|
|
30
|
+
return fetchFn(args, api, {});
|
|
31
|
+
default:
|
|
32
|
+
const graphqlFn = graphqlRequestBaseQuery({
|
|
33
|
+
url: graphqlEndpointCore,
|
|
34
|
+
});
|
|
35
|
+
return graphqlFn(args, api, {});
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
endpoints: () => ({}),
|
|
39
|
+
tagTypes: ['engineStatus'],
|
|
40
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Customer, CustomersResult } from '@/types';
|
|
2
|
+
|
|
3
|
+
import { orchestratorApi } from '../api';
|
|
4
|
+
|
|
5
|
+
const customersQuery = `query Customers {
|
|
6
|
+
customers(first: 1000000, after: 0) {
|
|
7
|
+
page {
|
|
8
|
+
fullname
|
|
9
|
+
identifier
|
|
10
|
+
shortcode
|
|
11
|
+
}:
|
|
12
|
+
}
|
|
13
|
+
}`;
|
|
14
|
+
|
|
15
|
+
const customersApi = orchestratorApi.injectEndpoints({
|
|
16
|
+
endpoints: (build) => ({
|
|
17
|
+
getCustomers: build.query<Customer[], void>({
|
|
18
|
+
query: () => ({ document: customersQuery }),
|
|
19
|
+
transformResponse: (response: CustomersResult): Customer[] => {
|
|
20
|
+
const customers = response?.customers?.page || [];
|
|
21
|
+
return customers;
|
|
22
|
+
},
|
|
23
|
+
}),
|
|
24
|
+
}),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export const { useGetCustomersQuery } = customersApi;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseGraphQlResult,
|
|
3
|
+
GraphqlQueryVariables,
|
|
4
|
+
Process,
|
|
5
|
+
ProcessListResult,
|
|
6
|
+
} from '@/types';
|
|
7
|
+
|
|
8
|
+
import { orchestratorApi } from '../api';
|
|
9
|
+
|
|
10
|
+
export const processListQuery = `
|
|
11
|
+
query ProcessList(
|
|
12
|
+
$first: Int!
|
|
13
|
+
$after: Int!
|
|
14
|
+
$sortBy: [GraphqlSort!]
|
|
15
|
+
$filterBy: [GraphqlFilter!]
|
|
16
|
+
$query: String
|
|
17
|
+
) {
|
|
18
|
+
processes(
|
|
19
|
+
first: $first
|
|
20
|
+
after: $after
|
|
21
|
+
sortBy: $sortBy
|
|
22
|
+
filterBy: $filterBy
|
|
23
|
+
query: $query
|
|
24
|
+
) {
|
|
25
|
+
page {
|
|
26
|
+
workflowName
|
|
27
|
+
lastStep
|
|
28
|
+
lastStatus
|
|
29
|
+
workflowTarget
|
|
30
|
+
product {
|
|
31
|
+
name
|
|
32
|
+
tag
|
|
33
|
+
}
|
|
34
|
+
customer {
|
|
35
|
+
fullname
|
|
36
|
+
shortcode
|
|
37
|
+
}
|
|
38
|
+
createdBy
|
|
39
|
+
assignee
|
|
40
|
+
processId
|
|
41
|
+
startedAt
|
|
42
|
+
lastModifiedAt
|
|
43
|
+
isTask
|
|
44
|
+
subscriptions {
|
|
45
|
+
page {
|
|
46
|
+
subscriptionId
|
|
47
|
+
description
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
pageInfo {
|
|
52
|
+
hasNextPage
|
|
53
|
+
hasPreviousPage
|
|
54
|
+
startCursor
|
|
55
|
+
totalItems
|
|
56
|
+
endCursor
|
|
57
|
+
sortFields
|
|
58
|
+
filterFields
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
export type ProcessListResponse = {
|
|
65
|
+
processes: Process[];
|
|
66
|
+
} & BaseGraphQlResult;
|
|
67
|
+
|
|
68
|
+
const processApi = orchestratorApi.injectEndpoints({
|
|
69
|
+
endpoints: (build) => ({
|
|
70
|
+
getProcessList: build.query<
|
|
71
|
+
ProcessListResponse,
|
|
72
|
+
GraphqlQueryVariables<Process>
|
|
73
|
+
>({
|
|
74
|
+
query: (variables) => ({ document: processListQuery, variables }),
|
|
75
|
+
transformResponse: (
|
|
76
|
+
response: ProcessListResult,
|
|
77
|
+
): ProcessListResponse => {
|
|
78
|
+
const processes = response?.processes?.page || [];
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
processes,
|
|
82
|
+
pageInfo: response.processes?.pageInfo || {},
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
export const { useGetProcessListQuery } = processApi;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { EngineStatus } from '@/types';
|
|
2
|
+
|
|
3
|
+
import { BaseQueryTypes, orchestratorApi } from '../api';
|
|
4
|
+
|
|
5
|
+
interface EngineStatusReturnValue {
|
|
6
|
+
engineStatus: EngineStatus;
|
|
7
|
+
runningProcesses: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const statusApi = orchestratorApi.injectEndpoints({
|
|
11
|
+
endpoints: (build) => ({
|
|
12
|
+
getEngineStatus: build.query<EngineStatusReturnValue, void>({
|
|
13
|
+
query: () => '/settings/status',
|
|
14
|
+
extraOptions: {
|
|
15
|
+
baseQueryType: BaseQueryTypes.fetch,
|
|
16
|
+
},
|
|
17
|
+
transformResponse(data: {
|
|
18
|
+
global_status: string;
|
|
19
|
+
running_processes: number;
|
|
20
|
+
}) {
|
|
21
|
+
const engineStatus = (() => {
|
|
22
|
+
switch (data?.global_status) {
|
|
23
|
+
case 'RUNNING':
|
|
24
|
+
return EngineStatus.RUNNING;
|
|
25
|
+
case 'PAUSING':
|
|
26
|
+
return EngineStatus.PAUSING;
|
|
27
|
+
case 'PAUSED':
|
|
28
|
+
return EngineStatus.PAUSED;
|
|
29
|
+
default:
|
|
30
|
+
return EngineStatus.UNKNOWN;
|
|
31
|
+
}
|
|
32
|
+
})();
|
|
33
|
+
return {
|
|
34
|
+
engineStatus,
|
|
35
|
+
runningProcesses: data?.running_processes || 0,
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
providesTags: ['engineStatus'],
|
|
39
|
+
}),
|
|
40
|
+
clearCache: build.mutation<void, string>({
|
|
41
|
+
query: (settingName) => ({
|
|
42
|
+
url: `/settings/cache/${settingName}`,
|
|
43
|
+
method: 'DELETE',
|
|
44
|
+
}),
|
|
45
|
+
extraOptions: {
|
|
46
|
+
baseQueryType: BaseQueryTypes.fetch,
|
|
47
|
+
},
|
|
48
|
+
}),
|
|
49
|
+
setEngineStatus: build.mutation<EngineStatusReturnValue, boolean>({
|
|
50
|
+
query: (globalStatus) => ({
|
|
51
|
+
url: `/settings/status`,
|
|
52
|
+
method: 'PUT',
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
global_lock: globalStatus,
|
|
55
|
+
}),
|
|
56
|
+
headers: {
|
|
57
|
+
'Content-Type': 'application/json',
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
extraOptions: {
|
|
61
|
+
baseQueryType: BaseQueryTypes.fetch,
|
|
62
|
+
},
|
|
63
|
+
invalidatesTags: ['engineStatus'],
|
|
64
|
+
}),
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export const {
|
|
69
|
+
useGetEngineStatusQuery,
|
|
70
|
+
useClearCacheMutation,
|
|
71
|
+
useSetEngineStatusMutation,
|
|
72
|
+
} = statusApi;
|
package/src/rtk/hooks.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
2
|
+
import type { TypedUseSelectorHook } from 'react-redux';
|
|
3
|
+
|
|
4
|
+
import type { AppDispatch, RootState } from './store';
|
|
5
|
+
|
|
6
|
+
export const useAppDispatch: () => AppDispatch = useDispatch;
|
|
7
|
+
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
package/src/rtk/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './toastMessages';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
+
import type { Slice } from '@reduxjs/toolkit';
|
|
3
|
+
|
|
4
|
+
import type { OrchestratorConfig } from '@/types';
|
|
5
|
+
|
|
6
|
+
type OrchestratorConfigSlice = Slice<OrchestratorConfig>;
|
|
7
|
+
|
|
8
|
+
export const getOrchestratorConfigSlice = (
|
|
9
|
+
config: OrchestratorConfig,
|
|
10
|
+
): OrchestratorConfigSlice => {
|
|
11
|
+
return createSlice({
|
|
12
|
+
name: 'orchestrator',
|
|
13
|
+
initialState: config,
|
|
14
|
+
reducers: {},
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
+
import type { PayloadAction, Reducer, Slice } from '@reduxjs/toolkit';
|
|
3
|
+
|
|
4
|
+
import { Toast } from '@/types';
|
|
5
|
+
|
|
6
|
+
export type ToastState = {
|
|
7
|
+
messages: Toast[];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const initialState: ToastState = {
|
|
11
|
+
messages: [],
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type ToastMessagesSlice = Slice<
|
|
15
|
+
ToastState,
|
|
16
|
+
{
|
|
17
|
+
addToastMessage: (
|
|
18
|
+
state: ToastState,
|
|
19
|
+
action: PayloadAction<Toast>,
|
|
20
|
+
) => ToastState;
|
|
21
|
+
removeToastMessage: (
|
|
22
|
+
state: ToastState,
|
|
23
|
+
action: PayloadAction<Toast['id']>,
|
|
24
|
+
) => ToastState;
|
|
25
|
+
},
|
|
26
|
+
'toastMessages',
|
|
27
|
+
'toastMessages'
|
|
28
|
+
>;
|
|
29
|
+
|
|
30
|
+
export const toastMessagesSlice: ToastMessagesSlice = createSlice({
|
|
31
|
+
name: 'toastMessages',
|
|
32
|
+
initialState,
|
|
33
|
+
reducers: {
|
|
34
|
+
addToastMessage: (state, action: PayloadAction<Toast>) => {
|
|
35
|
+
return {
|
|
36
|
+
...state,
|
|
37
|
+
messages: [...state.messages, action.payload],
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
removeToastMessage: (state, action: PayloadAction<Toast['id']>) => {
|
|
41
|
+
return {
|
|
42
|
+
...state,
|
|
43
|
+
messages: state.messages.filter(
|
|
44
|
+
(message) => message.id !== action.payload,
|
|
45
|
+
),
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Action creators are generated for each case reducer function
|
|
52
|
+
export const { addToastMessage, removeToastMessage } =
|
|
53
|
+
toastMessagesSlice.actions;
|
|
54
|
+
|
|
55
|
+
export const toastMessagesReducer: Reducer<ToastState> =
|
|
56
|
+
toastMessagesSlice.reducer;
|
package/src/rtk/store.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { configureStore } from '@reduxjs/toolkit';
|
|
2
|
+
import type { EnhancedStore } from '@reduxjs/toolkit';
|
|
3
|
+
import type { Dispatch, UnknownAction } from '@reduxjs/toolkit';
|
|
4
|
+
import { CombinedState } from '@reduxjs/toolkit/query';
|
|
5
|
+
|
|
6
|
+
import type { OrchestratorConfig } from '@/types';
|
|
7
|
+
|
|
8
|
+
import { orchestratorApi } from './api';
|
|
9
|
+
import { getOrchestratorConfigSlice } from './slices/orchestratorConfig';
|
|
10
|
+
import { toastMessagesReducer } from './slices/toastMessages';
|
|
11
|
+
|
|
12
|
+
export type RootState = {
|
|
13
|
+
orchestratorApi: CombinedState<
|
|
14
|
+
Record<string, never>,
|
|
15
|
+
'engineStatus',
|
|
16
|
+
'orchestratorApi'
|
|
17
|
+
>;
|
|
18
|
+
toastMessages: ReturnType<typeof toastMessagesReducer>;
|
|
19
|
+
orchestratorConfig: OrchestratorConfig;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const getOrchestratorStore = (
|
|
23
|
+
orchestratorConfig: OrchestratorConfig,
|
|
24
|
+
): EnhancedStore<RootState> => {
|
|
25
|
+
const configSlice = getOrchestratorConfigSlice(orchestratorConfig);
|
|
26
|
+
|
|
27
|
+
const orchestratorStore = configureStore({
|
|
28
|
+
reducer: {
|
|
29
|
+
[orchestratorApi.reducerPath]: orchestratorApi.reducer,
|
|
30
|
+
toastMessages: toastMessagesReducer,
|
|
31
|
+
orchestratorConfig: configSlice.reducer,
|
|
32
|
+
},
|
|
33
|
+
middleware: (getDefaultMiddleware) =>
|
|
34
|
+
getDefaultMiddleware().concat(orchestratorApi.middleware),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return orchestratorStore;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type AppDispatch = Dispatch<UnknownAction>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import { Provider } from 'react-redux';
|
|
4
|
+
|
|
5
|
+
import { useOrchestratorConfig } from '@/hooks';
|
|
6
|
+
import type { OrchestratorConfig } from '@/types';
|
|
7
|
+
|
|
8
|
+
import { getOrchestratorStore } from './store';
|
|
9
|
+
|
|
10
|
+
export type StoreProviderProps = {
|
|
11
|
+
initialOrchestratorConfig: OrchestratorConfig;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const StoreProvider = ({
|
|
16
|
+
initialOrchestratorConfig,
|
|
17
|
+
children,
|
|
18
|
+
}: StoreProviderProps) => {
|
|
19
|
+
const { orchestratorConfig } = useOrchestratorConfig(
|
|
20
|
+
initialOrchestratorConfig,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const store = getOrchestratorStore(orchestratorConfig);
|
|
24
|
+
|
|
25
|
+
return <Provider store={store}>{children}</Provider>;
|
|
26
|
+
};
|
package/src/types/types.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
|
|
2
|
+
|
|
1
3
|
import { InputForm } from './forms';
|
|
2
4
|
|
|
3
5
|
export type Nullable<T> = T | null;
|
|
@@ -18,11 +20,12 @@ export enum EngineStatus {
|
|
|
18
20
|
RUNNING = 'RUNNING',
|
|
19
21
|
PAUSING = 'PAUSING',
|
|
20
22
|
PAUSED = 'PAUSED',
|
|
23
|
+
UNKNOWN = 'UNKNOWN',
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export type Customer = {
|
|
24
27
|
fullname: string;
|
|
25
|
-
|
|
28
|
+
customerId: string;
|
|
26
29
|
shortcode: string;
|
|
27
30
|
};
|
|
28
31
|
|
|
@@ -266,6 +269,10 @@ export type GraphQLPageInfo = {
|
|
|
266
269
|
filterFields: string[];
|
|
267
270
|
};
|
|
268
271
|
|
|
272
|
+
export type BaseGraphQlResult = {
|
|
273
|
+
pageInfo: GraphQLPageInfo;
|
|
274
|
+
};
|
|
275
|
+
|
|
269
276
|
export interface SubscriptionsResult<T = Subscription> {
|
|
270
277
|
subscriptions: GraphQlResultPage<T>;
|
|
271
278
|
}
|
|
@@ -377,7 +384,7 @@ export type SubscriptionDropdownOption = {
|
|
|
377
384
|
description: Subscription['description'];
|
|
378
385
|
subscriptionId: Subscription['subscriptionId'];
|
|
379
386
|
product: Pick<ProductDefinition, 'tag' | 'productId'>;
|
|
380
|
-
customer: Pick<Customer, 'fullname' | '
|
|
387
|
+
customer: Pick<Customer, 'fullname' | 'customerId'>;
|
|
381
388
|
productBlockInstances: ProductBlockInstance[];
|
|
382
389
|
fixedInputs: FieldValue[];
|
|
383
390
|
tag: string;
|
|
@@ -440,3 +447,27 @@ export type ExternalService = {
|
|
|
440
447
|
};
|
|
441
448
|
|
|
442
449
|
export type WfoTreeNodeMap = { [key: number]: TreeBlock };
|
|
450
|
+
|
|
451
|
+
export type { Toast };
|
|
452
|
+
|
|
453
|
+
export enum ToastTypes {
|
|
454
|
+
ERROR = 'ERROR',
|
|
455
|
+
SUCCESS = 'SUCCESS',
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export enum Environment {
|
|
459
|
+
DEVELOPMENT = 'Development',
|
|
460
|
+
PRODUCTION = 'Production',
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export type OrchestratorConfig = {
|
|
464
|
+
environmentName: Environment | string;
|
|
465
|
+
orchestratorApiBaseUrl: string;
|
|
466
|
+
graphqlEndpointCore: string;
|
|
467
|
+
engineStatusEndpoint: string;
|
|
468
|
+
processStatusCountsEndpoint: string;
|
|
469
|
+
processesEndpoint: string;
|
|
470
|
+
subscriptionActionsEndpoint: string;
|
|
471
|
+
subscriptionProcessesEndpoint: string;
|
|
472
|
+
authActive: boolean;
|
|
473
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { TranslationValues } from 'next-intl';
|
|
2
|
+
|
|
3
|
+
import { MAXIMUM_ITEMS_FOR_BULK_FETCHING } from '@/configuration/constants';
|
|
4
|
+
import { ToastTypes } from '@/types';
|
|
5
|
+
import { GraphQLPageInfo } from '@/types';
|
|
6
|
+
import { sortObjectKeys } from '@/utils/sortObjectKeys';
|
|
7
|
+
|
|
8
|
+
function toCsvFileContent<T extends object>(data: T[]): string {
|
|
9
|
+
const headers = Object.keys(data[0]).join(';');
|
|
10
|
+
const rows = data.map((row) =>
|
|
11
|
+
Object.values(row)
|
|
12
|
+
.map((value) => (value === null ? '' : `"${value}"`))
|
|
13
|
+
.join(';')
|
|
14
|
+
.split('\n')
|
|
15
|
+
.join(' '),
|
|
16
|
+
);
|
|
17
|
+
return [headers, ...rows].join('\n');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function startCsvDownload(csvFileContent: string, fileName: string) {
|
|
21
|
+
const blob = new Blob([csvFileContent], { type: 'text/csv' });
|
|
22
|
+
const url = URL.createObjectURL(blob);
|
|
23
|
+
const link = document.createElement('a');
|
|
24
|
+
link.href = url;
|
|
25
|
+
link.download = fileName.endsWith('.csv') ? fileName : `${fileName}.csv`;
|
|
26
|
+
link.click();
|
|
27
|
+
URL.revokeObjectURL(url);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function initiateCsvFileDownload<T extends object>(
|
|
31
|
+
data: T[],
|
|
32
|
+
fileName: string,
|
|
33
|
+
) {
|
|
34
|
+
const csvFileContent = toCsvFileContent(data);
|
|
35
|
+
startCsvDownload(csvFileContent, fileName);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const getCsvFileNameWithDate = (fileNameWithoutExtension: string) => {
|
|
39
|
+
const date = new Date();
|
|
40
|
+
const year = date.getFullYear();
|
|
41
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
42
|
+
const day = date.getDate();
|
|
43
|
+
|
|
44
|
+
const hour = date.getHours();
|
|
45
|
+
const minute = date.getMinutes();
|
|
46
|
+
const second = date.getSeconds();
|
|
47
|
+
|
|
48
|
+
return `${fileNameWithoutExtension}_${year}-${month}-${day}-${hour}${minute}${second}.csv`;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const csvDownloadHandler = <T extends object, U extends object>(
|
|
52
|
+
dataFetchFunction: () => Promise<T | undefined>,
|
|
53
|
+
dataMapper: (data: T) => U[],
|
|
54
|
+
pageInfoMapper: (data: T) => GraphQLPageInfo,
|
|
55
|
+
keyOrder: string[],
|
|
56
|
+
filename: string,
|
|
57
|
+
addToastFunction: (type: ToastTypes, text: string, title: string) => void,
|
|
58
|
+
translationFunction: (
|
|
59
|
+
translationKey: string,
|
|
60
|
+
variables?: TranslationValues,
|
|
61
|
+
) => string,
|
|
62
|
+
) => {
|
|
63
|
+
return async () => {
|
|
64
|
+
const data: T | undefined = await dataFetchFunction();
|
|
65
|
+
|
|
66
|
+
if (data) {
|
|
67
|
+
const dataForExport = dataMapper(data).map((d) =>
|
|
68
|
+
sortObjectKeys(d, keyOrder),
|
|
69
|
+
);
|
|
70
|
+
const pageInfo = pageInfoMapper(data);
|
|
71
|
+
(pageInfo.totalItems ?? 0) > MAXIMUM_ITEMS_FOR_BULK_FETCHING &&
|
|
72
|
+
addToastFunction(
|
|
73
|
+
ToastTypes.ERROR,
|
|
74
|
+
translationFunction('notAllResultsExported', {
|
|
75
|
+
totalResults: pageInfo.totalItems,
|
|
76
|
+
maximumExportedResults: MAXIMUM_ITEMS_FOR_BULK_FETCHING,
|
|
77
|
+
}),
|
|
78
|
+
translationFunction('notAllResultsExportedTitle'),
|
|
79
|
+
);
|
|
80
|
+
initiateCsvFileDownload(dataForExport, filename);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
@@ -64,19 +64,17 @@ export const getDefaultTableConfig = <T>(storageKey: string) => {
|
|
|
64
64
|
const activeProcessColumns: (keyof ProcessListItem)[] = [
|
|
65
65
|
'productName',
|
|
66
66
|
'customer',
|
|
67
|
-
'createdBy',
|
|
68
67
|
'assignee',
|
|
69
68
|
'processId',
|
|
69
|
+
'startedAt',
|
|
70
70
|
];
|
|
71
71
|
return getTableConfig<T>(activeProcessColumns as (keyof T)[]);
|
|
72
72
|
|
|
73
73
|
case COMPLETED_PROCESSES_LIST_TABLE_LOCAL_STORAGE_KEY:
|
|
74
74
|
const completedProcessColumns: (keyof ProcessListItem)[] = [
|
|
75
75
|
'lastStep',
|
|
76
|
-
'lastStatus',
|
|
77
76
|
'productName',
|
|
78
77
|
'customer',
|
|
79
|
-
'createdBy',
|
|
80
78
|
'assignee',
|
|
81
79
|
'processId',
|
|
82
80
|
'startedAt',
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getQueryVariablesForExport } from './getQueryVariablesForExport';
|
|
2
|
+
|
|
3
|
+
describe('getQueryVariablesForExport', () => {
|
|
4
|
+
it('returns queryVariables with first and after property set to 1000 and 0', () => {
|
|
5
|
+
const queryVariables = {
|
|
6
|
+
first: 10,
|
|
7
|
+
after: 20,
|
|
8
|
+
otherField: 'test',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const result = getQueryVariablesForExport(queryVariables);
|
|
12
|
+
|
|
13
|
+
expect(result).toEqual({
|
|
14
|
+
first: 1000,
|
|
15
|
+
after: 0,
|
|
16
|
+
otherField: 'test',
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GraphqlQueryVariables } from '@/types';
|
|
2
|
+
|
|
3
|
+
import { MAXIMUM_ITEMS_FOR_BULK_FETCHING } from '../configuration/constants';
|
|
4
|
+
|
|
5
|
+
export const getQueryVariablesForExport = <T extends object>(
|
|
6
|
+
queryVariables: GraphqlQueryVariables<T>,
|
|
7
|
+
) => ({
|
|
8
|
+
...queryVariables,
|
|
9
|
+
first: MAXIMUM_ITEMS_FOR_BULK_FETCHING,
|
|
10
|
+
after: 0,
|
|
11
|
+
});
|
package/src/utils/index.ts
CHANGED