@orchestrator-ui/orchestrator-ui-components 6.1.1 → 6.2.1
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 +8 -8
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +6 -6
- package/CHANGELOG.md +16 -0
- package/dist/index.d.ts +44 -8
- package/dist/index.js +2196 -1889
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
- package/src/components/WfoMonacoCodeBlock/WfoMonacoCodeBlock.tsx +92 -0
- package/src/components/WfoMonacoCodeBlock/index.ts +1 -0
- package/src/components/WfoMonacoCodeBlock/styles.ts +16 -0
- package/src/components/WfoSubscription/WfoInSyncField/WfoInSyncErrorToastMessage.tsx +25 -0
- package/src/components/WfoSubscription/{WfoInSyncField.tsx → WfoInSyncField/WfoInSyncField.tsx} +12 -4
- package/src/components/WfoSubscription/index.ts +1 -1
- package/src/components/WfoSubscription/utils/utils.spec.ts +50 -0
- package/src/components/WfoSubscription/utils/utils.ts +22 -0
- package/src/components/WfoWorkflowSteps/WfoStep/WfoCodeViewSelector.tsx +116 -0
- package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +24 -27
- package/src/components/index.ts +1 -0
- package/src/configuration/version.ts +1 -1
- package/src/hooks/useShowToastMessage.ts +3 -1
- package/src/icons/heroicons/WfoBracketSquare.tsx +29 -0
- package/src/icons/heroicons/WfoCommandLine.tsx +29 -0
- package/src/icons/heroicons/WfoTableCells.tsx +29 -0
- package/src/icons/heroicons/index.ts +3 -0
- package/src/messages/en-GB.json +5 -2
- package/src/messages/nl-NL.json +5 -2
- package/src/pages/processes/WfoProcessDetail.tsx +20 -2
- package/src/rtk/slices/toastMessages.ts +1 -1
- package/src/types/types.ts +4 -5
- package/src/utils/getToastMessage.ts +6 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchestrator-ui/orchestrator-ui-components",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Library of UI Components used to display the workflow orchestrator frontend",
|
|
6
6
|
"author": {
|
|
@@ -34,13 +34,14 @@
|
|
|
34
34
|
"dev": "npm run build -- --watch"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@ag-ui/client": "
|
|
37
|
+
"@ag-ui/client": "0.0.39",
|
|
38
38
|
"@copilotkit/react-core": "^1.3.18",
|
|
39
39
|
"@copilotkit/react-ui": "^1.3.18",
|
|
40
40
|
"@copilotkit/runtime": "^1.3.18",
|
|
41
41
|
"@elastic/eui": "101.3.0",
|
|
42
42
|
"@emotion/css": "^11.11.2",
|
|
43
43
|
"@emotion/react": "^11.11.4",
|
|
44
|
+
"@monaco-editor/react": "^4.7.0",
|
|
44
45
|
"@rtk-query/graphql-request-base-query": "^2.3.1",
|
|
45
46
|
"graphql-request": "^6.1.0",
|
|
46
47
|
"invariant": "^2.2.4",
|
|
@@ -91,5 +92,8 @@
|
|
|
91
92
|
"type": "module",
|
|
92
93
|
"main": "./dist/index.js",
|
|
93
94
|
"browser": "./dist/index.js",
|
|
94
|
-
"types": "./dist/index.d.ts"
|
|
95
|
+
"types": "./dist/index.d.ts",
|
|
96
|
+
"overrides": {
|
|
97
|
+
"@monaco-editor/loader": "1.5.0"
|
|
98
|
+
}
|
|
95
99
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import React, { FC, useCallback, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { editor } from 'monaco-editor';
|
|
4
|
+
|
|
5
|
+
import { EuiFlexItem } from '@elastic/eui';
|
|
6
|
+
import Editor from '@monaco-editor/react';
|
|
7
|
+
import type { Monaco } from '@monaco-editor/react';
|
|
8
|
+
|
|
9
|
+
import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
|
|
10
|
+
|
|
11
|
+
import { getStyles } from './styles';
|
|
12
|
+
|
|
13
|
+
export type WfoMonacoCodeBlockProps = {
|
|
14
|
+
data: object;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const MONACO_THEME: { light: editor.BuiltinTheme; dark: editor.BuiltinTheme } =
|
|
18
|
+
{
|
|
19
|
+
light: 'vs',
|
|
20
|
+
dark: 'hc-black',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* WfoMonacoCodeBlock is used to render objects in JSON format using the Monaco Editor
|
|
25
|
+
* @param data
|
|
26
|
+
* @constructor
|
|
27
|
+
*/
|
|
28
|
+
export const WfoMonacoCodeBlock: FC<WfoMonacoCodeBlockProps> = ({ data }) => {
|
|
29
|
+
const { theme, isDarkThemeActive } = useOrchestratorTheme();
|
|
30
|
+
const { monacoEditorStyle } = useWithOrchestratorTheme(getStyles);
|
|
31
|
+
const [monacoInstance, setMonacoInstance] = useState<Monaco | undefined>(
|
|
32
|
+
undefined,
|
|
33
|
+
);
|
|
34
|
+
const json = JSON.stringify(data, null, 4);
|
|
35
|
+
|
|
36
|
+
const [editorHeight, setEditorHeight] = useState(0);
|
|
37
|
+
|
|
38
|
+
const addThemeToEditor = useCallback(
|
|
39
|
+
(monaco: Monaco) => {
|
|
40
|
+
monaco.editor.defineTheme('wfoTheme', {
|
|
41
|
+
base: isDarkThemeActive
|
|
42
|
+
? MONACO_THEME.dark
|
|
43
|
+
: MONACO_THEME.light,
|
|
44
|
+
inherit: true,
|
|
45
|
+
rules: [],
|
|
46
|
+
colors: {
|
|
47
|
+
'editor.background': theme.colors.body,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
monaco.editor.setTheme('wfoTheme');
|
|
51
|
+
},
|
|
52
|
+
[theme, isDarkThemeActive],
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (monacoInstance) {
|
|
57
|
+
addThemeToEditor(monacoInstance);
|
|
58
|
+
}
|
|
59
|
+
}, [addThemeToEditor, isDarkThemeActive, monacoInstance]);
|
|
60
|
+
|
|
61
|
+
function editorDidMount(
|
|
62
|
+
editor: editor.IStandaloneCodeEditor,
|
|
63
|
+
monaco: Monaco,
|
|
64
|
+
) {
|
|
65
|
+
const scrollHeight = editor.getScrollHeight();
|
|
66
|
+
setEditorHeight(Math.min(scrollHeight, 500));
|
|
67
|
+
setMonacoInstance(monaco);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<EuiFlexItem css={monacoEditorStyle}>
|
|
72
|
+
<Editor
|
|
73
|
+
height={editorHeight}
|
|
74
|
+
options={{
|
|
75
|
+
readOnly: true,
|
|
76
|
+
lineNumbers: 'on',
|
|
77
|
+
scrollBeyondLastLine: false,
|
|
78
|
+
contextmenu: false,
|
|
79
|
+
minimap: { enabled: false },
|
|
80
|
+
mouseWheelZoom: true,
|
|
81
|
+
renderLineHighlight: 'none',
|
|
82
|
+
fontFamily: theme.font.family,
|
|
83
|
+
tabSize: 8,
|
|
84
|
+
}}
|
|
85
|
+
beforeMount={addThemeToEditor}
|
|
86
|
+
onMount={editorDidMount}
|
|
87
|
+
language="json"
|
|
88
|
+
value={json}
|
|
89
|
+
/>
|
|
90
|
+
</EuiFlexItem>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './WfoMonacoCodeBlock';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { css } from '@emotion/react';
|
|
2
|
+
|
|
3
|
+
import { WfoTheme } from '@/hooks';
|
|
4
|
+
|
|
5
|
+
export const getStyles = ({ theme }: WfoTheme) => {
|
|
6
|
+
const monacoEditorStyle = css({
|
|
7
|
+
marginTop: 10,
|
|
8
|
+
padding: 10,
|
|
9
|
+
backgroundColor: theme.colors.body,
|
|
10
|
+
borderRadius: theme.border.radius.medium,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
monacoEditorStyle,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
|
|
5
|
+
import { PATH_WORKFLOWS, parseErrorDetail } from '@/components';
|
|
6
|
+
|
|
7
|
+
export const WfoInSyncErrorToastMessage: FC<{ errorDetail: string }> = ({
|
|
8
|
+
errorDetail,
|
|
9
|
+
}) => {
|
|
10
|
+
const { failedIds, filteredInput } = parseErrorDetail(errorDetail);
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div css={{ whiteSpace: 'normal', wordBreak: 'break-word' }}>
|
|
14
|
+
<div>{filteredInput}</div>
|
|
15
|
+
{failedIds.map((processId) => {
|
|
16
|
+
const processUrl = `${PATH_WORKFLOWS}/${processId}`;
|
|
17
|
+
return (
|
|
18
|
+
<div key={processId}>
|
|
19
|
+
<Link href={processUrl}>{processId}</Link>
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
})}
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
package/src/components/WfoSubscription/{WfoInSyncField.tsx → WfoInSyncField/WfoInSyncField.tsx}
RENAMED
|
@@ -8,6 +8,7 @@ import { EuiButton } from '@elastic/eui';
|
|
|
8
8
|
import { WfoIsAllowedToRender } from '@/components';
|
|
9
9
|
import { WfoInsyncIcon } from '@/components';
|
|
10
10
|
import { PATH_TASKS, PATH_WORKFLOWS } from '@/components';
|
|
11
|
+
import { WfoInSyncErrorToastMessage } from '@/components/WfoSubscription/WfoInSyncField/WfoInSyncErrorToastMessage';
|
|
11
12
|
import { PolicyResource } from '@/configuration/policy-resources';
|
|
12
13
|
import { ConfirmationDialogContext } from '@/contexts';
|
|
13
14
|
import { useOrchestratorTheme, useShowToastMessage } from '@/hooks';
|
|
@@ -15,7 +16,7 @@ import { useSetSubscriptionInSyncMutation } from '@/rtk/endpoints';
|
|
|
15
16
|
import { SubscriptionDetail, ToastTypes } from '@/types';
|
|
16
17
|
import { formatDate } from '@/utils';
|
|
17
18
|
|
|
18
|
-
import { getLastUncompletedProcess, getLatestTaskDate } from '
|
|
19
|
+
import { getLastUncompletedProcess, getLatestTaskDate } from '../utils';
|
|
19
20
|
|
|
20
21
|
interface WfoInSyncFieldProps {
|
|
21
22
|
subscriptionDetail: SubscriptionDetail;
|
|
@@ -31,6 +32,7 @@ export const WfoInSyncField = ({ subscriptionDetail }: WfoInSyncFieldProps) => {
|
|
|
31
32
|
const lastUncompletedProcess = getLastUncompletedProcess(
|
|
32
33
|
subscriptionDetail?.processes?.page,
|
|
33
34
|
);
|
|
35
|
+
|
|
34
36
|
const [setSubscriptionInSync, { isLoading }] =
|
|
35
37
|
useSetSubscriptionInSyncMutation();
|
|
36
38
|
const { showToastMessage } = useShowToastMessage();
|
|
@@ -52,11 +54,17 @@ export const WfoInSyncField = ({ subscriptionDetail }: WfoInSyncFieldProps) => {
|
|
|
52
54
|
);
|
|
53
55
|
})
|
|
54
56
|
.catch((error) => {
|
|
57
|
+
const errorToastMessage = error?.data?.detail ? (
|
|
58
|
+
<WfoInSyncErrorToastMessage
|
|
59
|
+
errorDetail={error.data?.detail}
|
|
60
|
+
/>
|
|
61
|
+
) : (
|
|
62
|
+
t('setInSyncFailed.text').toString()
|
|
63
|
+
);
|
|
64
|
+
|
|
55
65
|
showToastMessage(
|
|
56
66
|
ToastTypes.ERROR,
|
|
57
|
-
|
|
58
|
-
? error.data.detail
|
|
59
|
-
: t('setInSyncFailed.text').toString,
|
|
67
|
+
errorToastMessage,
|
|
60
68
|
t('setInSyncFailed.title'),
|
|
61
69
|
);
|
|
62
70
|
console.error('Failed to set subscription in sync.', error);
|
|
@@ -5,7 +5,7 @@ export * from './overrides';
|
|
|
5
5
|
export * from './WfoSubscriptionGeneralSections';
|
|
6
6
|
|
|
7
7
|
export * from './SubscriptionKeyValueBlock';
|
|
8
|
-
export * from './WfoInSyncField';
|
|
8
|
+
export * from './WfoInSyncField/WfoInSyncField';
|
|
9
9
|
export * from './WfoProcessesTimeline';
|
|
10
10
|
export * from './WfoRelatedSubscriptions';
|
|
11
11
|
export * from './WfoSubscription';
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
getWorkflowTargetColor,
|
|
18
18
|
getWorkflowTargetIconContent,
|
|
19
19
|
mapProductBlockInstancesToEuiSelectableOptions,
|
|
20
|
+
parseErrorDetail,
|
|
20
21
|
} from './utils';
|
|
21
22
|
|
|
22
23
|
describe('getFieldFromProductBlockInstanceValues()', () => {
|
|
@@ -468,3 +469,52 @@ describe('mapProductBlockInstancesToEuiSelectableOptions', () => {
|
|
|
468
469
|
]);
|
|
469
470
|
});
|
|
470
471
|
});
|
|
472
|
+
|
|
473
|
+
describe('parseErrorDetail', () => {
|
|
474
|
+
it('parses a single UUID inside brackets', () => {
|
|
475
|
+
const input =
|
|
476
|
+
"Subscription 123 has still failed processes with id's: ['11111111-1111-1111-1111-111111111111']";
|
|
477
|
+
|
|
478
|
+
const { failedIds, filteredInput } = parseErrorDetail(input);
|
|
479
|
+
|
|
480
|
+
expect(failedIds).toEqual(['11111111-1111-1111-1111-111111111111']);
|
|
481
|
+
expect(filteredInput).toBe(
|
|
482
|
+
"Subscription 123 has still failed processes with id's:",
|
|
483
|
+
);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('parses multiple UUIDs inside brackets', () => {
|
|
487
|
+
const input =
|
|
488
|
+
"Failed processes: ['11111111-1111-1111-1111-111111111111', '22222222-2222-2222-2222-222222222222']";
|
|
489
|
+
|
|
490
|
+
const { failedIds, filteredInput } = parseErrorDetail(input);
|
|
491
|
+
|
|
492
|
+
expect(failedIds).toEqual([
|
|
493
|
+
'11111111-1111-1111-1111-111111111111',
|
|
494
|
+
'22222222-2222-2222-2222-222222222222',
|
|
495
|
+
]);
|
|
496
|
+
expect(filteredInput).toBe('Failed processes:');
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it('returns empty array when no brackets present', () => {
|
|
500
|
+
const input = 'No failed processes.';
|
|
501
|
+
|
|
502
|
+
const { failedIds, filteredInput } = parseErrorDetail(input);
|
|
503
|
+
|
|
504
|
+
expect(failedIds).toEqual([]);
|
|
505
|
+
expect(filteredInput).toBe('No failed processes.');
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('ignores extra spaces or commas inside brackets', () => {
|
|
509
|
+
const input =
|
|
510
|
+
"Errors: [ '11111111-1111-1111-1111-111111111111' , '22222222-2222-2222-2222-222222222222' ]";
|
|
511
|
+
|
|
512
|
+
const { failedIds, filteredInput } = parseErrorDetail(input);
|
|
513
|
+
|
|
514
|
+
expect(failedIds).toEqual([
|
|
515
|
+
'11111111-1111-1111-1111-111111111111',
|
|
516
|
+
'22222222-2222-2222-2222-222222222222',
|
|
517
|
+
]);
|
|
518
|
+
expect(filteredInput).toBe('Errors:');
|
|
519
|
+
});
|
|
520
|
+
});
|
|
@@ -122,6 +122,28 @@ export const getLastUncompletedProcess = (
|
|
|
122
122
|
: undefined;
|
|
123
123
|
};
|
|
124
124
|
|
|
125
|
+
const uuidRegex =
|
|
126
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
127
|
+
|
|
128
|
+
const extractUUIDsFromBrackets = (input: string) => {
|
|
129
|
+
const start = input.indexOf('[');
|
|
130
|
+
const end = input.indexOf(']', start);
|
|
131
|
+
if (start === -1 || end === -1) return [];
|
|
132
|
+
const content = input.slice(start + 1, end).trim();
|
|
133
|
+
if (!content) return [];
|
|
134
|
+
|
|
135
|
+
return content
|
|
136
|
+
.split(',')
|
|
137
|
+
.map((s) => s.trim().replace(/^['"]|['"]$/g, '')) // remove surrounding ' or "
|
|
138
|
+
.filter((s) => uuidRegex.test(s));
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export function parseErrorDetail(errorDetail: string) {
|
|
142
|
+
const failedIds = extractUUIDsFromBrackets(errorDetail);
|
|
143
|
+
const filteredInput = errorDetail.split('[')[0].trim();
|
|
144
|
+
return { failedIds, filteredInput };
|
|
145
|
+
}
|
|
146
|
+
|
|
125
147
|
export const getLatestTaskDate = (processes?: SubscriptionDetailProcess[]) => {
|
|
126
148
|
if (!processes || processes.length === 0) {
|
|
127
149
|
return '';
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
4
|
+
|
|
5
|
+
import { EuiButtonGroup } from '@elastic/eui';
|
|
6
|
+
|
|
7
|
+
import { useOrchestratorTheme } from '@/hooks';
|
|
8
|
+
import { WfoBracketSquare, WfoCommandLine, WfoTableCells } from '@/icons';
|
|
9
|
+
|
|
10
|
+
export enum CodeView {
|
|
11
|
+
JSON = 'json',
|
|
12
|
+
TABLE = 'table',
|
|
13
|
+
RAW = 'raw',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface WfoCodeViewSelectorProps {
|
|
17
|
+
codeView: CodeView;
|
|
18
|
+
handleCodeViewChange: (codeView: CodeView) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const WfoCodeViewSelector = ({
|
|
22
|
+
codeView,
|
|
23
|
+
handleCodeViewChange,
|
|
24
|
+
}: WfoCodeViewSelectorProps) => {
|
|
25
|
+
const t = useTranslations('processes.steps');
|
|
26
|
+
const { theme, toSecondaryColor } = useOrchestratorTheme();
|
|
27
|
+
|
|
28
|
+
const isSelected = (buttonView: CodeView): boolean =>
|
|
29
|
+
buttonView === codeView;
|
|
30
|
+
|
|
31
|
+
const codeViewOptions = [
|
|
32
|
+
{
|
|
33
|
+
id: CodeView.JSON,
|
|
34
|
+
label: t('codeView.json'),
|
|
35
|
+
iconType: () => (
|
|
36
|
+
<WfoBracketSquare
|
|
37
|
+
color={
|
|
38
|
+
isSelected(CodeView.JSON)
|
|
39
|
+
? theme.colors.ghost
|
|
40
|
+
: theme.colors.textPrimary
|
|
41
|
+
}
|
|
42
|
+
/>
|
|
43
|
+
),
|
|
44
|
+
'data-test-id': 'jsonCodeViewButton',
|
|
45
|
+
toolTipContent: t('codeView.json'),
|
|
46
|
+
style: {
|
|
47
|
+
backgroundColor: isSelected(CodeView.JSON)
|
|
48
|
+
? theme.colors.textPrimary
|
|
49
|
+
: toSecondaryColor(theme.colors.primary),
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: CodeView.TABLE,
|
|
54
|
+
label: t('codeView.table'),
|
|
55
|
+
iconType: () => (
|
|
56
|
+
<WfoTableCells
|
|
57
|
+
color={
|
|
58
|
+
isSelected(CodeView.TABLE)
|
|
59
|
+
? theme.colors.ghost
|
|
60
|
+
: theme.colors.textPrimary
|
|
61
|
+
}
|
|
62
|
+
/>
|
|
63
|
+
),
|
|
64
|
+
'data-test-id': 'tableCodeViewButton',
|
|
65
|
+
toolTipContent: t('codeView.table'),
|
|
66
|
+
style: {
|
|
67
|
+
backgroundColor: isSelected(CodeView.TABLE)
|
|
68
|
+
? theme.colors.textPrimary
|
|
69
|
+
: toSecondaryColor(theme.colors.primary),
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: CodeView.RAW,
|
|
74
|
+
label: t('codeView.raw'),
|
|
75
|
+
iconType: () => (
|
|
76
|
+
<WfoCommandLine
|
|
77
|
+
color={
|
|
78
|
+
isSelected(CodeView.RAW)
|
|
79
|
+
? theme.colors.ghost
|
|
80
|
+
: theme.colors.textPrimary
|
|
81
|
+
}
|
|
82
|
+
/>
|
|
83
|
+
),
|
|
84
|
+
'data-test-id': 'rawCodeViewButton',
|
|
85
|
+
toolTipContent: t('codeView.raw'),
|
|
86
|
+
style: {
|
|
87
|
+
backgroundColor: isSelected(CodeView.RAW)
|
|
88
|
+
? theme.colors.textPrimary
|
|
89
|
+
: toSecondaryColor(theme.colors.primary),
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const handle = useCallback(
|
|
95
|
+
(id: string) => handleCodeViewChange(id as CodeView),
|
|
96
|
+
[handleCodeViewChange],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<EuiButtonGroup
|
|
101
|
+
style={{
|
|
102
|
+
gap: 0,
|
|
103
|
+
borderRadius: theme.border.radius.medium,
|
|
104
|
+
}}
|
|
105
|
+
legend=""
|
|
106
|
+
options={codeViewOptions}
|
|
107
|
+
idSelected={codeView}
|
|
108
|
+
isIconOnly={true}
|
|
109
|
+
onChange={handle}
|
|
110
|
+
onClick={(e) => {
|
|
111
|
+
e.stopPropagation();
|
|
112
|
+
}}
|
|
113
|
+
type="single"
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import React, { LegacyRef, useState } from 'react';
|
|
1
|
+
import React, { LegacyRef, useCallback, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { useTranslations } from 'next-intl';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
EuiButton,
|
|
7
|
-
EuiFlexGroup,
|
|
8
|
-
EuiFlexItem,
|
|
9
|
-
EuiPanel,
|
|
10
|
-
EuiText,
|
|
11
|
-
} from '@elastic/eui';
|
|
5
|
+
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui';
|
|
12
6
|
|
|
13
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
WfoJsonCodeBlock,
|
|
9
|
+
WfoMonacoCodeBlock,
|
|
10
|
+
WfoTableCodeBlock,
|
|
11
|
+
} from '@/components';
|
|
14
12
|
import { WfoStepFormOld } from '@/components/WfoWorkflowSteps/WfoStep/WfoStepFormOld';
|
|
15
13
|
import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
|
|
16
14
|
import { WfoChevronDown, WfoChevronUp } from '@/icons';
|
|
@@ -23,6 +21,7 @@ import { WfoStepStatusIcon } from '../WfoStepStatusIcon';
|
|
|
23
21
|
import type { StepListItem } from '../WfoWorkflowStepList';
|
|
24
22
|
import { getStepContent } from '../stepListUtils';
|
|
25
23
|
import { getWorkflowStepsStyles } from '../styles';
|
|
24
|
+
import { CodeView, WfoCodeViewSelector } from './WfoCodeViewSelector';
|
|
26
25
|
import { WfoStepForm } from './WfoStepForm';
|
|
27
26
|
|
|
28
27
|
export interface WfoStepProps {
|
|
@@ -53,7 +52,7 @@ export const WfoStep = React.forwardRef(
|
|
|
53
52
|
ref: LegacyRef<HTMLDivElement>,
|
|
54
53
|
) => {
|
|
55
54
|
const { isExpanded, step, userInputForm } = stepListItem;
|
|
56
|
-
const [
|
|
55
|
+
const [codeView, setCodeView] = useState<CodeView>(CodeView.JSON);
|
|
57
56
|
|
|
58
57
|
const { theme } = useOrchestratorTheme();
|
|
59
58
|
const {
|
|
@@ -123,6 +122,13 @@ export const WfoStep = React.forwardRef(
|
|
|
123
122
|
Object.keys(userInputForm?.properties ?? {})[0],
|
|
124
123
|
);
|
|
125
124
|
|
|
125
|
+
const handle = useCallback(
|
|
126
|
+
(newCodeView: string) => {
|
|
127
|
+
setCodeView(newCodeView as CodeView);
|
|
128
|
+
},
|
|
129
|
+
[setCodeView],
|
|
130
|
+
);
|
|
131
|
+
|
|
126
132
|
return (
|
|
127
133
|
<div ref={ref}>
|
|
128
134
|
<EuiPanel>
|
|
@@ -150,21 +156,10 @@ export const WfoStep = React.forwardRef(
|
|
|
150
156
|
{step.completed && (
|
|
151
157
|
<>
|
|
152
158
|
{isExpanded && (
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
setTableView(!tableView);
|
|
158
|
-
event.stopPropagation();
|
|
159
|
-
}}
|
|
160
|
-
size="s"
|
|
161
|
-
>
|
|
162
|
-
{t(
|
|
163
|
-
tableView
|
|
164
|
-
? 'jsonView'
|
|
165
|
-
: 'tableView',
|
|
166
|
-
)}
|
|
167
|
-
</EuiButton>
|
|
159
|
+
<WfoCodeViewSelector
|
|
160
|
+
codeView={codeView}
|
|
161
|
+
handleCodeViewChange={handle}
|
|
162
|
+
/>
|
|
168
163
|
)}
|
|
169
164
|
<EuiFlexItem
|
|
170
165
|
grow={0}
|
|
@@ -203,10 +198,12 @@ export const WfoStep = React.forwardRef(
|
|
|
203
198
|
{hasStepContent &&
|
|
204
199
|
!hasHtmlMail &&
|
|
205
200
|
isExpanded &&
|
|
206
|
-
(
|
|
201
|
+
(codeView === CodeView.TABLE ? (
|
|
207
202
|
<WfoTableCodeBlock stepState={stepContent} />
|
|
208
|
-
) : (
|
|
203
|
+
) : codeView === CodeView.RAW ? (
|
|
209
204
|
<WfoJsonCodeBlock data={stepContent} />
|
|
205
|
+
) : (
|
|
206
|
+
<WfoMonacoCodeBlock data={stepContent} />
|
|
210
207
|
))}
|
|
211
208
|
{isExpanded && hasHtmlMail && (
|
|
212
209
|
<div css={stepEmailContainerStyle}>
|
package/src/components/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '6.
|
|
1
|
+
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '6.2.1';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
1
3
|
import { useAppDispatch } from '@/rtk/hooks';
|
|
2
4
|
import { addToastMessage } from '@/rtk/slices/toastMessages';
|
|
3
5
|
import { ToastTypes } from '@/types';
|
|
@@ -8,7 +10,7 @@ export const useShowToastMessage = () => {
|
|
|
8
10
|
|
|
9
11
|
const showToastMessage = (
|
|
10
12
|
type: ToastTypes,
|
|
11
|
-
text:
|
|
13
|
+
text: ReactNode,
|
|
12
14
|
title: string, // same as above for string instead of Toast['title'],
|
|
13
15
|
) => {
|
|
14
16
|
const toastMessage = getToastMessage(type, text, title);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
import { WfoIconProps } from '@/icons/WfoIconProps';
|
|
4
|
+
|
|
5
|
+
import { withWfoHeroIconsWrapper } from './WfoHeroIconsWrapper';
|
|
6
|
+
|
|
7
|
+
export const WfoBracketSquareSvg: FC<WfoIconProps> = ({
|
|
8
|
+
width = 24,
|
|
9
|
+
height = 24,
|
|
10
|
+
color = 'currentColor',
|
|
11
|
+
}) => (
|
|
12
|
+
<svg
|
|
13
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
14
|
+
fill="none"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
width={width}
|
|
17
|
+
height={height}
|
|
18
|
+
strokeWidth={1.5}
|
|
19
|
+
stroke={color}
|
|
20
|
+
>
|
|
21
|
+
<path
|
|
22
|
+
strokeLinecap="round"
|
|
23
|
+
strokeLinejoin="round"
|
|
24
|
+
d="M14.25 9.75 16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0 0 20.25 18V6A2.25 2.25 0 0 0 18 3.75H6A2.25 2.25 0 0 0 3.75 6v12A2.25 2.25 0 0 0 6 20.25Z"
|
|
25
|
+
/>
|
|
26
|
+
</svg>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const WfoBracketSquare = withWfoHeroIconsWrapper(WfoBracketSquareSvg);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
import { WfoIconProps } from '@/icons/WfoIconProps';
|
|
4
|
+
|
|
5
|
+
import { withWfoHeroIconsWrapper } from './WfoHeroIconsWrapper';
|
|
6
|
+
|
|
7
|
+
export const WfoCommandLineSvg: FC<WfoIconProps> = ({
|
|
8
|
+
width = 24,
|
|
9
|
+
height = 24,
|
|
10
|
+
color = 'currentColor',
|
|
11
|
+
}) => (
|
|
12
|
+
<svg
|
|
13
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
14
|
+
fill="none"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
strokeWidth={1.5}
|
|
17
|
+
width={width}
|
|
18
|
+
height={height}
|
|
19
|
+
stroke={color}
|
|
20
|
+
>
|
|
21
|
+
<path
|
|
22
|
+
strokeLinecap="round"
|
|
23
|
+
strokeLinejoin="round"
|
|
24
|
+
d="m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z"
|
|
25
|
+
/>
|
|
26
|
+
</svg>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const WfoCommandLine = withWfoHeroIconsWrapper(WfoCommandLineSvg);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
import { WfoIconProps } from '@/icons/WfoIconProps';
|
|
4
|
+
|
|
5
|
+
import { withWfoHeroIconsWrapper } from './WfoHeroIconsWrapper';
|
|
6
|
+
|
|
7
|
+
export const WfoTableCellsSvg: FC<WfoIconProps> = ({
|
|
8
|
+
width = 24,
|
|
9
|
+
height = 24,
|
|
10
|
+
color = 'currentColor',
|
|
11
|
+
}) => (
|
|
12
|
+
<svg
|
|
13
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
14
|
+
fill="none"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
strokeWidth={1.5}
|
|
17
|
+
stroke={color}
|
|
18
|
+
width={width}
|
|
19
|
+
height={height}
|
|
20
|
+
>
|
|
21
|
+
<path
|
|
22
|
+
strokeLinecap="round"
|
|
23
|
+
strokeLinejoin="round"
|
|
24
|
+
d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"
|
|
25
|
+
/>
|
|
26
|
+
</svg>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const WfoTableCells = withWfoHeroIconsWrapper(WfoTableCellsSvg);
|
package/src/messages/en-GB.json
CHANGED
|
@@ -252,8 +252,11 @@
|
|
|
252
252
|
"submitTaskFormLabel": "Please submit the form to start this task",
|
|
253
253
|
"submitWorkflowFormLabel": "Please submit the form to start this workflow",
|
|
254
254
|
"traceback": "Traceback",
|
|
255
|
-
"
|
|
256
|
-
|
|
255
|
+
"codeView": {
|
|
256
|
+
"json": "JSON",
|
|
257
|
+
"table": "Tab",
|
|
258
|
+
"raw": "Raw"
|
|
259
|
+
}
|
|
257
260
|
},
|
|
258
261
|
"delta": {
|
|
259
262
|
"title": "Subscription delta",
|