Skip to content

Commit

Permalink
More Sort UI (#799)
Browse files Browse the repository at this point in the history
- Adds Sort Option for QRep Table
- Fixes width issue of Select components where when typing it shrinks
- Align table button options better
- Set sort for initial copy to be descending by default
  • Loading branch information
Amogh-Bharadwaj authored Dec 12, 2023
1 parent a7b615f commit 1e07923
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 64 deletions.
32 changes: 17 additions & 15 deletions ui/app/mirrors/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,21 +137,23 @@ export default function CreateMirrors() {
alignItems: 'center',
}}
>
<ReactSelect
placeholder={`Select the ${
peerEnd === 'src' ? 'source' : 'destination'
} peer`}
onChange={(val, action) =>
handlePeer(val, peerEnd as 'src' | 'dst', setConfig)
}
options={
(peerEnd === 'src'
? peers.filter((peer) => peer.type == DBType.POSTGRES)
: peers) ?? []
}
getOptionValue={getPeerValue}
formatOptionLabel={getPeerLabel}
/>
<div style={{ width: '100%' }}>
<ReactSelect
placeholder={`Select the ${
peerEnd === 'src' ? 'source' : 'destination'
} peer`}
onChange={(val, action) =>
handlePeer(val, peerEnd as 'src' | 'dst', setConfig)
}
options={
(peerEnd === 'src'
? peers.filter((peer) => peer.type == DBType.POSTGRES)
: peers) ?? []
}
getOptionValue={getPeerValue}
formatOptionLabel={getPeerLabel}
/>
</div>
<InfoPopover
tips={
'The peer from which we will be replicating data. Ensure the prerequisites for this peer are met.'
Expand Down
42 changes: 24 additions & 18 deletions ui/app/mirrors/edit/[mirrorId]/cdc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const SnapshotStatusTable = ({ status }: SnapshotStatusProps) => {
const [currentPage, setCurrentPage] = useState(1);
const totalPages = Math.ceil(allRows.length / ROWS_PER_PAGE);
const [searchQuery, setSearchQuery] = useState<string>('');
const [sortDir, setSortDir] = useState<'asc' | 'dsc'>('asc');
const [sortDir, setSortDir] = useState<'asc' | 'dsc'>('dsc');
const displayedRows = useMemo(() => {
const shownRows = allRows.filter((row: any) =>
row.tableName.toLowerCase().includes(searchQuery.toLowerCase())
Expand Down Expand Up @@ -156,7 +156,7 @@ export const SnapshotStatusTable = ({ status }: SnapshotStatusProps) => {
title={<Label variant='headline'>Initial Copy</Label>}
toolbar={{
left: (
<>
<div style={{ display: 'flex', alignItems: 'center' }}>
<Button variant='normalBorderless' onClick={handlePrevPage}>
<Icon name='chevron_left' />
</Button>
Expand All @@ -170,21 +170,27 @@ export const SnapshotStatusTable = ({ status }: SnapshotStatusProps) => {
>
<Icon name='refresh' />
</Button>
<ReactSelect
options={sortOptions}
onChange={(val, _) => {
const sortVal =
(val?.value as 'cloneStartTime' | 'avgTimePerPartition') ??
'cloneStartTime';
setSortField(sortVal);
}}
value={{
value: sortField,
label: sortOptions.find((opt) => opt.value === sortField)
?.label,
}}
defaultValue={{ value: 'cloneStartTime', label: 'Start Time' }}
/>
<div style={{ minWidth: '10em' }}>
<ReactSelect
options={sortOptions}
onChange={(val, _) => {
const sortVal =
(val?.value as
| 'cloneStartTime'
| 'avgTimePerPartition') ?? 'cloneStartTime';
setSortField(sortVal);
}}
value={{
value: sortField,
label: sortOptions.find((opt) => opt.value === sortField)
?.label,
}}
defaultValue={{
value: 'cloneStartTime',
label: 'Start Time',
}}
/>
</div>
<button
className='IconButton'
onClick={() => setSortDir('asc')}
Expand All @@ -201,7 +207,7 @@ export const SnapshotStatusTable = ({ status }: SnapshotStatusProps) => {
>
<Icon name='arrow_downward' />
</button>
</>
</div>
),
right: (
<SearchField
Expand Down
42 changes: 22 additions & 20 deletions ui/app/mirrors/edit/[mirrorId]/syncStatusTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const SyncStatusTable = ({ rows }: SyncStatusTableProps) => {
title={<Label variant='headline'>CDC Syncs</Label>}
toolbar={{
left: (
<>
<div style={{ display: 'flex', alignItems: 'center' }}>
<Button variant='normalBorderless' onClick={handlePrevPage}>
<Icon name='chevron_left' />
</Button>
Expand All @@ -118,24 +118,26 @@ export const SyncStatusTable = ({ rows }: SyncStatusTableProps) => {
>
<Icon name='refresh' />
</Button>
<ReactSelect
options={sortOptions}
value={{
value: sortField,
label: sortOptions.find((opt) => opt.value === sortField)
?.label,
}}
onChange={(val, _) => {
const sortVal =
(val?.value as
| 'startTime'
| 'endTime'
| 'numRows'
| 'batchId') ?? 'batchId';
setSortField(sortVal);
}}
defaultValue={{ value: 'batchId', label: 'Batch ID' }}
/>
<div style={{ minWidth: '10em' }}>
<ReactSelect
options={sortOptions}
value={{
value: sortField,
label: sortOptions.find((opt) => opt.value === sortField)
?.label,
}}
onChange={(val, _) => {
const sortVal =
(val?.value as
| 'startTime'
| 'endTime'
| 'numRows'
| 'batchId') ?? 'batchId';
setSortField(sortVal);
}}
defaultValue={{ value: 'batchId', label: 'Batch ID' }}
/>
</div>
<button
className='IconButton'
onClick={() => setSortDir('asc')}
Expand All @@ -152,7 +154,7 @@ export const SyncStatusTable = ({ rows }: SyncStatusTableProps) => {
>
<Icon name='arrow_downward' />
</button>
</>
</div>
),
right: (
<SearchField
Expand Down
77 changes: 66 additions & 11 deletions ui/app/mirrors/status/qrep/[mirrorId]/qrepStatusTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SearchField } from '@/lib/SearchField';
import { Table, TableCell, TableRow } from '@/lib/Table';
import moment from 'moment';
import { useMemo, useState } from 'react';
import ReactSelect from 'react-select';

export type QRepPartitionStatus = {
partitionId: string;
Expand Down Expand Up @@ -61,9 +62,7 @@ function RowPerPartition({
<TimeLabel timeVal={moment(startTime)?.format('YYYY-MM-DD HH:mm:ss')} />
</TableCell>
<TableCell>
<Label>
<TimeOrProgressBar time={endTime} />
</Label>
<TimeOrProgressBar time={endTime} />
</TableCell>
<TableCell>
<Label>{numRows}</Label>
Expand Down Expand Up @@ -91,15 +90,35 @@ export default function QRepStatusTable({
);

const [searchQuery, setSearchQuery] = useState<string>('');
const displayedPartitions = useMemo(
() =>
visiblePartitions.filter((partition: QRepPartitionStatus) => {
const [sortField, setSortField] = useState<'startTime' | 'endTime'>(
'startTime'
);
const [sortDir, setSortDir] = useState<'asc' | 'dsc'>('dsc');
const displayedPartitions = useMemo(() => {
let currentPartitions = [...visiblePartitions];
(currentPartitions = currentPartitions.filter(
(partition: QRepPartitionStatus) => {
return partition.partitionId
.toLowerCase()
.includes(searchQuery.toLowerCase());
}),
[visiblePartitions, searchQuery]
);
}
)),
currentPartitions.sort((a, b) => {
const aValue = a[sortField];
const bValue = b[sortField];
if (aValue === null || bValue === null) {
return 0;
}
if (aValue < bValue) {
return sortDir === 'dsc' ? 1 : -1;
} else if (aValue > bValue) {
return sortDir === 'dsc' ? -1 : 1;
} else {
return 0;
}
});
return currentPartitions;
}, [visiblePartitions, searchQuery, sortField, sortDir]);

const handleNext = () => {
if (currentPage < totalPages) setCurrentPage(currentPage + 1);
Expand All @@ -109,12 +128,16 @@ export default function QRepStatusTable({
if (currentPage > 1) setCurrentPage(currentPage - 1);
};

const sortOptions = [
{ value: 'startTime', label: 'Start Time' },
{ value: 'endTime', label: 'End Time' },
];
return (
<Table
title={<Label>Progress</Label>}
toolbar={{
left: (
<>
<div style={{ display: 'flex', alignItems: 'center' }}>
<Button
variant='normalBorderless'
onClick={handlePrevious}
Expand All @@ -138,12 +161,44 @@ export default function QRepStatusTable({
<Button variant='normalBorderless' disabled>
<Icon name='download' />
</Button>
<div style={{ minWidth: '10em' }}>
<ReactSelect
options={sortOptions}
value={{
value: sortField,
label: sortOptions.find((opt) => opt.value === sortField)
?.label,
}}
onChange={(val, _) => {
const sortVal =
(val?.value as 'startTime' | 'endTime') ?? 'startTime';
setSortField(sortVal);
}}
defaultValue={{ value: 'startTime', label: 'Start Time' }}
/>
</div>
<button
className='IconButton'
onClick={() => setSortDir('asc')}
aria-label='sort up'
style={{ color: sortDir == 'asc' ? 'green' : 'gray' }}
>
<Icon name='arrow_upward' />
</button>
<button
className='IconButton'
onClick={() => setSortDir('dsc')}
aria-label='sort down'
style={{ color: sortDir == 'dsc' ? 'green' : 'gray' }}
>
<Icon name='arrow_downward' />
</button>
<div>
<Label>
{currentPage} of {totalPages}
</Label>
</div>
</>
</div>
),
right: (
<SearchField
Expand Down
1 change: 1 addition & 0 deletions ui/components/SelectSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default function SelectSource({

return (
<ReactSelect
className='w-1/2'
placeholder='Select a source'
options={dbTypes}
defaultValue={dbTypes.find((opt) => opt.value === peerType)}
Expand Down

0 comments on commit 1e07923

Please sign in to comment.