mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Implement shift + click selection
This commit is contained in:
parent
22ce5094d4
commit
c1fc52821b
|
@ -100,6 +100,7 @@ function DataTable<TData extends RowData>({
|
|||
...restProps
|
||||
}: DataTableProps<TData>) {
|
||||
const [sorting, setSorting] = useState<SortingState>(initialSorting ? [initialSorting] : []);
|
||||
const [lastSelected, setLastSelected] = useState<string | undefined>(undefined);
|
||||
|
||||
const [pagination, setPagination] = useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
|
@ -147,6 +148,7 @@ function DataTable<TData extends RowData>({
|
|||
enableRowSelection={enableRowSelection}
|
||||
enableSorting={enableSorting}
|
||||
headPosition={headPosition}
|
||||
setLastSelected={setLastSelected}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
@ -155,6 +157,8 @@ function DataTable<TData extends RowData>({
|
|||
dense={dense}
|
||||
conditionalRowStyles={conditionalRowStyles}
|
||||
enableRowSelection={enableRowSelection}
|
||||
lastSelected={lastSelected}
|
||||
setLastSelected={setLastSelected}
|
||||
onRowClicked={onRowClicked}
|
||||
onRowDoubleClicked={onRowDoubleClicked}
|
||||
/>
|
||||
|
|
|
@ -4,9 +4,15 @@ import CheckboxTristate from '@/components/ui/CheckboxTristate';
|
|||
|
||||
interface SelectAllProps<TData> {
|
||||
table: Table<TData>;
|
||||
setLastSelected: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
}
|
||||
|
||||
function SelectAll<TData>({ table }: SelectAllProps<TData>) {
|
||||
function SelectAll<TData>({ table, setLastSelected }: SelectAllProps<TData>) {
|
||||
function handleChange(value: boolean | null) {
|
||||
setLastSelected(undefined);
|
||||
table.toggleAllPageRowsSelected(value !== false);
|
||||
}
|
||||
|
||||
return (
|
||||
<CheckboxTristate
|
||||
tabIndex={-1}
|
||||
|
@ -14,7 +20,7 @@ function SelectAll<TData>({ table }: SelectAllProps<TData>) {
|
|||
value={
|
||||
!table.getIsAllPageRowsSelected() && table.getIsSomePageRowsSelected() ? null : table.getIsAllPageRowsSelected()
|
||||
}
|
||||
setValue={value => table.toggleAllPageRowsSelected(value !== false)}
|
||||
setValue={handleChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,16 @@ import Checkbox from '@/components/ui/Checkbox';
|
|||
|
||||
interface SelectRowProps<TData> {
|
||||
row: Row<TData>;
|
||||
setLastSelected: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
}
|
||||
|
||||
function SelectRow<TData>({ row }: SelectRowProps<TData>) {
|
||||
return <Checkbox tabIndex={-1} value={row.getIsSelected()} setValue={row.getToggleSelectedHandler()} />;
|
||||
function SelectRow<TData>({ row, setLastSelected }: SelectRowProps<TData>) {
|
||||
function handleChange(value: boolean) {
|
||||
setLastSelected(row.id);
|
||||
row.toggleSelected(value);
|
||||
}
|
||||
|
||||
return <Checkbox tabIndex={-1} value={row.getIsSelected()} setValue={handleChange} />;
|
||||
}
|
||||
|
||||
export default SelectRow;
|
||||
|
|
|
@ -8,6 +8,10 @@ interface TableBodyProps<TData> {
|
|||
dense?: boolean;
|
||||
enableRowSelection?: boolean;
|
||||
conditionalRowStyles?: IConditionalStyle<TData>[];
|
||||
|
||||
lastSelected: string | undefined;
|
||||
setLastSelected: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
|
||||
onRowClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void;
|
||||
onRowDoubleClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void;
|
||||
}
|
||||
|
@ -17,15 +21,34 @@ function TableBody<TData>({
|
|||
dense,
|
||||
enableRowSelection,
|
||||
conditionalRowStyles,
|
||||
lastSelected,
|
||||
setLastSelected,
|
||||
onRowClicked,
|
||||
onRowDoubleClicked
|
||||
}: TableBodyProps<TData>) {
|
||||
function handleRowClicked(row: Row<TData>, event: React.MouseEvent<Element, MouseEvent>) {
|
||||
function handleRowClicked(target: Row<TData>, event: React.MouseEvent<Element, MouseEvent>) {
|
||||
if (onRowClicked) {
|
||||
onRowClicked(row.original, event);
|
||||
onRowClicked(target.original, event);
|
||||
}
|
||||
if (enableRowSelection && target.getCanSelect()) {
|
||||
if (event.shiftKey && !!lastSelected && lastSelected !== target.id) {
|
||||
const { rows, rowsById } = table.getRowModel();
|
||||
const lastIndex = rowsById[lastSelected].index;
|
||||
const currentIndex = target.index;
|
||||
const toggleRows = rows.slice(
|
||||
lastIndex > currentIndex ? currentIndex : lastIndex + 1,
|
||||
lastIndex > currentIndex ? lastIndex : currentIndex + 1
|
||||
);
|
||||
const newSelection: { [key: string]: boolean } = {};
|
||||
toggleRows.forEach(row => {
|
||||
newSelection[row.id] = !target.getIsSelected();
|
||||
});
|
||||
table.setRowSelection(prev => ({ ...prev, ...newSelection }));
|
||||
setLastSelected(undefined);
|
||||
} else {
|
||||
setLastSelected(target.id);
|
||||
target.toggleSelected(!target.getIsSelected());
|
||||
}
|
||||
if (enableRowSelection && row.getCanSelect()) {
|
||||
row.getToggleSelectedHandler()(!row.getIsSelected());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +76,7 @@ function TableBody<TData>({
|
|||
>
|
||||
{enableRowSelection ? (
|
||||
<td key={`select-${row.id}`} className='pl-3 pr-1 align-middle border-y'>
|
||||
<SelectRow row={row} />
|
||||
<SelectRow row={row} setLastSelected={setLastSelected} />
|
||||
</td>
|
||||
) : null}
|
||||
{row.getVisibleCells().map((cell: Cell<TData, unknown>) => (
|
||||
|
|
|
@ -8,9 +8,16 @@ interface TableHeaderProps<TData> {
|
|||
headPosition?: string;
|
||||
enableRowSelection?: boolean;
|
||||
enableSorting?: boolean;
|
||||
setLastSelected: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
}
|
||||
|
||||
function TableHeader<TData>({ table, headPosition, enableRowSelection, enableSorting }: TableHeaderProps<TData>) {
|
||||
function TableHeader<TData>({
|
||||
table,
|
||||
headPosition,
|
||||
enableRowSelection,
|
||||
enableSorting,
|
||||
setLastSelected
|
||||
}: TableHeaderProps<TData>) {
|
||||
return (
|
||||
<thead
|
||||
className='clr-app shadow-border'
|
||||
|
@ -23,7 +30,7 @@ function TableHeader<TData>({ table, headPosition, enableRowSelection, enableSor
|
|||
<tr key={headerGroup.id}>
|
||||
{enableRowSelection ? (
|
||||
<th className='pl-3 pr-1 align-middle'>
|
||||
<SelectAll table={table} />
|
||||
<SelectAll table={table} setLastSelected={setLastSelected} />
|
||||
</th>
|
||||
) : null}
|
||||
{headerGroup.headers.map((header: Header<TData, unknown>) => (
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
import clsx from 'clsx';
|
||||
import { useLayoutEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { type RowSelectionState } from '@/components/ui/DataTable';
|
||||
import SelectedCounter from '@/components/info/SelectedCounter';
|
||||
import { type RowSelectionState } from '@/components/ui/DataTable';
|
||||
import { useConceptTheme } from '@/context/ThemeContext';
|
||||
import { ConstituentaID, CstType } from '@/models/rsform';
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user