|
| 1 | +import React from 'react'; |
| 2 | + |
1 | 3 | import {ArrowRotateLeft} from '@gravity-ui/icons'; |
2 | 4 | import type {Column as DataTableColumn} from '@gravity-ui/react-data-table'; |
3 | 5 | import {Icon, Text} from '@gravity-ui/uikit'; |
| 6 | +import {StringParam, useQueryParams} from 'use-query-params'; |
4 | 7 |
|
5 | 8 | import {ButtonWithConfirmDialog} from '../../components/ButtonWithConfirmDialog/ButtonWithConfirmDialog'; |
6 | 9 | import {EntityStatus} from '../../components/EntityStatus/EntityStatus'; |
| 10 | +import {ResponseError} from '../../components/Errors/ResponseError'; |
7 | 11 | import {InternalLink} from '../../components/InternalLink'; |
8 | 12 | import {ResizeableDataTable} from '../../components/ResizeableDataTable/ResizeableDataTable'; |
9 | | -import {TableSkeleton} from '../../components/TableSkeleton/TableSkeleton'; |
| 13 | +import {Search} from '../../components/Search/Search'; |
| 14 | +import {TableWithControlsLayout} from '../../components/TableWithControlsLayout/TableWithControlsLayout'; |
10 | 15 | import {TabletNameWrapper} from '../../components/TabletNameWrapper/TabletNameWrapper'; |
11 | 16 | import {TabletState} from '../../components/TabletState/TabletState'; |
12 | 17 | import {TabletUptime} from '../../components/UptimeViewer/UptimeViewer'; |
@@ -156,19 +161,45 @@ interface TabletsTableProps { |
156 | 161 | })[]; |
157 | 162 | className?: string; |
158 | 163 | loading?: boolean; |
| 164 | + error?: unknown; |
159 | 165 | } |
160 | 166 |
|
161 | | -export function TabletsTable({database, tablets, className, loading}: TabletsTableProps) { |
162 | | - if (loading) { |
163 | | - return <TableSkeleton />; |
164 | | - } |
| 167 | +export function TabletsTable({database, tablets, loading, error}: TabletsTableProps) { |
| 168 | + const [{tabletsSearch}, setQueryParams] = useQueryParams({ |
| 169 | + tabletsSearch: StringParam, |
| 170 | + }); |
| 171 | + |
| 172 | + const columns = React.useMemo(() => getColumns({database}), [database]); |
| 173 | + |
| 174 | + const data = React.useMemo(() => { |
| 175 | + return tablets.filter((tablet) => { |
| 176 | + return String(tablet.TabletId).includes(tabletsSearch ?? ''); |
| 177 | + }); |
| 178 | + }, [tablets, tabletsSearch]); |
| 179 | + |
| 180 | + const handleSearchQueryChange = (value: string) => { |
| 181 | + setQueryParams({tabletsSearch: value || undefined}, 'replaceIn'); |
| 182 | + }; |
| 183 | + |
165 | 184 | return ( |
166 | | - <ResizeableDataTable |
167 | | - wrapperClassName={className} |
168 | | - columns={getColumns({database})} |
169 | | - data={tablets} |
170 | | - settings={DEFAULT_TABLE_SETTINGS} |
171 | | - emptyDataMessage={i18n('noTabletsData')} |
172 | | - /> |
| 185 | + <TableWithControlsLayout> |
| 186 | + <TableWithControlsLayout.Controls> |
| 187 | + <Search |
| 188 | + placeholder={i18n('controls.search-placeholder')} |
| 189 | + onChange={handleSearchQueryChange} |
| 190 | + value={tabletsSearch ?? ''} |
| 191 | + width={190} |
| 192 | + /> |
| 193 | + </TableWithControlsLayout.Controls> |
| 194 | + {error ? <ResponseError error={error} /> : null} |
| 195 | + <TableWithControlsLayout.Table loading={loading}> |
| 196 | + <ResizeableDataTable |
| 197 | + columns={columns} |
| 198 | + data={data} |
| 199 | + settings={DEFAULT_TABLE_SETTINGS} |
| 200 | + emptyDataMessage={i18n('noTabletsData')} |
| 201 | + /> |
| 202 | + </TableWithControlsLayout.Table> |
| 203 | + </TableWithControlsLayout> |
173 | 204 | ); |
174 | 205 | } |
0 commit comments