@orchestrator-ui/orchestrator-ui-components 8.1.1 → 8.2.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 +8 -8
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +7 -7
- package/CHANGELOG.md +11 -0
- package/dist/index.d.ts +472 -2
- package/dist/index.js +1551 -1413
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/WfoDiff/WfoDiff.tsx +15 -0
- package/src/components/WfoProcessList/WfoProcessListDeltaPopover.tsx +71 -0
- package/src/components/WfoProcessList/WfoProcessesList.tsx +6 -0
- package/src/components/WfoProcessList/styles.ts +28 -0
- package/src/components/WfoPydanticForm/fields/WfoCallout.tsx +2 -1
- package/src/components/WfoPydanticForm/fields/WfoMarkdownField.tsx +26 -0
- package/src/components/WfoPydanticForm/fields/index.ts +1 -0
- package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActions.tsx +26 -9
- package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionsMenuItem.tsx +23 -15
- package/src/components/WfoSubscription/WfoSubscriptionActions/utils.ts +27 -0
- package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoWorkflowStepList.tsx +3 -14
- package/src/configuration/version.ts +1 -1
- package/src/hooks/useGetPydanticFormsConfig.tsx +12 -1
- package/src/messages/en-GB.json +2 -1
- package/src/messages/nl-NL.json +2 -1
- package/src/rtk/endpoints/subscriptionDetail.ts +1 -1
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@ import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@e
|
|
|
14
14
|
|
|
15
15
|
import { getWfoDiffStyles } from '@/components/WfoDiff/styles';
|
|
16
16
|
import { useWithOrchestratorTheme } from '@/hooks';
|
|
17
|
+
import { ProcessDetailResultRaw } from '@/types';
|
|
17
18
|
|
|
18
19
|
const EMPTY_HUNKS: never[] = [];
|
|
19
20
|
|
|
@@ -31,6 +32,20 @@ interface WfoDiffProps {
|
|
|
31
32
|
syntax?: 'javascript' | 'python';
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
export const stringifyDiffText = (text?: unknown) => (text ? JSON.stringify(text, null, 2) : '');
|
|
36
|
+
|
|
37
|
+
export const getSubscriptionDiffTexts = (data?: ProcessDetailResultRaw) => {
|
|
38
|
+
const subscriptionId = data?.current_state?.subscription?.subscription_id ?? '';
|
|
39
|
+
const newSubscription = data?.current_state?.subscription ?? null;
|
|
40
|
+
const oldSubscriptions = data?.current_state?.__old_subscriptions__ || {};
|
|
41
|
+
const oldSubscription =
|
|
42
|
+
subscriptionId && subscriptionId in oldSubscriptions ? oldSubscriptions[subscriptionId] : null;
|
|
43
|
+
return {
|
|
44
|
+
oldText: stringifyDiffText(oldSubscription),
|
|
45
|
+
newText: stringifyDiffText(newSubscription),
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
34
49
|
const WfoDiff: FC<WfoDiffProps> = ({ oldText, newText, syntax }) => {
|
|
35
50
|
const t = useTranslations('processes.delta');
|
|
36
51
|
const [showSplit, setShowSplit] = useState(true);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React, { FC, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
4
|
+
|
|
5
|
+
import { EuiButtonIcon, EuiLoadingSpinner, EuiPanel, EuiPopover } from '@elastic/eui';
|
|
6
|
+
|
|
7
|
+
import { ProcessListItem, WfoToolTip } from '@/components';
|
|
8
|
+
import WfoDiff, { getSubscriptionDiffTexts } from '@/components/WfoDiff/WfoDiff';
|
|
9
|
+
import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
|
|
10
|
+
import { WfoCode } from '@/icons';
|
|
11
|
+
import { useGetRawProcessDetailQuery } from '@/rtk/endpoints/processDetail';
|
|
12
|
+
import { WorkflowTarget } from '@/types';
|
|
13
|
+
|
|
14
|
+
import { getWfoProcessListDeltaPopoverStyles } from './styles';
|
|
15
|
+
|
|
16
|
+
interface WfoProcessListDeltaPopoverProps {
|
|
17
|
+
processListItem: ProcessListItem;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const WfoProcessListDeltaPopover: FC<WfoProcessListDeltaPopoverProps> = ({ processListItem }) => {
|
|
21
|
+
const { theme } = useOrchestratorTheme();
|
|
22
|
+
const { popoverPanelStyle, deltaContentPanelStyle, loadingSpinnerStyle } = useWithOrchestratorTheme(
|
|
23
|
+
getWfoProcessListDeltaPopoverStyles,
|
|
24
|
+
);
|
|
25
|
+
const t = useTranslations('processes.steps');
|
|
26
|
+
const [isPopoverOpen, setPopoverOpen] = useState(false);
|
|
27
|
+
const { processId, workflowTarget } = processListItem;
|
|
28
|
+
|
|
29
|
+
const { data, isFetching } = useGetRawProcessDetailQuery({ processId }, { skip: !isPopoverOpen });
|
|
30
|
+
|
|
31
|
+
if (workflowTarget.toUpperCase() !== WorkflowTarget.MODIFY.toUpperCase()) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const { oldText, newText } = getSubscriptionDiffTexts(data);
|
|
36
|
+
|
|
37
|
+
const iconButton = (
|
|
38
|
+
<EuiButtonIcon
|
|
39
|
+
iconType={() => <WfoCode color={theme.colors.primary} />}
|
|
40
|
+
onClick={() => setPopoverOpen(!isPopoverOpen)}
|
|
41
|
+
aria-label={t('showDelta')}
|
|
42
|
+
isLoading={isFetching}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const button = isPopoverOpen ? iconButton : <WfoToolTip tooltipContent={t('showDelta')}>{iconButton}</WfoToolTip>;
|
|
47
|
+
|
|
48
|
+
const SubscriptionDeltaContent = () => <WfoDiff oldText={oldText} newText={newText} syntax="javascript" />;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<EuiPopover
|
|
52
|
+
id={`delta-${processId}`}
|
|
53
|
+
button={button}
|
|
54
|
+
isOpen={isPopoverOpen}
|
|
55
|
+
closePopover={() => setPopoverOpen((isPopoverOpen) => !isPopoverOpen)}
|
|
56
|
+
panelPaddingSize="s"
|
|
57
|
+
hasArrow
|
|
58
|
+
ownFocus
|
|
59
|
+
repositionOnScroll
|
|
60
|
+
panelStyle={popoverPanelStyle}
|
|
61
|
+
>
|
|
62
|
+
<EuiPanel color="transparent" paddingSize="s" css={deltaContentPanelStyle}>
|
|
63
|
+
{isFetching ?
|
|
64
|
+
<div css={loadingSpinnerStyle}>
|
|
65
|
+
<EuiLoadingSpinner size="xl" />
|
|
66
|
+
</div>
|
|
67
|
+
: <SubscriptionDeltaContent />}
|
|
68
|
+
</EuiPanel>
|
|
69
|
+
</EuiPopover>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
@@ -36,6 +36,7 @@ import { parseDateToLocaleDateTimeString } from '@/utils';
|
|
|
36
36
|
import { getQueryVariablesForExport } from '@/utils';
|
|
37
37
|
import { csvDownloadHandler, getCsvFileNameWithDate } from '@/utils/csvDownload';
|
|
38
38
|
|
|
39
|
+
import { WfoProcessListDeltaPopover } from './WfoProcessListDeltaPopover';
|
|
39
40
|
import {
|
|
40
41
|
graphQlProcessFilterMapper,
|
|
41
42
|
graphQlProcessSortMapper,
|
|
@@ -96,6 +97,11 @@ export const WfoProcessesList = ({
|
|
|
96
97
|
const router = useRouter();
|
|
97
98
|
|
|
98
99
|
const defaultTableColumns: WfoAdvancedTableColumnConfig<ProcessListItem> = {
|
|
100
|
+
delta: {
|
|
101
|
+
columnType: ColumnType.CONTROL,
|
|
102
|
+
width: '50px',
|
|
103
|
+
renderControl: (row) => <WfoProcessListDeltaPopover processListItem={row} />,
|
|
104
|
+
},
|
|
99
105
|
workflowName: {
|
|
100
106
|
columnType: ColumnType.DATA,
|
|
101
107
|
label: t('workflowName'),
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { css } from '@emotion/react';
|
|
2
|
+
|
|
3
|
+
import { WfoThemeHelpers } from '@/hooks';
|
|
4
|
+
|
|
5
|
+
export const getWfoProcessListDeltaPopoverStyles = ({ theme }: WfoThemeHelpers) => {
|
|
6
|
+
const popoverPanelStyle = {
|
|
7
|
+
backgroundColor: `${theme.colors.backgroundBasePlain}DD`,
|
|
8
|
+
boxShadow: 'none',
|
|
9
|
+
backdropFilter: 'blur(2px)',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const deltaContentPanelStyle = css({
|
|
13
|
+
backgroundColor: 'transparent',
|
|
14
|
+
width: '1300px',
|
|
15
|
+
height: '500px',
|
|
16
|
+
overflow: 'auto',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const loadingSpinnerStyle = css({
|
|
20
|
+
padding: theme.size.m,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
popoverPanelStyle,
|
|
25
|
+
deltaContentPanelStyle,
|
|
26
|
+
loadingSpinnerStyle,
|
|
27
|
+
};
|
|
28
|
+
};
|
|
@@ -4,7 +4,8 @@ import { PydanticFormElementProps } from 'pydantic-forms';
|
|
|
4
4
|
|
|
5
5
|
import { EuiCallOut } from '@elastic/eui';
|
|
6
6
|
|
|
7
|
-
const CALLOUT_COLORS = ['primary', 'success', 'warning', 'danger', 'accent'];
|
|
7
|
+
export const CALLOUT_COLORS = ['primary', 'success', 'warning', 'danger', 'accent'] as const;
|
|
8
|
+
export type CalloutColor = (typeof CALLOUT_COLORS)[number];
|
|
8
9
|
|
|
9
10
|
export const WfoCallout = ({ pydanticFormField }: PydanticFormElementProps) => {
|
|
10
11
|
const { header, message, icon_type, message_type } = pydanticFormField.default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { PydanticFormElementProps } from 'pydantic-forms';
|
|
4
|
+
|
|
5
|
+
import { EuiCallOut, EuiMarkdownFormat } from '@elastic/eui';
|
|
6
|
+
|
|
7
|
+
import { CALLOUT_COLORS, CalloutColor } from './WfoCallout';
|
|
8
|
+
|
|
9
|
+
type MarkdownFieldDefault = string | { content: string; color: CalloutColor };
|
|
10
|
+
|
|
11
|
+
export const WfoMarkdownField = ({ pydanticFormField }: PydanticFormElementProps) => {
|
|
12
|
+
const markdownValue: MarkdownFieldDefault = pydanticFormField.default;
|
|
13
|
+
const content = typeof markdownValue === 'string' ? markdownValue : (markdownValue?.content ?? '');
|
|
14
|
+
const color =
|
|
15
|
+
typeof markdownValue === 'object' && CALLOUT_COLORS.includes(markdownValue?.color) ?
|
|
16
|
+
markdownValue?.color
|
|
17
|
+
: undefined;
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div data-testid={pydanticFormField.id} css={{ marginBottom: '2rem' }}>
|
|
21
|
+
<EuiCallOut color={color}>
|
|
22
|
+
<EuiMarkdownFormat>{content}</EuiMarkdownFormat>
|
|
23
|
+
</EuiCallOut>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
@@ -3,11 +3,11 @@ import React, { FC, useState } from 'react';
|
|
|
3
3
|
import { useTranslations } from 'next-intl';
|
|
4
4
|
import { useRouter } from 'next/router';
|
|
5
5
|
|
|
6
|
-
import { EuiButton, EuiButtonIcon, EuiTitle } from '@elastic/eui';
|
|
6
|
+
import { EuiButton, EuiButtonIcon, EuiLoadingSpinner, EuiTitle } from '@elastic/eui';
|
|
7
7
|
|
|
8
|
-
import { WfoPopover } from '@/components';
|
|
9
|
-
import { PATH_START_NEW_TASK, PATH_START_NEW_WORKFLOW, WfoInSyncField } from '@/components';
|
|
8
|
+
import { PATH_START_NEW_TASK, PATH_START_NEW_WORKFLOW, WfoInSyncField, WfoPopover } from '@/components';
|
|
10
9
|
import { WfoSubscriptionActionsMenuItem } from '@/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionsMenuItem';
|
|
10
|
+
import { useActiveProcess } from '@/components/WfoSubscription/WfoSubscriptionActions/utils';
|
|
11
11
|
import { PolicyResource } from '@/configuration/policy-resources';
|
|
12
12
|
import { useOrchestratorTheme, usePolicy } from '@/hooks';
|
|
13
13
|
import { WfoDotsHorizontal } from '@/icons/WfoDotsHorizontal';
|
|
@@ -39,20 +39,24 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
39
39
|
const [isPopoverOpen, setPopover] = useState<boolean>(false);
|
|
40
40
|
const router = useRouter();
|
|
41
41
|
const disableQuery = isLoading || (!isPopoverOpen && compactMode);
|
|
42
|
+
const { isAllowed } = usePolicy();
|
|
42
43
|
const { data: subscriptionActions, isLoading: subscriptionActionsIsLoading } = useGetSubscriptionActionsQuery(
|
|
43
44
|
{ subscriptionId },
|
|
44
45
|
{ skip: disableQuery },
|
|
45
46
|
);
|
|
46
47
|
const [startProcess] = useStartProcessMutation();
|
|
47
48
|
|
|
48
|
-
const { data: subscriptionDetail } = useGetSubscriptionDetailQuery(
|
|
49
|
+
const { data: subscriptionDetail, isLoading: subscriptionDetailIsLoading } = useGetSubscriptionDetailQuery(
|
|
49
50
|
{
|
|
50
51
|
subscriptionId,
|
|
51
52
|
},
|
|
52
|
-
{ skip: !isPopoverOpen && compactMode },
|
|
53
|
+
{ skip: !isPopoverOpen && compactMode, refetchOnMountOrArgChange: true },
|
|
53
54
|
);
|
|
54
55
|
|
|
55
|
-
const
|
|
56
|
+
const processes = subscriptionDetail?.subscription?.processes?.page;
|
|
57
|
+
const { hasActiveProcess, isCompleted, setProcessId } = useActiveProcess(processes);
|
|
58
|
+
|
|
59
|
+
const buttonIsLoading = isCompleted ? !isCompleted : hasActiveProcess;
|
|
56
60
|
|
|
57
61
|
const onButtonClick = () => setPopover(!isPopoverOpen);
|
|
58
62
|
const closePopover = () => setPopover(false);
|
|
@@ -60,7 +64,9 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
60
64
|
const button =
|
|
61
65
|
compactMode ?
|
|
62
66
|
<EuiButtonIcon
|
|
63
|
-
iconType={() =>
|
|
67
|
+
iconType={() =>
|
|
68
|
+
buttonIsLoading ? <EuiLoadingSpinner /> : <WfoDotsHorizontal color={theme.colors.textDisabled} />
|
|
69
|
+
}
|
|
64
70
|
onClick={onButtonClick}
|
|
65
71
|
aria-label="Row context menu"
|
|
66
72
|
isLoading={isLoading}
|
|
@@ -94,6 +100,11 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
94
100
|
],
|
|
95
101
|
})
|
|
96
102
|
.unwrap()
|
|
103
|
+
.then((response) => {
|
|
104
|
+
if (response?.id) {
|
|
105
|
+
setProcessId(response.id);
|
|
106
|
+
}
|
|
107
|
+
})
|
|
97
108
|
.catch((error) => {
|
|
98
109
|
console.error(`Failed to start action:`, error);
|
|
99
110
|
})
|
|
@@ -122,6 +133,7 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
122
133
|
target={WorkflowTarget.VALIDATE}
|
|
123
134
|
setPopover={setPopover}
|
|
124
135
|
onClick={() => handleActionClick(subscriptionAction.name, compactMode, true)}
|
|
136
|
+
isLoading={buttonIsLoading}
|
|
125
137
|
/>
|
|
126
138
|
))}
|
|
127
139
|
</>
|
|
@@ -133,10 +145,15 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
133
145
|
{subscriptionActions?.reconcile.map((subscriptionAction, index) => (
|
|
134
146
|
<WfoSubscriptionActionsMenuItem
|
|
135
147
|
key={`r_${index}`}
|
|
136
|
-
subscriptionAction={
|
|
148
|
+
subscriptionAction={
|
|
149
|
+
buttonIsLoading && !subscriptionAction.reason ?
|
|
150
|
+
{ ...subscriptionAction, reason: 'subscription.running_process' }
|
|
151
|
+
: subscriptionAction
|
|
152
|
+
}
|
|
137
153
|
target={WorkflowTarget.RECONCILE}
|
|
138
154
|
setPopover={setPopover}
|
|
139
155
|
onClick={() => handleActionClick(subscriptionAction.name, compactMode, false)}
|
|
156
|
+
isLoading={buttonIsLoading}
|
|
140
157
|
/>
|
|
141
158
|
))}
|
|
142
159
|
</>
|
|
@@ -197,7 +214,7 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
197
214
|
return (
|
|
198
215
|
<WfoPopover
|
|
199
216
|
id={'subscriptionActionPopover'}
|
|
200
|
-
isLoading={subscriptionActionsIsLoading || isLoading || false}
|
|
217
|
+
isLoading={subscriptionActionsIsLoading || (compactMode && subscriptionDetailIsLoading) || isLoading || false}
|
|
201
218
|
button={button}
|
|
202
219
|
PopoverContent={MenuItemsList}
|
|
203
220
|
isPopoverOpen={isPopoverOpen}
|
package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionsMenuItem.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import React, { FC } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { useTranslations } from 'next-intl';
|
|
4
4
|
|
|
5
|
-
import { EuiContextMenuItem, EuiToolTip } from '@elastic/eui';
|
|
5
|
+
import { EuiContextMenuItem, EuiLoadingSpinner, EuiToolTip } from '@elastic/eui';
|
|
6
6
|
|
|
7
7
|
import { flattenArrayProps } from '@/components';
|
|
8
8
|
import { WfoSubscriptionActionExpandableMenuItem } from '@/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionExpandableMenuItem';
|
|
@@ -18,6 +18,7 @@ interface MenuItemProps {
|
|
|
18
18
|
target: WorkflowTarget;
|
|
19
19
|
setPopover: (isOpen: boolean) => void;
|
|
20
20
|
onClick: () => void;
|
|
21
|
+
isLoading?: boolean;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export const WfoSubscriptionActionsMenuItem: FC<MenuItemProps> = ({
|
|
@@ -25,6 +26,7 @@ export const WfoSubscriptionActionsMenuItem: FC<MenuItemProps> = ({
|
|
|
25
26
|
onClick,
|
|
26
27
|
target,
|
|
27
28
|
setPopover,
|
|
29
|
+
isLoading = false,
|
|
28
30
|
}) => {
|
|
29
31
|
const { linkMenuItemStyle, tooltipMenuItemStyle, disabledIconStyle, iconStyle, secondaryIconStyle } =
|
|
30
32
|
useWithOrchestratorTheme(getSubscriptionActionStyles);
|
|
@@ -32,6 +34,10 @@ export const WfoSubscriptionActionsMenuItem: FC<MenuItemProps> = ({
|
|
|
32
34
|
const { isEngineRunningNow } = useCheckEngineStatus();
|
|
33
35
|
const t = useTranslations('subscriptions.detail.actions');
|
|
34
36
|
const { theme } = useOrchestratorTheme();
|
|
37
|
+
const subscriptionActionReason =
|
|
38
|
+
subscriptionAction.reason ? subscriptionAction.reason
|
|
39
|
+
: isLoading ? 'subscription.running_process'
|
|
40
|
+
: undefined;
|
|
35
41
|
|
|
36
42
|
const linkIt = (actionItem: React.ReactNode) => {
|
|
37
43
|
const handleLinkClick = async (e: React.MouseEvent) => {
|
|
@@ -51,8 +57,8 @@ export const WfoSubscriptionActionsMenuItem: FC<MenuItemProps> = ({
|
|
|
51
57
|
};
|
|
52
58
|
|
|
53
59
|
const tooltipIt = (actionItem: React.ReactNode) => {
|
|
54
|
-
if (!
|
|
55
|
-
const tooltipContent = t(
|
|
60
|
+
if (!subscriptionActionReason) return actionItem;
|
|
61
|
+
const tooltipContent = t(subscriptionActionReason, flattenArrayProps(subscriptionAction));
|
|
56
62
|
|
|
57
63
|
return (
|
|
58
64
|
<div css={tooltipMenuItemStyle}>
|
|
@@ -68,22 +74,24 @@ export const WfoSubscriptionActionsMenuItem: FC<MenuItemProps> = ({
|
|
|
68
74
|
);
|
|
69
75
|
};
|
|
70
76
|
|
|
71
|
-
const getIcon = () =>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
+
const getIcon = () => {
|
|
78
|
+
if (isLoading) return <EuiLoadingSpinner size="m" />;
|
|
79
|
+
return subscriptionActionReason ?
|
|
80
|
+
<div css={disabledIconStyle}>
|
|
81
|
+
<WfoTargetTypeIcon target={target} disabled />
|
|
82
|
+
<div css={secondaryIconStyle}>
|
|
83
|
+
<WfoXCircleFill width={20} height={20} color={theme.colors.danger} />
|
|
84
|
+
</div>
|
|
77
85
|
</div>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
: <div css={iconStyle}>
|
|
87
|
+
<WfoTargetTypeIcon target={target} />
|
|
88
|
+
</div>;
|
|
89
|
+
};
|
|
82
90
|
|
|
83
91
|
const ActionItem = () => (
|
|
84
92
|
<EuiContextMenuItem
|
|
85
93
|
icon={getIcon()}
|
|
86
|
-
disabled={!!
|
|
94
|
+
disabled={!!subscriptionActionReason}
|
|
87
95
|
css={{
|
|
88
96
|
whiteSpace: 'nowrap',
|
|
89
97
|
}}
|
|
@@ -92,5 +100,5 @@ export const WfoSubscriptionActionsMenuItem: FC<MenuItemProps> = ({
|
|
|
92
100
|
</EuiContextMenuItem>
|
|
93
101
|
);
|
|
94
102
|
|
|
95
|
-
return
|
|
103
|
+
return subscriptionActionReason ? tooltipIt(<ActionItem />) : linkIt(<ActionItem />);
|
|
96
104
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useGetProcessDetailQuery } from '@/rtk';
|
|
4
|
+
import { ProcessStatus, StepStatus, SubscriptionDetailProcess } from '@/types';
|
|
5
|
+
|
|
6
|
+
export const useActiveProcess = (processes: SubscriptionDetailProcess[] | undefined) => {
|
|
7
|
+
const lastProcess = processes?.[processes.length - 1];
|
|
8
|
+
const isLastProcessRunning = lastProcess?.lastStatus.toLowerCase() === ProcessStatus.RUNNING;
|
|
9
|
+
|
|
10
|
+
const [processId, setProcessId] = useState<string | null>(null);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (isLastProcessRunning) {
|
|
14
|
+
setProcessId(lastProcess.processId);
|
|
15
|
+
}
|
|
16
|
+
}, [lastProcess, isLastProcessRunning]);
|
|
17
|
+
|
|
18
|
+
const { data: activeProcessData } = useGetProcessDetailQuery({ processId: processId ?? '' }, { skip: !processId });
|
|
19
|
+
|
|
20
|
+
const processDetail = activeProcessData?.processes[0];
|
|
21
|
+
const lastStatus = processDetail?.lastStatus.toLowerCase() as ProcessStatus;
|
|
22
|
+
const hasActiveProcess = lastStatus === ProcessStatus.RUNNING || isLastProcessRunning;
|
|
23
|
+
const lastState = processDetail?.steps?.[processDetail.steps.length - 1]?.status;
|
|
24
|
+
const isCompleted = lastState !== undefined && [StepStatus.COMPLETE, StepStatus.SUCCESS].includes(lastState);
|
|
25
|
+
|
|
26
|
+
return { hasActiveProcess, isCompleted, setProcessId };
|
|
27
|
+
};
|
|
@@ -3,7 +3,7 @@ import React, { Ref, useEffect, useState } from 'react';
|
|
|
3
3
|
import { useTranslations } from 'next-intl';
|
|
4
4
|
|
|
5
5
|
import { WfoJsonCodeBlock, WfoLoading, WfoStepList, WfoStepListHeader, WfoStepListRef } from '@/components';
|
|
6
|
-
import WfoDiff from '@/components/WfoDiff/WfoDiff';
|
|
6
|
+
import WfoDiff, { getSubscriptionDiffTexts } from '@/components/WfoDiff/WfoDiff';
|
|
7
7
|
import { WfoTraceback } from '@/components/WfoWorkflowSteps/WfoTraceback/WfoTraceback';
|
|
8
8
|
import { useGetRawProcessDetailQuery } from '@/rtk/endpoints/processDetail';
|
|
9
9
|
import { ProcessStatus, Step, StepStatus } from '@/types';
|
|
@@ -33,20 +33,9 @@ export const WfoProcessRawData = ({ processId }: { processId: string }) => {
|
|
|
33
33
|
|
|
34
34
|
export const WfoProcessSubscriptionDelta = ({ processId }: { processId: string }) => {
|
|
35
35
|
const { data, isFetching } = useGetRawProcessDetailQuery({ processId });
|
|
36
|
+
const { oldText, newText } = getSubscriptionDiffTexts(data);
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
const newText = data?.current_state?.subscription ?? null;
|
|
39
|
-
const oldSubscriptions = data?.current_state?.__old_subscriptions__ || {};
|
|
40
|
-
const oldSubscription = subscriptionId in oldSubscriptions ? oldSubscriptions[subscriptionId] : null;
|
|
41
|
-
const oldText = oldSubscription || null;
|
|
42
|
-
|
|
43
|
-
return isFetching ?
|
|
44
|
-
<WfoLoading />
|
|
45
|
-
: <WfoDiff
|
|
46
|
-
oldText={oldText ? JSON.stringify(oldText, null, 2) : ''}
|
|
47
|
-
newText={newText ? JSON.stringify(newText, null, 2) : ''}
|
|
48
|
-
syntax="javascript"
|
|
49
|
-
/>;
|
|
38
|
+
return isFetching ? <WfoLoading /> : <WfoDiff oldText={oldText} newText={newText} syntax="javascript" />;
|
|
50
39
|
};
|
|
51
40
|
|
|
52
41
|
export const WfoWorkflowStepList = React.forwardRef(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '8.
|
|
1
|
+
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '8.2.0';
|
|
@@ -21,11 +21,13 @@ import { Header } from '@/components/WfoPydanticForm/Header';
|
|
|
21
21
|
import { Row } from '@/components/WfoPydanticForm/Row';
|
|
22
22
|
import {
|
|
23
23
|
WfoArrayField,
|
|
24
|
+
WfoCallout,
|
|
24
25
|
WfoCheckbox,
|
|
25
26
|
WfoDivider,
|
|
26
27
|
WfoDropdown,
|
|
27
28
|
WfoInteger,
|
|
28
29
|
WfoLabel,
|
|
30
|
+
WfoMarkdownField,
|
|
29
31
|
WfoMultiCheckboxField,
|
|
30
32
|
WfoObjectField,
|
|
31
33
|
WfoRadio,
|
|
@@ -34,7 +36,6 @@ import {
|
|
|
34
36
|
WfoTextArea,
|
|
35
37
|
WfoTimestampField,
|
|
36
38
|
} from '@/components/WfoPydanticForm/fields';
|
|
37
|
-
import { WfoCallout } from '@/components/WfoPydanticForm/fields';
|
|
38
39
|
import { useAppSelector } from '@/rtk/hooks';
|
|
39
40
|
|
|
40
41
|
const useGetComponentMatcherExtender = (): ComponentMatcherExtender => {
|
|
@@ -180,6 +181,16 @@ const useGetComponentMatcherExtender = (): ComponentMatcherExtender => {
|
|
|
180
181
|
return type === PydanticFormFieldType.STRING && format === ('callout' as PydanticFormFieldFormat);
|
|
181
182
|
},
|
|
182
183
|
},
|
|
184
|
+
{
|
|
185
|
+
id: 'markdownField',
|
|
186
|
+
ElementMatch: {
|
|
187
|
+
isControlledElement: false,
|
|
188
|
+
Element: WfoMarkdownField,
|
|
189
|
+
},
|
|
190
|
+
matcher: ({ format }) => {
|
|
191
|
+
return format === PydanticFormFieldFormat.MARKDOWN;
|
|
192
|
+
},
|
|
193
|
+
},
|
|
183
194
|
...currentMatchers
|
|
184
195
|
.filter((matcher) => matcher.id !== 'text')
|
|
185
196
|
.filter((matcher) => matcher.id !== 'array')
|
package/src/messages/en-GB.json
CHANGED
|
@@ -365,7 +365,8 @@
|
|
|
365
365
|
"not_in_sync": "This subscription can not be modified because it is not in-sync. This means there is some error in the registration of the subscription or that it is being modified by another workflow.",
|
|
366
366
|
"relations_not_in_sync": "This subscription can not be modified because some related subscriptions are not in-sync. Locked subscriptions: {locked_relations}",
|
|
367
367
|
"no_modify_subscription_in_use_by_others": "This subscription can not be modified because it is in use by one or more other subscriptions: {unterminated_parents}",
|
|
368
|
-
"insufficient_workflow_permissions": "Insufficient user permissions to run this workflow"
|
|
368
|
+
"insufficient_workflow_permissions": "Insufficient user permissions to run this workflow",
|
|
369
|
+
"running_process": "This action cannot be started because this subscription already has a running process or task."
|
|
369
370
|
}
|
|
370
371
|
},
|
|
371
372
|
"subscriptionInstanceId": "Instance ID",
|
package/src/messages/nl-NL.json
CHANGED
|
@@ -364,7 +364,8 @@
|
|
|
364
364
|
"not_in_sync": "Deze subscription kan niet worden gewijzigd omdat het niet in-sync is. Dit betekent dat er een fout zit in de registratie van de subscription of dat het wordt gewijzigd door een andere workflow.",
|
|
365
365
|
"relations_not_in_sync": "Deze subscription kan niet worden gewijzigd omdat sommige gerelateerde subscriptions niet in-sync zijn. Geblokkeerde subscriptions: {locked_relations}",
|
|
366
366
|
"no_modify_subscription_in_use_by_others": "Deze subscription kan niet worden gewijzigd omdat het in gebruik is door een of meer andere subscriptions: {unterminated_parents}",
|
|
367
|
-
"insufficient_workflow_permissions": "Onvoldoende rechten om deze actie uit te kunnen voeren"
|
|
367
|
+
"insufficient_workflow_permissions": "Onvoldoende rechten om deze actie uit te kunnen voeren",
|
|
368
|
+
"running_process": "Deze actie kan niet worden gestart omdat deze subscription al een lopend proces of taak heeft."
|
|
368
369
|
}
|
|
369
370
|
},
|
|
370
371
|
"subscriptionInstanceId": "Instance ID",
|
|
@@ -105,4 +105,4 @@ const subscriptionDetailApi = orchestratorApi.injectEndpoints({
|
|
|
105
105
|
}),
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
-
export const { useGetSubscriptionDetailQuery } = subscriptionDetailApi;
|
|
108
|
+
export const { useGetSubscriptionDetailQuery, useLazyGetSubscriptionDetailQuery } = subscriptionDetailApi;
|