@orchestrator-ui/orchestrator-ui-components 2.8.0 → 2.8.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestrator-ui/orchestrator-ui-components",
3
- "version": "2.8.0",
3
+ "version": "2.8.2",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Library of UI Components used to display the workflow orchestrator frontend",
6
6
  "author": {
@@ -4,6 +4,10 @@ import { useTranslations } from 'next-intl';
4
4
 
5
5
  import { EuiTab, EuiTabs } from '@elastic/eui';
6
6
 
7
+ import { useWithOrchestratorTheme } from '@/hooks';
8
+
9
+ import { getStyles } from './styles';
10
+
7
11
  export type FilterQuery<DataType> = {
8
12
  field: keyof DataType;
9
13
  value: string;
@@ -14,6 +18,7 @@ export type WfoFilterTab<TabType, DataType = object> = {
14
18
  translationKey: string;
15
19
  alwaysOnFilters?: FilterQuery<DataType>[];
16
20
  prepend?: React.ReactNode | string;
21
+ append?: React.ReactNode | string;
17
22
  };
18
23
 
19
24
  export type WfoFilterTabsProps<TabType, DataType> = {
@@ -30,18 +35,23 @@ export const WfoFilterTabs = <TabType extends string, DataType>({
30
35
  onChangeTab,
31
36
  }: WfoFilterTabsProps<TabType, DataType>) => {
32
37
  const t = useTranslations(translationNamespace);
38
+ const { tabStyle } = useWithOrchestratorTheme(getStyles);
33
39
  return (
34
40
  <EuiTabs>
35
- {tabs.map(({ id, translationKey: name, prepend = '' }) => (
36
- <EuiTab
37
- key={id}
38
- isSelected={id === selectedTab}
39
- onClick={() => id !== selectedTab && onChangeTab(id)}
40
- prepend={prepend}
41
- >
42
- {t(name)}
43
- </EuiTab>
44
- ))}
41
+ {tabs.map(
42
+ ({ id, translationKey: name, prepend = '', append = '' }) => (
43
+ <EuiTab
44
+ css={tabStyle}
45
+ key={id}
46
+ isSelected={id === selectedTab}
47
+ onClick={() => id !== selectedTab && onChangeTab(id)}
48
+ prepend={prepend}
49
+ append={append}
50
+ >
51
+ {t(name)}
52
+ </EuiTab>
53
+ ),
54
+ )}
45
55
  </EuiTabs>
46
56
  );
47
57
  };
@@ -0,0 +1,14 @@
1
+ import { css } from '@emotion/react';
2
+
3
+ import { WfoTheme } from '@/hooks';
4
+
5
+ export const getStyles = ({ theme }: WfoTheme) => {
6
+ const tabStyle = css({
7
+ gap: `${theme.size.xxs}`,
8
+ '.euiTab__prepend': {
9
+ marginRight: `${theme.size.xs}`,
10
+ },
11
+ });
12
+
13
+ return { tabStyle };
14
+ };
@@ -98,7 +98,9 @@ export function UnconnectedSelectField({
98
98
  useWithOrchestratorTheme(getSelectFieldStyles);
99
99
 
100
100
  useEffect(() => {
101
- onChange(selectedValue?.value);
101
+ if (selectedValue && selectedValue.value !== 'undefined') {
102
+ onChange(selectedValue.value);
103
+ }
102
104
  }, []);
103
105
 
104
106
  if (fieldType === Array) {
@@ -18,7 +18,7 @@ import {
18
18
  WfoProductBlockKeyValueRow,
19
19
  WfoValueCell,
20
20
  } from '@/components';
21
- import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
21
+ import { useWithOrchestratorTheme } from '@/hooks';
22
22
  import { ProductBlockInstance, Subscription } from '@/types';
23
23
  import { getFirstUuidPart } from '@/utils';
24
24
 
@@ -41,9 +41,9 @@ export const WfoSubscriptionProductBlock = ({
41
41
  subscriptionId,
42
42
  }: WfoSubscriptionProductBlockProps) => {
43
43
  const t = useTranslations('subscriptions.detail');
44
- const { theme } = useOrchestratorTheme();
45
44
  const {
46
45
  iconStyle,
46
+ iconOutsideCurrentSubscriptionStyle,
47
47
  panelStyle,
48
48
  panelStyleOutsideCurrentSubscription,
49
49
  leftColumnStyle,
@@ -79,11 +79,14 @@ export const WfoSubscriptionProductBlock = ({
79
79
  >
80
80
  <EuiFlexGroup>
81
81
  <EuiFlexItem grow={false}>
82
- <div css={iconStyle}>
83
- <EuiIcon
84
- type="filebeatApp"
85
- color={theme.colors.primary}
86
- />
82
+ <div
83
+ css={
84
+ isOutsideCurrentSubscription
85
+ ? iconOutsideCurrentSubscriptionStyle
86
+ : iconStyle
87
+ }
88
+ >
89
+ <EuiIcon type="filebeatApp" color="currentColor" />
87
90
  </div>
88
91
  </EuiFlexItem>
89
92
  <EuiFlexItem>
@@ -8,17 +8,29 @@ export const getStyles = (wfoTheme: WfoTheme) => {
8
8
  width: 45,
9
9
  height: 45,
10
10
  backgroundColor: toSecondaryColor(theme.colors.primary),
11
+ color: theme.colors.primary,
11
12
  paddingTop: 13,
12
13
  paddingLeft: 15,
13
14
  borderRadius: 7,
14
15
  });
15
16
 
17
+ const iconOutsideCurrentSubscriptionStyle = css([
18
+ iconStyle,
19
+ {
20
+ backgroundColor: theme.colors.lightShade,
21
+ color: theme.colors.darkestShade,
22
+ },
23
+ ]);
24
+
16
25
  const panelStyle = css({
17
- backgroundColor: theme.colors.lightestShade,
26
+ backgroundColor: toSecondaryColor(
27
+ toSecondaryColor(theme.colors.primary),
28
+ ),
29
+ border: `solid 1px ${toSecondaryColor(theme.colors.primary)}`,
18
30
  });
19
31
 
20
32
  const panelStyleOutsideCurrentSubscription = css({
21
- backgroundColor: toSecondaryColor(theme.colors.lightestShade),
33
+ backgroundColor: toSecondaryColor(theme.colors.emptyShade),
22
34
  border: `dashed 1px ${theme.colors.lightShade}`,
23
35
  });
24
36
 
@@ -51,6 +63,7 @@ export const getStyles = (wfoTheme: WfoTheme) => {
51
63
 
52
64
  return {
53
65
  iconStyle,
66
+ iconOutsideCurrentSubscriptionStyle,
54
67
  panelStyle,
55
68
  leftColumnStyle,
56
69
  leftColumnStyleWithAlignSelf,
@@ -0,0 +1,55 @@
1
+ import React, { FC, useEffect, useRef, useState } from 'react';
2
+
3
+ import {
4
+ EuiButtonIcon,
5
+ EuiContextMenu,
6
+ EuiContextMenuPanelDescriptor,
7
+ EuiPopover,
8
+ } from '@elastic/eui';
9
+
10
+ import { WfoDotsHorizontal } from '@/icons/WfoDotsHorizontal';
11
+
12
+ export type WfoRowContextMenuProps = {
13
+ items: EuiContextMenuPanelDescriptor[];
14
+ onOpenContextMenu?: () => void;
15
+ };
16
+
17
+ export const WfoRowContextMenu: FC<WfoRowContextMenuProps> = ({
18
+ items,
19
+ onOpenContextMenu,
20
+ }) => {
21
+ const [isOpen, setIsOpen] = useState(false);
22
+
23
+ const onOpenContextMenuRef = useRef(onOpenContextMenu);
24
+
25
+ useEffect(() => {
26
+ if (isOpen) {
27
+ onOpenContextMenuRef.current?.();
28
+ }
29
+ }, [isOpen, onOpenContextMenuRef]);
30
+
31
+ const closePopover = () => setIsOpen(false);
32
+ const togglePopover = () => setIsOpen(!isOpen);
33
+
34
+ return (
35
+ <EuiPopover
36
+ button={
37
+ <EuiButtonIcon
38
+ iconType={() => <WfoDotsHorizontal />}
39
+ onClick={togglePopover}
40
+ aria-label="Row context menu"
41
+ />
42
+ }
43
+ isOpen={isOpen}
44
+ closePopover={closePopover}
45
+ panelPaddingSize="none"
46
+ anchorPosition="leftUp"
47
+ >
48
+ <EuiContextMenu
49
+ initialPanelId={0}
50
+ panels={items}
51
+ onClick={closePopover}
52
+ />
53
+ </EuiPopover>
54
+ );
55
+ };
@@ -0,0 +1 @@
1
+ export * from './WfoRowContextMenu';
@@ -12,6 +12,7 @@ export * from './WfoTableWithFilter';
12
12
  export * from './WfoSortButtons';
13
13
  export * from './WfoFirstPartUUID';
14
14
  export * from './WfoInlineJson';
15
+ export * from './WfoRowContextMenu';
15
16
 
16
17
  export * from './WfoAdvancedTable';
17
18
  export * from './WfoTable';
@@ -19,33 +19,35 @@ import { WfoCode, WfoEyeFill } from '@/icons';
19
19
  import { getStyles } from '../styles';
20
20
 
21
21
  export type WfoStepListHeaderProps = {
22
+ allDetailToggleText: string;
23
+ showDelta: boolean;
22
24
  showHiddenKeys: boolean;
23
25
  showRaw: boolean;
24
- showDelta: boolean;
25
26
  showTraceback: boolean;
26
27
  showTracebackButton: boolean;
27
- allDetailToggleText: string;
28
+ isRunningWorkflow: boolean;
29
+ isTask: boolean;
30
+ onChangeShowDelta: (showDelta: boolean) => void;
28
31
  onChangeShowRaw: (showRaw: boolean) => void;
29
- onChangeShowDelta: (showRaw: boolean) => void;
30
32
  onChangeShowHiddenKeys: (showHiddenKeys: boolean) => void;
31
33
  onShowTraceback: (showTraceback: boolean) => void;
32
34
  onToggleAllDetailsIsOpen: () => void;
33
- isTask: boolean;
34
35
  };
35
36
 
36
37
  export const WfoStepListHeader: FC<WfoStepListHeaderProps> = ({
38
+ allDetailToggleText,
39
+ showDelta,
37
40
  showHiddenKeys,
38
41
  showRaw,
39
- showDelta,
40
42
  showTraceback,
41
43
  showTracebackButton,
42
- onChangeShowHiddenKeys,
43
- onChangeShowRaw,
44
+ isRunningWorkflow,
45
+ isTask,
44
46
  onChangeShowDelta,
45
- allDetailToggleText,
46
- onToggleAllDetailsIsOpen,
47
+ onChangeShowRaw,
48
+ onChangeShowHiddenKeys,
47
49
  onShowTraceback,
48
- isTask,
50
+ onToggleAllDetailsIsOpen,
49
51
  }) => {
50
52
  const t = useTranslations('processes.steps');
51
53
  const { theme } = useOrchestratorTheme();
@@ -107,9 +109,18 @@ export const WfoStepListHeader: FC<WfoStepListHeaderProps> = ({
107
109
  )}
108
110
  <EuiButton
109
111
  onClick={() => onChangeShowDelta(!showDelta)}
112
+ disabled={isRunningWorkflow}
110
113
  iconSide="right"
111
114
  size="s"
112
- iconType={() => <WfoCode color={theme.colors.link} />}
115
+ iconType={() => (
116
+ <WfoCode
117
+ color={
118
+ isRunningWorkflow
119
+ ? theme.colors.disabledText
120
+ : theme.colors.link
121
+ }
122
+ />
123
+ )}
113
124
  >
114
125
  {showDelta ? t('hideDelta') : t('showDelta')}
115
126
  </EuiButton>
@@ -12,7 +12,7 @@ import {
12
12
  import WfoDiff from '@/components/WfoDiff/WfoDiff';
13
13
  import { WfoTraceback } from '@/components/WfoWorkflowSteps/WfoTraceback/WfoTraceback';
14
14
  import { useGetRawProcessDetailQuery } from '@/rtk/endpoints/processDetail';
15
- import { Step, StepStatus } from '@/types';
15
+ import { ProcessStatus, Step, StepStatus } from '@/types';
16
16
  import { InputForm } from '@/types/forms';
17
17
 
18
18
  export type StepListItem = {
@@ -23,6 +23,7 @@ export type StepListItem = {
23
23
 
24
24
  export interface WfoWorkflowStepListProps {
25
25
  steps: Step[];
26
+ lastStatus: ProcessStatus;
26
27
  traceBack: string | null;
27
28
  startedAt: string;
28
29
  processId: string;
@@ -66,6 +67,7 @@ export const WfoWorkflowStepList = React.forwardRef(
66
67
  (
67
68
  {
68
69
  steps = [],
70
+ lastStatus,
69
71
  traceBack,
70
72
  startedAt,
71
73
  processId,
@@ -164,6 +166,15 @@ export const WfoWorkflowStepList = React.forwardRef(
164
166
  isExpanded: true,
165
167
  }));
166
168
 
169
+ // The value of lastStatus is not in lowercase despite the ProcessStatus enum definition
170
+ const isRunningWorkflow: boolean = ![
171
+ ProcessStatus.FAILED,
172
+ ProcessStatus.ABORTED,
173
+ ProcessStatus.COMPLETED,
174
+ ]
175
+ .map((status) => status.toLowerCase())
176
+ .includes(lastStatus.toLowerCase());
177
+
167
178
  return (
168
179
  <>
169
180
  <WfoStepListHeader
@@ -183,6 +194,7 @@ export const WfoWorkflowStepList = React.forwardRef(
183
194
  }
184
195
  onShowTraceback={setShowTraceback}
185
196
  isTask={isTask}
197
+ isRunningWorkflow={isRunningWorkflow}
186
198
  />
187
199
  {showTraceback && <WfoTraceback>{traceBack}</WfoTraceback>}
188
200
  {showRaw && <WfoProcessRawData processId={processId} />}
@@ -1 +1 @@
1
- export const ORCHESTRATOR_UI_LIBRARY_VERSION = '2.8.0';
1
+ export const ORCHESTRATOR_UI_LIBRARY_VERSION = '2.8.2';
@@ -0,0 +1,33 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { WfoIconProps } from '@/icons/WfoIconProps';
4
+
5
+ export const WfoDotsHorizontal: FC<WfoIconProps> = ({
6
+ width = 20,
7
+ height = 20,
8
+ color = 'currentColor',
9
+ }) => (
10
+ <svg
11
+ width={width}
12
+ height={height}
13
+ viewBox="0 0 24 24"
14
+ version="1.1"
15
+ xmlns="http://www.w3.org/2000/svg"
16
+ >
17
+ <title>icon/dots-horizontal</title>
18
+ <g
19
+ id="Symbols"
20
+ stroke="none"
21
+ strokeWidth="1"
22
+ fill="none"
23
+ fillRule="evenodd"
24
+ >
25
+ <g id="icon/dots-horizontal" fill={color} fillRule="nonzero">
26
+ <path
27
+ d="M8,12 C8,13.1046 7.10457,14 6,14 C4.89543,14 4,13.1046 4,12 C4,10.89543 4.89543,10 6,10 C7.10457,10 8,10.89543 8,12 Z M14,12 C14,13.1046 13.1046,14 12,14 C10.89543,14 10,13.1046 10,12 C10,10.89543 10.89543,10 12,10 C13.1046,10 14,10.89543 14,12 Z M18,14 C19.1046,14 20,13.1046 20,12 C20,10.89543 19.1046,10 18,10 C16.8954,10 16,10.89543 16,12 C16,13.1046 16.8954,14 18,14 Z"
28
+ id="Combined-Shape"
29
+ ></path>
30
+ </g>
31
+ </g>
32
+ </svg>
33
+ );
@@ -22,6 +22,7 @@ export const WfoHeroIconsWrapper: FC<WfoHeroIconsWrapperProps> = ({
22
22
  marginRight: theme.size.xs,
23
23
  display: 'flex',
24
24
  alignItems: 'center',
25
+ height: '100%',
25
26
  }}
26
27
  >
27
28
  {children}
@@ -0,0 +1,27 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { WfoIconProps } from '@/icons';
4
+
5
+ import { withWfoHeroIconsWrapper } from './WfoHeroIconsWrapper';
6
+
7
+ const WfoWrenchSvg: FC<WfoIconProps> = ({
8
+ width = 20,
9
+ height = 20,
10
+ color = 'currentColor',
11
+ }) => (
12
+ <svg
13
+ width={width}
14
+ height={height}
15
+ viewBox="0 0 24 24"
16
+ fill={color}
17
+ xmlns="http://www.w3.org/2000/svg"
18
+ >
19
+ <path
20
+ fillRule="evenodd"
21
+ d="M12 6.75a5.25 5.25 0 0 1 6.775-5.025.75.75 0 0 1 .313 1.248l-3.32 3.319c.063.475.276.934.641 1.299.365.365.824.578 1.3.64l3.318-3.319a.75.75 0 0 1 1.248.313 5.25 5.25 0 0 1-5.472 6.756c-1.018-.086-1.87.1-2.309.634L7.344 21.3A3.298 3.298 0 1 1 2.7 16.657l8.684-7.151c.533-.44.72-1.291.634-2.309A5.342 5.342 0 0 1 12 6.75ZM4.117 19.125a.75.75 0 0 1 .75-.75h.008a.75.75 0 0 1 .75.75v.008a.75.75 0 0 1-.75.75h-.008a.75.75 0 0 1-.75-.75v-.008Z"
22
+ clipRule="evenodd"
23
+ />
24
+ </svg>
25
+ );
26
+
27
+ export const WfoWrench = withWfoHeroIconsWrapper(WfoWrenchSvg);
@@ -1,2 +1,4 @@
1
- export * from './WfoArrowsUpDown';
2
1
  export * from './WfoHeroIconsWrapper';
2
+
3
+ export * from './WfoArrowsUpDown';
4
+ export * from './WfoWrench';
@@ -62,6 +62,7 @@ export const WfoProcessDetailPage = ({
62
62
  (processDetail !== undefined && (
63
63
  <WfoWorkflowStepList
64
64
  ref={stepListRef}
65
+ lastStatus={processDetail.lastStatus}
65
66
  processId={processDetail.processId}
66
67
  steps={groupedSteps.flatMap(
67
68
  (groupedStep) => groupedStep.steps,
@@ -10,6 +10,7 @@ export * from './relatedSubscriptions';
10
10
  export * from './settings';
11
11
  export * from './startOptions';
12
12
  export * from './streamMessages';
13
+ export * from './subscriptionActions';
13
14
  export * from './subscriptionDetail';
14
15
  export * from './subscriptionInUseByRelationsList';
15
16
  export * from './subscriptionList';
@@ -27,4 +27,7 @@ const subscriptionActionsApi = orchestratorApi.injectEndpoints({
27
27
  }),
28
28
  });
29
29
 
30
- export const { useGetSubscriptionActionsQuery } = subscriptionActionsApi;
30
+ export const {
31
+ useGetSubscriptionActionsQuery,
32
+ useLazyGetSubscriptionActionsQuery,
33
+ } = subscriptionActionsApi;