|
1 | | -import React from 'react'; |
2 | | - |
3 | | -import type {Column} from '@gravity-ui/react-data-table'; |
4 | 1 | import DataTable from '@gravity-ui/react-data-table'; |
5 | 2 |
|
6 | | -import {Icon} from '../../../../components/Icon'; |
7 | | -import type {EPathType, TColumnDescription} from '../../../../types/api/schema'; |
| 3 | +import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton'; |
| 4 | +import type {EPathType} from '../../../../types/api/schema'; |
8 | 5 | import {cn} from '../../../../utils/cn'; |
9 | 6 | import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants'; |
10 | | -import {isExternalTable} from '../../utils/schema'; |
| 7 | +import {useTypedSelector} from '../../../../utils/hooks'; |
| 8 | + |
| 9 | +import { |
| 10 | + SchemaViewerColumns, |
| 11 | + prepareColumnDescriptions, |
| 12 | + prepareFamilies, |
| 13 | + prepareSchemaTableColumns, |
| 14 | +} from './helpers'; |
11 | 15 |
|
12 | 16 | import './SchemaViewer.scss'; |
13 | 17 |
|
14 | 18 | const b = cn('schema-viewer'); |
15 | 19 |
|
16 | | -const SchemaViewerColumns = { |
17 | | - id: 'Id', |
18 | | - name: 'Name', |
19 | | - key: 'Key', |
20 | | - type: 'Type', |
21 | | - notNull: 'NotNull', |
22 | | -}; |
23 | | - |
24 | 20 | interface SchemaViewerProps { |
25 | | - keyColumnIds?: number[]; |
26 | | - columns?: TColumnDescription[]; |
| 21 | + className?: string; |
27 | 22 | type?: EPathType; |
| 23 | + path?: string; |
| 24 | + withFamilies?: boolean; |
28 | 25 | } |
29 | 26 |
|
30 | | -export const SchemaViewer = ({keyColumnIds = [], columns = [], type}: SchemaViewerProps) => { |
31 | | - // Keys should be displayd by their order in keyColumnIds (Primary Key) |
32 | | - const keyColumnsOrderValues = React.useMemo(() => { |
33 | | - return keyColumnIds.reduce<Record<number, number>>((result, keyColumnId, index) => { |
34 | | - // Put columns with negative values, so they will be the first with ascending sort |
35 | | - // Minus keyColumnIds.length for the first key, -1 for the last |
36 | | - result[keyColumnId] = index - keyColumnIds.length; |
37 | | - return result; |
38 | | - }, {}); |
39 | | - }, [keyColumnIds]); |
| 27 | +export const SchemaViewer = ({className, type, path, withFamilies = false}: SchemaViewerProps) => { |
| 28 | + const {data, loading} = useTypedSelector((state) => state.schema); |
| 29 | + const currentObjectData = path ? data[path] : undefined; |
40 | 30 |
|
41 | | - let dataTableColumns: Column<TColumnDescription>[] = [ |
42 | | - { |
43 | | - name: SchemaViewerColumns.id, |
44 | | - width: 40, |
45 | | - }, |
46 | | - { |
47 | | - name: SchemaViewerColumns.key, |
48 | | - width: 40, |
49 | | - // Table should start with key columns on sort click |
50 | | - defaultOrder: DataTable.ASCENDING, |
51 | | - sortAccessor: (row) => { |
52 | | - // Values in keyColumnsOrderValues are always negative, so it will be 1 for not key columns |
53 | | - return (row.Id && keyColumnsOrderValues[row.Id]) || 1; |
54 | | - }, |
55 | | - render: ({row}) => { |
56 | | - return row.Id && keyColumnIds.includes(row.Id) ? ( |
57 | | - <div className={b('key-icon')}> |
58 | | - <Icon name="key" viewBox="0 0 12 7" width={12} height={7} /> |
59 | | - </div> |
60 | | - ) : null; |
61 | | - }, |
62 | | - }, |
63 | | - { |
64 | | - name: SchemaViewerColumns.name, |
65 | | - width: 100, |
66 | | - }, |
67 | | - { |
68 | | - name: SchemaViewerColumns.type, |
69 | | - width: 100, |
70 | | - }, |
71 | | - { |
72 | | - name: SchemaViewerColumns.notNull, |
73 | | - width: 100, |
74 | | - // Table should start with notNull columns on sort click |
75 | | - defaultOrder: DataTable.DESCENDING, |
76 | | - render: ({row}) => { |
77 | | - if (row.NotNull) { |
78 | | - return '\u2713'; |
79 | | - } |
80 | | - |
81 | | - return undefined; |
82 | | - }, |
83 | | - }, |
84 | | - ]; |
85 | | - |
86 | | - if (isExternalTable(type)) { |
87 | | - // External tables don't have key columns |
88 | | - dataTableColumns = dataTableColumns.filter( |
89 | | - (column) => column.name !== SchemaViewerColumns.key, |
90 | | - ); |
91 | | - } |
| 31 | + const {columns, keyColumnIds} = prepareColumnDescriptions(type, currentObjectData); |
| 32 | + const families = prepareFamilies(currentObjectData); |
92 | 33 |
|
93 | 34 | return ( |
94 | | - <div className={b()}> |
95 | | - <DataTable |
96 | | - theme="yandex-cloud" |
97 | | - data={columns} |
98 | | - columns={dataTableColumns} |
99 | | - settings={DEFAULT_TABLE_SETTINGS} |
100 | | - initialSortOrder={{columnId: SchemaViewerColumns.key, order: DataTable.ASCENDING}} |
101 | | - /> |
| 35 | + <div className={b(null, className)}> |
| 36 | + {loading ? ( |
| 37 | + <TableSkeleton /> |
| 38 | + ) : ( |
| 39 | + <DataTable |
| 40 | + theme="yandex-cloud" |
| 41 | + data={columns} |
| 42 | + columns={prepareSchemaTableColumns({ |
| 43 | + type, |
| 44 | + b, |
| 45 | + families, |
| 46 | + keyColumnIds, |
| 47 | + withFamilies, |
| 48 | + })} |
| 49 | + settings={DEFAULT_TABLE_SETTINGS} |
| 50 | + initialSortOrder={{ |
| 51 | + columnId: SchemaViewerColumns.key, |
| 52 | + order: DataTable.ASCENDING, |
| 53 | + }} |
| 54 | + /> |
| 55 | + )} |
102 | 56 | </div> |
103 | 57 | ); |
104 | 58 | }; |
105 | | - |
106 | | -export default SchemaViewer; |
0 commit comments