Files
aso/frontend/dashboard/src/hooks/useTable.ts
2022-11-03 09:51:22 +07:00

139 lines
3.7 KiB
TypeScript
Executable File

import { useState } from 'react';
// ----------------------------------------------------------------------
export type UseTableProps = {
dense: boolean;
page: number;
setPage: React.Dispatch<React.SetStateAction<number>>;
rowsPerPage: number;
order: 'asc' | 'desc';
orderBy: string;
//
selected: string[];
setSelected: React.Dispatch<React.SetStateAction<string[]>>;
onSelectRow: (id: string) => void;
onSelectAllRows: (checked: boolean, newSelecteds: string[]) => void;
//
onSort: (id: string) => void;
onChangePage: (event: unknown, newPage: number) => void;
onChangeRowsPerPage: (event: React.ChangeEvent<HTMLInputElement>) => void;
onChangeDense: (event: React.ChangeEvent<HTMLInputElement>) => void;
};
export type Props = {
defaultDense?: boolean;
defaultOrder?: 'asc' | 'desc';
defaultOrderBy?: string;
defaultSelected?: string[];
defaultRowsPerPage?: number;
defaultCurrentPage?: number;
};
export default function useTable(props?: Props) {
const [dense, setDense] = useState(props?.defaultDense || false);
const [orderBy, setOrderBy] = useState(props?.defaultOrderBy || 'name');
const [order, setOrder] = useState<'asc' | 'desc'>(props?.defaultOrder || 'asc');
const [page, setPage] = useState(props?.defaultCurrentPage || 0);
const [rowsPerPage, setRowsPerPage] = useState(props?.defaultRowsPerPage || 5);
const [selected, setSelected] = useState<string[]>(props?.defaultSelected || []);
const onSort = (id: string) => {
const isAsc = orderBy === id && order === 'asc';
if (id !== '') {
setOrder(isAsc ? 'desc' : 'asc');
setOrderBy(id);
}
};
const onSelectRow = (id: string) => {
const selectedIndex = selected.indexOf(id);
let newSelected: string[] = [];
if (selectedIndex === -1) {
newSelected = newSelected.concat(selected, id);
} else if (selectedIndex === 0) {
newSelected = newSelected.concat(selected.slice(1));
} else if (selectedIndex === selected.length - 1) {
newSelected = newSelected.concat(selected.slice(0, -1));
} else if (selectedIndex > 0) {
newSelected = newSelected.concat(
selected.slice(0, selectedIndex),
selected.slice(selectedIndex + 1)
);
}
setSelected(newSelected);
};
const onSelectAllRows = (checked: boolean, newSelecteds: string[]) => {
if (checked) {
setSelected(newSelecteds);
return;
}
setSelected([]);
};
const onChangePage = (event: unknown, newPage: number) => {
setPage(newPage);
};
const onChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const onChangeDense = (event: React.ChangeEvent<HTMLInputElement>) => {
setDense(event.target.checked);
};
return {
dense,
order,
page,
setPage,
orderBy,
rowsPerPage,
//
selected,
setSelected,
onSelectRow,
onSelectAllRows,
//
onSort,
onChangePage,
onChangeDense,
onChangeRowsPerPage,
};
}
// ----------------------------------------------------------------------
export function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
export function getComparator<Key extends keyof any>(
order: 'asc' | 'desc',
orderBy: Key
): (a: { [key in Key]: number | string }, b: { [key in Key]: number | string }) => number {
return order === 'desc'
? (a, b) => descendingComparator(a, b, orderBy)
: (a, b) => -descendingComparator(a, b, orderBy);
}
export function emptyRows(page: number, rowsPerPage: number, arrayLength: number) {
return page > 0 ? Math.max(0, (1 + page) * rowsPerPage - arrayLength) : 0;
}