@orchestrator-ui/orchestrator-ui-components 1.7.0 → 1.9.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 (28) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +6 -6
  4. package/CHANGELOG.md +12 -0
  5. package/dist/index.d.ts +49 -16
  6. package/dist/index.js +1601 -1418
  7. package/package.json +1 -1
  8. package/src/components/WfoExpandableField/WfoExpandableField.tsx +46 -0
  9. package/src/components/WfoExpandableField/index.ts +1 -0
  10. package/src/components/WfoExpandableField/styles.ts +18 -0
  11. package/src/components/WfoPageTemplate/WfoSidebar/WfoMenuLink.tsx +50 -0
  12. package/src/components/WfoPageTemplate/WfoSidebar/WfoSidebar.tsx +106 -44
  13. package/src/components/WfoPageTemplate/WfoSidebar/index.ts +1 -0
  14. package/src/components/WfoPageTemplate/WfoSidebar/styles.ts +62 -1
  15. package/src/components/WfoSubscription/WfoSubscriptionProductBlock/WfoProductBlockKeyValueRow.tsx +46 -0
  16. package/src/components/WfoSubscription/{WfoSubscriptionProductBlock.tsx → WfoSubscriptionProductBlock/WfoSubscriptionProductBlock.tsx} +34 -91
  17. package/src/components/WfoSubscription/WfoSubscriptionProductBlock/index.ts +2 -0
  18. package/src/components/WfoSubscription/WfoSubscriptionProductBlock/styles.ts +48 -0
  19. package/src/components/WfoSubscription/index.ts +2 -0
  20. package/src/components/WfoSubscription/overrides/index.ts +1 -0
  21. package/src/components/WfoSubscription/overrides/useSubscriptionDetailValueOverride.ts +35 -0
  22. package/src/components/WfoSubscription/styles.ts +0 -48
  23. package/src/components/index.ts +1 -0
  24. package/src/rtk/slices/index.ts +2 -1
  25. package/src/rtk/slices/orchestratorComponentOverride.ts +26 -0
  26. package/src/rtk/store.ts +22 -5
  27. package/src/rtk/storeProvider.tsx +8 -1
  28. package/src/types/types.ts +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestrator-ui/orchestrator-ui-components",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Library of UI Components used to display the workflow orchestrator frontend",
6
6
  "author": {
@@ -0,0 +1,46 @@
1
+ import React, { FC, ReactNode } from 'react';
2
+
3
+ import { EuiButtonIcon } from '@elastic/eui';
4
+
5
+ import { useOrchestratorTheme } from '@/hooks';
6
+ import { WfoMinusCircleFill, WfoPlusCircleFill } from '@/icons';
7
+
8
+ import { getStyles } from './styles';
9
+
10
+ export type WfoExpandableFieldProps = {
11
+ isExpanded: boolean;
12
+ title: ReactNode;
13
+ onExpandedChange: (isExpanded: boolean) => void;
14
+ children: ReactNode;
15
+ };
16
+
17
+ export const WfoExpandableField: FC<WfoExpandableFieldProps> = ({
18
+ isExpanded,
19
+ title,
20
+ onExpandedChange,
21
+ children,
22
+ }) => {
23
+ const { theme } = useOrchestratorTheme();
24
+ const { titleRowStyle, titleStyle } = getStyles(theme);
25
+
26
+ return (
27
+ <>
28
+ <div css={titleRowStyle}>
29
+ <EuiButtonIcon
30
+ aria-label={isExpanded ? 'Collapse' : 'Expand'}
31
+ iconType={() =>
32
+ isExpanded ? (
33
+ <WfoMinusCircleFill color={theme.colors.primary} />
34
+ ) : (
35
+ <WfoPlusCircleFill color={theme.colors.primary} />
36
+ )
37
+ }
38
+ onClick={() => onExpandedChange(!isExpanded)}
39
+ />
40
+ <div css={titleStyle}>{title}</div>
41
+ </div>
42
+
43
+ {isExpanded && children}
44
+ </>
45
+ );
46
+ };
@@ -0,0 +1 @@
1
+ export * from './WfoExpandableField';
@@ -0,0 +1,18 @@
1
+ import { EuiThemeComputed } from '@elastic/eui';
2
+ import { css } from '@emotion/react';
3
+
4
+ export const getStyles = (theme: EuiThemeComputed) => {
5
+ const titleRowStyle = css({
6
+ display: 'flex',
7
+ alignItems: 'center',
8
+ });
9
+
10
+ const titleStyle = css({
11
+ marginLeft: theme.size.s,
12
+ });
13
+
14
+ return {
15
+ titleRowStyle,
16
+ titleStyle,
17
+ };
18
+ };
@@ -0,0 +1,50 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+ import Link from 'next/link';
5
+
6
+ import { useWithOrchestratorTheme } from '@/hooks';
7
+
8
+ import { getMenuItemStyles } from './styles';
9
+
10
+ type WfoMenuItemLinkProps = {
11
+ path: string;
12
+ translationString: string;
13
+ isSelected: boolean;
14
+ isSubItem?: boolean;
15
+ };
16
+
17
+ export const WfoMenuItemLink: FC<WfoMenuItemLinkProps> = ({
18
+ path,
19
+ translationString,
20
+ isSelected,
21
+ isSubItem,
22
+ }) => {
23
+ const {
24
+ menuItemStyle,
25
+ selectedMenuItem,
26
+ selectedSubMenuItem,
27
+ subMenuItemStyle,
28
+ } = useWithOrchestratorTheme(getMenuItemStyles);
29
+
30
+ const getMenuItemStyle = () => {
31
+ if (isSubItem) {
32
+ return isSelected ? selectedSubMenuItem : subMenuItemStyle;
33
+ } else {
34
+ return isSelected ? selectedMenuItem : menuItemStyle;
35
+ }
36
+ };
37
+
38
+ const t = useTranslations('main');
39
+
40
+ // This is a workaround to use the translation string as the link text if it's not found in the translation file.
41
+ const linkText =
42
+ t(translationString) === `main.${translationString}`
43
+ ? translationString
44
+ : t(translationString);
45
+ return (
46
+ <Link css={getMenuItemStyle()} href={path}>
47
+ {linkText}
48
+ </Link>
49
+ );
50
+ };
@@ -25,6 +25,7 @@ import {
25
25
  PATH_WORKFLOWS,
26
26
  } from '../paths';
27
27
  import { WfoCopyright } from './WfoCopyright';
28
+ import { WfoMenuItemLink } from './WfoMenuLink';
28
29
 
29
30
  export const renderEmptyElementWhenNotAllowedByPolicy = (isAllowed: boolean) =>
30
31
  isAllowed ? undefined : () => <></>;
@@ -46,6 +47,7 @@ export type WfoSidebarProps = {
46
47
  export const WfoSidebar: FC<WfoSidebarProps> = ({ overrideMenuItems }) => {
47
48
  const t = useTranslations('main');
48
49
  const router = useRouter();
50
+
49
51
  const [isSideNavOpenOnMobile, setIsSideNavOpenOnMobile] = useState(false);
50
52
  const { isAllowed } = usePolicy();
51
53
 
@@ -53,90 +55,144 @@ export const WfoSidebar: FC<WfoSidebarProps> = ({ overrideMenuItems }) => {
53
55
  setIsSideNavOpenOnMobile((openState) => !openState);
54
56
  };
55
57
 
58
+ // Note: href is used to determine if the user has access to the page in
59
+ // defaultMenuItemsFilteredByPolicy so we need to keep it in the item although we don't use it in the render.
56
60
  const defaultMenuItems: EuiSideNavItemType<object>[] = [
57
61
  {
58
62
  name: t('start'),
59
63
  id: '2',
60
64
  isSelected: router.pathname === PATH_START,
61
- onClick: (e) => {
62
- e.preventDefault();
63
- router.push(PATH_START);
64
- },
65
+ href: PATH_START,
66
+ renderItem: () => (
67
+ <WfoMenuItemLink
68
+ path={PATH_START}
69
+ translationString="start"
70
+ isSelected={router.pathname === PATH_START}
71
+ />
72
+ ),
65
73
  },
66
74
  {
67
75
  name: t('workflows'),
68
76
  id: '3',
69
77
  isSelected: router.pathname === PATH_WORKFLOWS,
70
78
  href: PATH_WORKFLOWS,
71
- onClick: (e) => {
72
- e.preventDefault();
73
- router.push(PATH_WORKFLOWS);
74
- },
79
+ renderItem: () => (
80
+ <WfoMenuItemLink
81
+ path={PATH_WORKFLOWS}
82
+ translationString="workflows"
83
+ isSelected={router.pathname === PATH_WORKFLOWS}
84
+ />
85
+ ),
75
86
  },
76
87
  {
77
88
  name: t('subscriptions'),
78
89
  id: '4',
79
90
  isSelected: router.pathname === PATH_SUBSCRIPTIONS,
80
91
  href: PATH_SUBSCRIPTIONS,
81
- onClick: (e) => {
82
- e.preventDefault();
83
- router.push(PATH_SUBSCRIPTIONS);
84
- },
92
+ renderItem: () => (
93
+ <WfoMenuItemLink
94
+ path={PATH_SUBSCRIPTIONS}
95
+ translationString="subscriptions"
96
+ isSelected={router.pathname === PATH_SUBSCRIPTIONS}
97
+ />
98
+ ),
85
99
  },
86
100
  {
87
101
  name: t('metadata'),
88
102
  id: '5',
89
103
  href: PATH_METADATA,
90
- onClick: () => {
91
- router.push(PATH_METADATA);
92
- },
104
+ isSelected:
105
+ router.pathname.substring(0, PATH_METADATA.length) ===
106
+ PATH_METADATA,
107
+ renderItem: () => (
108
+ <WfoMenuItemLink
109
+ path={PATH_METADATA_PRODUCTS}
110
+ translationString="metadata"
111
+ isSelected={
112
+ router.pathname.substring(0, PATH_METADATA.length) ===
113
+ PATH_METADATA
114
+ }
115
+ />
116
+ ),
93
117
  items: [
94
118
  {
95
119
  name: t('metadataProducts'),
96
120
  id: '5.1',
97
- isSelected: router.pathname === PATH_METADATA_PRODUCTS,
98
- onClick: (e) => {
99
- e.preventDefault();
100
- router.push(PATH_METADATA_PRODUCTS);
101
- },
121
+ href: PATH_METADATA_PRODUCTS,
122
+ renderItem: () => (
123
+ <WfoMenuItemLink
124
+ path={PATH_METADATA_PRODUCTS}
125
+ translationString="metadataProducts"
126
+ isSelected={
127
+ router.pathname === PATH_METADATA_PRODUCTS
128
+ }
129
+ isSubItem={true}
130
+ />
131
+ ),
102
132
  },
103
133
  {
104
134
  name: t('metadataProductblocks'),
105
135
  id: '5.2',
106
136
  isSelected:
107
137
  router.pathname === PATH_METADATA_PRODUCT_BLOCKS,
108
- onClick: (e) => {
109
- e.preventDefault();
110
- router.push(PATH_METADATA_PRODUCT_BLOCKS);
111
- },
138
+ href: PATH_METADATA_PRODUCT_BLOCKS,
139
+ renderItem: () => (
140
+ <WfoMenuItemLink
141
+ path={PATH_METADATA_PRODUCT_BLOCKS}
142
+ translationString="metadataProductblocks"
143
+ isSelected={
144
+ router.pathname === PATH_METADATA_PRODUCT_BLOCKS
145
+ }
146
+ isSubItem={true}
147
+ />
148
+ ),
112
149
  },
113
150
  {
114
151
  name: t('metadataResourceTypes'),
115
152
  id: '5.3',
153
+ href: PATH_METADATA_RESOURCE_TYPES,
116
154
  isSelected:
117
155
  router.pathname === PATH_METADATA_RESOURCE_TYPES,
118
- onClick: (e) => {
119
- e.preventDefault();
120
- router.push(PATH_METADATA_RESOURCE_TYPES);
121
- },
156
+ renderItem: () => (
157
+ <WfoMenuItemLink
158
+ path={PATH_METADATA_RESOURCE_TYPES}
159
+ translationString="metadataResourceTypes"
160
+ isSelected={
161
+ router.pathname === PATH_METADATA_RESOURCE_TYPES
162
+ }
163
+ isSubItem={true}
164
+ />
165
+ ),
122
166
  },
123
167
  {
124
168
  name: t('metadataWorkflows'),
125
169
  id: '5.4',
126
170
  isSelected: router.pathname === PATH_METADATA_WORKFLOWS,
127
- onClick: (e) => {
128
- e.preventDefault();
129
- router.push(PATH_METADATA_WORKFLOWS);
130
- },
171
+ href: PATH_METADATA_WORKFLOWS,
172
+ renderItem: () => (
173
+ <WfoMenuItemLink
174
+ path={PATH_METADATA_WORKFLOWS}
175
+ translationString="metadataWorkflows"
176
+ isSelected={
177
+ router.pathname === PATH_METADATA_WORKFLOWS
178
+ }
179
+ isSubItem={true}
180
+ />
181
+ ),
131
182
  },
132
183
  {
133
184
  name: t('metadataTasks'),
134
185
  id: '5.5',
135
186
  isSelected: router.pathname === PATH_METADATA_TASKS,
136
- onClick: (e) => {
137
- e.preventDefault();
138
- router.push(PATH_METADATA_TASKS);
139
- },
187
+ href: PATH_METADATA_TASKS,
188
+ renderItem: () => (
189
+ <WfoMenuItemLink
190
+ path={PATH_METADATA_TASKS}
191
+ translationString="metadataTasks"
192
+ isSelected={router.pathname === PATH_METADATA_TASKS}
193
+ isSubItem={true}
194
+ />
195
+ ),
140
196
  },
141
197
  ],
142
198
  },
@@ -144,21 +200,27 @@ export const WfoSidebar: FC<WfoSidebarProps> = ({ overrideMenuItems }) => {
144
200
  name: t('tasks'),
145
201
  isSelected: router.pathname === PATH_TASKS,
146
202
  id: '6',
147
- onClick: (e) => {
148
- e.preventDefault();
149
- router.push(PATH_TASKS);
150
- },
151
203
  href: PATH_TASKS,
204
+ renderItem: () => (
205
+ <WfoMenuItemLink
206
+ path={PATH_TASKS}
207
+ translationString="tasks"
208
+ isSelected={router.pathname === PATH_TASKS}
209
+ />
210
+ ),
152
211
  },
153
212
  {
154
213
  name: t('settings'),
155
214
  isSelected: router.pathname === PATH_SETTINGS,
156
215
  id: '7',
157
- onClick: (e) => {
158
- e.preventDefault();
159
- router.push(PATH_SETTINGS);
160
- },
161
216
  href: PATH_SETTINGS,
217
+ renderItem: () => (
218
+ <WfoMenuItemLink
219
+ path={PATH_SETTINGS}
220
+ translationString="settings"
221
+ isSelected={router.pathname === PATH_SETTINGS}
222
+ />
223
+ ),
162
224
  },
163
225
  ];
164
226
 
@@ -1 +1,2 @@
1
1
  export * from './WfoSidebar';
2
+ export * from './WfoMenuLink';
@@ -1,5 +1,5 @@
1
1
  import { EuiThemeComputed } from '@elastic/eui';
2
- import { css } from '@emotion/react';
2
+ import { CSSObject, css } from '@emotion/react';
3
3
 
4
4
  export const getCopyrightStyles = (theme: EuiThemeComputed) => {
5
5
  const copyrightStyle = css({
@@ -15,3 +15,64 @@ export const getCopyrightStyles = (theme: EuiThemeComputed) => {
15
15
  copyrightStyle,
16
16
  };
17
17
  };
18
+
19
+ export const getMenuItemStyles = (theme: EuiThemeComputed) => {
20
+ const baseStyles: CSSObject = {
21
+ lineHeight: `${theme.base * 1.25}px`,
22
+ display: 'flex',
23
+ alignItems: 'center',
24
+ ':hover': {
25
+ textDecoration: 'underline',
26
+ },
27
+ color: theme.colors.text,
28
+ padding: `${theme.base * 0.5}px ${theme.base * 0.75}px`,
29
+ };
30
+
31
+ const baseSubMenuStyles: CSSObject = {
32
+ ...baseStyles,
33
+ ':after': {
34
+ content: "''",
35
+ top: '16px',
36
+ left: 0,
37
+ width: '4px',
38
+ height: '1px',
39
+ backgroundColor: '#d3dae6',
40
+ position: 'absolute',
41
+ },
42
+ padding: '8px 12px',
43
+ ':last-child': {
44
+ top: '-4px',
45
+ position: 'relative',
46
+ },
47
+ };
48
+
49
+ const menuItemStyle = css({
50
+ ...baseStyles,
51
+ color: theme.colors.title,
52
+ });
53
+
54
+ const selectedMenuItem = css({
55
+ ...baseStyles,
56
+ height: `${theme.base * 2.25}px`,
57
+ backgroundColor: theme.colors.lightShade,
58
+ borderRadius: theme.border.radius.medium,
59
+ fontWeight: theme.font.weight.semiBold,
60
+ color: theme.colors.primaryText,
61
+ });
62
+
63
+ const selectedSubMenuItem = css({
64
+ ...baseSubMenuStyles,
65
+ fontWeight: theme.font.weight.semiBold,
66
+ });
67
+
68
+ const subMenuItemStyle = css({
69
+ ...baseSubMenuStyles,
70
+ });
71
+
72
+ return {
73
+ menuItemStyle,
74
+ selectedMenuItem,
75
+ selectedSubMenuItem,
76
+ subMenuItemStyle,
77
+ };
78
+ };
@@ -0,0 +1,46 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { EuiBadge } from '@elastic/eui';
4
+
5
+ import { useSubscriptionDetailValueOverride } from '@/components';
6
+ import { useWithOrchestratorTheme } from '@/hooks';
7
+ import { FieldValue } from '@/types';
8
+ import { camelToHuman } from '@/utils';
9
+
10
+ import { getStyles } from './styles';
11
+
12
+ export type WfoProductBlockKeyValueRowProps = {
13
+ fieldValue: FieldValue;
14
+ };
15
+
16
+ export const WfoProductBlockKeyValueRow: FC<
17
+ WfoProductBlockKeyValueRowProps
18
+ > = ({ fieldValue }) => {
19
+ const { leftColumnStyle, rightColumnStyle, rowStyle } =
20
+ useWithOrchestratorTheme(getStyles);
21
+ const { getOverriddenValue } = useSubscriptionDetailValueOverride();
22
+
23
+ const { field, value } = fieldValue;
24
+
25
+ const WfoProductBlockValue: FC<{ value: FieldValue['value'] }> = ({
26
+ value,
27
+ }) =>
28
+ typeof value === 'boolean' ? (
29
+ <EuiBadge>{value.toString()}</EuiBadge>
30
+ ) : (
31
+ <>{value}</>
32
+ );
33
+
34
+ return (
35
+ <tr css={rowStyle}>
36
+ <td css={leftColumnStyle}>
37
+ <b>{camelToHuman(field)}</b>
38
+ </td>
39
+ <td css={rightColumnStyle}>
40
+ {getOverriddenValue(fieldValue) ?? (
41
+ <WfoProductBlockValue value={value} />
42
+ )}
43
+ </td>
44
+ </tr>
45
+ );
46
+ };
@@ -6,7 +6,6 @@ import { useRouter } from 'next/router';
6
6
  import {
7
7
  EuiBadge,
8
8
  EuiButtonEmpty,
9
- EuiCodeBlock,
10
9
  EuiFlexGroup,
11
10
  EuiFlexItem,
12
11
  EuiIcon,
@@ -15,15 +14,19 @@ import {
15
14
  EuiText,
16
15
  } from '@elastic/eui';
17
16
 
18
- import { useOrchestratorTheme, useWithOrchestratorTheme } from '../../hooks';
19
- import { FieldValue, InUseByRelation } from '../../types';
20
- import { camelToHuman } from '../../utils';
21
- import { PATH_SUBSCRIPTIONS } from '../WfoPageTemplate';
22
- import { getStyles } from './styles';
17
+ import {
18
+ PATH_SUBSCRIPTIONS,
19
+ WfoJsonCodeBlock,
20
+ WfoProductBlockKeyValueRow,
21
+ } from '@/components';
22
+ import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
23
+ import { FieldValue, InUseByRelation } from '@/types';
24
+
23
25
  import {
24
26
  getFieldFromProductBlockInstanceValues,
25
27
  getProductBlockTitle,
26
- } from './utils';
28
+ } from '../utils';
29
+ import { getStyles } from './styles';
27
30
 
28
31
  interface WfoSubscriptionProductBlockProps {
29
32
  ownerSubscriptionId: string;
@@ -47,32 +50,22 @@ export const WfoSubscriptionProductBlock = ({
47
50
  const t = useTranslations('subscriptions.detail');
48
51
  const { theme } = useOrchestratorTheme();
49
52
  const {
50
- productBlockIconStyle,
51
- productBlockPanelStyle,
52
- productBlockLeftColStyle,
53
- productBlockFirstLeftColStyle,
54
- productBlockRightColStyle,
55
- productBlockFirstRightColStyle,
53
+ iconStyle,
54
+ panelStyle,
55
+ leftColumnStyle,
56
+ rightColumnStyle,
57
+ rowStyle,
56
58
  } = useWithOrchestratorTheme(getStyles);
57
59
 
58
60
  const [hideDetails, setHideDetails] = useState(true);
59
61
 
60
- const isFirstBlock = (index: number): boolean => {
61
- if (!hideDetails) return false;
62
- return index === 0;
63
- };
64
-
65
62
  return (
66
63
  <>
67
64
  <EuiSpacer size={'m'}></EuiSpacer>
68
- <EuiPanel
69
- color="transparent"
70
- hasShadow={false}
71
- css={productBlockPanelStyle}
72
- >
65
+ <EuiPanel color="transparent" hasShadow={false} css={panelStyle}>
73
66
  <EuiFlexGroup>
74
67
  <EuiFlexItem grow={false}>
75
- <div css={productBlockIconStyle}>
68
+ <div css={iconStyle}>
76
69
  <EuiIcon
77
70
  type="filebeatApp"
78
71
  color={theme.colors.primary}
@@ -115,31 +108,19 @@ export const WfoSubscriptionProductBlock = ({
115
108
  <tbody>
116
109
  {!hideDetails && (
117
110
  <>
118
- <tr key={-3}>
119
- <td
120
- valign={'top'}
121
- css={productBlockFirstLeftColStyle}
122
- >
111
+ <tr key={-3} css={rowStyle}>
112
+ <td css={leftColumnStyle}>
123
113
  <b>{t('subscriptionInstanceId')}</b>
124
114
  </td>
125
- <td
126
- valign={'top'}
127
- css={productBlockFirstRightColStyle}
128
- >
115
+ <td css={rightColumnStyle}>
129
116
  {subscriptionInstanceId}
130
117
  </td>
131
118
  </tr>
132
- <tr key={-2}>
133
- <td
134
- valign={'top'}
135
- css={productBlockFirstLeftColStyle}
136
- >
119
+ <tr key={-2} css={rowStyle}>
120
+ <td css={leftColumnStyle}>
137
121
  <b>{t('ownerSubscriptionId')}</b>
138
122
  </td>
139
- <td
140
- valign={'top'}
141
- css={productBlockFirstRightColStyle}
142
- >
123
+ <td css={rightColumnStyle}>
143
124
  {subscriptionId ===
144
125
  ownerSubscriptionId ? (
145
126
  <>
@@ -157,24 +138,15 @@ export const WfoSubscriptionProductBlock = ({
157
138
  )}
158
139
  </td>
159
140
  </tr>
160
- <tr key={-1}>
161
- <td
162
- valign={'top'}
163
- css={productBlockLeftColStyle}
164
- >
141
+ <tr key={-1} css={rowStyle}>
142
+ <td css={leftColumnStyle}>
165
143
  <b>{t('inUseByRelations')}</b>
166
144
  </td>
167
- <td
168
- valign={'top'}
169
- css={productBlockRightColStyle}
170
- >
171
- <EuiCodeBlock language="json">
172
- {JSON.stringify(
173
- inUseByRelations,
174
- null,
175
- 4,
176
- )}
177
- </EuiCodeBlock>
145
+ <td css={rightColumnStyle}>
146
+ <WfoJsonCodeBlock
147
+ data={inUseByRelations}
148
+ isBasicStyle
149
+ />
178
150
  </td>
179
151
  </tr>
180
152
  </>
@@ -188,39 +160,10 @@ export const WfoSubscriptionProductBlock = ({
188
160
  ),
189
161
  )
190
162
  .map((productBlockInstanceValue, index) => (
191
- <tr key={index}>
192
- <td
193
- valign={'top'}
194
- css={
195
- isFirstBlock(index)
196
- ? productBlockFirstLeftColStyle
197
- : productBlockLeftColStyle
198
- }
199
- >
200
- <b>
201
- {camelToHuman(
202
- productBlockInstanceValue.field,
203
- )}
204
- </b>
205
- </td>
206
- <td
207
- valign={'top'}
208
- css={
209
- isFirstBlock(index)
210
- ? productBlockFirstRightColStyle
211
- : productBlockRightColStyle
212
- }
213
- >
214
- {typeof productBlockInstanceValue.value ===
215
- 'boolean' ? (
216
- <EuiBadge>
217
- {productBlockInstanceValue.value.toString()}
218
- </EuiBadge>
219
- ) : (
220
- productBlockInstanceValue.value
221
- )}
222
- </td>
223
- </tr>
163
+ <WfoProductBlockKeyValueRow
164
+ fieldValue={productBlockInstanceValue}
165
+ key={index}
166
+ />
224
167
  ))}
225
168
  </tbody>
226
169
  </table>
@@ -0,0 +1,2 @@
1
+ export * from './WfoSubscriptionProductBlock';
2
+ export * from './WfoProductBlockKeyValueRow';