feat: showing users in work time tab instead of hiding
This commit is contained in:
@@ -3,19 +3,9 @@ import { DatePickerInput, MonthPickerInput } from "@mantine/dates";
|
|||||||
import useWorkTableState from "../hooks/useWorkTableState.tsx";
|
import useWorkTableState from "../hooks/useWorkTableState.tsx";
|
||||||
import { BaseTable } from "../../../../../components/BaseTable/BaseTable.tsx";
|
import { BaseTable } from "../../../../../components/BaseTable/BaseTable.tsx";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import useWorkTableColumns, {
|
import useWorkTableColumns, { EmployeeData } from "../hooks/useWorkTableColumns.tsx";
|
||||||
EmployeeData,
|
import { TimeTrackingRecord, TimeTrackingService, UserSchema } from "../../../../../client";
|
||||||
} from "../hooks/useWorkTableColumns.tsx";
|
import { dateWithoutTimezone, getDatesBetween, getDatesInMonth } from "../../../../../shared/lib/date.ts";
|
||||||
import {
|
|
||||||
TimeTrackingRecord,
|
|
||||||
TimeTrackingService,
|
|
||||||
UserSchema,
|
|
||||||
} from "../../../../../client";
|
|
||||||
import {
|
|
||||||
dateWithoutTimezone,
|
|
||||||
getDatesBetween,
|
|
||||||
getDatesInMonth,
|
|
||||||
} from "../../../../../shared/lib/date.ts";
|
|
||||||
import useUsersList from "../../../hooks/useUsersList.tsx";
|
import useUsersList from "../../../hooks/useUsersList.tsx";
|
||||||
import { notifications } from "../../../../../shared/lib/notifications.ts";
|
import { notifications } from "../../../../../shared/lib/notifications.ts";
|
||||||
import { PaySchemeType } from "../../../../../shared/enums/PaySchemeType.ts";
|
import { PaySchemeType } from "../../../../../shared/enums/PaySchemeType.ts";
|
||||||
@@ -23,18 +13,19 @@ import { IconEyeOff } from "@tabler/icons-react";
|
|||||||
import { MRT_TableOptions } from "mantine-react-table";
|
import { MRT_TableOptions } from "mantine-react-table";
|
||||||
import { difference, omit } from "lodash";
|
import { difference, omit } from "lodash";
|
||||||
import { strTimeToFloatHours } from "../../../../../types/utils.ts";
|
import { strTimeToFloatHours } from "../../../../../types/utils.ts";
|
||||||
|
import { useListState } from "@mantine/hooks";
|
||||||
|
|
||||||
const WorkTimeTable = () => {
|
const WorkTimeTable = () => {
|
||||||
const [data, setData] = useState<EmployeeData[]>([]);
|
const [data, setData] = useState<EmployeeData[]>([]);
|
||||||
const { dateBoundaries, month, setMonth, trackingRecords, refetch } =
|
const { dateBoundaries, month, setMonth, trackingRecords, refetch } =
|
||||||
useWorkTableState();
|
useWorkTableState();
|
||||||
const [hiddenUsers, setHiddenUsers] = useState<UserSchema[]>([]);
|
const [shownUsers, shownUsersHandlers] = useListState<UserSchema>([]);
|
||||||
const [selectedBoundaries, setSelectedBoundaries] = useState<
|
const [selectedBoundaries, setSelectedBoundaries] = useState<
|
||||||
[Date | null, Date | null]
|
[Date | null, Date | null]
|
||||||
>([null, null]);
|
>([null, null]);
|
||||||
|
|
||||||
const users = useUsersList().objects.filter(
|
const users = useUsersList().objects.filter(
|
||||||
user => user.payRate?.payrollScheme.key === PaySchemeType.HOURLY
|
user => user.payRate?.payrollScheme.key === PaySchemeType.HOURLY,
|
||||||
);
|
);
|
||||||
|
|
||||||
const getRange = () => {
|
const getRange = () => {
|
||||||
@@ -49,7 +40,7 @@ const WorkTimeTable = () => {
|
|||||||
const range = getRange();
|
const range = getRange();
|
||||||
|
|
||||||
const transformTrackingRecordsToData = (
|
const transformTrackingRecordsToData = (
|
||||||
trackingRecords: TimeTrackingRecord[]
|
trackingRecords: TimeTrackingRecord[],
|
||||||
): EmployeeData[] => {
|
): EmployeeData[] => {
|
||||||
if (!month) return [];
|
if (!month) return [];
|
||||||
const rangeDays = range.map(r => r.date());
|
const rangeDays = range.map(r => r.date());
|
||||||
@@ -57,7 +48,7 @@ const WorkTimeTable = () => {
|
|||||||
trackingRecords = trackingRecords.map(tr => ({
|
trackingRecords = trackingRecords.map(tr => ({
|
||||||
...tr,
|
...tr,
|
||||||
data: tr.data.filter(d =>
|
data: tr.data.filter(d =>
|
||||||
rangeDays.includes(new Date(d.date).getDate())
|
rangeDays.includes(new Date(d.date).getDate()),
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
const existingUserIds = trackingRecords.map(tr => tr.user.id);
|
const existingUserIds = trackingRecords.map(tr => tr.user.id);
|
||||||
@@ -70,15 +61,15 @@ const WorkTimeTable = () => {
|
|||||||
...Object.fromEntries(
|
...Object.fromEntries(
|
||||||
getDatesInMonth(month).reduce((acc, day) => {
|
getDatesInMonth(month).reduce((acc, day) => {
|
||||||
return acc.set(day.date().toString(), 0);
|
return acc.set(day.date().toString(), 0);
|
||||||
}, new Map<string, number>())
|
}, new Map<string, number>()),
|
||||||
),
|
),
|
||||||
...Object.fromEntries(
|
...Object.fromEntries(
|
||||||
record.data.reduce((acc, recordData) => {
|
record.data.reduce((acc, recordData) => {
|
||||||
return acc.set(
|
return acc.set(
|
||||||
new Date(recordData.date).getDate().toString(),
|
new Date(recordData.date).getDate().toString(),
|
||||||
recordData.hours
|
recordData.hours,
|
||||||
);
|
);
|
||||||
}, new Map<string, number>())
|
}, new Map<string, number>()),
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
const restUsersResult = users
|
const restUsersResult = users
|
||||||
@@ -91,25 +82,25 @@ const WorkTimeTable = () => {
|
|||||||
...Object.fromEntries(
|
...Object.fromEntries(
|
||||||
getDatesInMonth(month).reduce((acc, day) => {
|
getDatesInMonth(month).reduce((acc, day) => {
|
||||||
return acc.set(day.date().toString(), 0);
|
return acc.set(day.date().toString(), 0);
|
||||||
}, new Map<string, number>())
|
}, new Map<string, number>()),
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
const hiddenUserIds = hiddenUsers.map(user => user.id);
|
const shownUserIds = shownUsers.map(user => user.id);
|
||||||
|
|
||||||
|
|
||||||
const result = firstResult
|
const result = firstResult
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
.concat(restUsersResult)
|
.concat(restUsersResult)
|
||||||
.filter(r => !hiddenUserIds.includes(r.userId));
|
.filter(r => shownUserIds.includes(r.userId));
|
||||||
const firstDate = selectedBoundaries[0];
|
const firstDate = selectedBoundaries[0];
|
||||||
const lastDate = selectedBoundaries[1];
|
const lastDate = selectedBoundaries[1];
|
||||||
if (firstDate && lastDate) {
|
if (firstDate && lastDate) {
|
||||||
const allDays = getDatesInMonth(month).map(d =>
|
const allDays = getDatesInMonth(month).map(d =>
|
||||||
d.date().toString()
|
d.date().toString(),
|
||||||
);
|
);
|
||||||
const allowedDays = getDatesBetween(firstDate, lastDate).map(d =>
|
const allowedDays = getDatesBetween(firstDate, lastDate).map(d =>
|
||||||
d.date().toString()
|
d.date().toString(),
|
||||||
);
|
);
|
||||||
const omitDays = difference(allDays, allowedDays);
|
const omitDays = difference(allDays, allowedDays);
|
||||||
|
|
||||||
@@ -118,7 +109,7 @@ const WorkTimeTable = () => {
|
|||||||
}) as unknown as EmployeeData[];
|
}) as unknown as EmployeeData[];
|
||||||
}
|
}
|
||||||
return (result as unknown as EmployeeData[]).sort(
|
return (result as unknown as EmployeeData[]).sort(
|
||||||
(a, b) => a.userId - b.userId
|
(a, b) => a.userId - b.userId,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,21 +144,26 @@ const WorkTimeTable = () => {
|
|||||||
await refetch();
|
await refetch();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = useWorkTableColumns({
|
const columns = useWorkTableColumns({
|
||||||
month,
|
month,
|
||||||
selectedBoundaries,
|
selectedBoundaries,
|
||||||
data,
|
data,
|
||||||
onUpdate: optimisticUpdate,
|
onUpdate: optimisticUpdate,
|
||||||
selectedCells: [],
|
selectedCells: [],
|
||||||
setSelectedCells: () => {},
|
setSelectedCells: () => {
|
||||||
|
},
|
||||||
range,
|
range,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setData(transformTrackingRecordsToData(trackingRecords));
|
setData(transformTrackingRecordsToData(trackingRecords));
|
||||||
}, [trackingRecords, hiddenUsers, selectedBoundaries]);
|
}, [trackingRecords, shownUsers, selectedBoundaries]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelectedBoundaries([null, null]);
|
setSelectedBoundaries([null, null]);
|
||||||
}, [month]);
|
}, [month]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
direction={"column"}
|
direction={"column"}
|
||||||
@@ -183,15 +179,15 @@ const WorkTimeTable = () => {
|
|||||||
value: user.id.toString(),
|
value: user.id.toString(),
|
||||||
}))}
|
}))}
|
||||||
onChange={event =>
|
onChange={event =>
|
||||||
setHiddenUsers(
|
shownUsersHandlers.setState(
|
||||||
users.filter(user =>
|
users.filter(user =>
|
||||||
event.includes(user.id.toString())
|
event.includes(user.id.toString()),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
value={hiddenUsers.map(user => user.id.toString())}
|
value={shownUsers.map(user => user.id.toString())}
|
||||||
placeholder={
|
placeholder={
|
||||||
hiddenUsers.length > 0 ? "" : "Скрытые пользователи"
|
shownUsers.length > 0 ? "" : "Показанные пользователи"
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Flex gap={rem(10)}>
|
<Flex gap={rem(10)}>
|
||||||
@@ -232,16 +228,9 @@ const WorkTimeTable = () => {
|
|||||||
<Tooltip label="Скрыть">
|
<Tooltip label="Скрыть">
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const user = users.find(
|
shownUsersHandlers.filter(
|
||||||
user =>
|
user => user.id !== row.original.userId,
|
||||||
user.id ===
|
|
||||||
row.original.userId
|
|
||||||
);
|
);
|
||||||
if (!user) return;
|
|
||||||
setHiddenUsers(prevState => [
|
|
||||||
...prevState,
|
|
||||||
user,
|
|
||||||
]);
|
|
||||||
}}
|
}}
|
||||||
variant={"default"}>
|
variant={"default"}>
|
||||||
<IconEyeOff />
|
<IconEyeOff />
|
||||||
|
|||||||
Reference in New Issue
Block a user