Преглед изворни кода

Show only ongoing projects and add new leave entry for team leads

tags/Baseline_30082024_FRONTEND_UAT
Wayne пре 1 година
родитељ
комит
8538d1bbec
5 измењених фајлова са 89 додато и 8 уклоњено
  1. +1
    -0
      src/app/api/projects/index.ts
  2. +4
    -1
      src/components/LeaveModal/LeaveModal.tsx
  3. +70
    -4
      src/components/TimesheetAmendment/TimesheetAmendment.tsx
  4. +4
    -1
      src/components/TimesheetModal/TimesheetModal.tsx
  5. +10
    -2
      src/components/TimesheetTable/ProjectSelect.tsx

+ 1
- 0
src/app/api/projects/index.ts Прегледај датотеку

@@ -75,6 +75,7 @@ export interface WorkNature {
export interface ProjectWithTasks {
id: number;
code: string;
status?: string;
name: string;
tasks: Task[];
milestones: {


+ 4
- 1
src/components/LeaveModal/LeaveModal.tsx Прегледај датотеку

@@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from "react";
import React, { useCallback, useEffect, useMemo } from "react";
import {
Box,
Button,
@@ -78,6 +78,9 @@ const LeaveModal: React.FC<Props> = ({
}, [defaultLeaveRecords]);

const formProps = useForm<RecordLeaveInput>({ defaultValues });
useEffect(() => {
formProps.reset(defaultValues);
}, [defaultValues, formProps]);

const onSubmit = useCallback<SubmitHandler<RecordLeaveInput>>(
async (data) => {


+ 70
- 4
src/components/TimesheetAmendment/TimesheetAmendment.tsx Прегледај датотеку

@@ -4,7 +4,15 @@ import { HolidaysResult } from "@/app/api/holidays";
import { LeaveType, TeamLeaves, TeamTimeSheets } from "@/app/api/timesheets";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";
import { Autocomplete, Stack, TextField, useTheme } from "@mui/material";
import {
Autocomplete,
Menu,
MenuItem,
Stack,
SxProps,
TextField,
useTheme,
} from "@mui/material";
import { useTranslation } from "react-i18next";
import transform from "lodash/transform";
import {
@@ -33,6 +41,7 @@ import LeaveEditModal from "../LeaveTable/LeaveEditModal";
import dayjs from "dayjs";
import { checkTotalHours } from "@/app/api/timesheets/utils";
import unionBy from "lodash/unionBy";
import { Luggage, MoreTime } from "@mui/icons-material";

export interface Props {
leaveTypes: LeaveType[];
@@ -56,6 +65,11 @@ interface EventClickArg {
};
}

const menuItemSx: SxProps = {
gap: 1,
color: "neutral.700",
};

const TimesheetAmendment: React.FC<Props> = ({
teamTimesheets,
teamLeaves,
@@ -192,6 +206,32 @@ const TimesheetAmendment: React.FC<Props> = ({
setLeaveEditModalOpen(false);
}, []);

// New time / leave menu
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [selectedDateInfo, setSelectedDateInfo] = useState<
{ dateStr: string; isHoliday: boolean } | undefined
>();
const handleCloseActionMenu = useCallback(() => {
setAnchorEl(null);
setSelectedDateInfo(undefined);
}, []);
const openNewTimeEditModal = useCallback(() => {
openEditModal(
undefined,
selectedDateInfo?.dateStr,
selectedDateInfo?.isHoliday,
);
setAnchorEl(null);
}, [openEditModal, selectedDateInfo]);
const openNewLeaveEditModal = useCallback(() => {
openLeaveEditModal(
undefined,
selectedDateInfo?.dateStr,
selectedDateInfo?.isHoliday,
);
setAnchorEl(null);
}, [openLeaveEditModal, selectedDateInfo]);

// calendar related
const holidays = useMemo(() => {
return [
@@ -289,13 +329,17 @@ const TimesheetAmendment: React.FC<Props> = ({
);

const handleDateClick = useCallback(
(e: { dateStr: string }) => {
(e: { dateStr: string; dayEl: HTMLElement }) => {
const dayJsObj = dayjs(e.dateStr);
const holiday = getHolidayForDate(e.dateStr, companyHolidays);
const isHoliday = holiday || dayJsObj.day() === 0 || dayJsObj.day() === 6;
openEditModal(undefined, e.dateStr, Boolean(isHoliday));
setSelectedDateInfo({
dateStr: e.dateStr,
isHoliday: Boolean(isHoliday),
});
setAnchorEl(e.dayEl);
},
[companyHolidays, openEditModal],
[companyHolidays],
);

const checkTotalHoursForDate = useCallback(
@@ -413,6 +457,28 @@ const TimesheetAmendment: React.FC<Props> = ({
onSave={handleSaveLeave}
{...leaveEditModalProps}
/>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleCloseActionMenu}
anchorOrigin={{
vertical: "center",
horizontal: "center",
}}
transformOrigin={{
vertical: "center",
horizontal: "center",
}}
>
<MenuItem onClick={openNewTimeEditModal} sx={menuItemSx}>
<MoreTime />
{t("Enter Time")}
</MenuItem>
<MenuItem onClick={openNewLeaveEditModal} sx={menuItemSx}>
<Luggage />
{t("Record Leave")}
</MenuItem>
</Menu>
</Stack>
);
};


+ 4
- 1
src/components/TimesheetModal/TimesheetModal.tsx Прегледај датотеку

@@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from "react";
import React, { useCallback, useEffect, useMemo } from "react";
import {
Box,
Button,
@@ -82,6 +82,9 @@ const TimesheetModal: React.FC<Props> = ({
}, [defaultTimesheets]);

const formProps = useForm<RecordTimesheetInput>({ defaultValues });
useEffect(() => {
formProps.reset(defaultValues);
}, [defaultValues, formProps]);

const onSubmit = useCallback<SubmitHandler<RecordTimesheetInput>>(
async (data) => {


+ 10
- 2
src/components/TimesheetTable/ProjectSelect.tsx Прегледај датотеку

@@ -18,6 +18,7 @@ interface CommonProps {
assignedProjects: AssignedProject[];
error?: boolean;
multiple?: boolean;
showOnlyOngoing?: boolean;
}

interface SingleAutocompleteProps extends CommonProps {
@@ -51,6 +52,7 @@ const getGroupName = (t: TFunction, groupName: string): string => {

const AutocompleteProjectSelect: React.FC<Props> = ({
allProjects,
showOnlyOngoing = true,
assignedProjects,
value,
onProjectSelect,
@@ -58,9 +60,15 @@ const AutocompleteProjectSelect: React.FC<Props> = ({
multiple,
}) => {
const { t } = useTranslation("home");
const allFilteredProjects = useMemo(() => {
return showOnlyOngoing
? allProjects.filter((p) => p.status === "On-going")
: allProjects;
}, [showOnlyOngoing, allProjects]);

const nonAssignedProjects = useMemo(() => {
return differenceBy(allProjects, assignedProjects, "id");
}, [allProjects, assignedProjects]);
return differenceBy(allFilteredProjects, assignedProjects, "id");
}, [allFilteredProjects, assignedProjects]);

const options = useMemo(() => {
return [


Loading…
Откажи
Сачувај