@orchestrator-ui/orchestrator-ui-components 8.7.3 → 8.8.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 +16 -14
- package/CHANGELOG.md +22 -0
- package/dist/index.d.ts +23 -18
- package/dist/index.js +389 -267
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/WfoBadges/WfoWorkflowTargetBadge/WfoWorkflowTargetBadge.tsx +2 -2
- package/src/components/WfoContentHeader/WfoContentHeader.tsx +1 -1
- package/src/components/WfoInlineNoteEdit/WfoProcessListNoteEdit.spec.tsx +35 -0
- package/src/components/WfoInlineNoteEdit/WfoProcessListNoteEdit.tsx +7 -9
- package/src/components/WfoProcessList/WfoProcessListDeltaPopover.tsx +1 -1
- package/src/components/WfoProcessList/WfoProcessesList.tsx +7 -5
- package/src/components/WfoSubscription/WfoProcessesTimeline.tsx +21 -7
- package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActions.tsx +25 -9
- package/src/components/WfoSubscription/WfoSubscriptionGeneralSections/WfoSubscriptionDetailSection.tsx +1 -1
- package/src/components/WfoSubscription/styles.ts +6 -0
- package/src/components/WfoSubscription/utils/utils.ts +2 -4
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoExpandingSearchRow.tsx +0 -1
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoStructuredSearchTable.tsx +40 -1
- package/src/components/WfoTable/WfoStructuredSearchTable/styles.ts +8 -9
- package/src/components/WfoTable/WfoTable/WfoTable.tsx +5 -1
- package/src/components/WfoTable/WfoTable/WfoTableDataRows.tsx +11 -2
- package/src/components/WfoTable/WfoTable/WfoTableExpandedRowReveal.spec.tsx +120 -0
- package/src/components/WfoTable/WfoTable/styles.ts +6 -0
- package/src/components/WfoTable/utils/tableConfigPersistence.ts +1 -0
- package/src/components/WfoTimeline/styles.ts +1 -1
- package/src/components/WfoWorkflowUserGuide/WfoPageWithUserGuide.tsx +8 -2
- package/src/components/WfoWorkflowUserGuide/WfoWorkflowGuideExpandablePanel.tsx +39 -30
- package/src/components/WfoWorkflowUserGuide/styles.ts +55 -7
- package/src/configuration/constants.ts +1 -1
- package/src/configuration/version.ts +1 -1
- package/src/hooks/useStoredTableConfig.ts +1 -0
- package/src/messages/en-GB.json +3 -1
- package/src/messages/nl-NL.json +4 -2
- package/src/pages/WfoSearchPocPage.tsx +1 -1
- package/src/pages/tasks/WfoTasksListPage.tsx +1 -0
- package/src/types/types.ts +11 -11
- package/src/utils/getDefaultTableConfig.ts +2 -0
package/package.json
CHANGED
|
@@ -13,11 +13,11 @@ export const WfoWorkflowTargetBadge: FC<WfoWorkflowTargetBadgeProps> = ({ target
|
|
|
13
13
|
const { theme, toSecondaryColor } = useOrchestratorTheme();
|
|
14
14
|
if (!target) return null;
|
|
15
15
|
|
|
16
|
-
const getBadgeColorFromTarget = (_target:
|
|
16
|
+
const getBadgeColorFromTarget = (_target: WorkflowTarget) => {
|
|
17
17
|
const { primary, danger, textDanger, textPrimary, success, textSuccess, warning, textWarning, accent, textAccent } =
|
|
18
18
|
theme.colors;
|
|
19
19
|
|
|
20
|
-
switch (_target
|
|
20
|
+
switch (_target) {
|
|
21
21
|
case WorkflowTarget.CREATE:
|
|
22
22
|
return {
|
|
23
23
|
badgeColor: toSecondaryColor(success),
|
|
@@ -19,7 +19,7 @@ export const WfoContentHeader: FC<WfoContentHeaderProps> = ({ title, subtitle, c
|
|
|
19
19
|
</WfoRenderElementOrString>
|
|
20
20
|
{subtitle && (
|
|
21
21
|
<div>
|
|
22
|
-
<EuiSpacer size="
|
|
22
|
+
<EuiSpacer size="s" />
|
|
23
23
|
<WfoRenderElementOrString>{subtitle}</WfoRenderElementOrString>
|
|
24
24
|
</div>
|
|
25
25
|
)}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for the note column going stale while paginating: the table reuses row
|
|
3
|
+
* components across pages, and EuiInlineEditText only follows its value prop while the value
|
|
4
|
+
* is truthy. A row whose note is empty must therefore still pass a truthy value (the
|
|
5
|
+
* invisible character), otherwise the cell keeps showing the previous page's note.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import '@testing-library/jest-dom';
|
|
10
|
+
import { render, screen } from '@testing-library/react';
|
|
11
|
+
|
|
12
|
+
import { WfoProcessListNoteEdit } from './WfoProcessListNoteEdit';
|
|
13
|
+
|
|
14
|
+
jest.mock('@/rtk', () => ({
|
|
15
|
+
...jest.requireActual('@/rtk'),
|
|
16
|
+
usePatchProcessMutation: () => [jest.fn()],
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe('WfoProcessListNoteEdit', () => {
|
|
20
|
+
it('stops showing the previous note when the reused row has no note', () => {
|
|
21
|
+
const { rerender } = render(<WfoProcessListNoteEdit processId="process-1" note="Note from page one" />);
|
|
22
|
+
expect(screen.getByText('Note from page one')).toBeInTheDocument();
|
|
23
|
+
|
|
24
|
+
rerender(<WfoProcessListNoteEdit processId="process-2" note={null} />);
|
|
25
|
+
expect(screen.queryByText('Note from page one')).not.toBeInTheDocument();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('shows the new note when the reused row has a different note', () => {
|
|
29
|
+
const { rerender } = render(<WfoProcessListNoteEdit processId="process-1" note="Note from page one" />);
|
|
30
|
+
|
|
31
|
+
rerender(<WfoProcessListNoteEdit processId="process-2" note="Note from page two" />);
|
|
32
|
+
expect(screen.getByText('Note from page two')).toBeInTheDocument();
|
|
33
|
+
expect(screen.queryByText('Note from page one')).not.toBeInTheDocument();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { FC } from 'react';
|
|
2
|
-
import React
|
|
2
|
+
import React from 'react';
|
|
3
3
|
|
|
4
4
|
import { usePatchProcessMutation } from '@/rtk';
|
|
5
5
|
import { ProcessDetail } from '@/types';
|
|
6
|
+
import { INVISIBLE_CHARACTER } from '@/utils';
|
|
6
7
|
|
|
7
8
|
import { WfoInlineEdit } from '../WfoInlineEdit';
|
|
8
9
|
|
|
@@ -13,13 +14,6 @@ interface WfoProcessDetailNoteEditProps {
|
|
|
13
14
|
|
|
14
15
|
export const WfoProcessListNoteEdit: FC<WfoProcessDetailNoteEditProps> = ({ processId, note }) => {
|
|
15
16
|
const [patchProcess] = usePatchProcessMutation();
|
|
16
|
-
const [noteValue, setNoteValue] = useState(note);
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
if (note !== noteValue) {
|
|
20
|
-
setNoteValue(note);
|
|
21
|
-
}
|
|
22
|
-
}, [note, noteValue]);
|
|
23
17
|
|
|
24
18
|
const onSaveNote = async (note: string) => {
|
|
25
19
|
const noteModifyPayload = { id: processId, note: note };
|
|
@@ -27,5 +21,9 @@ export const WfoProcessListNoteEdit: FC<WfoProcessDetailNoteEditProps> = ({ proc
|
|
|
27
21
|
return note;
|
|
28
22
|
};
|
|
29
23
|
|
|
30
|
-
|
|
24
|
+
// An empty note must still be passed as a non-empty string (the invisible character):
|
|
25
|
+
// EuiInlineEditText only follows its value prop while the value is truthy, so an empty
|
|
26
|
+
// string would freeze the cell on the note of whichever row rendered here before it,
|
|
27
|
+
// e.g. when the table rows are reused while paginating.
|
|
28
|
+
return <WfoInlineEdit value={note?.trim() ? note : INVISIBLE_CHARACTER} onSave={onSaveNote} />;
|
|
31
29
|
};
|
|
@@ -28,7 +28,7 @@ export const WfoProcessListDeltaPopover: FC<WfoProcessListDeltaPopoverProps> = (
|
|
|
28
28
|
|
|
29
29
|
const { data, isFetching } = useGetRawProcessDetailQuery({ processId }, { skip: !isPopoverOpen });
|
|
30
30
|
|
|
31
|
-
if (workflowTarget
|
|
31
|
+
if (workflowTarget !== WorkflowTarget.MODIFY) {
|
|
32
32
|
return null;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -241,15 +241,17 @@ export const WfoProcessesList = ({
|
|
|
241
241
|
const getProcessListForExport = () =>
|
|
242
242
|
getProcessListTrigger(getQueryVariablesForExport(processListQueryVars)).unwrap();
|
|
243
243
|
|
|
244
|
+
const tableConfig = mapSortableAndFilterableValuesToTableColumnConfig(
|
|
245
|
+
tableColumns,
|
|
246
|
+
pageInfo?.sortFields,
|
|
247
|
+
pageInfo?.filterFields,
|
|
248
|
+
);
|
|
249
|
+
|
|
244
250
|
return (
|
|
245
251
|
<WfoAdvancedTable<ProcessListItem>
|
|
246
252
|
queryString={queryString}
|
|
247
253
|
data={mapGraphQlProcessListResultToProcessListItems(processes || [])}
|
|
248
|
-
tableColumnConfig={
|
|
249
|
-
tableColumns,
|
|
250
|
-
pageInfo?.sortFields,
|
|
251
|
-
pageInfo?.filterFields,
|
|
252
|
-
)}
|
|
254
|
+
tableColumnConfig={tableConfig}
|
|
253
255
|
dataSorting={[dataSorting]}
|
|
254
256
|
pagination={pagination}
|
|
255
257
|
isLoading={isFetching}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { useTranslations } from 'next-intl';
|
|
4
4
|
import Link from 'next/link';
|
|
5
5
|
|
|
6
|
-
import { EuiComment, EuiCommentList, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui';
|
|
6
|
+
import { EuiComment, EuiCommentList, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiSwitch, EuiText } from '@elastic/eui';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
PATH_TASKS,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
sortProcessesByDate,
|
|
16
16
|
} from '@/components';
|
|
17
17
|
import { useWithOrchestratorTheme } from '@/hooks';
|
|
18
|
-
import { SortOrder, SubscriptionDetailProcess } from '@/types';
|
|
18
|
+
import { SortOrder, SubscriptionDetailProcess, WorkflowTarget } from '@/types';
|
|
19
19
|
import { parseDate, parseDateToLocaleDateTimeString, upperCaseFirstChar } from '@/utils';
|
|
20
20
|
|
|
21
21
|
import { WfoProcessStatusBadge } from '../WfoBadges';
|
|
@@ -122,8 +122,9 @@ export const WfoProcessesTimeline = ({ subscriptionDetailProcesses }: WfoProcess
|
|
|
122
122
|
value: SortOrder.DESC,
|
|
123
123
|
},
|
|
124
124
|
];
|
|
125
|
-
|
|
126
|
-
const [selectedOption, setSelectedOption] =
|
|
125
|
+
const { processToggleStyles } = useWithOrchestratorTheme(getSubscriptionDetailStyles);
|
|
126
|
+
const [selectedOption, setSelectedOption] = useState(options[0]);
|
|
127
|
+
const [hideValidateTasks, setHideValidateTasks] = useState<boolean>(true);
|
|
127
128
|
|
|
128
129
|
const handleOnSelectOption = (option: WfoRadioDropdownOption<SortOrder>) => {
|
|
129
130
|
setSelectedOption(option);
|
|
@@ -135,11 +136,24 @@ export const WfoProcessesTimeline = ({ subscriptionDetailProcesses }: WfoProcess
|
|
|
135
136
|
<>
|
|
136
137
|
<EuiSpacer size={'m'} />
|
|
137
138
|
{!subscriptionDetailProcesses && <WfoLoading />}
|
|
138
|
-
<
|
|
139
|
+
<EuiFlexGroup alignItems={'center'} css={processToggleStyles}>
|
|
140
|
+
<EuiSwitch
|
|
141
|
+
showLabel={true}
|
|
142
|
+
label={t('hideValidateTasks')}
|
|
143
|
+
type="button"
|
|
144
|
+
checked={hideValidateTasks}
|
|
145
|
+
onChange={() => setHideValidateTasks((value) => !value)}
|
|
146
|
+
/>
|
|
147
|
+
<WfoRadioDropdown options={options} onUpdateOption={handleOnSelectOption} selectedOption={selectedOption} />
|
|
148
|
+
</EuiFlexGroup>
|
|
149
|
+
|
|
139
150
|
{sortedProcesses && (
|
|
140
151
|
<EuiCommentList aria-label="Processes">
|
|
141
152
|
{sortedProcesses
|
|
142
|
-
.filter(
|
|
153
|
+
.filter(
|
|
154
|
+
(process) =>
|
|
155
|
+
!process.isTask || (process.workflowTarget === WorkflowTarget.VALIDATE && !hideValidateTasks),
|
|
156
|
+
)
|
|
143
157
|
.map((subscriptionDetailProcess, index) => (
|
|
144
158
|
<WfoRenderSubscriptionProcess key={index} subscriptionDetailProcess={subscriptionDetailProcess} />
|
|
145
159
|
))}
|
|
@@ -18,7 +18,7 @@ import { PolicyResource } from '@/configuration/policy-resources';
|
|
|
18
18
|
import { useOrchestratorTheme, usePolicy } from '@/hooks';
|
|
19
19
|
import { WfoDotsHorizontal } from '@/icons/WfoDotsHorizontal';
|
|
20
20
|
import { useGetSubscriptionActionsQuery, useGetSubscriptionDetailQuery, useStartProcessMutation } from '@/rtk';
|
|
21
|
-
import { WorkflowTarget } from '@/types';
|
|
21
|
+
import { SubscriptionAction, WorkflowTarget } from '@/types';
|
|
22
22
|
|
|
23
23
|
type MenuBlockProps = {
|
|
24
24
|
title: string;
|
|
@@ -129,12 +129,28 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
129
129
|
}
|
|
130
130
|
};
|
|
131
131
|
|
|
132
|
+
const getActionItems = (workflowTarget: WorkflowTarget): SubscriptionAction[] => {
|
|
133
|
+
// Core versions 5.2 and lower return subscriptionActions result with lowercase keynames. Higher version return them uppercased to align
|
|
134
|
+
// with all the other places they are used. We support both for now. The lowercase keys are deliberately not part of the
|
|
135
|
+
// SubscriptionActions type, so the fallback is a runtime-only check behind a cast.
|
|
136
|
+
const actionsByTarget = subscriptionActions as unknown as
|
|
137
|
+
| Record<string, SubscriptionAction[] | undefined>
|
|
138
|
+
| undefined;
|
|
139
|
+
|
|
140
|
+
return actionsByTarget?.[workflowTarget] ?? actionsByTarget?.[workflowTarget.toLowerCase()] ?? [];
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const validateActionItems = getActionItems(WorkflowTarget.VALIDATE);
|
|
144
|
+
const reconcileActionItems = getActionItems(WorkflowTarget.RECONCILE);
|
|
145
|
+
const modifyActionItems = getActionItems(WorkflowTarget.MODIFY);
|
|
146
|
+
const terminateActionItems = getActionItems(WorkflowTarget.TERMINATE);
|
|
147
|
+
|
|
132
148
|
const compactItems = (
|
|
133
149
|
<>
|
|
134
|
-
{isAllowed(SUBSCRIPTION_VALIDATE + subscriptionId) &&
|
|
150
|
+
{isAllowed(SUBSCRIPTION_VALIDATE + subscriptionId) && validateActionItems.length > 0 && (
|
|
135
151
|
<>
|
|
136
152
|
{!compactMode && <MenuBlock title={t('tasks')} />}
|
|
137
|
-
{
|
|
153
|
+
{validateActionItems.map((subscriptionAction, index) => (
|
|
138
154
|
<WfoSubscriptionActionsMenuItem
|
|
139
155
|
key={`s_${index}`}
|
|
140
156
|
subscriptionAction={subscriptionAction}
|
|
@@ -148,10 +164,10 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
148
164
|
</>
|
|
149
165
|
)}
|
|
150
166
|
|
|
151
|
-
{isAllowed(SUBSCRIPTION_RECONCILE + subscriptionId) &&
|
|
167
|
+
{isAllowed(SUBSCRIPTION_RECONCILE + subscriptionId) && reconcileActionItems.length > 0 && (
|
|
152
168
|
<>
|
|
153
169
|
{!compactMode && <MenuBlock title={t('reconcile')} />}
|
|
154
|
-
{
|
|
170
|
+
{reconcileActionItems.map((subscriptionAction, index) => (
|
|
155
171
|
<WfoSubscriptionActionsMenuItem
|
|
156
172
|
key={`r_${index}`}
|
|
157
173
|
subscriptionAction={
|
|
@@ -183,10 +199,10 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
183
199
|
|
|
184
200
|
const fullItems = (
|
|
185
201
|
<>
|
|
186
|
-
{isAllowed(SUBSCRIPTION_MODIFY + subscriptionId) &&
|
|
202
|
+
{isAllowed(SUBSCRIPTION_MODIFY + subscriptionId) && modifyActionItems.length > 0 && (
|
|
187
203
|
<>
|
|
188
204
|
<MenuBlock title={t('modify')} />
|
|
189
|
-
{
|
|
205
|
+
{modifyActionItems.map((subscriptionAction, index) => (
|
|
190
206
|
<WfoSubscriptionActionsMenuItem
|
|
191
207
|
key={`m_${index}`}
|
|
192
208
|
subscriptionAction={subscriptionAction}
|
|
@@ -201,10 +217,10 @@ export const WfoSubscriptionActions: FC<WfoSubscriptionActionsProps> = ({
|
|
|
201
217
|
</>
|
|
202
218
|
)}
|
|
203
219
|
{compactItems}
|
|
204
|
-
{isAllowed(SUBSCRIPTION_TERMINATE + subscriptionId) &&
|
|
220
|
+
{isAllowed(SUBSCRIPTION_TERMINATE + subscriptionId) && terminateActionItems.length > 0 && (
|
|
205
221
|
<>
|
|
206
222
|
<MenuBlock title={t('terminate')} />
|
|
207
|
-
{
|
|
223
|
+
{terminateActionItems.map((subscriptionAction, index) => (
|
|
208
224
|
<WfoSubscriptionActionsMenuItem
|
|
209
225
|
key={`t_${index}`}
|
|
210
226
|
subscriptionAction={subscriptionAction}
|
|
@@ -67,7 +67,7 @@ export const WfoSubscriptionDetailSection = ({ subscriptionDetail }: WfoSubscrip
|
|
|
67
67
|
key: t('lastRunValidation'),
|
|
68
68
|
value: (() => {
|
|
69
69
|
const lastValidate = processes?.page
|
|
70
|
-
?.filter((process) => process.workflowTarget
|
|
70
|
+
?.filter((process) => process.workflowTarget === WorkflowTarget.VALIDATE)
|
|
71
71
|
.slice(-1)[0];
|
|
72
72
|
|
|
73
73
|
if (!lastValidate) {
|
|
@@ -54,6 +54,11 @@ export const getSubscriptionDetailStyles = ({ theme, isDarkModeActive }: WfoThem
|
|
|
54
54
|
flexDirection: 'column',
|
|
55
55
|
alignItems: 'flex-start',
|
|
56
56
|
});
|
|
57
|
+
|
|
58
|
+
const processToggleStyles = css({
|
|
59
|
+
justifySelf: 'flex-end',
|
|
60
|
+
});
|
|
61
|
+
|
|
57
62
|
return {
|
|
58
63
|
rowStyle,
|
|
59
64
|
labelCellStyle,
|
|
@@ -66,5 +71,6 @@ export const getSubscriptionDetailStyles = ({ theme, isDarkModeActive }: WfoThem
|
|
|
66
71
|
productBlockTreeWidth,
|
|
67
72
|
customerDescriptionsCustomerNameStyle,
|
|
68
73
|
customerDescriptionsFormStyle,
|
|
74
|
+
processToggleStyles,
|
|
69
75
|
};
|
|
70
76
|
};
|
|
@@ -59,8 +59,7 @@ export const flattenSubscriptionActionProps = (action?: SubscriptionAction | nul
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
export const getWorkflowTargetColor = (workflowTarget: WorkflowTarget, theme: EuiThemeComputed) => {
|
|
62
|
-
|
|
63
|
-
switch (workflowTarget.toLocaleLowerCase()) {
|
|
62
|
+
switch (workflowTarget) {
|
|
64
63
|
case WorkflowTarget.CREATE:
|
|
65
64
|
return theme.colors.textSuccess;
|
|
66
65
|
case WorkflowTarget.MODIFY:
|
|
@@ -78,8 +77,7 @@ export const getWorkflowTargetColor = (workflowTarget: WorkflowTarget, theme: Eu
|
|
|
78
77
|
};
|
|
79
78
|
|
|
80
79
|
export const getWorkflowTargetIconContent = (workflowTarget: WorkflowTarget) => {
|
|
81
|
-
|
|
82
|
-
switch (workflowTarget.toLocaleLowerCase()) {
|
|
80
|
+
switch (workflowTarget) {
|
|
83
81
|
case WorkflowTarget.CREATE:
|
|
84
82
|
return 'C';
|
|
85
83
|
case WorkflowTarget.SYSTEM:
|
|
@@ -19,7 +19,6 @@ export const WfoExpandingSearchRow = ({ score, matchingFields }: WfoExpandingSea
|
|
|
19
19
|
|
|
20
20
|
if (!matchingFields || matchingFields.length === 0) return null;
|
|
21
21
|
|
|
22
|
-
// Note: The row is shown on hover by the row above is as configured in the table component expandableRow config
|
|
23
22
|
return (
|
|
24
23
|
<tr css={hideExpandedRowStyle}>
|
|
25
24
|
<td colSpan={999} css={expandingSearchRowStyles}>
|
|
@@ -3,7 +3,16 @@ import type { RuleGroupType } from 'react-querybuilder';
|
|
|
3
3
|
|
|
4
4
|
import { useTranslations } from 'next-intl';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
EuiButton,
|
|
8
|
+
EuiFlexGroup,
|
|
9
|
+
EuiFlexItem,
|
|
10
|
+
EuiFormRow,
|
|
11
|
+
EuiSelect,
|
|
12
|
+
EuiSpacer,
|
|
13
|
+
EuiSwitch,
|
|
14
|
+
EuiText,
|
|
15
|
+
} from '@elastic/eui';
|
|
7
16
|
|
|
8
17
|
import {
|
|
9
18
|
DEFAULT_PAGE_SIZE,
|
|
@@ -70,6 +79,7 @@ export type WfoStructuredSearchTableProps<T extends object> = Omit<
|
|
|
70
79
|
tableColumnConfig: WfoStructuredSearchTableColumnConfig<T>;
|
|
71
80
|
rowExpandingConfiguration: WfoTableProps<T>['rowExpandingConfiguration'];
|
|
72
81
|
defaultHiddenColumns?: TableColumnKeys<T>;
|
|
82
|
+
defaultShowMatchDetails?: boolean;
|
|
73
83
|
queryText?: string;
|
|
74
84
|
localStorageKey: string;
|
|
75
85
|
exportDataIsLoading?: boolean;
|
|
@@ -100,6 +110,7 @@ export type WfoStructuredSearchTableProps<T extends object> = Omit<
|
|
|
100
110
|
export const WfoStructuredSearchTable = <T extends object>({
|
|
101
111
|
tableColumnConfig,
|
|
102
112
|
defaultHiddenColumns = [],
|
|
113
|
+
defaultShowMatchDetails = false,
|
|
103
114
|
queryText,
|
|
104
115
|
localStorageKey,
|
|
105
116
|
exportDataIsLoading,
|
|
@@ -136,6 +147,7 @@ export const WfoStructuredSearchTable = <T extends object>({
|
|
|
136
147
|
const [showTableSettingsModal, setShowTableSettingsModal] = useState(false);
|
|
137
148
|
const [rowDetailModalData, setRowDetailModalData] = useState<T | undefined>(undefined);
|
|
138
149
|
const [showInformationModal, setShowInformationModal] = useState(false);
|
|
150
|
+
const [showMatchDetails, setShowMatchDetails] = useState(defaultShowMatchDetails);
|
|
139
151
|
const t = useTranslations('common');
|
|
140
152
|
|
|
141
153
|
useEffect(() => {
|
|
@@ -144,6 +156,10 @@ export const WfoStructuredSearchTable = <T extends object>({
|
|
|
144
156
|
}
|
|
145
157
|
}, [defaultHiddenColumns]);
|
|
146
158
|
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
setShowMatchDetails(defaultShowMatchDetails);
|
|
161
|
+
}, [defaultShowMatchDetails]);
|
|
162
|
+
|
|
147
163
|
useEffect(() => {
|
|
148
164
|
if (filterString) {
|
|
149
165
|
setIsFilterBuilderVisible(true);
|
|
@@ -182,6 +198,18 @@ export const WfoStructuredSearchTable = <T extends object>({
|
|
|
182
198
|
setTableConfigToLocalStorage(localStorageKey, {
|
|
183
199
|
hiddenColumns: updatedHiddenColumns,
|
|
184
200
|
selectedPageSize: updatedTableConfig.selectedPageSize,
|
|
201
|
+
showMatchDetails,
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// The toggle applies live, so persist it immediately alongside the currently committed
|
|
206
|
+
// hidden columns and page size instead of waiting for the modal's "Update" action.
|
|
207
|
+
const handleToggleShowMatchDetails = (checked: boolean) => {
|
|
208
|
+
setShowMatchDetails(checked);
|
|
209
|
+
setTableConfigToLocalStorage(localStorageKey, {
|
|
210
|
+
hiddenColumns,
|
|
211
|
+
selectedPageSize: pageSize ?? DEFAULT_PAGE_SIZE,
|
|
212
|
+
showMatchDetails: checked,
|
|
185
213
|
});
|
|
186
214
|
};
|
|
187
215
|
|
|
@@ -189,6 +217,7 @@ export const WfoStructuredSearchTable = <T extends object>({
|
|
|
189
217
|
const defaultTableConfig = getDefaultTableConfig<T>(localStorageKey);
|
|
190
218
|
setHiddenColumns(defaultTableConfig.hiddenColumns);
|
|
191
219
|
setPageSize(defaultTableConfig.selectedPageSize);
|
|
220
|
+
setShowMatchDetails(defaultTableConfig.showMatchDetails ?? false);
|
|
192
221
|
setShowTableSettingsModal(false);
|
|
193
222
|
clearTableConfigFromLocalStorage(localStorageKey);
|
|
194
223
|
};
|
|
@@ -255,6 +284,7 @@ export const WfoStructuredSearchTable = <T extends object>({
|
|
|
255
284
|
columnConfig={tableColumnsWithControlColumns}
|
|
256
285
|
hiddenColumns={hiddenColumns}
|
|
257
286
|
rowExpandingConfiguration={rowExpandingConfiguration}
|
|
287
|
+
showExpandedRows={showMatchDetails}
|
|
258
288
|
onUpdateDataSorting={onUpdateDataSorting}
|
|
259
289
|
onUpdateDataSearch={handleColumnFilterSearch}
|
|
260
290
|
dataSorting={dataSorting}
|
|
@@ -284,6 +314,15 @@ export const WfoStructuredSearchTable = <T extends object>({
|
|
|
284
314
|
onResetToDefaults={handleResetToDefaults}
|
|
285
315
|
extraSettings={
|
|
286
316
|
<>
|
|
317
|
+
<EuiFormRow label={t('showMatchDetails')} display="columnCompressed">
|
|
318
|
+
<EuiSwitch
|
|
319
|
+
showLabel={false}
|
|
320
|
+
label={t('showMatchDetails')}
|
|
321
|
+
checked={showMatchDetails}
|
|
322
|
+
onChange={(event) => handleToggleShowMatchDetails(event.target.checked)}
|
|
323
|
+
compressed
|
|
324
|
+
/>
|
|
325
|
+
</EuiFormRow>
|
|
287
326
|
<EuiFormRow label={t('retrieval')} display="columnCompressed">
|
|
288
327
|
<EuiSelect
|
|
289
328
|
options={[
|
|
@@ -2,7 +2,7 @@ import { css } from '@emotion/react';
|
|
|
2
2
|
|
|
3
3
|
import { WfoThemeHelpers } from '@/hooks';
|
|
4
4
|
|
|
5
|
-
export const getWfoStructuredSearchTableStyles = ({ theme }: WfoThemeHelpers) => {
|
|
5
|
+
export const getWfoStructuredSearchTableStyles = ({ theme, isDarkModeActive }: WfoThemeHelpers) => {
|
|
6
6
|
const queryBuilderContainerStyles = css({
|
|
7
7
|
backgroundColor: theme.colors.backgroundBaseSubdued,
|
|
8
8
|
padding: theme.base / 2,
|
|
@@ -63,7 +63,7 @@ export const getWfoStructuredSearchTableStyles = ({ theme }: WfoThemeHelpers) =>
|
|
|
63
63
|
const ruleGroupContainerBlueStyles = css({
|
|
64
64
|
...ruleGroupContainerBase,
|
|
65
65
|
borderRadius: theme.border.radius.small,
|
|
66
|
-
backgroundColor: '#E9F1F9',
|
|
66
|
+
backgroundColor: isDarkModeActive ? theme.colors.backgroundLightPrimary : '#E9F1F9',
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
const ruleGroupContainerWhiteStyles = css({
|
|
@@ -83,7 +83,7 @@ export const getWfoStructuredSearchTableStyles = ({ theme }: WfoThemeHelpers) =>
|
|
|
83
83
|
...ruleGroupContainerBase,
|
|
84
84
|
borderBottomLeftRadius: theme.border.radius.small,
|
|
85
85
|
borderTopLeftRadius: theme.border.radius.small,
|
|
86
|
-
backgroundColor: '#E9F1F9',
|
|
86
|
+
backgroundColor: isDarkModeActive ? theme.colors.backgroundLightPrimary : '#E9F1F9',
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
const removeGroupActionStyles = css({
|
|
@@ -99,11 +99,10 @@ export const getWfoStructuredSearchTableStyles = ({ theme }: WfoThemeHelpers) =>
|
|
|
99
99
|
});
|
|
100
100
|
|
|
101
101
|
const expandingSearchRowStyles = css({
|
|
102
|
-
padding: theme.base / 2
|
|
103
|
-
height: theme.base * 2,
|
|
102
|
+
padding: `${theme.base / 4}px ${theme.base / 2}px`,
|
|
104
103
|
borderRadius: theme.border.radius.medium,
|
|
105
|
-
border:
|
|
106
|
-
backgroundColor:
|
|
104
|
+
border: `thin solid ${theme.colors.highlight}`,
|
|
105
|
+
backgroundColor: theme.colors.highlight,
|
|
107
106
|
});
|
|
108
107
|
const expandingRowBodyStyles = css({
|
|
109
108
|
display: 'flex',
|
|
@@ -166,12 +165,12 @@ export const getWfoStructuredSearchTableStyles = ({ theme }: WfoThemeHelpers) =>
|
|
|
166
165
|
display: 'none',
|
|
167
166
|
});
|
|
168
167
|
const dotStyles = css({
|
|
169
|
-
padding: theme.base / 4
|
|
168
|
+
padding: `${theme.base / 8}px ${theme.base / 4}px`,
|
|
170
169
|
});
|
|
171
170
|
|
|
172
171
|
const expandingRowFieldStyles = css({
|
|
173
172
|
display: 'flex',
|
|
174
|
-
padding: theme.base / 4
|
|
173
|
+
padding: `${theme.base / 8}px ${theme.base / 4}px`,
|
|
175
174
|
alignItems: 'center',
|
|
176
175
|
});
|
|
177
176
|
|
|
@@ -82,8 +82,9 @@ export type WfoTableProps<T extends object> = {
|
|
|
82
82
|
rowExpandingConfiguration?: {
|
|
83
83
|
uniqueRowId: keyof WfoTableColumnConfig<T>;
|
|
84
84
|
uniqueRowIdToExpandedRowMap: Record<string, ReactNode>;
|
|
85
|
-
shouldOnlyShowOnHover?: boolean;
|
|
86
85
|
};
|
|
86
|
+
// When true, every row's expanded detail row is revealed at once (otherwise all are hidden)
|
|
87
|
+
showExpandedRows?: boolean;
|
|
87
88
|
pagination?: Pagination;
|
|
88
89
|
overrideHeader?: (
|
|
89
90
|
tableHeaderEntries: Array<[string, WfoTableControlColumnConfigItem<T> | WfoTableDataColumnConfigItem<T, keyof T>]>,
|
|
@@ -107,6 +108,7 @@ export const WfoTable = <T extends object>({
|
|
|
107
108
|
isLoading = false,
|
|
108
109
|
dataSorting = [],
|
|
109
110
|
rowExpandingConfiguration,
|
|
111
|
+
showExpandedRows = false,
|
|
110
112
|
pagination,
|
|
111
113
|
overrideHeader,
|
|
112
114
|
onUpdateDataSorting,
|
|
@@ -236,6 +238,7 @@ export const WfoTable = <T extends object>({
|
|
|
236
238
|
hiddenColumns={hiddenColumns}
|
|
237
239
|
columnOrder={columnOrder}
|
|
238
240
|
rowExpandingConfiguration={rowExpandingConfiguration}
|
|
241
|
+
showExpandedRows={showExpandedRows}
|
|
239
242
|
onRowClick={onRowClick}
|
|
240
243
|
/>
|
|
241
244
|
))}
|
|
@@ -252,6 +255,7 @@ export const WfoTable = <T extends object>({
|
|
|
252
255
|
hiddenColumns={hiddenColumns}
|
|
253
256
|
columnOrder={columnOrder}
|
|
254
257
|
rowExpandingConfiguration={rowExpandingConfiguration}
|
|
258
|
+
showExpandedRows={showExpandedRows}
|
|
255
259
|
onRowClick={onRowClick}
|
|
256
260
|
/>
|
|
257
261
|
</tbody>
|
|
@@ -11,7 +11,14 @@ import { getSortedVisibleColumns } from './utils';
|
|
|
11
11
|
|
|
12
12
|
export type WfoTableDataRowsProps<T extends object> = Pick<
|
|
13
13
|
WfoTableProps<T>,
|
|
14
|
-
|
|
14
|
+
| 'data'
|
|
15
|
+
| 'columnConfig'
|
|
16
|
+
| 'hiddenColumns'
|
|
17
|
+
| 'columnOrder'
|
|
18
|
+
| 'rowExpandingConfiguration'
|
|
19
|
+
| 'showExpandedRows'
|
|
20
|
+
| 'onRowClick'
|
|
21
|
+
| 'className'
|
|
15
22
|
>;
|
|
16
23
|
|
|
17
24
|
export const DATA_ROW_CLASS = 'data-row';
|
|
@@ -24,6 +31,7 @@ export const WfoTableDataRows = <T extends object>({
|
|
|
24
31
|
hiddenColumns = [],
|
|
25
32
|
columnOrder = [],
|
|
26
33
|
rowExpandingConfiguration,
|
|
34
|
+
showExpandedRows,
|
|
27
35
|
onRowClick,
|
|
28
36
|
className,
|
|
29
37
|
}: WfoTableDataRowsProps<T>) => {
|
|
@@ -34,6 +42,7 @@ export const WfoTableDataRows = <T extends object>({
|
|
|
34
42
|
dataRowStyle,
|
|
35
43
|
clickableStyle,
|
|
36
44
|
setWidth,
|
|
45
|
+
showExpandedRowStyle,
|
|
37
46
|
toggleExpandedRowOnHoverStyle,
|
|
38
47
|
} = useWithOrchestratorTheme(getWfoTableStyles);
|
|
39
48
|
|
|
@@ -49,7 +58,7 @@ export const WfoTableDataRows = <T extends object>({
|
|
|
49
58
|
rowStyle,
|
|
50
59
|
dataRowStyle,
|
|
51
60
|
onRowClick && clickableStyle,
|
|
52
|
-
rowExpandingConfiguration
|
|
61
|
+
rowExpandingConfiguration && (showExpandedRows ? showExpandedRowStyle : toggleExpandedRowOnHoverStyle),
|
|
53
62
|
]}
|
|
54
63
|
onClick={() => onRowClick?.(row)}
|
|
55
64
|
>
|