|
| 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'; |
| 9 | +import {EntitiesCount} from '../../components/EntitiesCount'; |
6 | 10 | import {EntityStatus} from '../../components/EntityStatus/EntityStatus'; |
| 11 | +import {ResponseError} from '../../components/Errors/ResponseError'; |
7 | 12 | import {InternalLink} from '../../components/InternalLink'; |
8 | 13 | import {ResizeableDataTable} from '../../components/ResizeableDataTable/ResizeableDataTable'; |
9 | | -import {TableSkeleton} from '../../components/TableSkeleton/TableSkeleton'; |
| 14 | +import {Search} from '../../components/Search/Search'; |
| 15 | +import {TableWithControlsLayout} from '../../components/TableWithControlsLayout/TableWithControlsLayout'; |
10 | 16 | import {TabletNameWrapper} from '../../components/TabletNameWrapper/TabletNameWrapper'; |
11 | 17 | import {TabletState} from '../../components/TabletState/TabletState'; |
12 | 18 | import {TabletUptime} from '../../components/UptimeViewer/UptimeViewer'; |
@@ -156,19 +162,51 @@ interface TabletsTableProps { |
156 | 162 | })[]; |
157 | 163 | className?: string; |
158 | 164 | loading?: boolean; |
| 165 | + error?: unknown; |
159 | 166 | } |
160 | 167 |
|
161 | | -export function TabletsTable({database, tablets, className, loading}: TabletsTableProps) { |
162 | | - if (loading) { |
163 | | - return <TableSkeleton />; |
164 | | - } |
| 168 | +export function TabletsTable({database, tablets, loading, error}: TabletsTableProps) { |
| 169 | + const [{tabletsSearch}, setQueryParams] = useQueryParams({ |
| 170 | + tabletsSearch: StringParam, |
| 171 | + }); |
| 172 | + |
| 173 | + const columns = React.useMemo(() => getColumns({database}), [database]); |
| 174 | + |
| 175 | + const filteredTablets = React.useMemo(() => { |
| 176 | + return tablets.filter((tablet) => { |
| 177 | + return String(tablet.TabletId).includes(tabletsSearch ?? ''); |
| 178 | + }); |
| 179 | + }, [tablets, tabletsSearch]); |
| 180 | + |
| 181 | + const handleSearchQueryChange = (value: string) => { |
| 182 | + setQueryParams({tabletsSearch: value || undefined}, 'replaceIn'); |
| 183 | + }; |
| 184 | + |
165 | 185 | return ( |
166 | | - <ResizeableDataTable |
167 | | - wrapperClassName={className} |
168 | | - columns={getColumns({database})} |
169 | | - data={tablets} |
170 | | - settings={DEFAULT_TABLE_SETTINGS} |
171 | | - emptyDataMessage={i18n('noTabletsData')} |
172 | | - /> |
| 186 | + <TableWithControlsLayout> |
| 187 | + <TableWithControlsLayout.Controls> |
| 188 | + <Search |
| 189 | + placeholder={i18n('controls.search-placeholder')} |
| 190 | + onChange={handleSearchQueryChange} |
| 191 | + value={tabletsSearch ?? ''} |
| 192 | + width={238} |
| 193 | + /> |
| 194 | + <EntitiesCount |
| 195 | + label={i18n('controls.entities-count-label')} |
| 196 | + loading={loading} |
| 197 | + total={tablets.length} |
| 198 | + current={filteredTablets.length} |
| 199 | + /> |
| 200 | + </TableWithControlsLayout.Controls> |
| 201 | + {error ? <ResponseError error={error} /> : null} |
| 202 | + <TableWithControlsLayout.Table loading={loading}> |
| 203 | + <ResizeableDataTable |
| 204 | + columns={columns} |
| 205 | + data={filteredTablets} |
| 206 | + settings={DEFAULT_TABLE_SETTINGS} |
| 207 | + emptyDataMessage={i18n('noTabletsData')} |
| 208 | + /> |
| 209 | + </TableWithControlsLayout.Table> |
| 210 | + </TableWithControlsLayout> |
173 | 211 | ); |
174 | 212 | } |
0 commit comments