feat: cancel deal bill, date range in timetable
This commit is contained in:
@@ -1,35 +1,75 @@
|
||||
import {useMemo} from "react";
|
||||
import {MRT_ColumnDef} from "mantine-react-table";
|
||||
import {getDatesInMonth, getDayOfWeek} from "../../../../../shared/lib/date.ts";
|
||||
import {Box, Flex, NumberInput} from "@mantine/core";
|
||||
import {isNumber} from "lodash";
|
||||
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
|
||||
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}: Props) => {
|
||||
const totalAmount = useMemo(() => data.reduce((acc, value) => acc + value.totalAmount, 0), [data]);
|
||||
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: "ФИО"
|
||||
},
|
||||
|
||||
...getDatesInMonth(month).map(date => ({
|
||||
...range.map(date => ({
|
||||
size: 80,
|
||||
accessorKey: date.date().toString(),
|
||||
header: date.date().toString(),
|
||||
enableSorting: false,
|
||||
enableColumnActions: false,
|
||||
|
||||
Header: (
|
||||
<Flex
|
||||
align={"center"}
|
||||
@@ -44,6 +84,19 @@ const useWorkTableColumns = ({month, onUpdate, data}: Props) => {
|
||||
),
|
||||
// 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"}>
|
||||
@@ -71,9 +124,13 @@ const useWorkTableColumns = ({month, onUpdate, data}: Props) => {
|
||||
{
|
||||
accessorKey: "totalAmount",
|
||||
header: "Итоговая сумма заработка",
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
Cell: ({cell}) => cell.renderValue().toLocaleString("ru-RU"),
|
||||
|
||||
Cell: ({row}) => {
|
||||
return (row.original.data || []).reduce((acc, value) => {
|
||||
acc += value.amount;
|
||||
return acc;
|
||||
}, 0);
|
||||
},
|
||||
Footer: (
|
||||
<Flex>
|
||||
Всего: {totalAmount.toLocaleString("ru-RU")}
|
||||
@@ -82,7 +139,7 @@ const useWorkTableColumns = ({month, onUpdate, data}: Props) => {
|
||||
},
|
||||
|
||||
|
||||
], [month]);
|
||||
], [month, selectedCells, selectedBoundaries, totalAmount]);
|
||||
}
|
||||
|
||||
export default useWorkTableColumns;
|
||||
@@ -1,10 +1,16 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {TimeTrackingRecord, TimeTrackingService} from "../../../../../client";
|
||||
import {dateWithoutTimezone} from "../../../../../shared/lib/date.ts";
|
||||
import {dateWithoutTimezone, getDatesInMonth} from "../../../../../shared/lib/date.ts";
|
||||
import {last} from "lodash";
|
||||
|
||||
const getDateBoundaries = (month: Date) => {
|
||||
return [getDatesInMonth(month)[0].toDate(), last(getDatesInMonth(month))?.toDate()]
|
||||
}
|
||||
const useWorkTableState = () => {
|
||||
const [month, setMonth] = useState<Date>(new Date(new Date().getFullYear(), new Date().getMonth(), 1));
|
||||
const [trackingRecords, setTrackingRecords] = useState<TimeTrackingRecord[]>([]);
|
||||
const [dateBoundaries, setDateBoundaries] = useState(getDateBoundaries(month));
|
||||
|
||||
const refetch = async () => {
|
||||
return TimeTrackingService.getTimeTrackingRecords({
|
||||
requestBody: {
|
||||
@@ -13,16 +19,20 @@ const useWorkTableState = () => {
|
||||
}
|
||||
}).then((response) => setTrackingRecords(response.records));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
refetch().then(_ => {
|
||||
setDateBoundaries(getDateBoundaries(month));
|
||||
});
|
||||
|
||||
}, [month])
|
||||
return {
|
||||
month,
|
||||
setMonth,
|
||||
refetch,
|
||||
trackingRecords
|
||||
trackingRecords,
|
||||
dateBoundaries
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user