ydb-embedded-ui 4.27.1 → 4.28.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 (42) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/components/EmptyState/EmptyState.scss +5 -2
  3. package/dist/components/EmptyState/EmptyState.tsx +11 -3
  4. package/dist/components/Errors/403/AccessDenied.tsx +4 -3
  5. package/dist/components/ProblemFilter/ProblemFilter.tsx +1 -1
  6. package/dist/components/UptimeFIlter/UptimeFilter.tsx +1 -1
  7. package/dist/components/VirtualTable/VirtualTable.scss +1 -1
  8. package/dist/containers/Cluster/Cluster.tsx +11 -12
  9. package/dist/containers/Nodes/Nodes.tsx +4 -4
  10. package/dist/containers/Nodes/NodesWrapper.tsx +21 -0
  11. package/dist/containers/Nodes/VirtualNodes.tsx +4 -14
  12. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +1 -0
  13. package/dist/containers/Storage/EmptyFilter/EmptyFilter.tsx +1 -0
  14. package/dist/containers/Storage/PDisk/PDisk.tsx +5 -7
  15. package/dist/containers/Storage/Storage.tsx +30 -67
  16. package/dist/containers/Storage/StorageControls/StorageControls.tsx +104 -0
  17. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +18 -62
  18. package/dist/containers/Storage/StorageGroups/StorageGroupsEmptyDataMessage.tsx +30 -0
  19. package/dist/containers/Storage/StorageGroups/VirtualStorageGroups.tsx +94 -0
  20. package/dist/containers/Storage/StorageGroups/getGroups.ts +21 -0
  21. package/dist/containers/Storage/StorageGroups/getStorageGroupsColumns.tsx +73 -50
  22. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +23 -138
  23. package/dist/containers/Storage/StorageNodes/StorageNodesEmptyDataMessage.tsx +44 -0
  24. package/dist/containers/Storage/StorageNodes/VirtualStorageNodes.tsx +105 -0
  25. package/dist/containers/Storage/StorageNodes/getNodes.ts +26 -0
  26. package/dist/containers/Storage/StorageNodes/getStorageNodesColumns.tsx +125 -0
  27. package/dist/containers/Storage/StorageNodes/shared.ts +9 -0
  28. package/dist/containers/Storage/StorageTypeFilter/StorageTypeFilter.tsx +1 -1
  29. package/dist/containers/Storage/StorageVisibleEntitiesFilter/StorageVisibleEntitiesFilter.tsx +1 -1
  30. package/dist/containers/Storage/StorageWrapper.tsx +23 -0
  31. package/dist/containers/Storage/UsageFilter/UsageFilter.tsx +3 -4
  32. package/dist/containers/Storage/VirtualStorage.tsx +112 -0
  33. package/dist/containers/Storage/i18n/en.json +7 -0
  34. package/dist/containers/Storage/i18n/index.ts +11 -0
  35. package/dist/containers/Storage/i18n/ru.json +7 -0
  36. package/dist/containers/Storage/shared.ts +3 -0
  37. package/dist/containers/Tenants/Tenants.tsx +2 -2
  38. package/dist/containers/UserSettings/i18n/en.json +2 -2
  39. package/dist/containers/UserSettings/i18n/ru.json +2 -2
  40. package/dist/containers/UserSettings/settings.ts +4 -4
  41. package/dist/store/reducers/storage/selectors.ts +0 -20
  42. package/package.json +6 -6
@@ -1,31 +1,17 @@
1
- import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
1
+ import {useMemo} from 'react';
2
+
3
+ import DataTable, {Settings, SortOrder} from '@gravity-ui/react-data-table';
2
4
 
3
5
  import type {NodesMap} from '../../../types/store/nodesList';
4
6
  import type {PreparedStorageGroup, VisibleEntities} from '../../../store/reducers/storage/types';
5
7
  import type {HandleSort} from '../../../utils/hooks/useTableSort';
6
8
  import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
7
- import {isSortableStorageProperty} from '../../../utils/storage';
8
- import {EmptyFilter} from '../EmptyFilter/EmptyFilter';
9
- import {getStorageGroupsColumns} from './getStorageGroupsColumns';
9
+ import {getPreparedStorageGroupsColumns} from './getStorageGroupsColumns';
10
+ import {StorageGroupsEmptyDataMessage} from './StorageGroupsEmptyDataMessage';
10
11
 
11
12
  import i18n from './i18n';
12
13
  import './StorageGroups.scss';
13
14
 
14
- const TableColumnsIds = {
15
- PoolName: 'PoolName',
16
- Kind: 'Kind',
17
- Erasure: 'Erasure',
18
- GroupId: 'GroupId',
19
- Used: 'Used',
20
- Limit: 'Limit',
21
- Usage: 'Usage',
22
- UsedSpaceFlag: 'UsedSpaceFlag',
23
- Read: 'Read',
24
- Write: 'Write',
25
- VDisks: 'VDisks',
26
- Degraded: 'Degraded',
27
- } as const;
28
-
29
15
  interface StorageGroupsProps {
30
16
  data: PreparedStorageGroup[];
31
17
  nodes?: NodesMap;
@@ -45,50 +31,20 @@ export function StorageGroups({
45
31
  sort,
46
32
  handleSort,
47
33
  }: StorageGroupsProps) {
48
- const rawColumns: Column<PreparedStorageGroup>[] = getStorageGroupsColumns(nodes);
49
-
50
- let columns = rawColumns.map((column) => ({
51
- ...column,
52
- sortable: isSortableStorageProperty(column.name),
53
- }));
54
-
55
- if (visibleEntities === VISIBLE_ENTITIES.all) {
56
- columns = columns.filter((col) => {
57
- return (
58
- col.name !== TableColumnsIds.Degraded && col.name !== TableColumnsIds.UsedSpaceFlag
59
- );
60
- });
61
- }
62
-
63
- if (visibleEntities === VISIBLE_ENTITIES.space) {
64
- columns = columns.filter((col) => col.name !== TableColumnsIds.Degraded);
65
-
66
- if (!data.length) {
67
- return (
68
- <EmptyFilter
69
- title={i18n('empty.out_of_space')}
70
- showAll={i18n('show_all')}
71
- onShowAll={onShowAll}
72
- />
73
- );
74
- }
75
- }
76
-
77
- if (visibleEntities === VISIBLE_ENTITIES.missing) {
78
- columns = columns.filter((col) => col.name !== TableColumnsIds.UsedSpaceFlag);
79
-
80
- if (!data.length) {
81
- return (
82
- <EmptyFilter
83
- title={i18n('empty.degraded')}
84
- showAll={i18n('show_all')}
85
- onShowAll={onShowAll}
86
- />
87
- );
88
- }
34
+ const columns = useMemo(() => {
35
+ return getPreparedStorageGroupsColumns(nodes, visibleEntities);
36
+ }, [nodes, visibleEntities]);
37
+
38
+ if (!data.length && visibleEntities !== VISIBLE_ENTITIES.all) {
39
+ return (
40
+ <StorageGroupsEmptyDataMessage
41
+ onShowAll={onShowAll}
42
+ visibleEntities={visibleEntities}
43
+ />
44
+ );
89
45
  }
90
46
 
91
- return data ? (
47
+ return (
92
48
  <DataTable
93
49
  key={visibleEntities}
94
50
  theme="yandex-cloud"
@@ -99,5 +55,5 @@ export function StorageGroups({
99
55
  sortOrder={sort}
100
56
  onSort={handleSort}
101
57
  />
102
- ) : null;
58
+ );
103
59
  }
@@ -0,0 +1,30 @@
1
+ import type {VisibleEntities} from '../../../store/reducers/storage/types';
2
+ import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
3
+ import {EmptyFilter} from '../EmptyFilter/EmptyFilter';
4
+ import i18n from './i18n';
5
+
6
+ interface StorageNodesEmptyDataMessageProps {
7
+ visibleEntities?: VisibleEntities;
8
+ onShowAll?: VoidFunction;
9
+ }
10
+
11
+ export const StorageGroupsEmptyDataMessage = ({
12
+ visibleEntities,
13
+ onShowAll,
14
+ }: StorageNodesEmptyDataMessageProps) => {
15
+ let message;
16
+
17
+ if (visibleEntities === VISIBLE_ENTITIES.space) {
18
+ message = i18n('empty.out_of_space');
19
+ }
20
+
21
+ if (visibleEntities === VISIBLE_ENTITIES.missing) {
22
+ message = i18n('empty.degraded');
23
+ }
24
+
25
+ if (message) {
26
+ return <EmptyFilter title={message} showAll={i18n('show_all')} onShowAll={onShowAll} />;
27
+ }
28
+
29
+ return null;
30
+ };
@@ -0,0 +1,94 @@
1
+ import {useCallback, useMemo} from 'react';
2
+
3
+ import type {NodesMap} from '../../../types/store/nodesList';
4
+ import type {StorageSortValue} from '../../../utils/storage';
5
+ import {
6
+ VirtualTable,
7
+ type FetchData,
8
+ type RenderControls,
9
+ type RenderErrorMessage,
10
+ } from '../../../components/VirtualTable';
11
+ import type {PreparedStorageGroup, VisibleEntities} from '../../../store/reducers/storage/types';
12
+ import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
13
+
14
+ import {StorageGroupsEmptyDataMessage} from './StorageGroupsEmptyDataMessage';
15
+ import {getPreparedStorageGroupsColumns} from './getStorageGroupsColumns';
16
+ import {getStorageGroups} from './getGroups';
17
+ import i18n from './i18n';
18
+
19
+ interface VirtualStorageGroupsProps {
20
+ searchValue: string;
21
+ visibleEntities: VisibleEntities;
22
+ tenant?: string;
23
+ nodeId?: string;
24
+ nodesMap?: NodesMap;
25
+
26
+ onShowAll: VoidFunction;
27
+
28
+ parentContainer?: Element | null;
29
+ renderControls: RenderControls;
30
+ renderErrorMessage: RenderErrorMessage;
31
+ }
32
+
33
+ export const VirtualStorageGroups = ({
34
+ searchValue,
35
+ visibleEntities,
36
+ tenant,
37
+ nodeId,
38
+ nodesMap,
39
+ onShowAll,
40
+ parentContainer,
41
+ renderControls,
42
+ renderErrorMessage,
43
+ }: VirtualStorageGroupsProps) => {
44
+ const filters = useMemo(() => {
45
+ return [searchValue, visibleEntities, tenant, nodeId];
46
+ }, [searchValue, visibleEntities, tenant, nodeId]);
47
+
48
+ const fetchData = useCallback<FetchData<PreparedStorageGroup>>(
49
+ async (limit, offset, {sortOrder, columnId} = {}) => {
50
+ return await getStorageGroups({
51
+ limit,
52
+ offset,
53
+ filter: searchValue,
54
+ visibleEntities,
55
+ tenant,
56
+ nodeId,
57
+
58
+ sortOrder,
59
+ sortValue: columnId as StorageSortValue,
60
+ });
61
+ },
62
+ [nodeId, searchValue, tenant, visibleEntities],
63
+ );
64
+
65
+ const columns = useMemo(() => {
66
+ return getPreparedStorageGroupsColumns(nodesMap, visibleEntities);
67
+ }, [nodesMap, visibleEntities]);
68
+
69
+ const renderEmptyDataMessage = () => {
70
+ if (visibleEntities !== VISIBLE_ENTITIES.all) {
71
+ return (
72
+ <StorageGroupsEmptyDataMessage
73
+ onShowAll={onShowAll}
74
+ visibleEntities={visibleEntities}
75
+ />
76
+ );
77
+ }
78
+
79
+ return i18n('empty.default');
80
+ };
81
+
82
+ return (
83
+ <VirtualTable
84
+ parentContainer={parentContainer}
85
+ columns={columns}
86
+ fetchData={fetchData}
87
+ limit={50}
88
+ renderControls={renderControls}
89
+ renderErrorMessage={renderErrorMessage}
90
+ renderEmptyDataMessage={renderEmptyDataMessage}
91
+ dependencyArray={filters}
92
+ />
93
+ );
94
+ };
@@ -0,0 +1,21 @@
1
+ import type {StorageApiRequestParams} from '../../../store/reducers/storage/types';
2
+ import {prepareStorageGroupsResponse} from '../../../store/reducers/storage/utils';
3
+ import {EVersion} from '../../../types/api/storage';
4
+
5
+ const getConcurrentId = (limit?: number, offset?: number) => {
6
+ return `getStorageGroups|offset${offset}|limit${limit}`;
7
+ };
8
+
9
+ export const getStorageGroups = async ({limit, offset, ...params}: StorageApiRequestParams) => {
10
+ const response = await window.api.getStorageInfo(
11
+ {version: EVersion.v2, limit, offset, ...params},
12
+ {concurrentId: getConcurrentId(limit, offset)},
13
+ );
14
+ const preparedResponse = prepareStorageGroupsResponse(response);
15
+
16
+ return {
17
+ data: preparedResponse.groups || [],
18
+ found: preparedResponse.found || 0,
19
+ total: preparedResponse.total || 0,
20
+ };
21
+ };
@@ -1,13 +1,14 @@
1
1
  import cn from 'bem-cn-lite';
2
2
 
3
- import DataTable, {type Column} from '@gravity-ui/react-data-table';
3
+ import DataTable, {type Column as DataTableColumn} from '@gravity-ui/react-data-table';
4
4
  import {Icon, Label, Popover, PopoverBehavior} from '@gravity-ui/uikit';
5
5
 
6
+ import type {Column as VirtualTableColumn} from '../../../components/VirtualTable';
6
7
  import shieldIcon from '../../../assets/icons/shield.svg';
7
- import type {ValueOf} from '../../../types/common';
8
8
  import type {NodesMap} from '../../../types/store/nodesList';
9
- import type {PreparedStorageGroup} from '../../../store/reducers/storage/types';
10
- import {getUsage, isFullVDiskData} from '../../../utils/storage';
9
+ import type {PreparedStorageGroup, VisibleEntities} from '../../../store/reducers/storage/types';
10
+ import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
11
+ import {getUsage, isFullVDiskData, isSortableStorageProperty} from '../../../utils/storage';
11
12
  import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
12
13
  import {stringifyVdiskId} from '../../../utils/dataFormatters/dataFormatters';
13
14
  import EntityStatus from '../../../components/EntityStatus/EntityStatus';
@@ -21,7 +22,10 @@ import './StorageGroups.scss';
21
22
 
22
23
  const b = cn('global-storage-groups');
23
24
 
24
- const GROUPS_COLUMNS_IDS = {
25
+ type StorageGroupsColumn = VirtualTableColumn<PreparedStorageGroup> &
26
+ DataTableColumn<PreparedStorageGroup>;
27
+
28
+ export const GROUPS_COLUMNS_IDS = {
25
29
  PoolName: 'PoolName',
26
30
  Kind: 'Kind',
27
31
  Erasure: 'Erasure',
@@ -36,26 +40,9 @@ const GROUPS_COLUMNS_IDS = {
36
40
  Degraded: 'Degraded',
37
41
  } as const;
38
42
 
39
- type GroupsColumns = ValueOf<typeof GROUPS_COLUMNS_IDS>;
40
-
41
- const tableColumnsNames: Record<GroupsColumns, string> = {
42
- PoolName: 'Pool Name',
43
- Kind: 'Type',
44
- Erasure: 'Erasure',
45
- GroupId: 'Group ID',
46
- Used: 'Used',
47
- Limit: 'Limit',
48
- UsedSpaceFlag: 'Space',
49
- Usage: 'Usage',
50
- Read: 'Read',
51
- Write: 'Write',
52
- VDisks: 'VDisks',
53
- Degraded: 'Degraded',
54
- };
55
-
56
- const poolNameColumn: Column<PreparedStorageGroup> = {
43
+ const poolNameColumn: StorageGroupsColumn = {
57
44
  name: GROUPS_COLUMNS_IDS.PoolName,
58
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.PoolName],
45
+ header: 'Pool Name',
59
46
  width: 250,
60
47
  render: ({row}) => {
61
48
  const splitted = row.PoolName?.split('/');
@@ -75,14 +62,15 @@ const poolNameColumn: Column<PreparedStorageGroup> = {
75
62
  align: DataTable.LEFT,
76
63
  };
77
64
 
78
- const kindColumn: Column<PreparedStorageGroup> = {
65
+ const kindColumn: StorageGroupsColumn = {
79
66
  name: GROUPS_COLUMNS_IDS.Kind,
80
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Kind],
81
- // prettier-ignore
67
+ header: 'Type',
68
+ width: 100,
69
+ align: DataTable.LEFT,
82
70
  render: ({row}) => (
83
71
  <>
84
72
  <Label>{row.Kind || '—'}</Label>
85
- {' '}
73
+ {'\u00a0'}
86
74
  {row.Encryption && (
87
75
  <Popover
88
76
  content={i18n('encrypted')}
@@ -99,17 +87,18 @@ const kindColumn: Column<PreparedStorageGroup> = {
99
87
  sortable: false,
100
88
  };
101
89
 
102
- const erasureColumn: Column<PreparedStorageGroup> = {
90
+ const erasureColumn: StorageGroupsColumn = {
103
91
  name: GROUPS_COLUMNS_IDS.Erasure,
104
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Erasure],
92
+ header: 'Erasure',
93
+ width: 100,
105
94
  render: ({row}) => (row.ErasureSpecies ? row.ErasureSpecies : '-'),
106
95
  align: DataTable.LEFT,
107
96
  sortable: false,
108
97
  };
109
98
 
110
- const degradedColumn: Column<PreparedStorageGroup> = {
99
+ const degradedColumn: StorageGroupsColumn = {
111
100
  name: GROUPS_COLUMNS_IDS.Degraded,
112
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Degraded],
101
+ header: 'Degraded',
113
102
  width: 100,
114
103
  render: ({row}) =>
115
104
  row.Degraded ? (
@@ -121,9 +110,9 @@ const degradedColumn: Column<PreparedStorageGroup> = {
121
110
  defaultOrder: DataTable.DESCENDING,
122
111
  };
123
112
 
124
- const usageColumn: Column<PreparedStorageGroup> = {
113
+ const usageColumn: StorageGroupsColumn = {
125
114
  name: GROUPS_COLUMNS_IDS.Usage,
126
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Usage],
115
+ header: 'Usage',
127
116
  width: 100,
128
117
  render: ({row}) => {
129
118
  // without a limit the usage can be evaluated as 0,
@@ -140,9 +129,9 @@ const usageColumn: Column<PreparedStorageGroup> = {
140
129
  sortable: false,
141
130
  };
142
131
 
143
- const groupIdColumn: Column<PreparedStorageGroup> = {
132
+ const groupIdColumn: StorageGroupsColumn = {
144
133
  name: GROUPS_COLUMNS_IDS.GroupId,
145
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.GroupId],
134
+ header: 'Group ID',
146
135
  width: 130,
147
136
  render: ({row}) => {
148
137
  return <span className={b('group-id')}>{row.GroupID}</span>;
@@ -152,9 +141,9 @@ const groupIdColumn: Column<PreparedStorageGroup> = {
152
141
  sortable: false,
153
142
  };
154
143
 
155
- const usedColumn: Column<PreparedStorageGroup> = {
144
+ const usedColumn: StorageGroupsColumn = {
156
145
  name: GROUPS_COLUMNS_IDS.Used,
157
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Used],
146
+ header: 'Used',
158
147
  width: 100,
159
148
  render: ({row}) => {
160
149
  return bytesToGB(row.Used, true);
@@ -163,9 +152,9 @@ const usedColumn: Column<PreparedStorageGroup> = {
163
152
  sortable: false,
164
153
  };
165
154
 
166
- const limitColumn: Column<PreparedStorageGroup> = {
155
+ const limitColumn: StorageGroupsColumn = {
167
156
  name: GROUPS_COLUMNS_IDS.Limit,
168
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Limit],
157
+ header: 'Limit',
169
158
  width: 100,
170
159
  render: ({row}) => {
171
160
  return bytesToGB(row.Limit);
@@ -174,9 +163,9 @@ const limitColumn: Column<PreparedStorageGroup> = {
174
163
  sortable: false,
175
164
  };
176
165
 
177
- const usedSpaceFlagColumn: Column<PreparedStorageGroup> = {
166
+ const usedSpaceFlagColumn: StorageGroupsColumn = {
178
167
  name: GROUPS_COLUMNS_IDS.UsedSpaceFlag,
179
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.UsedSpaceFlag],
168
+ header: 'Space',
180
169
  width: 110,
181
170
  render: ({row}) => {
182
171
  const value = row.UsedSpaceFlag;
@@ -195,9 +184,9 @@ const usedSpaceFlagColumn: Column<PreparedStorageGroup> = {
195
184
  align: DataTable.CENTER,
196
185
  };
197
186
 
198
- const readColumn: Column<PreparedStorageGroup> = {
187
+ const readColumn: StorageGroupsColumn = {
199
188
  name: GROUPS_COLUMNS_IDS.Read,
200
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Read],
189
+ header: 'Read',
201
190
  width: 100,
202
191
  render: ({row}) => {
203
192
  return row.Read ? bytesToSpeed(row.Read) : '-';
@@ -205,9 +194,9 @@ const readColumn: Column<PreparedStorageGroup> = {
205
194
  align: DataTable.RIGHT,
206
195
  };
207
196
 
208
- const writeColumn: Column<PreparedStorageGroup> = {
197
+ const writeColumn: StorageGroupsColumn = {
209
198
  name: GROUPS_COLUMNS_IDS.Write,
210
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.Write],
199
+ header: 'Write',
211
200
  width: 100,
212
201
  render: ({row}) => {
213
202
  return row.Write ? bytesToSpeed(row.Write) : '-';
@@ -215,10 +204,10 @@ const writeColumn: Column<PreparedStorageGroup> = {
215
204
  align: DataTable.RIGHT,
216
205
  };
217
206
 
218
- const getVdiscksColumn = (nodes?: NodesMap): Column<PreparedStorageGroup> => ({
207
+ const getVdiscksColumn = (nodes?: NodesMap): StorageGroupsColumn => ({
219
208
  name: GROUPS_COLUMNS_IDS.VDisks,
220
209
  className: b('vdisks-column'),
221
- header: tableColumnsNames[GROUPS_COLUMNS_IDS.VDisks],
210
+ header: 'VDisks',
222
211
  render: ({row}) => (
223
212
  <div className={b('vdisks-wrapper')}>
224
213
  {row.VDisks?.map((vDisk) => {
@@ -252,11 +241,11 @@ const getVdiscksColumn = (nodes?: NodesMap): Column<PreparedStorageGroup> => ({
252
241
  width: 900,
253
242
  });
254
243
 
255
- export const getStorageTopGroupsColumns = (): Column<PreparedStorageGroup>[] => {
244
+ export const getStorageTopGroupsColumns = (): StorageGroupsColumn[] => {
256
245
  return [groupIdColumn, kindColumn, erasureColumn, usageColumn, usedColumn, limitColumn];
257
246
  };
258
247
 
259
- export const getStorageGroupsColumns = (nodes?: NodesMap): Column<PreparedStorageGroup>[] => {
248
+ const getStorageGroupsColumns = (nodes?: NodesMap): StorageGroupsColumn[] => {
260
249
  return [
261
250
  poolNameColumn,
262
251
  kindColumn,
@@ -272,3 +261,37 @@ export const getStorageGroupsColumns = (nodes?: NodesMap): Column<PreparedStorag
272
261
  getVdiscksColumn(nodes),
273
262
  ];
274
263
  };
264
+
265
+ const filterStorageGroupsColumns = (
266
+ columns: StorageGroupsColumn[],
267
+ visibleEntities: VisibleEntities,
268
+ ) => {
269
+ if (visibleEntities === VISIBLE_ENTITIES.space) {
270
+ return columns.filter((col) => col.name !== GROUPS_COLUMNS_IDS.Degraded);
271
+ }
272
+
273
+ if (visibleEntities === VISIBLE_ENTITIES.missing) {
274
+ return columns.filter((col) => col.name !== GROUPS_COLUMNS_IDS.UsedSpaceFlag);
275
+ }
276
+
277
+ return columns.filter((col) => {
278
+ return (
279
+ col.name !== GROUPS_COLUMNS_IDS.Degraded &&
280
+ col.name !== GROUPS_COLUMNS_IDS.UsedSpaceFlag
281
+ );
282
+ });
283
+ };
284
+
285
+ export const getPreparedStorageGroupsColumns = (
286
+ nodesMap: NodesMap | undefined,
287
+ visibleEntities: VisibleEntities,
288
+ ) => {
289
+ const rawColumns = getStorageGroupsColumns(nodesMap);
290
+
291
+ const filteredColumns = filterStorageGroupsColumns(rawColumns, visibleEntities);
292
+
293
+ return filteredColumns.map((column) => ({
294
+ ...column,
295
+ sortable: isSortableStorageProperty(column.name),
296
+ }));
297
+ };