@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.
Files changed (31) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +6 -6
  4. package/CHANGELOG.md +16 -0
  5. package/dist/index.d.ts +44 -8
  6. package/dist/index.js +2196 -1889
  7. package/dist/index.js.map +1 -1
  8. package/package.json +7 -3
  9. package/src/components/WfoMonacoCodeBlock/WfoMonacoCodeBlock.tsx +92 -0
  10. package/src/components/WfoMonacoCodeBlock/index.ts +1 -0
  11. package/src/components/WfoMonacoCodeBlock/styles.ts +16 -0
  12. package/src/components/WfoSubscription/WfoInSyncField/WfoInSyncErrorToastMessage.tsx +25 -0
  13. package/src/components/WfoSubscription/{WfoInSyncField.tsx → WfoInSyncField/WfoInSyncField.tsx} +12 -4
  14. package/src/components/WfoSubscription/index.ts +1 -1
  15. package/src/components/WfoSubscription/utils/utils.spec.ts +50 -0
  16. package/src/components/WfoSubscription/utils/utils.ts +22 -0
  17. package/src/components/WfoWorkflowSteps/WfoStep/WfoCodeViewSelector.tsx +116 -0
  18. package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +24 -27
  19. package/src/components/index.ts +1 -0
  20. package/src/configuration/version.ts +1 -1
  21. package/src/hooks/useShowToastMessage.ts +3 -1
  22. package/src/icons/heroicons/WfoBracketSquare.tsx +29 -0
  23. package/src/icons/heroicons/WfoCommandLine.tsx +29 -0
  24. package/src/icons/heroicons/WfoTableCells.tsx +29 -0
  25. package/src/icons/heroicons/index.ts +3 -0
  26. package/src/messages/en-GB.json +5 -2
  27. package/src/messages/nl-NL.json +5 -2
  28. package/src/pages/processes/WfoProcessDetail.tsx +20 -2
  29. package/src/rtk/slices/toastMessages.ts +1 -1
  30. package/src/types/types.ts +4 -5
  31. 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.1.1",
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": "^0.0.39",
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
+ };
@@ -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 './utils';
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
- error?.data?.detail
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 { WfoJsonCodeBlock, WfoTableCodeBlock } from '@/components';
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 [tableView, setTableView] = useState<boolean>(false);
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
- <EuiButton
154
- onClick={(
155
- event: React.MouseEvent<HTMLButtonElement>,
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
- (tableView ? (
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}>
@@ -38,3 +38,4 @@ export * from './WfoInlineEdit';
38
38
  export * from './WfoPydanticForm';
39
39
  export * from './WfoSearchPage';
40
40
  export * from './WfoAgent';
41
+ export * from './WfoMonacoCodeBlock';
@@ -1 +1 @@
1
- export const ORCHESTRATOR_UI_LIBRARY_VERSION = '6.1.1';
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: string, // We use string here instead of Toast['text'] because we want to prevent passing in react component because they trigger an "unsynchronizable values in payload detected" error',
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);
@@ -5,3 +5,6 @@ export * from './WfoArrowsUpDown';
5
5
  export * from './WfoArrowUp';
6
6
  export * from './WfoWrench';
7
7
  export * from './WfoSquareStack3dStack';
8
+ export * from './WfoBracketSquare';
9
+ export * from './WfoCommandLine';
10
+ export * from './WfoTableCells';
@@ -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
- "tableView": "Table view",
256
- "jsonView": "JSON view"
255
+ "codeView": {
256
+ "json": "JSON",
257
+ "table": "Tab",
258
+ "raw": "Raw"
259
+ }
257
260
  },
258
261
  "delta": {
259
262
  "title": "Subscription delta",