Files
Fulfillment-Frontend/src/pages/AdminPage/tabs/WorkTimeTable/hooks/useWorkTableColumns.tsx

145 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {useMemo} from "react";
import {MRT_ColumnDef} from "mantine-react-table";
import {getDayOfWeek} from "../../../../../shared/lib/date.ts";
import {Box, Flex, NumberInput, rem} from "@mantine/core";
import {isNumber, last} from "lodash";
import {processSelectedCells} from "../../../../../shared/lib/interpolateCells.ts";
import {TimeTrackingData} from "../../../../../client";
import dayjs from "dayjs";
export type EmployeeData = {
name: string;
userId: number;
totalAmount: number;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
data?: TimeTrackingData[],
[key: string]: number | string;
};
type Props = {
month: Date;
data: EmployeeData[];
onUpdate: (date: Date, userId: number, value: number) => void,
selectedCells: string[];
setSelectedCells: (cells: string[]) => void
selectedBoundaries: [Date | null, Date | null];
range: dayjs.Dayjs[];
}
const useWorkTableColumns = ({
month,
onUpdate,
data,
selectedCells,
setSelectedCells,
selectedBoundaries,
range
}: Props) => {
const totalAmount = useMemo(() => {
return data.reduce((acc, value) => {
if (value.data) {
const sum = value.data.reduce((innerAcc, item) => innerAcc + item.amount, 0);
return acc + sum;
}
return acc;
}, 0);
}, [data, month, selectedCells, selectedBoundaries]);
const getBorderStyles = (cellId: string) => {
if (selectedCells.length <= 1) return {}
if (selectedCells[0] === cellId)
return {
borderTopLeftRadius: rem(20),
borderBottomLeftRadius: rem(20),
}
else if (last(selectedCells) === cellId)
return {
borderTopRightRadius: rem(20),
borderBottomRightRadius: rem(20),
}
return {}
}
return useMemo<MRT_ColumnDef<EmployeeData>[]>(() => [
{
accessorKey: "name",
header: "ФИО"
},
...range.map(date => ({
size: 80,
accessorKey: date.date().toString(),
header: date.date().toString(),
enableSorting: false,
enableColumnActions: false,
Header: (
<Flex
align={"center"}
direction={"column"}>
<Box>
{date.date()}
</Box>
<Box>
{getDayOfWeek(date.day())}
</Box>
</Flex>
),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
mantineTableBodyCellProps: ({cell}) => ({
style: selectedCells.includes(cell.id) ? {
backgroundColor: "var(--mantine-primary-color-filled)",
...getBorderStyles(cell.id)
} : {},
onClick: () => {
const result = processSelectedCells(selectedCells, cell.id);
setSelectedCells(result);
},
}),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
Cell: ({cell, row}) => {
return (
<Flex direction={"column"}>
<NumberInput
// key={row.original.name + date.date().toString()}
onChange={event => isNumber(event) && onUpdate(date.toDate(), row.original.userId, event)}
styles={{input: {textAlign: "center"}}}
hideControls
value={cell.renderValue()}
/>
</Flex>
);
}
})),
{
header: "Всего часов",
Cell: ({row}) => {
return Object.entries(row.original).reduce((acc, [key, value]) => {
if (isNaN(parseInt(key)) || !isNumber(value)) return acc;
acc += value;
return acc;
}, 0);
},
},
{
accessorKey: "totalAmount",
header: "Итоговая сумма заработка",
Cell: ({row}) => {
return (row.original.data || []).reduce((acc, value) => {
acc += value.amount;
return acc;
}, 0);
},
Footer: (
<Flex>
Всего: {totalAmount.toLocaleString("ru-RU")}
</Flex>
)
},
], [month, selectedCells, selectedBoundaries, totalAmount]);
}
export default useWorkTableColumns;