@orchestrator-ui/orchestrator-ui-components 0.2.7 → 0.3.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 +6 -6
- package/.turbo/turbo-lint.log +0 -6
- package/.turbo/turbo-test.log +10 -9
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +1005 -123
- package/dist/index.js +33849 -6199
- package/package.json +14 -12
- package/src/api/index.ts +55 -0
- package/src/components/WfoDiff/WfoDiff.tsx +119 -0
- package/src/components/WfoDiff/index.ts +1 -0
- package/src/components/WfoDiff/unidiff.d.ts +1 -0
- package/src/components/WfoForms/AutoFieldLoader.tsx +5 -1
- package/src/components/WfoForms/CreateForm.tsx +1 -0
- package/src/components/WfoForms/UserInputForm.tsx +75 -44
- package/src/components/WfoForms/UserInputFormWizard.tsx +11 -4
- package/src/components/WfoForms/formFields/AcceptField.tsx +8 -5
- package/src/components/WfoForms/formFields/BoolField.tsx +1 -1
- package/src/components/WfoForms/formFields/ImsNodeIdField.tsx +2 -2
- package/src/components/WfoForms/formFields/ImsPortIdField.tsx +238 -0
- package/src/components/WfoForms/formFields/ImsPortIdFieldStyling.ts +17 -0
- package/src/components/WfoForms/formFields/ListAddField.tsx +1 -1
- package/src/components/WfoForms/formFields/ListDelField.tsx +1 -1
- package/src/components/WfoForms/formFields/OptGroupField.tsx +1 -1
- package/src/components/WfoForms/formFields/SubscriptionField.tsx +2 -1
- package/src/components/WfoForms/formFields/SummaryField.tsx +103 -0
- package/src/components/WfoForms/formFields/SummaryFieldStyling.ts +46 -0
- package/src/components/WfoForms/formFields/VlanField.tsx +10 -10
- package/src/components/WfoForms/formFields/index.ts +2 -0
- package/src/components/WfoForms/formFields/surf/types.ts +26 -0
- package/src/components/WfoForms/formFields/utils.spec.ts +1 -0
- package/src/components/WfoJsonCodeBlock/index.ts +1 -0
- package/src/components/WfoPageTemplate/WfoPageHeader/WfoPageHeader.tsx +4 -3
- package/src/components/WfoPageTemplate/WfoSidebar/WfoSidebar.tsx +14 -14
- package/src/components/WfoPageTemplate/WfoSidebar/WfoStartCreateWorkflowButtonComboBox.tsx +15 -9
- package/src/components/WfoPageTemplate/paths.ts +3 -2
- package/src/components/{WfoProcessesList → WfoProcessList}/WfoProcessList.tsx +18 -14
- package/src/components/WfoProcessList/index.ts +1 -0
- package/src/components/{WfoProcessesList → WfoProcessList}/processListObjectMappers.ts +4 -2
- package/src/components/WfoSearchBar/WfoSearchField.tsx +27 -37
- package/src/components/{WfoSettingsPage → WfoSettings}/WfoEngineStatusButton.tsx +7 -4
- package/src/components/{WfoSettingsPage → WfoSettings}/WfoFlushSettings.tsx +13 -12
- package/src/components/WfoSettings/WfoModifySettings.tsx +38 -0
- package/src/components/WfoSettings/WfoSettings.tsx +40 -0
- package/src/components/{WfoSettingsPage → WfoSettings}/WfoStatus.tsx +21 -14
- package/src/components/WfoStartPage/WfoListStartPage.tsx +3 -3
- package/src/components/WfoStartTaskButtonComboBox/WfoStartTaskButtonComboBox.tsx +14 -8
- package/src/components/WfoSubscription/WfoProcessesTimeline.tsx +11 -18
- package/src/components/WfoSubscription/WfoSubscription.tsx +1 -1
- package/src/components/WfoSubscription/WfoSubscriptionActions.tsx +41 -33
- package/src/components/WfoSubscription/WfoSubscriptionDetailTree.tsx +32 -22
- package/src/components/WfoSubscription/WfoSubscriptionProductBlock.tsx +94 -90
- package/src/components/WfoSubscription/WfoTargetTypeIcon.tsx +26 -0
- package/src/components/WfoSubscription/utils/utils.spec.ts +24 -0
- package/src/components/WfoSubscription/utils/utils.ts +16 -0
- package/src/components/WfoSubscriptionsList/WfoSubscriptionsList.tsx +17 -37
- package/src/components/WfoTable/WfoTableWithFilter/WfoTableWithFilter.tsx +20 -19
- package/src/components/WfoTable/WfoTableWithFilter/updateQueryString.spec.ts +95 -0
- package/src/components/WfoTable/WfoTableWithFilter/updateQueryString.ts +60 -0
- package/src/components/WfoTable/utils/tableUtils.ts +3 -3
- package/src/components/WfoTextAnchor/WfoTextAnchor.stories.tsx +18 -0
- package/src/components/WfoTextAnchor/WfoTextAnchor.tsx +22 -0
- package/src/components/WfoTextAnchor/index.ts +1 -0
- package/src/components/WfoTextAnchor/styles.ts +17 -0
- package/src/components/WfoTimeline/styles.ts +10 -4
- package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +39 -24
- package/src/components/WfoWorkflowSteps/WfoStep/WfoStepForm.tsx +48 -0
- package/src/components/WfoWorkflowSteps/WfoStepList/WfoStepList.tsx +10 -10
- package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoStepListHeader.tsx +22 -23
- package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoWorkflowStepList.tsx +97 -17
- package/src/components/WfoWorkflowSteps/stepListUtils.ts +1 -28
- package/src/components/confirmationDialog/WfoConfirmationDialog.tsx +3 -3
- package/src/components/index.ts +6 -1
- package/src/contexts/ConfirmationDialogProvider.tsx +2 -2
- package/src/contexts/TreeContext.tsx +5 -0
- package/src/graphqlQueries/index.ts +1 -0
- package/src/graphqlQueries/processDetailQuery.ts +8 -0
- package/src/graphqlQueries/processListQuery.ts +7 -6
- package/src/graphqlQueries/processStepsQuery.ts +22 -0
- package/src/graphqlQueries/productBlocksQuery.ts +9 -5
- package/src/graphqlQueries/productsQuery.ts +7 -3
- package/src/graphqlQueries/relatedSubscriptionsQuery.ts +2 -2
- package/src/graphqlQueries/resourceTypesQuery.ts +8 -4
- package/src/graphqlQueries/subscriptionDetailQuery.ts +1 -0
- package/src/graphqlQueries/subscriptionsListQuery.ts +5 -3
- package/src/graphqlQueries/workflows/workflowsQuery.ts +8 -4
- package/src/graphqlQueries/workflows/workflowsQueryForDropdownList.ts +2 -2
- package/src/hooks/DataFetchHooks.ts +9 -4
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useCheckEngineStatus.ts +30 -0
- package/src/hooks/useDataDisplayParams.ts +3 -3
- package/src/hooks/useEngineStatusQuery.ts +9 -7
- package/src/hooks/useMutateProcess.ts +96 -0
- package/src/messages/{en-US.json → en-GB.json} +85 -37
- package/src/messages/getTranslationMessages.spec.ts +25 -40
- package/src/messages/index.ts +1 -1
- package/src/messages/nl-NL.json +95 -48
- package/src/messages/useGetTranslationMessages.ts +51 -0
- package/src/pages/metadata/WfoProductBlocksPage.tsx +12 -10
- package/src/pages/metadata/WfoProductsPage.tsx +24 -25
- package/src/pages/metadata/WfoResourceTypesPage.tsx +12 -10
- package/src/pages/metadata/WfoWorkflowsPage.tsx +12 -10
- package/src/pages/processes/WfoProcessDetail.tsx +96 -79
- package/src/pages/processes/WfoProcessDetailPage.tsx +5 -3
- package/src/pages/{workflow/WfoStartWorkflowPage.tsx → processes/WfoStartProcessPage.tsx} +100 -50
- package/src/pages/processes/index.ts +1 -3
- package/src/pages/settings/WfoSettingsPage.tsx +30 -0
- package/src/pages/settings/index.ts +1 -0
- package/src/pages/tasks/WfoTaskListPage.tsx +35 -9
- package/src/pages/{processes/WfoProcessListPage.tsx → workflow/WfoWorkflowListPage.tsx} +22 -23
- package/src/pages/workflow/getWorkflowListTabTypeFromString.ts +19 -0
- package/src/pages/workflow/index.ts +1 -1
- package/src/pages/{processes → workflow}/tabConfig.ts +6 -6
- package/src/types/types.ts +33 -3
- package/src/utils/getDefaultTableConfig.ts +1 -1
- package/src/components/WfoSettingsPage/WfoModifySettings.tsx +0 -33
- package/src/components/WfoSettingsPage/WfoSettings.tsx +0 -40
- package/src/hooks/ProcessesHooks/useDeleteProcess.ts +0 -37
- package/src/messages/getTranslationMessages.ts +0 -26
- package/src/pages/processes/getProcessListTabTypeFromString.ts +0 -19
- /package/src/components/{WfoSettingsPage → WfoSettings}/index.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchestrator-ui/orchestrator-ui-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "jest",
|
|
@@ -9,17 +9,19 @@
|
|
|
9
9
|
"lint": "eslint \"src/**/*.ts*\"",
|
|
10
10
|
"dev": "yarn build -- --watch",
|
|
11
11
|
"storybook": "storybook dev -p 6006",
|
|
12
|
-
"build-storybook": "storybook build"
|
|
13
|
-
"reset": "rm -rf node_modules"
|
|
12
|
+
"build-storybook": "storybook build"
|
|
14
13
|
},
|
|
15
14
|
"dependencies": {
|
|
16
15
|
"@graphql-typed-document-node/core": "3.2.0",
|
|
17
|
-
"axios": "^
|
|
16
|
+
"axios": "^1.6.2",
|
|
18
17
|
"invariant": "^2.2.4",
|
|
19
18
|
"moment": "2.29.4",
|
|
20
19
|
"moment-timezone": "^0.5.43",
|
|
21
|
-
"object-hash": "^
|
|
20
|
+
"object-hash": "^3.0.0",
|
|
22
21
|
"react-select": "^5.8.0",
|
|
22
|
+
"react-diff-view": "^3.2.0",
|
|
23
|
+
"unidiff": "^1.0.4",
|
|
24
|
+
"prism-themes": "^1.9.0",
|
|
23
25
|
"scroll-into-view": "^1.16.2",
|
|
24
26
|
"uniforms": "^3.8.1",
|
|
25
27
|
"uniforms-bridge-json-schema": "^3.8.1",
|
|
@@ -35,8 +37,8 @@
|
|
|
35
37
|
"next-auth": "^4.23.1",
|
|
36
38
|
"next-intl": "2.19.0",
|
|
37
39
|
"next-query-params": "4.2.2",
|
|
38
|
-
"react": "
|
|
39
|
-
"react
|
|
40
|
+
"react-query": "3.39.3",
|
|
41
|
+
"react": "^18.2.0"
|
|
40
42
|
},
|
|
41
43
|
"devDependencies": {
|
|
42
44
|
"@orchestrator-ui/eslint-config-custom": "*",
|
|
@@ -44,20 +46,20 @@
|
|
|
44
46
|
"@storybook/addon-essentials": "^7.2.1",
|
|
45
47
|
"@storybook/addon-interactions": "^7.2.1",
|
|
46
48
|
"@storybook/addon-links": "^7.2.1",
|
|
47
|
-
"@storybook/addon-onboarding": "^1.0.
|
|
49
|
+
"@storybook/addon-onboarding": "^1.0.10",
|
|
48
50
|
"@storybook/blocks": "^7.2.1",
|
|
49
51
|
"@storybook/nextjs": "^7.2.1",
|
|
50
52
|
"@storybook/react": "^7.2.1",
|
|
51
53
|
"@storybook/testing-library": "^0.2.0",
|
|
52
|
-
"@testing-library/jest-dom": "^
|
|
54
|
+
"@testing-library/jest-dom": "^6.1.5",
|
|
53
55
|
"@testing-library/react": "^14.0.0",
|
|
54
56
|
"@testing-library/react-hooks": "^8.0.1",
|
|
55
57
|
"@testing-library/user-event": "^14.4.3",
|
|
56
58
|
"@types/invariant": "^2.2.33",
|
|
57
59
|
"@types/jest": "^29.5.8",
|
|
58
|
-
"@types/object-hash": "^
|
|
60
|
+
"@types/object-hash": "^3.0.6",
|
|
59
61
|
"@types/scroll-into-view": "^1.16.3",
|
|
60
|
-
"esbuild": "^0.
|
|
62
|
+
"esbuild": "^0.19.9",
|
|
61
63
|
"esbuild-jest": "^0.5.0",
|
|
62
64
|
"jest": "^29.7.0",
|
|
63
65
|
"jest-watch-typeahead": "^2.2.2",
|
|
@@ -65,7 +67,7 @@
|
|
|
65
67
|
"react": "^18.2.0",
|
|
66
68
|
"react-dom": "^18.2.0",
|
|
67
69
|
"storybook": "^7.2.1",
|
|
68
|
-
"tsup": "^
|
|
70
|
+
"tsup": "^8.0.1",
|
|
69
71
|
"uniforms-bridge-simple-schema-2": "^3.8.1"
|
|
70
72
|
},
|
|
71
73
|
"type": "module",
|
package/src/api/index.ts
CHANGED
|
@@ -15,8 +15,10 @@
|
|
|
15
15
|
import { AxiosInstance } from 'axios';
|
|
16
16
|
|
|
17
17
|
import {
|
|
18
|
+
ImsPort,
|
|
18
19
|
IpBlock,
|
|
19
20
|
IpPrefix,
|
|
21
|
+
NodeSubscription,
|
|
20
22
|
} from '../components/WfoForms/formFields/surf/types';
|
|
21
23
|
import { ProductDefinition } from '../types';
|
|
22
24
|
import { getAxiosInstance } from './axios';
|
|
@@ -122,6 +124,17 @@ export class ApiClient extends ApiClientInterface {
|
|
|
122
124
|
true,
|
|
123
125
|
);
|
|
124
126
|
};
|
|
127
|
+
|
|
128
|
+
resumeProcess = (processId: string, userInput: object[]) => {
|
|
129
|
+
return this.postPutJson(
|
|
130
|
+
`processes/${processId}/resume`,
|
|
131
|
+
userInput,
|
|
132
|
+
'put',
|
|
133
|
+
false,
|
|
134
|
+
false,
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
125
138
|
products = (): Promise<ProductDefinition[]> => {
|
|
126
139
|
return this.fetchJson<ProductDefinition[]>(PRODUCTS_ENDPOINT);
|
|
127
140
|
};
|
|
@@ -160,6 +173,48 @@ export class ApiClient extends ApiClientInterface {
|
|
|
160
173
|
prefixlen,
|
|
161
174
|
);
|
|
162
175
|
};
|
|
176
|
+
getFreePortsByNodeSubscriptionIdAndSpeed = (
|
|
177
|
+
nodeSubscriptionId: string,
|
|
178
|
+
interfaceSpeed: number,
|
|
179
|
+
mode: string,
|
|
180
|
+
): Promise<ImsPort[]> => {
|
|
181
|
+
return this.fetchJson(
|
|
182
|
+
`surf/ims/free_ports/${nodeSubscriptionId}/${interfaceSpeed}/${mode}`,
|
|
183
|
+
);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// legacy : for imsPort selector
|
|
187
|
+
subscriptions = (
|
|
188
|
+
tagList: string[] = [],
|
|
189
|
+
statusList: string[] = [],
|
|
190
|
+
productList: string[] = [],
|
|
191
|
+
): Promise<NodeSubscription[]> => {
|
|
192
|
+
const filters = [];
|
|
193
|
+
|
|
194
|
+
if (tagList.length)
|
|
195
|
+
filters.push(`tags,${encodeURIComponent(tagList.join('-'))}`);
|
|
196
|
+
if (statusList.length)
|
|
197
|
+
filters.push(
|
|
198
|
+
`statuses,${encodeURIComponent(statusList.join('-'))}`,
|
|
199
|
+
);
|
|
200
|
+
if (productList.length)
|
|
201
|
+
filters.push(
|
|
202
|
+
`products,${encodeURIComponent(productList.join('-'))}`,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
const params = new URLSearchParams();
|
|
206
|
+
if (filters.length) params.set('filter', filters.join(','));
|
|
207
|
+
|
|
208
|
+
return this.fetchJson(
|
|
209
|
+
`subscriptions/${filters.length ? '?' : ''}${params.toString()}`,
|
|
210
|
+
);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
nodeSubscriptions = (
|
|
214
|
+
statusList: string[] = [],
|
|
215
|
+
): Promise<NodeSubscription[]> => {
|
|
216
|
+
return this.subscriptions(['Node'], statusList);
|
|
217
|
+
};
|
|
163
218
|
}
|
|
164
219
|
|
|
165
220
|
export function getApiClient(apiEndPoint: string) {
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { Diff, Hunk, parseDiff, tokenize } from 'react-diff-view';
|
|
3
|
+
import 'react-diff-view/style/index.css';
|
|
4
|
+
import { DiffType } from 'react-diff-view/types/Diff';
|
|
5
|
+
import { HunkData } from 'react-diff-view/types/utils/parse';
|
|
6
|
+
|
|
7
|
+
import { useTranslations } from 'next-intl';
|
|
8
|
+
// CSS for syntax highlight
|
|
9
|
+
import 'prism-themes/themes/prism-ghcolors.min.css';
|
|
10
|
+
import * as refractor from 'refractor';
|
|
11
|
+
import { diffLines, formatLines } from 'unidiff';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
EuiButtonIcon,
|
|
15
|
+
EuiFlexGroup,
|
|
16
|
+
EuiFlexItem,
|
|
17
|
+
EuiSpacer,
|
|
18
|
+
EuiText,
|
|
19
|
+
} from '@elastic/eui';
|
|
20
|
+
|
|
21
|
+
const EMPTY_HUNKS: never[] = [];
|
|
22
|
+
|
|
23
|
+
const SMALL_CONTEXT = 3;
|
|
24
|
+
const FULL_CONTEXT = 1000000;
|
|
25
|
+
|
|
26
|
+
interface DiffState {
|
|
27
|
+
type: DiffType;
|
|
28
|
+
hunks: HunkData[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface WfoDiffProps {
|
|
32
|
+
oldText: string;
|
|
33
|
+
newText: string;
|
|
34
|
+
syntax?: 'javascript' | 'python';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const WfoDiff: FC<WfoDiffProps> = ({ oldText, newText, syntax }) => {
|
|
38
|
+
const t = useTranslations('processes.delta');
|
|
39
|
+
const [showSplit, setShowSplit] = useState(true);
|
|
40
|
+
const [showFull, setShowFull] = useState(false);
|
|
41
|
+
|
|
42
|
+
const [{ type, hunks }, setDiff] = useState<DiffState>({
|
|
43
|
+
type: 'modify',
|
|
44
|
+
hunks: [],
|
|
45
|
+
});
|
|
46
|
+
const updateDiffText = useCallback(() => {
|
|
47
|
+
const diffText = formatLines(diffLines(oldText, newText), {
|
|
48
|
+
context: showFull ? FULL_CONTEXT : SMALL_CONTEXT,
|
|
49
|
+
});
|
|
50
|
+
const [diff] = parseDiff(diffText, { nearbySequences: 'zip' });
|
|
51
|
+
setDiff(diff);
|
|
52
|
+
}, [oldText, newText, setDiff, showFull]);
|
|
53
|
+
|
|
54
|
+
const tokens = useMemo(() => {
|
|
55
|
+
if (!hunks) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const options = {
|
|
60
|
+
refractor,
|
|
61
|
+
highlight: !!syntax,
|
|
62
|
+
language: syntax ?? '',
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
return tokenize(hunks, options);
|
|
67
|
+
} catch (ex) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
}, [hunks, syntax]);
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
updateDiffText();
|
|
74
|
+
}, [updateDiffText, showFull]);
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div>
|
|
78
|
+
<EuiFlexGroup gutterSize={'xs'}>
|
|
79
|
+
<EuiFlexItem grow={false}>
|
|
80
|
+
<EuiText>
|
|
81
|
+
<h3>{t('title')}</h3>
|
|
82
|
+
</EuiText>
|
|
83
|
+
</EuiFlexItem>
|
|
84
|
+
<EuiFlexItem grow={false}>
|
|
85
|
+
<EuiButtonIcon
|
|
86
|
+
size={'s'}
|
|
87
|
+
iconType={
|
|
88
|
+
showSplit
|
|
89
|
+
? 'continuityAboveBelow'
|
|
90
|
+
: 'continuityWithin'
|
|
91
|
+
}
|
|
92
|
+
onClick={() => setShowSplit(!showSplit)}
|
|
93
|
+
/>
|
|
94
|
+
</EuiFlexItem>
|
|
95
|
+
<EuiFlexItem grow={false}>
|
|
96
|
+
<EuiButtonIcon
|
|
97
|
+
size={'s'}
|
|
98
|
+
iconType={showFull ? 'fullScreenExit' : 'fullScreen'}
|
|
99
|
+
onClick={() => setShowFull(!showFull)}
|
|
100
|
+
/>
|
|
101
|
+
</EuiFlexItem>
|
|
102
|
+
</EuiFlexGroup>
|
|
103
|
+
|
|
104
|
+
<EuiSpacer />
|
|
105
|
+
<Diff
|
|
106
|
+
viewType={showSplit ? 'split' : 'unified'}
|
|
107
|
+
diffType={type}
|
|
108
|
+
hunks={hunks || EMPTY_HUNKS}
|
|
109
|
+
tokens={tokens}
|
|
110
|
+
>
|
|
111
|
+
{(hunks) =>
|
|
112
|
+
hunks.map((hunk) => <Hunk key={hunk.content} hunk={hunk} />)
|
|
113
|
+
}
|
|
114
|
+
</Diff>
|
|
115
|
+
</div>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default WfoDiff;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './WfoDiff';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'unidiff';
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
DateField,
|
|
9
9
|
DividerField,
|
|
10
10
|
ImsNodeIdField,
|
|
11
|
+
ImsPortIdField,
|
|
11
12
|
IpNetworkField,
|
|
12
13
|
LabelField,
|
|
13
14
|
ListField,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
SelectField,
|
|
23
24
|
SubscriptionField,
|
|
24
25
|
SubscriptionSummaryField,
|
|
26
|
+
SummaryField,
|
|
25
27
|
TextField,
|
|
26
28
|
TimestampField,
|
|
27
29
|
VlanField,
|
|
@@ -43,7 +45,7 @@ export function autoFieldFunction(
|
|
|
43
45
|
case Number:
|
|
44
46
|
switch (format) {
|
|
45
47
|
case 'imsPortId': // Surf specific
|
|
46
|
-
return
|
|
48
|
+
return ImsPortIdField;
|
|
47
49
|
case 'imsNodeId': // Surf specific
|
|
48
50
|
return ImsNodeIdField;
|
|
49
51
|
case 'timestamp':
|
|
@@ -68,6 +70,8 @@ export function autoFieldFunction(
|
|
|
68
70
|
return LabelField;
|
|
69
71
|
case 'divider':
|
|
70
72
|
return DividerField;
|
|
73
|
+
case 'summary':
|
|
74
|
+
return SummaryField;
|
|
71
75
|
case 'subscription':
|
|
72
76
|
return SubscriptionSummaryField;
|
|
73
77
|
case 'organisationId':
|
|
@@ -34,11 +34,11 @@ import {
|
|
|
34
34
|
EuiHorizontalRule,
|
|
35
35
|
} from '@elastic/eui';
|
|
36
36
|
|
|
37
|
-
import ConfirmationDialogContext from '
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
|
|
37
|
+
import { ConfirmDialogActions, ConfirmationDialogContext } from '@/contexts';
|
|
38
|
+
import { useOrchestratorTheme } from '@/hooks';
|
|
39
|
+
import { WfoPlayFill } from '@/icons';
|
|
40
|
+
import { ValidationError } from '@/types/forms';
|
|
41
|
+
|
|
42
42
|
import { autoFieldFunction } from './AutoFieldLoader';
|
|
43
43
|
import AutoFields from './AutoFields';
|
|
44
44
|
import { userInputFormStyling } from './UserInputFormStyling';
|
|
@@ -52,11 +52,13 @@ interface IProps {
|
|
|
52
52
|
router: NextRouter;
|
|
53
53
|
stepUserInput: JSONSchema6;
|
|
54
54
|
validSubmit: (userInput: { [index: string]: unknown }) => Promise<unknown>;
|
|
55
|
-
cancel
|
|
55
|
+
cancel?: ConfirmDialogActions['closeConfirmDialog'];
|
|
56
56
|
previous: ConfirmDialogActions['closeConfirmDialog'];
|
|
57
57
|
hasNext?: boolean;
|
|
58
58
|
hasPrev?: boolean;
|
|
59
59
|
userInput: object;
|
|
60
|
+
isTask?: boolean;
|
|
61
|
+
isResuming?: boolean;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
interface Buttons {
|
|
@@ -116,6 +118,18 @@ function resolveRef(reference: string, schema: Record<string, any>) {
|
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
class CustomTitleJSONSchemaBridge extends JSONSchemaBridge {
|
|
121
|
+
t: any;
|
|
122
|
+
|
|
123
|
+
constructor(schema: JSONSchema6, validator: any, t: any) {
|
|
124
|
+
super(schema, validator);
|
|
125
|
+
this.t = t;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
translationKeyExists(key: string): boolean {
|
|
129
|
+
const translation = this.t(key);
|
|
130
|
+
return translation !== key ? true : false;
|
|
131
|
+
}
|
|
132
|
+
|
|
119
133
|
// This a copy of the super class function to provide a fix for https://github.com/vazco/uniforms/issues/863
|
|
120
134
|
getField(name: string) {
|
|
121
135
|
return joinName(null, name).reduce(
|
|
@@ -246,12 +260,11 @@ class CustomTitleJSONSchemaBridge extends JSONSchemaBridge {
|
|
|
246
260
|
getProps(name: string) {
|
|
247
261
|
const props = super.getProps(name);
|
|
248
262
|
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
let label = props.label;
|
|
263
|
+
const translationKey = name.replace(/\.\d+(.\d+)*/, '_fields'); // This is evaluates to name or name_fields
|
|
264
|
+
const nextIntlKey = `pydanticForms.backendTranslations.${translationKey}`;
|
|
265
|
+
let label = this.translationKeyExists(nextIntlKey)
|
|
266
|
+
? this.t(nextIntlKey)
|
|
267
|
+
: props.label;
|
|
255
268
|
|
|
256
269
|
// Mark required inputs. Might be delegated to the form components itself in the future.
|
|
257
270
|
if (
|
|
@@ -264,9 +277,11 @@ class CustomTitleJSONSchemaBridge extends JSONSchemaBridge {
|
|
|
264
277
|
}
|
|
265
278
|
|
|
266
279
|
props.label = label;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
props.description =
|
|
280
|
+
|
|
281
|
+
const descriptionTranslationKey = `pydanticForms.backendTranslations.${translationKey}_info`;
|
|
282
|
+
props.description = this.translationKeyExists(descriptionTranslationKey)
|
|
283
|
+
? this.t(descriptionTranslationKey)
|
|
284
|
+
: ' ';
|
|
270
285
|
|
|
271
286
|
props.id = `input-${name}`;
|
|
272
287
|
|
|
@@ -369,11 +384,13 @@ function UserInputForm({
|
|
|
369
384
|
router,
|
|
370
385
|
stepUserInput,
|
|
371
386
|
validSubmit,
|
|
372
|
-
cancel,
|
|
387
|
+
cancel = () => {},
|
|
373
388
|
previous = () => {},
|
|
374
389
|
hasNext = false,
|
|
375
390
|
hasPrev = false,
|
|
376
391
|
userInput,
|
|
392
|
+
isTask = false,
|
|
393
|
+
isResuming = false,
|
|
377
394
|
}: IProps) {
|
|
378
395
|
const t = useTranslations('pydanticForms.userInputForm');
|
|
379
396
|
const { theme } = useOrchestratorTheme();
|
|
@@ -382,13 +399,17 @@ function UserInputForm({
|
|
|
382
399
|
const [nrOfValidationErrors, setNrOfValidationErrors] = useState<number>(0);
|
|
383
400
|
const [rootErrors, setRootErrors] = useState<string[]>([]);
|
|
384
401
|
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
402
|
+
const openLeavePageDialog = (
|
|
403
|
+
leaveAction: ConfirmDialogActions['closeConfirmDialog'],
|
|
404
|
+
leaveQuestion?: string,
|
|
405
|
+
) => {
|
|
406
|
+
return () =>
|
|
407
|
+
showConfirmDialog({
|
|
408
|
+
question: leaveQuestion || '',
|
|
409
|
+
confirmAction: () => {},
|
|
410
|
+
cancelAction: leaveAction,
|
|
411
|
+
leavePage: true,
|
|
412
|
+
});
|
|
392
413
|
};
|
|
393
414
|
|
|
394
415
|
const submit = async (userInput: any = {}) => {
|
|
@@ -448,12 +469,6 @@ function UserInputForm({
|
|
|
448
469
|
question: string | undefined,
|
|
449
470
|
confirm: ConfirmDialogActions['closeConfirmDialog'],
|
|
450
471
|
) => {
|
|
451
|
-
// eslint-disable-next-line no-console
|
|
452
|
-
console.log(e, question, confirm);
|
|
453
|
-
alert('TODO: Implement on buttonClick cancel with confirm modal');
|
|
454
|
-
// https://github.com/workfloworchestrator/orchestrator-ui/issues/325
|
|
455
|
-
|
|
456
|
-
/*
|
|
457
472
|
if (!question) {
|
|
458
473
|
return confirm(e);
|
|
459
474
|
}
|
|
@@ -464,7 +479,6 @@ function UserInputForm({
|
|
|
464
479
|
cancelAction: () => {},
|
|
465
480
|
leavePage: false,
|
|
466
481
|
});
|
|
467
|
-
*/
|
|
468
482
|
};
|
|
469
483
|
|
|
470
484
|
const renderButtons = (buttons: Buttons) => {
|
|
@@ -474,15 +488,23 @@ function UserInputForm({
|
|
|
474
488
|
fill
|
|
475
489
|
color={buttons.previous.color ?? 'primary'}
|
|
476
490
|
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
477
|
-
onButtonClick(
|
|
491
|
+
onButtonClick(
|
|
492
|
+
e,
|
|
493
|
+
buttons.previous.dialog,
|
|
494
|
+
openLeavePageDialog(previous, t('previousQuestion')),
|
|
495
|
+
);
|
|
478
496
|
}}
|
|
479
497
|
>
|
|
480
498
|
{buttons.previous.text ?? t('previous')}
|
|
481
499
|
</EuiButton>
|
|
482
|
-
) : (
|
|
500
|
+
) : !isResuming ? (
|
|
483
501
|
<div
|
|
484
502
|
onClick={(e) => {
|
|
485
|
-
onButtonClick(
|
|
503
|
+
onButtonClick(
|
|
504
|
+
e,
|
|
505
|
+
buttons.previous.dialog,
|
|
506
|
+
openLeavePageDialog(cancel),
|
|
507
|
+
);
|
|
486
508
|
}}
|
|
487
509
|
css={{
|
|
488
510
|
cursor: 'pointer',
|
|
@@ -493,10 +515,19 @@ function UserInputForm({
|
|
|
493
515
|
alignItems: 'center',
|
|
494
516
|
}}
|
|
495
517
|
>
|
|
496
|
-
{buttons.previous.text ?? t('
|
|
518
|
+
{buttons.previous.text ?? t('cancel')}
|
|
497
519
|
</div>
|
|
520
|
+
) : (
|
|
521
|
+
<div></div>
|
|
498
522
|
);
|
|
499
523
|
|
|
524
|
+
const nextButtonTranslationKey: string = (() => {
|
|
525
|
+
if (isResuming) {
|
|
526
|
+
return isTask ? 'resumeTask' : 'resumeWorkflow';
|
|
527
|
+
}
|
|
528
|
+
return isTask ? 'startTask' : 'startWorkflow';
|
|
529
|
+
})();
|
|
530
|
+
|
|
500
531
|
const nextButton = hasNext ? (
|
|
501
532
|
<EuiButton
|
|
502
533
|
id="button-next-form-submit"
|
|
@@ -519,7 +550,7 @@ function UserInputForm({
|
|
|
519
550
|
iconType={() => <WfoPlayFill color="#FFF" />}
|
|
520
551
|
iconSide="right"
|
|
521
552
|
>
|
|
522
|
-
{buttons.next.text ?? t(
|
|
553
|
+
{buttons.next.text ?? t(nextButtonTranslationKey)}
|
|
523
554
|
</EuiButton>
|
|
524
555
|
);
|
|
525
556
|
|
|
@@ -535,9 +566,12 @@ function UserInputForm({
|
|
|
535
566
|
);
|
|
536
567
|
};
|
|
537
568
|
|
|
538
|
-
//const prefilledForm = fillPreselection(stepUserInput, location.search);
|
|
539
569
|
const prefilledForm = fillPreselection(stepUserInput, router);
|
|
540
|
-
const bridge = new CustomTitleJSONSchemaBridge(
|
|
570
|
+
const bridge = new CustomTitleJSONSchemaBridge(
|
|
571
|
+
prefilledForm,
|
|
572
|
+
() => {},
|
|
573
|
+
useTranslations(),
|
|
574
|
+
);
|
|
541
575
|
const AutoFieldProvider = AutoField.componentDetectorContext.Provider;
|
|
542
576
|
|
|
543
577
|
// Get the Button config from the form default values, or default to empty config
|
|
@@ -571,13 +605,10 @@ function UserInputForm({
|
|
|
571
605
|
{nrOfValidationErrors > 0 && (
|
|
572
606
|
<section className="form-errors">
|
|
573
607
|
<em className="error backend-validation-metadata">
|
|
574
|
-
{t(
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
nrOfValidationErrors,
|
|
579
|
-
},
|
|
580
|
-
)}
|
|
608
|
+
{t('inputFieldsHaveValidationErrors', {
|
|
609
|
+
nrOfValidationErrors:
|
|
610
|
+
nrOfValidationErrors,
|
|
611
|
+
})}
|
|
581
612
|
</em>
|
|
582
613
|
</section>
|
|
583
614
|
)}
|
|
@@ -17,8 +17,9 @@ import React, { useEffect, useState } from 'react';
|
|
|
17
17
|
import { useRouter } from 'next/router';
|
|
18
18
|
import hash from 'object-hash';
|
|
19
19
|
|
|
20
|
-
import { ConfirmDialogActions } from '
|
|
21
|
-
import { FormNotCompleteResponse, InputForm } from '
|
|
20
|
+
import { ConfirmDialogActions } from '@/contexts';
|
|
21
|
+
import { FormNotCompleteResponse, InputForm } from '@/types/forms';
|
|
22
|
+
|
|
22
23
|
import UserInputForm from './UserInputForm';
|
|
23
24
|
import { useAxiosApiClient } from './useAxiosApiClient';
|
|
24
25
|
|
|
@@ -30,8 +31,10 @@ interface Form {
|
|
|
30
31
|
interface UserInputFormWizardProps {
|
|
31
32
|
stepUserInput: InputForm;
|
|
32
33
|
validSubmit: (processInput: object[]) => Promise<unknown>;
|
|
33
|
-
cancel
|
|
34
|
+
cancel?: () => void;
|
|
35
|
+
isTask: boolean;
|
|
34
36
|
hasNext?: boolean;
|
|
37
|
+
isResuming?: boolean;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
function stop(e: React.SyntheticEvent) {
|
|
@@ -41,11 +44,13 @@ function stop(e: React.SyntheticEvent) {
|
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
function UserInputFormWizard({
|
|
47
|
+
export function UserInputFormWizard({
|
|
45
48
|
hasNext = false,
|
|
46
49
|
stepUserInput,
|
|
47
50
|
validSubmit,
|
|
48
51
|
cancel,
|
|
52
|
+
isTask,
|
|
53
|
+
isResuming = false,
|
|
49
54
|
}: UserInputFormWizardProps) {
|
|
50
55
|
const router = useRouter();
|
|
51
56
|
const apiClient = useAxiosApiClient();
|
|
@@ -113,6 +118,8 @@ function UserInputFormWizard({
|
|
|
113
118
|
hasPrev={forms.length > 1}
|
|
114
119
|
cancel={cancel}
|
|
115
120
|
userInput={currentUserInput}
|
|
121
|
+
isTask={isTask}
|
|
122
|
+
isResuming={isResuming}
|
|
116
123
|
/>
|
|
117
124
|
);
|
|
118
125
|
}
|
|
@@ -71,11 +71,13 @@ function Accept({
|
|
|
71
71
|
data,
|
|
72
72
|
...props
|
|
73
73
|
}: AcceptFieldProps) {
|
|
74
|
-
const t = useTranslations(
|
|
74
|
+
const t = useTranslations();
|
|
75
75
|
const { acceptFieldStyle } = useWithOrchestratorTheme(getStyles);
|
|
76
76
|
|
|
77
77
|
const legacy = !data;
|
|
78
|
-
const i18nBaseKey = data
|
|
78
|
+
const i18nBaseKey = data
|
|
79
|
+
? `pydanticForms.backendTranslations.${name}_accept`
|
|
80
|
+
: 'pydanticForms.backendTranslations';
|
|
79
81
|
|
|
80
82
|
data = data ?? [
|
|
81
83
|
[name, 'label', {}],
|
|
@@ -111,8 +113,8 @@ function Accept({
|
|
|
111
113
|
state.skip
|
|
112
114
|
? 'SKIPPED'
|
|
113
115
|
: state.allChecked
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
? 'ACCEPTED'
|
|
117
|
+
: 'INCOMPLETE',
|
|
116
118
|
);
|
|
117
119
|
|
|
118
120
|
return { ...state };
|
|
@@ -128,6 +130,7 @@ function Accept({
|
|
|
128
130
|
>
|
|
129
131
|
{data.map((entry, index) => {
|
|
130
132
|
const label = t(`${i18nBaseKey}.${entry[0]}`, entry[2]);
|
|
133
|
+
|
|
131
134
|
switch (entry[1]) {
|
|
132
135
|
case 'label':
|
|
133
136
|
return (
|
|
@@ -170,7 +173,7 @@ function Accept({
|
|
|
170
173
|
key={index}
|
|
171
174
|
className="euiFormLabel euiFormRow__label warning"
|
|
172
175
|
>
|
|
173
|
-
{label}
|
|
176
|
+
{label}: <br />
|
|
174
177
|
</label>
|
|
175
178
|
);
|
|
176
179
|
case 'skip':
|
|
@@ -81,8 +81,8 @@ function ImsNodeId({
|
|
|
81
81
|
loading && locationCode
|
|
82
82
|
? t('widgets.node_select.nodes_loading')
|
|
83
83
|
: nodes.length
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
? t('widgets.node_select.select_node')
|
|
85
|
+
: t('forms.widgets.node_select.no_nodes_placeholder');
|
|
86
86
|
|
|
87
87
|
const imsNodeIdLabelLookup =
|
|
88
88
|
nodes?.reduce<{ [index: string]: string }>(function (mapping, node) {
|