@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.
Files changed (120) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/.turbo/turbo-lint.log +0 -6
  3. package/.turbo/turbo-test.log +10 -9
  4. package/CHANGELOG.md +6 -0
  5. package/dist/index.d.ts +1005 -123
  6. package/dist/index.js +33849 -6199
  7. package/package.json +14 -12
  8. package/src/api/index.ts +55 -0
  9. package/src/components/WfoDiff/WfoDiff.tsx +119 -0
  10. package/src/components/WfoDiff/index.ts +1 -0
  11. package/src/components/WfoDiff/unidiff.d.ts +1 -0
  12. package/src/components/WfoForms/AutoFieldLoader.tsx +5 -1
  13. package/src/components/WfoForms/CreateForm.tsx +1 -0
  14. package/src/components/WfoForms/UserInputForm.tsx +75 -44
  15. package/src/components/WfoForms/UserInputFormWizard.tsx +11 -4
  16. package/src/components/WfoForms/formFields/AcceptField.tsx +8 -5
  17. package/src/components/WfoForms/formFields/BoolField.tsx +1 -1
  18. package/src/components/WfoForms/formFields/ImsNodeIdField.tsx +2 -2
  19. package/src/components/WfoForms/formFields/ImsPortIdField.tsx +238 -0
  20. package/src/components/WfoForms/formFields/ImsPortIdFieldStyling.ts +17 -0
  21. package/src/components/WfoForms/formFields/ListAddField.tsx +1 -1
  22. package/src/components/WfoForms/formFields/ListDelField.tsx +1 -1
  23. package/src/components/WfoForms/formFields/OptGroupField.tsx +1 -1
  24. package/src/components/WfoForms/formFields/SubscriptionField.tsx +2 -1
  25. package/src/components/WfoForms/formFields/SummaryField.tsx +103 -0
  26. package/src/components/WfoForms/formFields/SummaryFieldStyling.ts +46 -0
  27. package/src/components/WfoForms/formFields/VlanField.tsx +10 -10
  28. package/src/components/WfoForms/formFields/index.ts +2 -0
  29. package/src/components/WfoForms/formFields/surf/types.ts +26 -0
  30. package/src/components/WfoForms/formFields/utils.spec.ts +1 -0
  31. package/src/components/WfoJsonCodeBlock/index.ts +1 -0
  32. package/src/components/WfoPageTemplate/WfoPageHeader/WfoPageHeader.tsx +4 -3
  33. package/src/components/WfoPageTemplate/WfoSidebar/WfoSidebar.tsx +14 -14
  34. package/src/components/WfoPageTemplate/WfoSidebar/WfoStartCreateWorkflowButtonComboBox.tsx +15 -9
  35. package/src/components/WfoPageTemplate/paths.ts +3 -2
  36. package/src/components/{WfoProcessesList → WfoProcessList}/WfoProcessList.tsx +18 -14
  37. package/src/components/WfoProcessList/index.ts +1 -0
  38. package/src/components/{WfoProcessesList → WfoProcessList}/processListObjectMappers.ts +4 -2
  39. package/src/components/WfoSearchBar/WfoSearchField.tsx +27 -37
  40. package/src/components/{WfoSettingsPage → WfoSettings}/WfoEngineStatusButton.tsx +7 -4
  41. package/src/components/{WfoSettingsPage → WfoSettings}/WfoFlushSettings.tsx +13 -12
  42. package/src/components/WfoSettings/WfoModifySettings.tsx +38 -0
  43. package/src/components/WfoSettings/WfoSettings.tsx +40 -0
  44. package/src/components/{WfoSettingsPage → WfoSettings}/WfoStatus.tsx +21 -14
  45. package/src/components/WfoStartPage/WfoListStartPage.tsx +3 -3
  46. package/src/components/WfoStartTaskButtonComboBox/WfoStartTaskButtonComboBox.tsx +14 -8
  47. package/src/components/WfoSubscription/WfoProcessesTimeline.tsx +11 -18
  48. package/src/components/WfoSubscription/WfoSubscription.tsx +1 -1
  49. package/src/components/WfoSubscription/WfoSubscriptionActions.tsx +41 -33
  50. package/src/components/WfoSubscription/WfoSubscriptionDetailTree.tsx +32 -22
  51. package/src/components/WfoSubscription/WfoSubscriptionProductBlock.tsx +94 -90
  52. package/src/components/WfoSubscription/WfoTargetTypeIcon.tsx +26 -0
  53. package/src/components/WfoSubscription/utils/utils.spec.ts +24 -0
  54. package/src/components/WfoSubscription/utils/utils.ts +16 -0
  55. package/src/components/WfoSubscriptionsList/WfoSubscriptionsList.tsx +17 -37
  56. package/src/components/WfoTable/WfoTableWithFilter/WfoTableWithFilter.tsx +20 -19
  57. package/src/components/WfoTable/WfoTableWithFilter/updateQueryString.spec.ts +95 -0
  58. package/src/components/WfoTable/WfoTableWithFilter/updateQueryString.ts +60 -0
  59. package/src/components/WfoTable/utils/tableUtils.ts +3 -3
  60. package/src/components/WfoTextAnchor/WfoTextAnchor.stories.tsx +18 -0
  61. package/src/components/WfoTextAnchor/WfoTextAnchor.tsx +22 -0
  62. package/src/components/WfoTextAnchor/index.ts +1 -0
  63. package/src/components/WfoTextAnchor/styles.ts +17 -0
  64. package/src/components/WfoTimeline/styles.ts +10 -4
  65. package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +39 -24
  66. package/src/components/WfoWorkflowSteps/WfoStep/WfoStepForm.tsx +48 -0
  67. package/src/components/WfoWorkflowSteps/WfoStepList/WfoStepList.tsx +10 -10
  68. package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoStepListHeader.tsx +22 -23
  69. package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoWorkflowStepList.tsx +97 -17
  70. package/src/components/WfoWorkflowSteps/stepListUtils.ts +1 -28
  71. package/src/components/confirmationDialog/WfoConfirmationDialog.tsx +3 -3
  72. package/src/components/index.ts +6 -1
  73. package/src/contexts/ConfirmationDialogProvider.tsx +2 -2
  74. package/src/contexts/TreeContext.tsx +5 -0
  75. package/src/graphqlQueries/index.ts +1 -0
  76. package/src/graphqlQueries/processDetailQuery.ts +8 -0
  77. package/src/graphqlQueries/processListQuery.ts +7 -6
  78. package/src/graphqlQueries/processStepsQuery.ts +22 -0
  79. package/src/graphqlQueries/productBlocksQuery.ts +9 -5
  80. package/src/graphqlQueries/productsQuery.ts +7 -3
  81. package/src/graphqlQueries/relatedSubscriptionsQuery.ts +2 -2
  82. package/src/graphqlQueries/resourceTypesQuery.ts +8 -4
  83. package/src/graphqlQueries/subscriptionDetailQuery.ts +1 -0
  84. package/src/graphqlQueries/subscriptionsListQuery.ts +5 -3
  85. package/src/graphqlQueries/workflows/workflowsQuery.ts +8 -4
  86. package/src/graphqlQueries/workflows/workflowsQueryForDropdownList.ts +2 -2
  87. package/src/hooks/DataFetchHooks.ts +9 -4
  88. package/src/hooks/index.ts +3 -0
  89. package/src/hooks/useCheckEngineStatus.ts +30 -0
  90. package/src/hooks/useDataDisplayParams.ts +3 -3
  91. package/src/hooks/useEngineStatusQuery.ts +9 -7
  92. package/src/hooks/useMutateProcess.ts +96 -0
  93. package/src/messages/{en-US.json → en-GB.json} +85 -37
  94. package/src/messages/getTranslationMessages.spec.ts +25 -40
  95. package/src/messages/index.ts +1 -1
  96. package/src/messages/nl-NL.json +95 -48
  97. package/src/messages/useGetTranslationMessages.ts +51 -0
  98. package/src/pages/metadata/WfoProductBlocksPage.tsx +12 -10
  99. package/src/pages/metadata/WfoProductsPage.tsx +24 -25
  100. package/src/pages/metadata/WfoResourceTypesPage.tsx +12 -10
  101. package/src/pages/metadata/WfoWorkflowsPage.tsx +12 -10
  102. package/src/pages/processes/WfoProcessDetail.tsx +96 -79
  103. package/src/pages/processes/WfoProcessDetailPage.tsx +5 -3
  104. package/src/pages/{workflow/WfoStartWorkflowPage.tsx → processes/WfoStartProcessPage.tsx} +100 -50
  105. package/src/pages/processes/index.ts +1 -3
  106. package/src/pages/settings/WfoSettingsPage.tsx +30 -0
  107. package/src/pages/settings/index.ts +1 -0
  108. package/src/pages/tasks/WfoTaskListPage.tsx +35 -9
  109. package/src/pages/{processes/WfoProcessListPage.tsx → workflow/WfoWorkflowListPage.tsx} +22 -23
  110. package/src/pages/workflow/getWorkflowListTabTypeFromString.ts +19 -0
  111. package/src/pages/workflow/index.ts +1 -1
  112. package/src/pages/{processes → workflow}/tabConfig.ts +6 -6
  113. package/src/types/types.ts +33 -3
  114. package/src/utils/getDefaultTableConfig.ts +1 -1
  115. package/src/components/WfoSettingsPage/WfoModifySettings.tsx +0 -33
  116. package/src/components/WfoSettingsPage/WfoSettings.tsx +0 -40
  117. package/src/hooks/ProcessesHooks/useDeleteProcess.ts +0 -37
  118. package/src/messages/getTranslationMessages.ts +0 -26
  119. package/src/pages/processes/getProcessListTabTypeFromString.ts +0 -19
  120. /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.2.7",
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": "^0.24.0",
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": "^2.1.1",
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": "^18.2.0",
39
- "react-query": "3.39.3"
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.8",
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": "^5.16.1",
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": "^2.1.0",
60
+ "@types/object-hash": "^3.0.6",
59
61
  "@types/scroll-into-view": "^1.16.3",
60
- "esbuild": "^0.14.10",
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": "^7.2.0",
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 NumField;
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':
@@ -63,6 +63,7 @@ export function CreateForm(props: IProps) {
63
63
  validSubmit={submit}
64
64
  cancel={() => alert('cancelled')}
65
65
  hasNext={hasNext ?? false}
66
+ isTask={false}
66
67
  />
67
68
  )}
68
69
  </div>
@@ -34,11 +34,11 @@ import {
34
34
  EuiHorizontalRule,
35
35
  } from '@elastic/eui';
36
36
 
37
- import ConfirmationDialogContext from '../../contexts/ConfirmationDialogProvider';
38
- import { ConfirmDialogActions } from '../../contexts/ConfirmationDialogProvider';
39
- import { useOrchestratorTheme } from '../../hooks';
40
- import { WfoPlayFill } from '../../icons';
41
- import { ValidationError } from '../../types/forms';
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: ConfirmDialogActions['closeConfirmDialog'];
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
- // not translated labels for now
250
- // const translation_key = name.replace(/\.\d+(.\d+)*/, "_fields");
251
- // const translation_intl_key = `forms.fields.${translation_key}`;
252
- // const translation = intl.formatMessage({ id: translation_intl_key, defaultMessage: translation_intl_key });
253
- // let label = translation !== translation_intl_key ? translation : props.label;
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
- // not translated labels for now
268
- // props.description = intl.formatMessage({ id: `forms.fields.${translation_key}_info`, defaultMessage: " " }); // Default must contain a space as not to be Falsy
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 openDialog = () => {
386
- showConfirmDialog({
387
- question: '',
388
- confirmAction: () => {},
389
- cancelAction: cancel,
390
- leavePage: true,
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(e, buttons.previous.dialog, previous);
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(e, buttons.previous.dialog, openDialog);
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('cancelProcess')}
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('runProcess')}
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(prefilledForm, () => {});
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
- 'input_fields_have_validation_errors',
576
- {
577
- nrOfValidationErrors:
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 '../../contexts/ConfirmationDialogProvider';
21
- import { FormNotCompleteResponse, InputForm } from '../../types/forms';
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: () => void;
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('pydanticForms.widgets');
74
+ const t = useTranslations();
75
75
  const { acceptFieldStyle } = useWithOrchestratorTheme(getStyles);
76
76
 
77
77
  const legacy = !data;
78
- const i18nBaseKey = data ? `forms.fields.${name}_accept` : 'forms.fields';
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
- ? 'ACCEPTED'
115
- : 'INCOMPLETE',
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':
@@ -57,7 +57,7 @@ function Bool({
57
57
  disabled={disabled}
58
58
  id={id}
59
59
  name={name}
60
- label={name}
60
+ label={label}
61
61
  onChange={() =>
62
62
  !disabled && !readOnly && onChange(!value)
63
63
  }
@@ -81,8 +81,8 @@ function ImsNodeId({
81
81
  loading && locationCode
82
82
  ? t('widgets.node_select.nodes_loading')
83
83
  : nodes.length
84
- ? t('widgets.node_select.select_node')
85
- : t('forms.widgets.node_select.no_nodes_placeholder');
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) {