Enable multi-selection on table views (#112)
* Enable multi-selection on table views * Enable multi-selection
This commit is contained in:
@ -4,6 +4,9 @@ import styled from '@emotion/styled';
|
||||
type OwnProps = {
|
||||
name: string;
|
||||
id: string;
|
||||
checked?: boolean;
|
||||
indeterminate?: boolean;
|
||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
};
|
||||
|
||||
const StyledContainer = styled.span`
|
||||
@ -28,14 +31,25 @@ const StyledContainer = styled.span`
|
||||
}
|
||||
`;
|
||||
|
||||
function Checkbox({ name, id }: OwnProps) {
|
||||
function Checkbox({ name, id, checked, onChange, indeterminate }: OwnProps) {
|
||||
const ref = React.useRef<HTMLInputElement>(null);
|
||||
React.useEffect(() => {
|
||||
if (ref.current === null) return;
|
||||
if (typeof indeterminate === 'boolean') {
|
||||
ref.current.indeterminate = !checked && indeterminate;
|
||||
}
|
||||
}, [ref, indeterminate, checked]);
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<input
|
||||
ref={ref}
|
||||
type="checkbox"
|
||||
data-testid="input-checkbox"
|
||||
id={id}
|
||||
name={name}
|
||||
checked={checked}
|
||||
onChange={onChange}
|
||||
></input>
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
18
front/src/components/table/SelectAllCheckbox.tsx
Normal file
18
front/src/components/table/SelectAllCheckbox.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import Checkbox from '../form/Checkbox';
|
||||
|
||||
export const SelectAllCheckbox = ({
|
||||
indeterminate,
|
||||
onChange,
|
||||
}: {
|
||||
indeterminate?: boolean;
|
||||
onChange?: any;
|
||||
} & React.HTMLProps<HTMLInputElement>) => {
|
||||
return (
|
||||
<Checkbox
|
||||
name="select-all-checkbox"
|
||||
id="select-all-checkbox"
|
||||
indeterminate={indeterminate}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -2,6 +2,7 @@ import * as React from 'react';
|
||||
|
||||
import {
|
||||
ColumnDef,
|
||||
RowSelectionState,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
useReactTable,
|
||||
@ -34,6 +35,7 @@ type OwnProps<TData, SortField, FilterProperties> = {
|
||||
filter: FilterType<FilterProperties> | null,
|
||||
searchValue: string,
|
||||
) => void;
|
||||
onRowSelectionChange?: (rowSelection: RowSelectionState) => void;
|
||||
};
|
||||
|
||||
const StyledTable = styled.table`
|
||||
@ -98,11 +100,23 @@ function Table<TData extends { id: string }, SortField, FilterProperies>({
|
||||
onSortsUpdate,
|
||||
onFiltersUpdate,
|
||||
onFilterSearch,
|
||||
onRowSelectionChange,
|
||||
}: OwnProps<TData, SortField, FilterProperies>) {
|
||||
const [rowSelection, setRowSelection] = React.useState({});
|
||||
|
||||
React.useEffect(() => {
|
||||
onRowSelectionChange && onRowSelectionChange(rowSelection);
|
||||
}, [rowSelection, onRowSelectionChange]);
|
||||
|
||||
const table = useReactTable<TData>({
|
||||
data,
|
||||
columns,
|
||||
state: {
|
||||
rowSelection,
|
||||
},
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
enableRowSelection: true, //enable row selection for all rows
|
||||
onRowSelectionChange: setRowSelection,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@ -99,6 +99,9 @@ function Companies() {
|
||||
setSearhInput(searchValue);
|
||||
setFilterSearch(filter);
|
||||
}}
|
||||
onRowSelectionChange={(selectedRows) => {
|
||||
console.log(selectedRows);
|
||||
}}
|
||||
/>
|
||||
</StyledCompaniesContainer>
|
||||
</WithTopBarContainer>
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import { createColumnHelper } from '@tanstack/react-table';
|
||||
import { CellContext, createColumnHelper } from '@tanstack/react-table';
|
||||
import {
|
||||
Company,
|
||||
GraphqlQueryCompany,
|
||||
} from '../../interfaces/company.interface';
|
||||
import { updateCompany } from '../../services/companies';
|
||||
import ColumnHead from '../../components/table/ColumnHead';
|
||||
import Checkbox from '../../components/form/Checkbox';
|
||||
import CompanyChip from '../../components/chips/CompanyChip';
|
||||
import EditableText from '../../components/table/editable-cell/EditableText';
|
||||
import {
|
||||
@ -39,6 +38,8 @@ import EditableDate from '../../components/table/editable-cell/EditableDate';
|
||||
import EditableRelation from '../../components/table/editable-cell/EditableRelation';
|
||||
import { GraphqlQueryUser, PartialUser } from '../../interfaces/user.interface';
|
||||
import { useMemo } from 'react';
|
||||
import { SelectAllCheckbox } from '../../components/table/SelectAllCheckbox';
|
||||
import Checkbox from '../../components/form/Checkbox';
|
||||
|
||||
export const availableSorts = [
|
||||
{
|
||||
@ -141,17 +142,24 @@ const columnHelper = createColumnHelper<Company>();
|
||||
export const useCompaniesColumns = () => {
|
||||
return useMemo(() => {
|
||||
return [
|
||||
columnHelper.accessor('id', {
|
||||
header: () => (
|
||||
<Checkbox id="company-select-all" name="company-select-all" />
|
||||
{
|
||||
id: 'select',
|
||||
header: ({ table }: any) => (
|
||||
<SelectAllCheckbox
|
||||
checked={table.getIsAllRowsSelected()}
|
||||
indeterminate={table.getIsSomeRowsSelected()}
|
||||
onChange={table.getToggleAllRowsSelectedHandler()}
|
||||
/>
|
||||
),
|
||||
cell: (props) => (
|
||||
cell: (props: CellContext<Company, string>) => (
|
||||
<Checkbox
|
||||
id={`company-selected-${props.row.original.id}`}
|
||||
name={`company-selected-${props.row.original.id}`}
|
||||
checked={props.row.getIsSelected()}
|
||||
onChange={props.row.getToggleSelectedHandler()}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
},
|
||||
columnHelper.accessor('name', {
|
||||
header: () => (
|
||||
<ColumnHead viewName="Name" viewIcon={<FaRegBuilding />} />
|
||||
|
||||
@ -98,6 +98,9 @@ function People() {
|
||||
setSearchInput(searchValue);
|
||||
setFilterSearch(filter);
|
||||
}}
|
||||
onRowSelectionChange={(selectedRows) => {
|
||||
console.log(selectedRows);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</StyledPeopleContainer>
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
FaUser,
|
||||
FaBuilding,
|
||||
} from 'react-icons/fa';
|
||||
import { createColumnHelper } from '@tanstack/react-table';
|
||||
import { CellContext, createColumnHelper } from '@tanstack/react-table';
|
||||
import ColumnHead from '../../components/table/ColumnHead';
|
||||
import Checkbox from '../../components/form/Checkbox';
|
||||
import CompanyChip, {
|
||||
@ -39,6 +39,7 @@ import EditableDate from '../../components/table/editable-cell/EditableDate';
|
||||
import EditableRelation from '../../components/table/editable-cell/EditableRelation';
|
||||
import { updatePerson } from '../../services/people';
|
||||
import { useMemo } from 'react';
|
||||
import { SelectAllCheckbox } from '../../components/table/SelectAllCheckbox';
|
||||
|
||||
export const availableSorts = [
|
||||
{
|
||||
@ -247,17 +248,24 @@ const columnHelper = createColumnHelper<Person>();
|
||||
export const usePeopleColumns = () => {
|
||||
return useMemo(() => {
|
||||
return [
|
||||
columnHelper.accessor('id', {
|
||||
header: () => (
|
||||
<Checkbox id={`person-select-all`} name={`person-select-all`} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<Checkbox
|
||||
id={`person-selected-${props.row.original.email}`}
|
||||
name={`person-selected-${props.row.original.email}`}
|
||||
{
|
||||
id: 'select',
|
||||
header: ({ table }: any) => (
|
||||
<SelectAllCheckbox
|
||||
checked={table.getIsAllRowsSelected()}
|
||||
indeterminate={table.getIsSomeRowsSelected()}
|
||||
onChange={table.getToggleAllRowsSelectedHandler()}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
cell: (props: CellContext<Person, string>) => (
|
||||
<Checkbox
|
||||
id={`person-selected-${props.row.original.id}`}
|
||||
name={`person-selected-${props.row.original.id}`}
|
||||
checked={props.row.getIsSelected()}
|
||||
onChange={props.row.getToggleSelectedHandler()}
|
||||
/>
|
||||
),
|
||||
},
|
||||
columnHelper.accessor('firstname', {
|
||||
header: () => <ColumnHead viewName="People" viewIcon={<FaRegUser />} />,
|
||||
cell: (props) => (
|
||||
|
||||
Reference in New Issue
Block a user