@orchestrator-ui/orchestrator-ui-components 1.38.1 → 2.0.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 (97) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/.turbo/turbo-lint.log +5 -2
  3. package/.turbo/turbo-test.log +11 -11
  4. package/CHANGELOG.md +25 -0
  5. package/dist/index.d.ts +252 -170
  6. package/dist/index.js +4355 -3498
  7. package/package.json +1 -1
  8. package/src/components/WfoForms/formFields/SubscriptionSummaryField.tsx +6 -5
  9. package/src/components/WfoPageTemplate/WfoPageHeader/WfoPageHeader.tsx +3 -1
  10. package/src/components/WfoPageTemplate/WfoSidebar/WfoCopyright.tsx +1 -1
  11. package/src/components/WfoProcessList/WfoProcessesList.tsx +52 -51
  12. package/src/components/WfoRadioDropdown/WfoRadioDropdown.tsx +88 -0
  13. package/src/components/WfoRadioDropdown/index.ts +1 -0
  14. package/src/components/WfoStartButton/WfoStartButtonComboBox.tsx +4 -0
  15. package/src/components/WfoStartButton/WfoStartTaskComboBox.tsx +1 -0
  16. package/src/components/WfoStartButton/WfoStartWorkflowComboBox.tsx +1 -0
  17. package/src/components/WfoStartButton/styles.ts +0 -4
  18. package/src/components/WfoSubscription/WfoInSyncField.tsx +13 -9
  19. package/src/components/WfoSubscription/WfoInUseByRelations.tsx +4 -2
  20. package/src/components/WfoSubscription/WfoProcessesTimeline.tsx +76 -29
  21. package/src/components/WfoSubscription/WfoRelatedSubscriptions.tsx +50 -56
  22. package/src/components/WfoSubscription/WfoSubscriptionDetailTree.tsx +17 -9
  23. package/src/components/WfoSubscription/WfoSubscriptionGeneral.tsx +29 -160
  24. package/src/components/WfoSubscription/WfoSubscriptionGeneralSections/WfoSubscriptionDetailSection.tsx +113 -0
  25. package/src/components/WfoSubscription/WfoSubscriptionGeneralSections/WfoSubscriptionFixedInputSection.tsx +28 -0
  26. package/src/components/WfoSubscription/WfoSubscriptionGeneralSections/WfoSubscriptionMetadataSection.tsx +29 -0
  27. package/src/components/WfoSubscription/WfoSubscriptionGeneralSections/WfoSubscriptionProductInfoSection.tsx +55 -0
  28. package/src/components/WfoSubscription/WfoSubscriptionGeneralSections/index.ts +4 -0
  29. package/src/components/WfoSubscription/index.ts +3 -0
  30. package/src/components/WfoSubscription/overrides/index.ts +1 -0
  31. package/src/components/WfoSubscription/styles.ts +4 -1
  32. package/src/components/WfoSubscription/utils/utils.spec.ts +0 -13
  33. package/src/components/WfoSubscription/utils/utils.ts +18 -5
  34. package/src/components/WfoSubscriptionsList/WfoSubscriptionsList.tsx +105 -100
  35. package/src/components/WfoTable/{WfoTableWithFilter/WfoTableWithFilter.tsx → WfoAdvancedTable/WfoAdvancedTable.tsx} +65 -123
  36. package/src/components/WfoTable/WfoAdvancedTable/getRowDetailData.tsx +55 -0
  37. package/src/components/WfoTable/WfoAdvancedTable/index.ts +4 -0
  38. package/src/components/WfoTable/WfoAdvancedTable/toSortedTableColumnConfig.ts +12 -0
  39. package/src/components/WfoTable/WfoAdvancedTable/types.ts +23 -0
  40. package/src/components/WfoTable/WfoStatusColorField/WfoStatusColorField.tsx +16 -0
  41. package/src/components/WfoTable/WfoStatusColorField/index.ts +1 -0
  42. package/src/components/WfoTable/WfoStatusColorField/styles.ts +20 -0
  43. package/src/components/WfoTable/WfoTable/WfoExpandedRow.tsx +33 -0
  44. package/src/components/WfoTable/WfoTable/WfoGroupedTable/WfoExpandableRow.tsx +48 -0
  45. package/src/components/WfoTable/WfoTable/WfoGroupedTable/WfoExpandedGroupRow.tsx +71 -0
  46. package/src/components/WfoTable/WfoTable/WfoGroupedTable/WfoGroupedTable.tsx +100 -0
  47. package/src/components/WfoTable/WfoTable/WfoGroupedTable/WfoGroupedTableGroups.tsx +74 -0
  48. package/src/components/WfoTable/WfoTable/WfoGroupedTable/styles.ts +39 -0
  49. package/src/components/WfoTable/WfoTable/WfoGroupedTable/useGroupedTableConfig.tsx +184 -0
  50. package/src/components/WfoTable/WfoTable/WfoGroupedTable/utils.spec.ts +133 -0
  51. package/src/components/WfoTable/WfoTable/WfoGroupedTable/utils.ts +41 -0
  52. package/src/components/WfoTable/WfoTable/WfoMultilineCell.tsx +13 -0
  53. package/src/components/WfoTable/WfoTable/WfoTable.tsx +201 -0
  54. package/src/components/WfoTable/WfoTable/WfoTableDataRows.tsx +112 -0
  55. package/src/components/WfoTable/{WfoBasicTable → WfoTable/WfoTableHeaderCell}/WfoSortDirectionIcon.tsx +3 -3
  56. package/src/components/WfoTable/{WfoBasicTable → WfoTable/WfoTableHeaderCell}/WfoTableHeaderCell.tsx +4 -3
  57. package/src/components/WfoTable/WfoTable/WfoTableHeaderCell/index.ts +2 -0
  58. package/src/components/WfoTable/WfoTable/WfoTableHeaderRow.tsx +114 -0
  59. package/src/components/WfoTable/WfoTable/WfoTruncateCell.tsx +23 -0
  60. package/src/components/WfoTable/WfoTable/constants.ts +1 -0
  61. package/src/components/WfoTable/WfoTable/index.ts +14 -0
  62. package/src/components/WfoTable/WfoTable/styles.ts +117 -0
  63. package/src/components/WfoTable/WfoTable/utils.spec.ts +79 -0
  64. package/src/components/WfoTable/WfoTable/utils.ts +78 -0
  65. package/src/components/WfoTable/WfoTableSettingsModal/WfoTableSettingsModal.tsx +13 -12
  66. package/src/components/WfoTable/WfoTableWithFilter/index.ts +1 -1
  67. package/src/components/WfoTable/index.ts +4 -5
  68. package/src/components/WfoTable/utils/columns.ts +1 -48
  69. package/src/components/WfoTable/utils/tableUtils.ts +13 -10
  70. package/src/components/WfoTree/WfoTreeBranch.tsx +10 -1
  71. package/src/components/WfoTree/WfoTreeNode.tsx +8 -57
  72. package/src/components/WfoTree/WfoTreeNodeListItem.tsx +65 -0
  73. package/src/components/WfoTree/styles.ts +28 -4
  74. package/src/components/index.ts +1 -0
  75. package/src/configuration/policy-resources.ts +1 -0
  76. package/src/configuration/version.ts +1 -1
  77. package/src/icons/WfoXMarkSmall.tsx +29 -0
  78. package/src/messages/en-GB.json +4 -0
  79. package/src/messages/nl-NL.json +4 -0
  80. package/src/pages/metadata/WfoProductBlocksPage.tsx +42 -59
  81. package/src/pages/metadata/WfoProductsPage.tsx +41 -47
  82. package/src/pages/metadata/WfoResourceTypesPage.tsx +26 -35
  83. package/src/pages/metadata/WfoTasksPage.tsx +35 -33
  84. package/src/pages/metadata/WfoWorkflowsPage.tsx +33 -29
  85. package/src/pages/tasks/WfoTasksListPage.tsx +25 -19
  86. package/src/utils/getObjectKeys.ts +3 -0
  87. package/src/utils/index.ts +5 -3
  88. package/src/components/WfoTable/WfoBasicTable/WfoBasicTable.tsx +0 -194
  89. package/src/components/WfoTable/WfoBasicTable/WfoStatusColorField.tsx +0 -21
  90. package/src/components/WfoTable/WfoBasicTable/index.ts +0 -5
  91. package/src/components/WfoTable/WfoDataGridTable/WfoDataGridTable.stories.tsx +0 -136
  92. package/src/components/WfoTable/WfoDataGridTable/WfoDataGridTable.tsx +0 -146
  93. package/src/components/WfoTable/WfoDataGridTable/WfodataGridColumns.spec.ts +0 -113
  94. package/src/components/WfoTable/WfoDataGridTable/WfodataGridColumns.ts +0 -81
  95. package/src/components/WfoTable/utils/mapSortableAndFilterableValuesToTableColumnConfig.spec.ts +0 -52
  96. package/src/components/WfoTable/utils/mapSortableAndFilterableValuesToTableColumnConfig.ts +0 -23
  97. /package/src/components/WfoTable/{WfoBasicTable → WfoTable/WfoTableHeaderCell}/styles.ts +0 -0
@@ -3,94 +3,70 @@ import React, { useEffect, useState } from 'react';
3
3
  import { useTranslations } from 'next-intl';
4
4
 
5
5
  import {
6
- Criteria,
7
6
  EuiButton,
8
7
  EuiButtonIcon,
9
8
  EuiFlexGroup,
10
9
  EuiFlexItem,
11
10
  EuiSpacer,
12
11
  EuiText,
13
- Pagination,
14
12
  } from '@elastic/eui';
15
13
 
16
- import { WfoErrorWithMessage } from '@/components';
17
- import { useOrchestratorTheme } from '@/hooks';
18
- import { WfoArrowsExpand } from '@/icons';
19
- import { WfoGraphqlError } from '@/rtk';
20
- import { getDefaultTableConfig } from '@/utils/getDefaultTableConfig';
21
-
22
- import { getTypedFieldFromObject } from '../../../utils';
23
14
  import {
15
+ DEFAULT_PAGE_SIZE,
16
+ DEFAULT_PAGE_SIZES,
17
+ TableColumnKeys,
18
+ TableSettingsColumnConfig,
19
+ TableSettingsConfig,
20
+ TableSettingsModal,
21
+ WfoErrorWithMessage,
22
+ WfoInformationModal,
24
23
  WfoKeyValueTable,
25
24
  WfoKeyValueTableDataType,
26
- } from '../../WfoKeyValueTable/WfoKeyValueTable';
27
- import { WfoSearchField } from '../../WfoSearchBar';
28
- import { WfoInformationModal } from '../../WfoSettingsModal';
29
- import {
30
- WfoBasicTable,
31
- WfoBasicTableColumnsWithControlColumns,
32
- } from '../WfoBasicTable';
33
- import {
34
- ColumnConfig,
35
- TableConfig,
36
- TableSettingsModal,
37
- } from '../WfoTableSettingsModal';
38
- import {
39
- TableColumnKeys,
40
- WfoDataSorting,
41
- WfoTableColumns,
42
- WfoTableControlColumnConfig,
43
- WfoTableDataColumnConfig,
44
- } from '../utils/columns';
45
- import { DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZES } from '../utils/constants';
46
- import {
25
+ WfoSearchField,
47
26
  clearTableConfigFromLocalStorage,
48
27
  setTableConfigToLocalStorage,
49
- } from '../utils/tableConfigPersistence';
50
- import { updateQueryString } from './updateQueryString';
28
+ } from '@/components';
29
+ import { getRowDetailData } from '@/components/WfoTable/WfoAdvancedTable/getRowDetailData';
30
+ import { useOrchestratorTheme } from '@/hooks';
31
+ import { WfoArrowsExpand } from '@/icons';
32
+ import { WfoGraphqlError } from '@/rtk';
33
+ import { getDefaultTableConfig } from '@/utils';
34
+
35
+ import { ColumnType, WfoTable, WfoTableProps } from '../WfoTable';
36
+ import { updateQueryString } from '../WfoTableWithFilter/updateQueryString';
37
+ import { WfoAdvancedTableColumnConfig } from './types';
51
38
 
52
- export type WfoTableWithFilterProps<T extends object> = {
53
- data: T[];
54
- tableColumns: WfoTableColumns<T>;
55
- leadingControlColumns?: WfoTableControlColumnConfig<T>;
56
- trailingControlColumns?: WfoTableControlColumnConfig<T>;
39
+ export type WfoAdvancedTableProps<T extends object> = Omit<
40
+ WfoTableProps<T>,
41
+ 'columnConfig'
42
+ > & {
43
+ tableColumnConfig: WfoAdvancedTableColumnConfig<T>;
57
44
  defaultHiddenColumns?: TableColumnKeys<T>;
58
- dataSorting: WfoDataSorting<T>;
59
- pagination: Pagination;
60
45
  queryString?: string;
61
- isLoading: boolean;
62
46
  localStorageKey: string;
63
47
  detailModal?: boolean;
64
48
  detailModalTitle?: string;
65
- onUpdateQueryString: (queryString: string) => void;
66
- onUpdatePage: (criterion: Criteria<T>['page']) => void;
67
- onUpdateDataSort: (dataSorting: WfoDataSorting<T>) => void;
49
+ exportDataIsLoading?: boolean;
68
50
  error?: WfoGraphqlError[];
51
+ onUpdateQueryString: (queryString: string) => void;
69
52
  onExportData?: () => void;
70
- exportDataIsLoading?: boolean;
71
53
  };
72
54
 
73
- export const WfoTableWithFilter = <T extends object>({
74
- data,
75
- tableColumns,
76
- leadingControlColumns,
77
- trailingControlColumns,
55
+ export const WfoAdvancedTable = <T extends object>({
56
+ tableColumnConfig,
78
57
  defaultHiddenColumns = [],
79
- dataSorting,
80
- pagination,
81
58
  queryString,
82
- isLoading,
83
59
  localStorageKey,
84
60
  detailModal = true,
85
61
  detailModalTitle = 'Details',
86
- onUpdateQueryString,
87
- onUpdatePage,
88
- onUpdateDataSort,
62
+ exportDataIsLoading,
89
63
  error,
64
+ onUpdateQueryString,
90
65
  onExportData,
91
- exportDataIsLoading = false,
92
- }: WfoTableWithFilterProps<T>) => {
66
+ ...tableProps
67
+ }: WfoAdvancedTableProps<T>) => {
93
68
  const { theme } = useOrchestratorTheme();
69
+
94
70
  const [hiddenColumns, setHiddenColumns] =
95
71
  useState<TableColumnKeys<T>>(defaultHiddenColumns);
96
72
  const [showSettingsModal, setShowSettingsModal] = useState(false);
@@ -105,11 +81,13 @@ export const WfoTableWithFilter = <T extends object>({
105
81
  }
106
82
  }, [defaultHiddenColumns]);
107
83
 
108
- const detailsIconColumn: WfoTableControlColumnConfig<T> = {
84
+ const { pagination } = tableProps;
85
+
86
+ const detailsIconColumn: WfoAdvancedTableColumnConfig<T> = {
109
87
  viewDetails: {
110
- field: 'viewDetails',
88
+ columnType: ColumnType.CONTROL,
111
89
  width: '36px',
112
- render: (_, row) => (
90
+ renderControl: (row) => (
113
91
  <EuiFlexItem
114
92
  css={{ cursor: 'pointer' }}
115
93
  onClick={() => setSelectedDataForDetailModal(row)}
@@ -120,54 +98,30 @@ export const WfoTableWithFilter = <T extends object>({
120
98
  },
121
99
  };
122
100
 
123
- const tableColumnsWithControlColumns: WfoBasicTableColumnsWithControlColumns<T> =
124
- {
125
- ...leadingControlColumns,
126
- ...tableColumns,
127
- ...trailingControlColumns,
128
- ...(detailModal ? detailsIconColumn : []),
129
- };
101
+ const tableColumnsWithControlColumns: WfoAdvancedTableColumnConfig<T> = {
102
+ ...(detailModal && detailsIconColumn),
103
+ ...tableColumnConfig,
104
+ };
105
+
106
+ const tableSettingsColumns: TableSettingsColumnConfig<T>[] = Object.entries(
107
+ tableColumnConfig,
108
+ ).map(([key, { label }]): TableSettingsColumnConfig<T> => {
109
+ const field = key as keyof T;
130
110
 
131
- const tableSettingsColumns: ColumnConfig<T>[] = Object.entries<
132
- WfoTableDataColumnConfig<T, keyof T>
133
- >(tableColumns).map((keyValuePair) => {
134
- const { field, name } = keyValuePair[1];
135
111
  return {
136
112
  field,
137
- name,
113
+ name: label,
138
114
  isVisible: hiddenColumns.indexOf(field) === -1,
139
115
  };
140
116
  });
141
117
 
142
118
  const rowDetailData: WfoKeyValueTableDataType[] | undefined =
143
119
  selectedDataForDetailModal &&
144
- Object.entries(tableColumns).map(([key]): WfoKeyValueTableDataType => {
145
- const dataField = getTypedFieldFromObject(key, tableColumns);
146
- if (dataField === null) {
147
- return {
148
- key,
149
- value: undefined,
150
- };
151
- }
120
+ getRowDetailData(selectedDataForDetailModal, tableColumnConfig);
152
121
 
153
- const { renderDetails, render, clipboardText, name } =
154
- tableColumns[dataField];
155
- const dataValue = selectedDataForDetailModal[dataField];
156
- return {
157
- key: name ?? dataField.toString(),
158
- value: (renderDetails &&
159
- renderDetails(dataValue, selectedDataForDetailModal)) ??
160
- (render &&
161
- render(dataValue, selectedDataForDetailModal)) ?? (
162
- <>{dataValue}</>
163
- ),
164
- textToCopy:
165
- clipboardText?.(dataValue, selectedDataForDetailModal) ??
166
- (typeof dataValue === 'string' ? dataValue : undefined),
167
- };
168
- });
169
-
170
- const handleUpdateTableConfig = (updatedTableConfig: TableConfig<T>) => {
122
+ const handleUpdateTableConfig = (
123
+ updatedTableConfig: TableSettingsConfig<T>,
124
+ ) => {
171
125
  const updatedHiddenColumns = updatedTableConfig.columns
172
126
  .filter((column) => !column.isVisible)
173
127
  .map((hiddenColumn) => hiddenColumn.field);
@@ -177,10 +131,8 @@ export const WfoTableWithFilter = <T extends object>({
177
131
  hiddenColumns: updatedHiddenColumns,
178
132
  selectedPageSize: updatedTableConfig.selectedPageSize,
179
133
  });
180
- onUpdatePage({
181
- index: 0,
182
- size: updatedTableConfig.selectedPageSize,
183
- });
134
+ pagination?.onChangeItemsPerPage?.(updatedTableConfig.selectedPageSize);
135
+ pagination?.onChangePage?.(0);
184
136
  };
185
137
 
186
138
  const handleResetToDefaults = () => {
@@ -188,16 +140,10 @@ export const WfoTableWithFilter = <T extends object>({
188
140
  setHiddenColumns(defaultTableConfig.hiddenColumns);
189
141
  setShowSettingsModal(false);
190
142
  clearTableConfigFromLocalStorage(localStorageKey);
191
- onUpdatePage({
192
- index: 0,
193
- size: defaultTableConfig.selectedPageSize ?? DEFAULT_PAGE_SIZE,
194
- });
195
- };
196
-
197
- const onCriteriaChange = (criterion: Criteria<T>) => {
198
- if (criterion.page) {
199
- onUpdatePage(criterion.page);
200
- }
143
+ pagination?.onChangeItemsPerPage?.(
144
+ defaultTableConfig.selectedPageSize ?? DEFAULT_PAGE_SIZE,
145
+ );
146
+ pagination?.onChangePage?.(0);
201
147
  };
202
148
 
203
149
  const searchModalText = t.rich('searchModalText', {
@@ -240,16 +186,10 @@ export const WfoTableWithFilter = <T extends object>({
240
186
  </EuiFlexGroup>
241
187
  {error && <WfoErrorWithMessage error={error} />}
242
188
  <EuiSpacer size="m" />
243
- <WfoBasicTable
244
- data={data}
245
- columns={tableColumnsWithControlColumns}
189
+ <WfoTable
190
+ columnConfig={tableColumnsWithControlColumns}
246
191
  hiddenColumns={hiddenColumns}
247
- dataSorting={dataSorting}
248
- onUpdateDataSorting={onUpdateDataSort}
249
- pagination={pagination}
250
- isLoading={isLoading}
251
- onCriteriaChange={onCriteriaChange}
252
- onDataSearch={({ field, searchText }) =>
192
+ onUpdateDataSearch={({ field, searchText }) =>
253
193
  onUpdateQueryString(
254
194
  updateQueryString(
255
195
  queryString ?? '',
@@ -258,16 +198,18 @@ export const WfoTableWithFilter = <T extends object>({
258
198
  ),
259
199
  )
260
200
  }
201
+ {...tableProps}
261
202
  />
203
+
262
204
  {showSettingsModal && (
263
205
  <TableSettingsModal
264
206
  tableConfig={{
265
207
  columns: tableSettingsColumns,
266
208
  selectedPageSize:
267
- pagination.pageSize ?? DEFAULT_PAGE_SIZE,
209
+ pagination?.pageSize ?? DEFAULT_PAGE_SIZE,
268
210
  }}
269
211
  pageSizeOptions={
270
- pagination.pageSizeOptions ?? DEFAULT_PAGE_SIZES
212
+ pagination?.pageSizeOptions ?? DEFAULT_PAGE_SIZES
271
213
  }
272
214
  onClose={() => setShowSettingsModal(false)}
273
215
  onUpdateTableConfig={handleUpdateTableConfig}
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+
3
+ import {
4
+ WfoAdvancedTableColumnConfig,
5
+ WfoAdvancedTableDataColumnConfigItem,
6
+ } from '@/components/WfoTable/WfoAdvancedTable/types';
7
+ import {
8
+ ColumnType,
9
+ WfoTableControlColumnConfigItem,
10
+ } from '@/components/WfoTable/WfoTable';
11
+ import { getTypedFieldFromObject } from '@/utils';
12
+
13
+ export const getRowDetailData = <T extends object>(
14
+ selectedDataForDetailModal: T,
15
+ tableColumnConfig: WfoAdvancedTableColumnConfig<T>,
16
+ ) => {
17
+ const tableColumnConfigEntries: [
18
+ string,
19
+ (
20
+ | WfoTableControlColumnConfigItem<T>
21
+ | WfoAdvancedTableDataColumnConfigItem<T, keyof T>
22
+ ),
23
+ ][] = Object.entries(tableColumnConfig);
24
+
25
+ const dataColumnEntries = tableColumnConfigEntries.filter(
26
+ ([, tableColumnConfig]) =>
27
+ tableColumnConfig.columnType === ColumnType.DATA,
28
+ ) as [string, WfoAdvancedTableDataColumnConfigItem<T, keyof T>][];
29
+
30
+ return dataColumnEntries.map(([key, value]) => {
31
+ const dataField = getTypedFieldFromObject(key, tableColumnConfig);
32
+ if (dataField === null) {
33
+ return {
34
+ key,
35
+ value: undefined,
36
+ };
37
+ }
38
+
39
+ const { renderDetails, renderData, clipboardText, label } = value;
40
+ const dataValue = selectedDataForDetailModal[dataField];
41
+
42
+ return {
43
+ key: label ?? dataField.toString(),
44
+ value: (renderDetails &&
45
+ renderDetails(dataValue, selectedDataForDetailModal)) ??
46
+ (renderData &&
47
+ renderData(dataValue, selectedDataForDetailModal)) ?? (
48
+ <>{dataValue}</>
49
+ ),
50
+ textToCopy:
51
+ clipboardText?.(dataValue, selectedDataForDetailModal) ??
52
+ (typeof dataValue === 'string' ? dataValue : undefined),
53
+ };
54
+ });
55
+ };
@@ -0,0 +1,4 @@
1
+ export * from './getRowDetailData';
2
+ export * from './toSortedTableColumnConfig';
3
+ export * from './types';
4
+ export * from './WfoAdvancedTable';
@@ -0,0 +1,12 @@
1
+ import { WfoAdvancedTableColumnConfig } from '@/components/WfoTable/WfoAdvancedTable/types';
2
+
3
+ export const toSortedTableColumnConfig = <T extends object>(
4
+ columnConfig: WfoAdvancedTableColumnConfig<T>,
5
+ columnKeys: (keyof WfoAdvancedTableColumnConfig<T>)[],
6
+ ): WfoAdvancedTableColumnConfig<T> =>
7
+ columnKeys.reduce((sortedConfig, key) => {
8
+ if (key in columnConfig) {
9
+ sortedConfig[key] = columnConfig[key];
10
+ }
11
+ return sortedConfig;
12
+ }, {} as WfoAdvancedTableColumnConfig<T>);
@@ -0,0 +1,23 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import {
4
+ WfoTableControlColumnConfig,
5
+ WfoTableControlColumnConfigItem,
6
+ WfoTableDataColumnConfigItem,
7
+ } from '@/components/WfoTable/WfoTable';
8
+
9
+ export type WfoAdvancedTableDataColumnConfigItem<
10
+ T extends object,
11
+ Property extends keyof T,
12
+ > = WfoTableDataColumnConfigItem<T, Property> & {
13
+ renderDetails?: (cellValue: T[Property], row: T) => ReactNode;
14
+ clipboardText?: (cellValue: T[Property], row: T) => string;
15
+ };
16
+ export type WfoAdvancedTableDataColumnConfig<T extends object> = {
17
+ [Property in keyof T]:
18
+ | WfoAdvancedTableDataColumnConfigItem<T, Property>
19
+ | WfoTableControlColumnConfigItem<T>;
20
+ };
21
+ export type WfoAdvancedTableColumnConfig<T extends object> = Partial<
22
+ WfoTableControlColumnConfig<T> | WfoAdvancedTableDataColumnConfig<T>
23
+ >;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+
3
+ import { getWfoStatusColorFieldStyles } from '@/components/WfoTable/WfoStatusColorField/styles';
4
+ import { useWithOrchestratorTheme } from '@/hooks';
5
+
6
+ export type WfoStatusColorFieldProps = {
7
+ color: string;
8
+ };
9
+
10
+ export const WfoStatusColorField = ({ color }: WfoStatusColorFieldProps) => {
11
+ const { getStatusColorFieldStyle } = useWithOrchestratorTheme(
12
+ getWfoStatusColorFieldStyles,
13
+ );
14
+
15
+ return <div css={getStatusColorFieldStyle(color)}></div>;
16
+ };
@@ -0,0 +1 @@
1
+ export * from './WfoStatusColorField';
@@ -0,0 +1,20 @@
1
+ import { tint } from '@elastic/eui';
2
+ import { css } from '@emotion/react';
3
+
4
+ import { TABLE_ROW_HEIGHT } from '@/components';
5
+ import { WfoTheme } from '@/hooks';
6
+
7
+ export const getWfoStatusColorFieldStyles = ({ theme }: WfoTheme) => {
8
+ const toStatusColorFieldColor = (color: string) => tint(color, 0.3);
9
+
10
+ const getStatusColorFieldStyle = (color: string) =>
11
+ css({
12
+ backgroundColor: toStatusColorFieldColor(color),
13
+ height: TABLE_ROW_HEIGHT,
14
+ width: theme.size.xs,
15
+ });
16
+
17
+ return {
18
+ getStatusColorFieldStyle,
19
+ };
20
+ };
@@ -0,0 +1,33 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import { WfoTableProps } from './WfoTable';
4
+
5
+ export type WfoExpandedRowProps<T extends object> = Pick<
6
+ WfoTableProps<T>,
7
+ 'rowExpandingConfiguration'
8
+ > & {
9
+ rowData: T;
10
+ };
11
+
12
+ export const WfoExpandedRow = <T extends object>({
13
+ rowExpandingConfiguration,
14
+ rowData,
15
+ }: WfoExpandedRowProps<T>) => {
16
+ if (!rowExpandingConfiguration) {
17
+ return null;
18
+ }
19
+
20
+ return Object.entries(rowExpandingConfiguration.uniqueRowIdToExpandedRowMap)
21
+ .map(([key, value]): [key: string, value: ReactNode] => [
22
+ key.toLowerCase(),
23
+ value,
24
+ ])
25
+ .filter(
26
+ ([key]) =>
27
+ key ===
28
+ (
29
+ rowData[rowExpandingConfiguration.uniqueRowId] as string
30
+ ).toLowerCase(),
31
+ )
32
+ .map(([, expandedRowComponent]) => expandedRowComponent);
33
+ };
@@ -0,0 +1,48 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import { EuiButtonIcon, EuiText } from '@elastic/eui';
6
+
7
+ import { useWithOrchestratorTheme } from '@/hooks';
8
+
9
+ import { getWfoGroupedTableStyles } from './styles';
10
+
11
+ export type WfoExpandableRowProps = {
12
+ isExpanded: boolean;
13
+ groupName: string;
14
+ updateExpandedRows: (groupName: string) => void;
15
+ numberOfRowsInGroup: number;
16
+ };
17
+
18
+ export const WfoExpandableRow: FC<WfoExpandableRowProps> = ({
19
+ groupName,
20
+ numberOfRowsInGroup,
21
+ updateExpandedRows,
22
+ isExpanded,
23
+ }) => {
24
+ const { expandableRowContainerStyle, expandableRowTextStyle } =
25
+ useWithOrchestratorTheme(getWfoGroupedTableStyles);
26
+ const t = useTranslations('wfoComponents');
27
+
28
+ const hasData = numberOfRowsInGroup > 0;
29
+
30
+ return (
31
+ <div css={expandableRowContainerStyle}>
32
+ <EuiButtonIcon
33
+ disabled={!hasData}
34
+ aria-label={isExpanded ? t('collapse') : t('expand')}
35
+ iconType={hasData && isExpanded ? 'arrowDown' : 'arrowRight'}
36
+ onClick={(event: React.MouseEvent<HTMLButtonElement>) => {
37
+ updateExpandedRows(groupName);
38
+ event.stopPropagation();
39
+ }}
40
+ />
41
+
42
+ <EuiText
43
+ size="s"
44
+ css={expandableRowTextStyle}
45
+ >{`${groupName} (${numberOfRowsInGroup})`}</EuiText>
46
+ </div>
47
+ );
48
+ };
@@ -0,0 +1,71 @@
1
+ import React, { Ref } from 'react';
2
+
3
+ import { useWithOrchestratorTheme } from '@/hooks';
4
+
5
+ import { WfoTableDataRows } from '../WfoTableDataRows';
6
+ import { WfoTableHeaderRow } from '../WfoTableHeaderRow';
7
+ import { getWfoTableStyles } from '../styles';
8
+ import { GroupedData } from './WfoGroupedTable';
9
+ import {
10
+ WfoGroupedTableGroups,
11
+ WfoGroupedTableGroupsProps,
12
+ WfoGroupedTableGroupsRef,
13
+ } from './WfoGroupedTableGroups';
14
+ import { getWfoGroupedTableStyles } from './styles';
15
+
16
+ export type WfoExpandedGroupRowProps<T extends object> = Pick<
17
+ WfoGroupedTableGroupsProps<T>,
18
+ 'columnConfig' | 'nestingLevel' | 'groupNameLabel'
19
+ > & {
20
+ data: GroupedData<T> | T[];
21
+ onExpandRowChange: (isAllExpanded: boolean) => void;
22
+ };
23
+
24
+ export const WfoExpandedGroupRow = React.forwardRef(
25
+ <T extends object>(
26
+ {
27
+ data,
28
+ columnConfig,
29
+ nestingLevel = 1,
30
+ groupNameLabel,
31
+ onExpandRowChange,
32
+ }: WfoExpandedGroupRowProps<T>,
33
+ reference: Ref<WfoGroupedTableGroupsRef>,
34
+ ) => {
35
+ const { expandedRowStyle } =
36
+ useWithOrchestratorTheme(getWfoTableStyles);
37
+ const { innerTableHeaderStyle, getNestingStyle } =
38
+ useWithOrchestratorTheme(getWfoGroupedTableStyles);
39
+
40
+ if (Array.isArray(data)) {
41
+ return (
42
+ <>
43
+ <WfoTableHeaderRow
44
+ css={[
45
+ innerTableHeaderStyle,
46
+ getNestingStyle(nestingLevel),
47
+ ]}
48
+ columnConfig={columnConfig}
49
+ />
50
+ <WfoTableDataRows
51
+ css={[expandedRowStyle, getNestingStyle(nestingLevel)]}
52
+ data={data}
53
+ columnConfig={columnConfig}
54
+ />
55
+ </>
56
+ );
57
+ }
58
+
59
+ return (
60
+ <WfoGroupedTableGroups
61
+ ref={reference}
62
+ data={data}
63
+ columnConfig={columnConfig}
64
+ groupNameLabel={groupNameLabel}
65
+ nestingLevel={nestingLevel}
66
+ onExpandRowChange={onExpandRowChange}
67
+ />
68
+ );
69
+ },
70
+ );
71
+ WfoExpandedGroupRow.displayName = 'WfoExpandedGroupRow';
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import { EuiButtonEmpty, EuiFlexGroup, EuiSpacer } from '@elastic/eui';
6
+
7
+ import { useWithOrchestratorTheme } from '@/hooks';
8
+
9
+ import { WfoTable, WfoTableProps } from '../WfoTable';
10
+ import { getWfoTableStyles } from '../styles';
11
+ import { useGroupedTableConfig } from './useGroupedTableConfig';
12
+
13
+ export type GroupType = {
14
+ groupName: string;
15
+ };
16
+
17
+ export type GroupedData<T> = {
18
+ [Key: string]: T[] | GroupedData<T>;
19
+ };
20
+
21
+ export type WfoGroupedTableProps<T extends object> = Pick<
22
+ WfoTableProps<T>,
23
+ 'columnConfig' | 'isLoading' | 'className'
24
+ > & {
25
+ data: GroupedData<T>;
26
+ groupNameLabel: string;
27
+ };
28
+
29
+ export const WfoGroupedTable = <T extends object>({
30
+ data,
31
+ columnConfig,
32
+ groupNameLabel,
33
+ isLoading,
34
+ className,
35
+ }: WfoGroupedTableProps<T>) => {
36
+ const { headerStyle, rowStyle, cellStyle } =
37
+ useWithOrchestratorTheme(getWfoTableStyles);
38
+
39
+ const t = useTranslations('wfoComponents.wfoGroupedTable');
40
+
41
+ const {
42
+ groups,
43
+ groupColumnConfig,
44
+ numberOfColumnsInnerTable,
45
+ uniqueRowIdToExpandedRowMap,
46
+ isAllGroupsAndSubgroupsExpanded,
47
+ toggleExpandedRow,
48
+ expandAllRows,
49
+ collapseAllRows,
50
+ } = useGroupedTableConfig({
51
+ data,
52
+ groupNameLabel,
53
+ columnConfig,
54
+ });
55
+
56
+ return (
57
+ <>
58
+ <EuiFlexGroup justifyContent="flexEnd">
59
+ <EuiButtonEmpty
60
+ size="xs"
61
+ onClick={() =>
62
+ isAllGroupsAndSubgroupsExpanded
63
+ ? collapseAllRows()
64
+ : expandAllRows()
65
+ }
66
+ >
67
+ {isAllGroupsAndSubgroupsExpanded
68
+ ? t('collapse')
69
+ : t('expand')}
70
+ </EuiButtonEmpty>
71
+ </EuiFlexGroup>
72
+
73
+ <EuiSpacer size="xs" />
74
+
75
+ <WfoTable
76
+ className={className}
77
+ data={groups}
78
+ columnConfig={groupColumnConfig}
79
+ isLoading={isLoading}
80
+ overrideHeader={() => (
81
+ <thead css={headerStyle}>
82
+ <tr css={rowStyle}>
83
+ <th
84
+ colSpan={numberOfColumnsInnerTable}
85
+ css={cellStyle}
86
+ >
87
+ {groupNameLabel}
88
+ </th>
89
+ </tr>
90
+ </thead>
91
+ )}
92
+ rowExpandingConfiguration={{
93
+ uniqueRowId: 'groupName',
94
+ uniqueRowIdToExpandedRowMap,
95
+ }}
96
+ onRowClick={({ groupName }) => toggleExpandedRow(groupName)}
97
+ />
98
+ </>
99
+ );
100
+ };