@orchestrator-ui/orchestrator-ui-components 8.4.4 → 8.5.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 +17 -0
- package/dist/index.d.ts +1890 -562
- package/dist/index.js +3814 -2103
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/src/components/WfoPydanticForm/WfoPydanticForm.tsx +23 -1
- package/src/components/WfoSearchBar/WfoSearchField.tsx +0 -1
- package/src/components/WfoSearchPage/WfoFilterGroup/WfoFilterGroup.tsx +5 -5
- package/src/components/WfoSearchPage/WfoSearch/WfoSearch.tsx +12 -5
- package/src/components/WfoSearchPage/constants.ts +0 -4
- package/src/components/WfoSearchPage/utils.ts +75 -20
- package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionExpandableMenuItem.tsx +36 -18
- package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionsMenuItem.tsx +38 -2
- package/src/components/WfoSubscription/utils/index.ts +3 -0
- package/src/components/WfoSubscription/utils/utils.spec.ts +39 -4
- package/src/components/WfoSubscription/utils/utils.ts +10 -4
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoAddGroupAction.tsx +19 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoAddRuleAction.tsx +23 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoCombinatorSelector.tsx +30 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoExpandingSearchRow.tsx +38 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoFieldSelector.tsx +84 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoFilterBuilder.tsx +189 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoOperatorSelector.tsx +33 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoRangeEditor.tsx +64 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoRemoveGroupAction.tsx +21 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoRemoveRuleAction.tsx +20 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoRule.tsx +16 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoRuleGroup.tsx +73 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoStructuredSearchTable.tsx +323 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoValueEditor.tsx +159 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/index.ts +2 -0
- package/src/components/WfoTable/WfoStructuredSearchTable/styles.ts +146 -0
- package/src/components/WfoTable/WfoTable/WfoDragHandler.tsx +4 -2
- package/src/components/WfoTable/index.ts +2 -6
- package/src/components/WfoTitleWithWebsocketBadge/WfoTitleWithWebsocketBadge.tsx +14 -6
- package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +1 -0
- package/src/components/WfoWorkflowSteps/WfoStepList/WfoStepList.tsx +3 -0
- package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoWorkflowStepList.tsx +32 -12
- package/src/components/WfoWorkflowUserGuide/WfoPageWithUserGuide.tsx +38 -0
- package/src/components/WfoWorkflowUserGuide/WfoWorkflowGuideExpandablePanel.tsx +151 -0
- package/src/components/WfoWorkflowUserGuide/index.ts +2 -0
- package/src/components/WfoWorkflowUserGuide/styles.ts +87 -0
- package/src/components/index.ts +1 -0
- package/src/configuration/version.ts +1 -1
- package/src/contexts/OrchestratorConfigContext.tsx +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/usePathAutoComplete.ts +3 -4
- package/src/hooks/useSearch.ts +20 -15
- package/src/hooks/useSearchPagination.ts +11 -8
- package/src/hooks/useUrlParams.ts +3 -5
- package/src/icons/WfoTrashFilled.tsx +13 -0
- package/src/icons/WfoXMarkSmall.tsx +2 -2
- package/src/icons/index.ts +1 -0
- package/src/messages/en-GB.json +94 -8
- package/src/messages/nl-NL.json +23 -5
- package/src/pages/WfoSearchPocPage.tsx +402 -0
- package/src/pages/index.ts +1 -0
- package/src/pages/processes/WfoProcessDetail.tsx +10 -10
- package/src/pages/processes/WfoProcessDetailPage.tsx +1 -0
- package/src/pages/processes/WfoStartProcessPage.tsx +15 -19
- package/src/rtk/api.ts +1 -0
- package/src/rtk/endpoints/index.ts +1 -0
- package/src/rtk/endpoints/search.ts +45 -10
- package/src/rtk/endpoints/workflowGuides.ts +25 -0
- package/src/types/search.ts +21 -5
- package/src/types/types.ts +10 -1
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import type { RuleGroupType } from 'react-querybuilder';
|
|
3
|
+
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
EuiButton,
|
|
8
|
+
EuiButtonIcon,
|
|
9
|
+
EuiFieldSearch,
|
|
10
|
+
EuiFlexGroup,
|
|
11
|
+
EuiFlexItem,
|
|
12
|
+
EuiFormRow,
|
|
13
|
+
EuiSelect,
|
|
14
|
+
EuiSpacer,
|
|
15
|
+
EuiText,
|
|
16
|
+
} from '@elastic/eui';
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
DEFAULT_PAGE_SIZE,
|
|
20
|
+
DEFAULT_PAGE_SIZES,
|
|
21
|
+
TableColumnKeys,
|
|
22
|
+
TableSettingsColumnConfig,
|
|
23
|
+
TableSettingsConfig,
|
|
24
|
+
TableSettingsModal,
|
|
25
|
+
WfoDataSorting,
|
|
26
|
+
WfoErrorWithMessage,
|
|
27
|
+
WfoInformationModal,
|
|
28
|
+
WfoKeyValueTable,
|
|
29
|
+
WfoKeyValueTableDataType,
|
|
30
|
+
clearTableConfigFromLocalStorage,
|
|
31
|
+
setTableConfigToLocalStorage,
|
|
32
|
+
} from '@/components';
|
|
33
|
+
import { getRowDetailData } from '@/components/WfoTable/WfoAdvancedTable/getRowDetailData';
|
|
34
|
+
import {
|
|
35
|
+
WfoTableControlColumnConfig,
|
|
36
|
+
WfoTableControlColumnConfigItem,
|
|
37
|
+
WfoTableDataColumnConfigItem,
|
|
38
|
+
} from '@/components/WfoTable/WfoTable';
|
|
39
|
+
import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
|
|
40
|
+
import { WfoArrowsExpand } from '@/icons';
|
|
41
|
+
import { WfoGraphqlError } from '@/rtk';
|
|
42
|
+
import { getFormFieldsBaseStyle } from '@/theme';
|
|
43
|
+
import { RetrieverType } from '@/types';
|
|
44
|
+
import { getDefaultTableConfig } from '@/utils';
|
|
45
|
+
|
|
46
|
+
import { ColumnType, WfoTable, WfoTableProps } from '../WfoTable';
|
|
47
|
+
import { WfoFilterBuilder } from './WfoFilterBuilder';
|
|
48
|
+
|
|
49
|
+
export type WfoStructuredSearchTableDataColumnConfigItem<
|
|
50
|
+
T extends object,
|
|
51
|
+
Property extends keyof T,
|
|
52
|
+
> = WfoTableDataColumnConfigItem<T, Property> & {
|
|
53
|
+
renderDetails?: (cellValue: T[Property], row: T) => React.ReactNode;
|
|
54
|
+
clipboardText?: (cellValue: T[Property], row: T) => string;
|
|
55
|
+
};
|
|
56
|
+
export type WfoStructuredSearchTableDataColumnConfig<T extends object> = {
|
|
57
|
+
[Property in keyof T]: WfoStructuredSearchTableDataColumnConfigItem<T, Property> | WfoTableControlColumnConfigItem<T>;
|
|
58
|
+
};
|
|
59
|
+
export type WfoStructuredSearchTableColumnConfig<T extends object> = Partial<
|
|
60
|
+
WfoTableControlColumnConfig<T> | WfoStructuredSearchTableDataColumnConfig<T>
|
|
61
|
+
>;
|
|
62
|
+
export type SearchParams = {
|
|
63
|
+
queryText?: string | false;
|
|
64
|
+
retrieverType?: RetrieverType;
|
|
65
|
+
ruleGroup?: RuleGroupType | false;
|
|
66
|
+
limit?: number;
|
|
67
|
+
sortBy?: {
|
|
68
|
+
field: string;
|
|
69
|
+
sortOrder: string;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type WfoStructuredSearchTableProps<T extends object> = Omit<
|
|
74
|
+
WfoTableProps<T>,
|
|
75
|
+
'columnConfig' | 'onUpdateDataSearch'
|
|
76
|
+
> & {
|
|
77
|
+
tableColumnConfig: WfoStructuredSearchTableColumnConfig<T>;
|
|
78
|
+
rowExpandingConfiguration: WfoTableProps<T>['rowExpandingConfiguration'];
|
|
79
|
+
defaultHiddenColumns?: TableColumnKeys<T>;
|
|
80
|
+
queryText?: string;
|
|
81
|
+
localStorageKey: string;
|
|
82
|
+
exportDataIsLoading?: boolean;
|
|
83
|
+
error?: WfoGraphqlError[];
|
|
84
|
+
onChangeQueryText: (queryString: string) => void;
|
|
85
|
+
onSearchQueryText: (queryString: string) => void;
|
|
86
|
+
onShowMore: () => void;
|
|
87
|
+
onUpdateDataSorting: (updateSorting: WfoDataSorting<T>) => void;
|
|
88
|
+
onExportData?: () => void;
|
|
89
|
+
retrieverType: RetrieverType;
|
|
90
|
+
onUpdateRetrieverType: (newRetrieverType: RetrieverType) => void;
|
|
91
|
+
filterString?: string;
|
|
92
|
+
onUpdateFilterString: (filterString: string) => void;
|
|
93
|
+
isValidFilterString?: boolean;
|
|
94
|
+
queryBuilderRuleGroup?: RuleGroupType;
|
|
95
|
+
onUpdateQueryBuilder: (ruleGroup: RuleGroupType | false) => void;
|
|
96
|
+
handleSearch: () => void;
|
|
97
|
+
pageSize: number;
|
|
98
|
+
setPageSize: React.Dispatch<React.SetStateAction<number>>;
|
|
99
|
+
totalItems: number | false;
|
|
100
|
+
hasNextPage: boolean;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const WfoStructuredSearchTable = <T extends object>({
|
|
104
|
+
tableColumnConfig,
|
|
105
|
+
defaultHiddenColumns = [],
|
|
106
|
+
queryText,
|
|
107
|
+
localStorageKey,
|
|
108
|
+
exportDataIsLoading,
|
|
109
|
+
error,
|
|
110
|
+
onChangeQueryText,
|
|
111
|
+
onSearchQueryText,
|
|
112
|
+
onShowMore,
|
|
113
|
+
onExportData,
|
|
114
|
+
retrieverType,
|
|
115
|
+
onUpdateRetrieverType,
|
|
116
|
+
filterString,
|
|
117
|
+
onUpdateFilterString,
|
|
118
|
+
isValidFilterString,
|
|
119
|
+
queryBuilderRuleGroup,
|
|
120
|
+
onUpdateQueryBuilder,
|
|
121
|
+
onUpdateDataSorting,
|
|
122
|
+
handleSearch,
|
|
123
|
+
pageSize,
|
|
124
|
+
setPageSize,
|
|
125
|
+
totalItems,
|
|
126
|
+
rowExpandingConfiguration,
|
|
127
|
+
dataSorting,
|
|
128
|
+
hasNextPage,
|
|
129
|
+
data,
|
|
130
|
+
isLoading,
|
|
131
|
+
...tableProps
|
|
132
|
+
}: WfoStructuredSearchTableProps<T>) => {
|
|
133
|
+
const { theme } = useOrchestratorTheme();
|
|
134
|
+
const { formFieldBaseStyle } = useWithOrchestratorTheme(getFormFieldsBaseStyle);
|
|
135
|
+
|
|
136
|
+
const [hiddenColumns, setHiddenColumns] = useState<TableColumnKeys<T>>(defaultHiddenColumns);
|
|
137
|
+
const [showTableSettingsModal, setShowTableSettingsModal] = useState(false);
|
|
138
|
+
const [rowDetailModalData, setRowDetailModalData] = useState<T | undefined>(undefined);
|
|
139
|
+
const [showInformationModal, setShowInformationModal] = useState(false);
|
|
140
|
+
const t = useTranslations('common');
|
|
141
|
+
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (defaultHiddenColumns) {
|
|
144
|
+
setHiddenColumns(defaultHiddenColumns);
|
|
145
|
+
}
|
|
146
|
+
}, [defaultHiddenColumns]);
|
|
147
|
+
|
|
148
|
+
const detailsIconColumn: WfoStructuredSearchTableColumnConfig<T> = {
|
|
149
|
+
viewDetails: {
|
|
150
|
+
columnType: ColumnType.CONTROL,
|
|
151
|
+
width: '36px',
|
|
152
|
+
renderControl: (row) => (
|
|
153
|
+
<EuiFlexItem css={{ cursor: 'pointer' }} onClick={() => setRowDetailModalData(row)}>
|
|
154
|
+
<WfoArrowsExpand color={theme.colors.borderBasePlain} />
|
|
155
|
+
</EuiFlexItem>
|
|
156
|
+
),
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const tableColumnsWithControlColumns: WfoStructuredSearchTableColumnConfig<T> = {
|
|
161
|
+
...detailsIconColumn,
|
|
162
|
+
...tableColumnConfig,
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const tableSettingsColumns: TableSettingsColumnConfig<T>[] = Object.entries(tableColumnConfig).map(
|
|
166
|
+
([key, { label }]): TableSettingsColumnConfig<T> => {
|
|
167
|
+
const field = key as keyof T;
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
field,
|
|
171
|
+
name: label,
|
|
172
|
+
isVisible: hiddenColumns.indexOf(field) === -1,
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const rowDetailData: WfoKeyValueTableDataType[] | undefined =
|
|
178
|
+
rowDetailModalData && getRowDetailData(rowDetailModalData, tableColumnConfig);
|
|
179
|
+
|
|
180
|
+
const handleUpdateTableConfig = (updatedTableConfig: TableSettingsConfig<T>) => {
|
|
181
|
+
const updatedHiddenColumns = updatedTableConfig.columns
|
|
182
|
+
.filter((column) => !column.isVisible)
|
|
183
|
+
.map((hiddenColumn) => hiddenColumn.field);
|
|
184
|
+
setHiddenColumns(updatedHiddenColumns);
|
|
185
|
+
setShowTableSettingsModal(false);
|
|
186
|
+
setPageSize(updatedTableConfig.selectedPageSize);
|
|
187
|
+
setTableConfigToLocalStorage(localStorageKey, {
|
|
188
|
+
hiddenColumns: updatedHiddenColumns,
|
|
189
|
+
selectedPageSize: updatedTableConfig.selectedPageSize,
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const handleResetToDefaults = () => {
|
|
194
|
+
const defaultTableConfig = getDefaultTableConfig<T>(localStorageKey);
|
|
195
|
+
setHiddenColumns(defaultTableConfig.hiddenColumns);
|
|
196
|
+
setPageSize(defaultTableConfig.selectedPageSize);
|
|
197
|
+
setShowTableSettingsModal(false);
|
|
198
|
+
clearTableConfigFromLocalStorage(localStorageKey);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<>
|
|
203
|
+
<EuiFlexGroup alignItems="center">
|
|
204
|
+
<EuiFlexItem>
|
|
205
|
+
<WfoFilterBuilder
|
|
206
|
+
filterString={filterString}
|
|
207
|
+
onUpdateFilterString={onUpdateFilterString}
|
|
208
|
+
isValidFilterString={isValidFilterString}
|
|
209
|
+
queryBuilderRuleGroup={queryBuilderRuleGroup}
|
|
210
|
+
onUpdateQueryBuilder={onUpdateQueryBuilder}
|
|
211
|
+
handleSearch={handleSearch}
|
|
212
|
+
/>
|
|
213
|
+
</EuiFlexItem>
|
|
214
|
+
</EuiFlexGroup>
|
|
215
|
+
|
|
216
|
+
<EuiFlexGroup alignItems="center">
|
|
217
|
+
<EuiFlexItem>
|
|
218
|
+
<EuiFormRow fullWidth>
|
|
219
|
+
<EuiFieldSearch
|
|
220
|
+
css={formFieldBaseStyle}
|
|
221
|
+
value={queryText}
|
|
222
|
+
placeholder={`${t('search')}...`}
|
|
223
|
+
onChange={(e) => onChangeQueryText(e.target.value)}
|
|
224
|
+
onSearch={(queryText) => onSearchQueryText(queryText)}
|
|
225
|
+
fullWidth
|
|
226
|
+
/>
|
|
227
|
+
</EuiFormRow>
|
|
228
|
+
</EuiFlexItem>
|
|
229
|
+
<EuiFlexItem grow={false}>
|
|
230
|
+
<EuiSelect
|
|
231
|
+
options={[
|
|
232
|
+
{
|
|
233
|
+
value: RetrieverType.Auto,
|
|
234
|
+
text: t('retrieverAuto'),
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
value: RetrieverType.Fuzzy,
|
|
238
|
+
text: t('retrieverFuzzy'),
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
value: RetrieverType.Semantic,
|
|
242
|
+
text: t('retrieverSemantic'),
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
value: RetrieverType.Hybrid,
|
|
246
|
+
text: t('retrieverHybrid'),
|
|
247
|
+
},
|
|
248
|
+
]}
|
|
249
|
+
value={retrieverType}
|
|
250
|
+
onChange={(e) => onUpdateRetrieverType(e.target.value as RetrieverType)}
|
|
251
|
+
compressed
|
|
252
|
+
prepend={t('retrieval')}
|
|
253
|
+
/>
|
|
254
|
+
</EuiFlexItem>
|
|
255
|
+
<EuiFlexItem grow={false}>
|
|
256
|
+
<EuiButtonIcon
|
|
257
|
+
onClick={() => setShowInformationModal(true)}
|
|
258
|
+
iconSize={'l'}
|
|
259
|
+
iconType={'info'}
|
|
260
|
+
aria-label={t('searchModalTitle')}
|
|
261
|
+
/>
|
|
262
|
+
</EuiFlexItem>
|
|
263
|
+
<EuiButton onClick={() => setShowTableSettingsModal(true)}>{t('editColumns')}</EuiButton>
|
|
264
|
+
{onExportData && (
|
|
265
|
+
<EuiButton isLoading={exportDataIsLoading} onClick={() => onExportData()}>
|
|
266
|
+
{t('export')}
|
|
267
|
+
</EuiButton>
|
|
268
|
+
)}
|
|
269
|
+
</EuiFlexGroup>
|
|
270
|
+
|
|
271
|
+
{error && <WfoErrorWithMessage error={error} />}
|
|
272
|
+
|
|
273
|
+
<EuiSpacer size="m" />
|
|
274
|
+
|
|
275
|
+
<WfoTable<T>
|
|
276
|
+
columnConfig={tableColumnsWithControlColumns}
|
|
277
|
+
hiddenColumns={hiddenColumns}
|
|
278
|
+
rowExpandingConfiguration={rowExpandingConfiguration}
|
|
279
|
+
onUpdateDataSorting={onUpdateDataSorting}
|
|
280
|
+
dataSorting={dataSorting}
|
|
281
|
+
data={data}
|
|
282
|
+
isLoading={isLoading}
|
|
283
|
+
{...tableProps}
|
|
284
|
+
/>
|
|
285
|
+
|
|
286
|
+
{totalItems && (
|
|
287
|
+
<EuiFlexGroup alignItems={'center'} justifyContent={'center'} css={{ padding: theme.base }}>
|
|
288
|
+
<EuiButton onClick={() => onShowMore()} disabled={!hasNextPage || isLoading}>
|
|
289
|
+
{t('loadMore')}
|
|
290
|
+
</EuiButton>
|
|
291
|
+
<div>{`${data.length}/${totalItems} records`}</div>
|
|
292
|
+
</EuiFlexGroup>
|
|
293
|
+
)}
|
|
294
|
+
|
|
295
|
+
{showTableSettingsModal && (
|
|
296
|
+
<TableSettingsModal
|
|
297
|
+
tableConfig={{
|
|
298
|
+
columns: tableSettingsColumns,
|
|
299
|
+
selectedPageSize: pageSize ?? DEFAULT_PAGE_SIZE,
|
|
300
|
+
}}
|
|
301
|
+
pageSizeOptions={DEFAULT_PAGE_SIZES}
|
|
302
|
+
onClose={() => setShowTableSettingsModal(false)}
|
|
303
|
+
onUpdateTableConfig={handleUpdateTableConfig}
|
|
304
|
+
onResetToDefaults={handleResetToDefaults}
|
|
305
|
+
/>
|
|
306
|
+
)}
|
|
307
|
+
|
|
308
|
+
{showInformationModal && (
|
|
309
|
+
<WfoInformationModal title={t('searchModalTitle')} onClose={() => setShowInformationModal(false)}>
|
|
310
|
+
<EuiText>
|
|
311
|
+
<p>TODO: Info about searching</p>
|
|
312
|
+
</EuiText>
|
|
313
|
+
</WfoInformationModal>
|
|
314
|
+
)}
|
|
315
|
+
|
|
316
|
+
{rowDetailData && (
|
|
317
|
+
<WfoInformationModal title={'TODO: Information modal title'} onClose={() => setRowDetailModalData(undefined)}>
|
|
318
|
+
<WfoKeyValueTable keyValues={rowDetailData} showCopyToClipboardIcon />
|
|
319
|
+
</WfoInformationModal>
|
|
320
|
+
)}
|
|
321
|
+
</>
|
|
322
|
+
);
|
|
323
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import React, { type KeyboardEventHandler, useEffect, useState } from 'react';
|
|
2
|
+
import type { ChangeEventHandler } from 'react';
|
|
3
|
+
import type { ValueEditorProps } from 'react-querybuilder';
|
|
4
|
+
|
|
5
|
+
import moment from 'moment';
|
|
6
|
+
import { useTranslations } from 'next-intl';
|
|
7
|
+
|
|
8
|
+
import { EuiButtonGroup, EuiDatePicker, EuiFieldNumber, EuiFieldText } from '@elastic/eui';
|
|
9
|
+
|
|
10
|
+
import { getWfoStructuredSearchTableStyles } from '@/components/WfoTable/WfoStructuredSearchTable/styles';
|
|
11
|
+
import { useWithOrchestratorTheme } from '@/hooks';
|
|
12
|
+
|
|
13
|
+
import { WfoRangeEditor, WfoRangeElementProps } from './WfoRangeEditor';
|
|
14
|
+
|
|
15
|
+
enum UiFieldType {
|
|
16
|
+
text = 'text',
|
|
17
|
+
number = 'number',
|
|
18
|
+
boolean = 'boolean',
|
|
19
|
+
datetime = 'datetime',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type HandleOnChange<T> = (value: T | undefined, rangeIndex?: number) => void;
|
|
23
|
+
|
|
24
|
+
export interface EditorProps<T> {
|
|
25
|
+
handleOnChange: HandleOnChange<T>;
|
|
26
|
+
value: T;
|
|
27
|
+
operator?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const BooleanEditor = ({ handleOnChange, value: currentValue = true }: EditorProps<boolean>) => {
|
|
31
|
+
const [value, setValue] = useState<string>(currentValue.toString());
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
handleOnChange(true);
|
|
35
|
+
// Sets the initial value to true so we allow empty dep array here
|
|
36
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
const { buttonGroupStyles } = useWithOrchestratorTheme(getWfoStructuredSearchTableStyles);
|
|
40
|
+
const options = [
|
|
41
|
+
{
|
|
42
|
+
id: 'true',
|
|
43
|
+
label: 'True',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'false',
|
|
47
|
+
label: 'False',
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<EuiButtonGroup
|
|
53
|
+
css={buttonGroupStyles}
|
|
54
|
+
legend="Combinator"
|
|
55
|
+
type="single"
|
|
56
|
+
options={options}
|
|
57
|
+
idSelected={value}
|
|
58
|
+
onChange={(id) => {
|
|
59
|
+
setValue(id);
|
|
60
|
+
handleOnChange(id === 'true');
|
|
61
|
+
}}
|
|
62
|
+
buttonSize="m"
|
|
63
|
+
color="primary"
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const TextEditor = ({ handleOnChange, value: currentValue = '' }: EditorProps<string>) => {
|
|
69
|
+
const [value, setValue] = useState<string>(currentValue);
|
|
70
|
+
|
|
71
|
+
const handleTextChange: ChangeEventHandler<HTMLInputElement> = (e) => {
|
|
72
|
+
setValue(e.target.value || '');
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const handleOnBlur = () => {
|
|
76
|
+
handleOnChange(value);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const handleOnKeyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
|
|
80
|
+
if (e.key === 'Enter') {
|
|
81
|
+
e.currentTarget.blur();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return <EuiFieldText value={value} onChange={handleTextChange} onBlur={handleOnBlur} onKeyDown={handleOnKeyDown} />;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const NumberEditor = ({ handleOnChange, rangeIndex, value: currentValue }: WfoRangeElementProps) => {
|
|
89
|
+
const [value, setValue] = useState<string>(currentValue?.toString() || '');
|
|
90
|
+
|
|
91
|
+
const handleNumberChange: ChangeEventHandler<HTMLInputElement> = (e) => {
|
|
92
|
+
setValue(e.target.value || '');
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const handleOnBlur = () => {
|
|
96
|
+
const numberValue = parseFloat(value);
|
|
97
|
+
handleOnChange(numberValue, rangeIndex);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const handleOnKeyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
|
|
101
|
+
if (e.key === 'Enter') {
|
|
102
|
+
e.currentTarget.blur();
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<EuiFieldNumber
|
|
108
|
+
value={value || undefined}
|
|
109
|
+
onChange={handleNumberChange}
|
|
110
|
+
onBlur={handleOnBlur}
|
|
111
|
+
onKeyDown={handleOnKeyDown}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const DatePicker = ({ handleOnChange, rangeIndex, value: currentValue }: WfoRangeElementProps) => {
|
|
117
|
+
const [date, setDate] = useState<string>(currentValue || '');
|
|
118
|
+
const t = useTranslations('search.page');
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<EuiDatePicker
|
|
122
|
+
selected={date && date !== '' ? moment.utc(date) : undefined}
|
|
123
|
+
onChange={(date) => {
|
|
124
|
+
const utcDate = date ? moment.utc(date) : undefined;
|
|
125
|
+
setDate(utcDate?.toISOString() || '');
|
|
126
|
+
handleOnChange(utcDate?.toISOString(), rangeIndex);
|
|
127
|
+
}}
|
|
128
|
+
id={rangeIndex ? `date-range-${rangeIndex}` : 'date-range'}
|
|
129
|
+
css={{ width: '330px' }}
|
|
130
|
+
showTimeSelect
|
|
131
|
+
dateFormat="yyyy-MM-dd HH:mm"
|
|
132
|
+
timeFormat="HH:mm"
|
|
133
|
+
placeholderText={t('selectDateAndTime')}
|
|
134
|
+
locale="nl"
|
|
135
|
+
shouldCloseOnSelect={true}
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const WfoValueEditor = ({ field: fieldName, context, handleOnChange, operator, value }: ValueEditorProps) => {
|
|
141
|
+
const fieldPathInfoMap = context?.fieldPathInfoMap;
|
|
142
|
+
|
|
143
|
+
const fieldInfo = fieldPathInfoMap && fieldPathInfoMap.has(fieldName) ? fieldPathInfoMap.get(fieldName) : undefined;
|
|
144
|
+
const uiFieldType = fieldInfo?.ui_types[0] || UiFieldType.text;
|
|
145
|
+
|
|
146
|
+
if (uiFieldType === UiFieldType.boolean) {
|
|
147
|
+
return <BooleanEditor handleOnChange={handleOnChange} value={value} />;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (uiFieldType === UiFieldType.datetime) {
|
|
151
|
+
return <WfoRangeEditor handleOnChange={handleOnChange} operator={operator} Element={DatePicker} value={value} />;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (uiFieldType === UiFieldType.number) {
|
|
155
|
+
return <WfoRangeEditor handleOnChange={handleOnChange} operator={operator} Element={NumberEditor} value={value} />;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return <TextEditor handleOnChange={handleOnChange} value={value} />;
|
|
159
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { css } from '@emotion/react';
|
|
2
|
+
|
|
3
|
+
import { WfoThemeHelpers } from '@/hooks';
|
|
4
|
+
|
|
5
|
+
export const getWfoStructuredSearchTableStyles = ({ theme, toSecondaryColor }: WfoThemeHelpers) => {
|
|
6
|
+
const queryBuilderContainerStyles = css({
|
|
7
|
+
backgroundColor: theme.colors.backgroundBaseSubdued,
|
|
8
|
+
padding: theme.base / 2,
|
|
9
|
+
marginBottom: theme.base,
|
|
10
|
+
border: `thin solid ${theme.colors.borderBasePlain}`,
|
|
11
|
+
borderRadius: theme.border.radius.small,
|
|
12
|
+
});
|
|
13
|
+
const toggleButtonStyles = css({
|
|
14
|
+
backgroundColor: 'primary',
|
|
15
|
+
padding: theme.base * 0.75,
|
|
16
|
+
marginLeft: theme.base,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const textAreaStyles = css({
|
|
20
|
+
width: '100%',
|
|
21
|
+
maxInlineSize: '100%',
|
|
22
|
+
height: '42px',
|
|
23
|
+
border: `this solid ${toSecondaryColor(theme.colors.borderBasePlain)}`,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const buttonGroupStyles = css({
|
|
27
|
+
backgroundColor: theme.colors.textGhost,
|
|
28
|
+
height: '100%',
|
|
29
|
+
borderRadius: theme.border.radius.small,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const ruleContainerStyles = css({
|
|
33
|
+
'& > .rule': {
|
|
34
|
+
display: 'flex',
|
|
35
|
+
flexDirection: 'row',
|
|
36
|
+
gap: theme.base / 2,
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
marginBottom: theme.base / 4,
|
|
39
|
+
marginTop: theme.base / 4,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const ruleGroupContainerBase = {
|
|
44
|
+
padding: theme.base / 2,
|
|
45
|
+
marginTop: theme.base / 4,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const ruleGroupContainerBlueStyles = css({
|
|
49
|
+
...ruleGroupContainerBase,
|
|
50
|
+
borderRadius: theme.border.radius.small,
|
|
51
|
+
backgroundColor: '#E9F1F9',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const ruleGroupContainerWhiteStyles = css({
|
|
55
|
+
...ruleGroupContainerBase,
|
|
56
|
+
borderRadius: theme.border.radius.small,
|
|
57
|
+
backgroundColor: theme.colors.backgroundBasePlain,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const innerGroupContainerWhiteStyles = css({
|
|
61
|
+
...ruleGroupContainerBase,
|
|
62
|
+
borderBottomLeftRadius: theme.border.radius.small,
|
|
63
|
+
borderTopLeftRadius: theme.border.radius.small,
|
|
64
|
+
backgroundColor: theme.colors.backgroundBasePlain,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const innerGroupContainerBlueStyles = css({
|
|
68
|
+
...ruleGroupContainerBase,
|
|
69
|
+
borderBottomLeftRadius: theme.border.radius.small,
|
|
70
|
+
borderTopLeftRadius: theme.border.radius.small,
|
|
71
|
+
backgroundColor: '#E9F1F9',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const removeGroupActionStyles = css({
|
|
75
|
+
backgroundColor: theme.colors.backgroundLightPrimary,
|
|
76
|
+
width: '40px',
|
|
77
|
+
marginTop: theme.base / 4,
|
|
78
|
+
height: 'stretch',
|
|
79
|
+
alignItems: 'center',
|
|
80
|
+
justifyContent: 'center',
|
|
81
|
+
borderBottomRightRadius: theme.border.radius.small,
|
|
82
|
+
borderTopRightRadius: theme.border.radius.small,
|
|
83
|
+
cursor: 'pointer',
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const expandingSearchRowStyles = css({
|
|
87
|
+
padding: theme.base / 2,
|
|
88
|
+
height: theme.base * 2,
|
|
89
|
+
borderRadius: theme.border.radius.medium,
|
|
90
|
+
border: 'thin solid FEF7E0',
|
|
91
|
+
backgroundColor: '#FEF7E0',
|
|
92
|
+
});
|
|
93
|
+
const expandingRowBodyStyles = css({
|
|
94
|
+
display: 'flex',
|
|
95
|
+
gap: theme.base,
|
|
96
|
+
fontWeight: theme.font.weight.bold,
|
|
97
|
+
span: {
|
|
98
|
+
fontWeight: 'bold',
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const addRulePlusStyles = css({
|
|
103
|
+
fontSize: theme.size.l,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const addRuleContainerStyles = css({
|
|
107
|
+
color: theme.colors.primary,
|
|
108
|
+
size: theme.size.m,
|
|
109
|
+
display: 'flex',
|
|
110
|
+
alignItems: 'center',
|
|
111
|
+
flexDirection: 'row',
|
|
112
|
+
gap: theme.base / 2,
|
|
113
|
+
alignSelf: 'end',
|
|
114
|
+
cursor: 'pointer',
|
|
115
|
+
marginRight: theme.base / 2,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const addGroupStyles = css({
|
|
119
|
+
border: `thin dashed ${theme.colors.backgroundFilledPrimary}`,
|
|
120
|
+
borderRadius: theme.border.radius.medium,
|
|
121
|
+
alignItems: 'center',
|
|
122
|
+
padding: theme.base,
|
|
123
|
+
color: theme.colors.primary,
|
|
124
|
+
justifyContent: 'center',
|
|
125
|
+
flexDirection: 'row',
|
|
126
|
+
cursor: 'pointer',
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
toggleButtonStyles,
|
|
131
|
+
queryBuilderContainerStyles,
|
|
132
|
+
textAreaStyles,
|
|
133
|
+
buttonGroupStyles,
|
|
134
|
+
ruleContainerStyles,
|
|
135
|
+
ruleGroupContainerBlueStyles,
|
|
136
|
+
ruleGroupContainerWhiteStyles,
|
|
137
|
+
innerGroupContainerWhiteStyles,
|
|
138
|
+
innerGroupContainerBlueStyles,
|
|
139
|
+
removeGroupActionStyles,
|
|
140
|
+
expandingSearchRowStyles,
|
|
141
|
+
expandingRowBodyStyles,
|
|
142
|
+
addRulePlusStyles,
|
|
143
|
+
addRuleContainerStyles,
|
|
144
|
+
addGroupStyles,
|
|
145
|
+
};
|
|
146
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
2
|
import type { FC } from 'react';
|
|
3
3
|
import Draggable from 'react-draggable';
|
|
4
4
|
import type { DraggableEventHandler } from 'react-draggable';
|
|
@@ -17,6 +17,7 @@ interface WfoDragHandlerProps {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const WfoDragHandler: FC<WfoDragHandlerProps> = ({ headerRowRef, fieldName, onUpdateColumWidth }) => {
|
|
20
|
+
const nodeRef = useRef(null);
|
|
20
21
|
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
21
22
|
const [isDragging, setIsDragging] = useState(false);
|
|
22
23
|
const { dragAndDropStyle } = useWithOrchestratorTheme(getWfoTableStyles);
|
|
@@ -66,8 +67,9 @@ export const WfoDragHandler: FC<WfoDragHandlerProps> = ({ headerRowRef, fieldNam
|
|
|
66
67
|
onDrag={onDrag}
|
|
67
68
|
bounds={bounds}
|
|
68
69
|
onStop={onStop}
|
|
70
|
+
nodeRef={nodeRef}
|
|
69
71
|
>
|
|
70
|
-
<div css={dragAndDropStyle} />
|
|
72
|
+
<div css={dragAndDropStyle} ref={nodeRef} />
|
|
71
73
|
</Draggable>
|
|
72
74
|
</div>
|
|
73
75
|
);
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
export * from './WfoTableSettingsModal';
|
|
2
|
-
|
|
3
1
|
export * from './utils/columns';
|
|
4
2
|
export * from './utils/constants';
|
|
5
|
-
|
|
6
3
|
export * from './utils/tableConfigPersistence';
|
|
7
4
|
export * from './utils/tableUtils';
|
|
8
|
-
|
|
5
|
+
export * from './WfoTableSettingsModal';
|
|
9
6
|
export * from './WfoStatusColorField';
|
|
10
7
|
export * from './WfoTableWithFilter';
|
|
11
|
-
|
|
12
8
|
export * from './WfoSortButtons';
|
|
13
9
|
export * from './WfoFirstPartUUID';
|
|
14
10
|
export * from './WfoInlineJson';
|
|
15
11
|
export * from './WfoRowContextMenu';
|
|
16
|
-
|
|
17
12
|
export * from './WfoAdvancedTable';
|
|
18
13
|
export * from './WfoTable';
|
|
14
|
+
export * from './WfoStructuredSearchTable';
|