Parcourir la source

Add ot hours to timesheet

tags/Baseline_30082024_FRONTEND_UAT
Wayne il y a 1 an
Parent
révision
5d09083340
6 fichiers modifiés avec 51 ajouts et 13 suppressions
  1. +2
    -1
      src/app/api/timesheets/actions.ts
  2. +10
    -5
      src/app/api/timesheets/utils.ts
  3. +11
    -1
      src/components/LeaveModal/LeaveModal.tsx
  4. +11
    -1
      src/components/TimesheetModal/TimesheetModal.tsx
  5. +13
    -4
      src/components/TimesheetTable/EntryInputTable.tsx
  6. +4
    -1
      src/components/TimesheetTable/TimesheetTable.tsx

+ 2
- 1
src/app/api/timesheets/actions.ts Voir le fichier

@@ -11,7 +11,8 @@ export interface TimeEntry {
projectId?: ProjectResult["id"];
taskGroupId?: TaskGroup["id"];
taskId?: Task["id"];
inputHours: number;
inputHours?: number;
otHours?: number;
remark?: string;
}



+ 10
- 5
src/app/api/timesheets/utils.ts Voir le fichier

@@ -8,19 +8,24 @@ export const isValidTimeEntry = (entry: Partial<TimeEntry>): string => {
// Test for errors
let error: keyof TimeEntry | "" = "";

// Either normal or other hours need to be inputted
if (!entry.inputHours && !entry.otHours) {
error = "inputHours";
} else if (entry.inputHours && entry.inputHours <= 0) {
error = "inputHours";
} else if (entry.otHours && entry.otHours <= 0) {
error = "otHours";
}

// If there is a project id, there should also be taskGroupId, taskId, inputHours
if (entry.projectId) {
if (!entry.taskGroupId) {
error = "taskGroupId";
} else if (!entry.taskId) {
error = "taskId";
} else if (!entry.inputHours || !(entry.inputHours >= 0)) {
error = "inputHours";
}
} else {
if (!entry.inputHours || !(entry.inputHours >= 0)) {
error = "inputHours";
} else if (!entry.remark) {
if (!entry.remark) {
error = "remark";
}
}


+ 11
- 1
src/components/LeaveModal/LeaveModal.tsx Voir le fichier

@@ -6,6 +6,7 @@ import {
CardActions,
CardContent,
Modal,
ModalProps,
SxProps,
Typography,
} from "@mui/material";
@@ -86,8 +87,17 @@ const LeaveModal: React.FC<Props> = ({
onClose();
}, [defaultValues, formProps, onClose]);

const onModalClose = useCallback<NonNullable<ModalProps["onClose"]>>(
(_, reason) => {
if (reason !== "backdropClick") {
onClose();
}
},
[onClose],
);

return (
<Modal open={isOpen} onClose={onClose}>
<Modal open={isOpen} onClose={onModalClose}>
<Card sx={modalSx}>
<FormProvider {...formProps}>
<CardContent


+ 11
- 1
src/components/TimesheetModal/TimesheetModal.tsx Voir le fichier

@@ -6,6 +6,7 @@ import {
CardActions,
CardContent,
Modal,
ModalProps,
SxProps,
Typography,
} from "@mui/material";
@@ -91,8 +92,17 @@ const TimesheetModal: React.FC<Props> = ({
onClose();
}, [defaultValues, formProps, onClose]);

const onModalClose = useCallback<NonNullable<ModalProps["onClose"]>>(
(_, reason) => {
if (reason !== "backdropClick") {
onClose();
}
},
[onClose],
);

return (
<Modal open={isOpen} onClose={onClose}>
<Modal open={isOpen} onClose={onModalClose}>
<Card sx={modalSx}>
<FormProvider {...formProps}>
<CardContent


+ 13
- 4
src/components/TimesheetTable/EntryInputTable.tsx Voir le fichier

@@ -211,7 +211,7 @@ const EntryInputTable: React.FC<Props> = ({
{
field: "projectId",
headerName: t("Project Code and Name"),
width: 400,
width: 300,
editable: true,
valueFormatter(params) {
const project = assignedProjects.find((p) => p.id === params.value);
@@ -310,7 +310,17 @@ const EntryInputTable: React.FC<Props> = ({
editable: true,
type: "number",
valueFormatter(params) {
return manhourFormatter.format(params.value);
return manhourFormatter.format(params.value || 0);
},
},
{
field: "otHours",
headerName: t("Other Hours"),
width: 150,
editable: true,
type: "number",
valueFormatter(params) {
return manhourFormatter.format(params.value || 0);
},
},
{
@@ -336,10 +346,9 @@ const EntryInputTable: React.FC<Props> = ({
useEffect(() => {
setValue(day, [
...entries
.filter((e) => !e._isNew && !e._error && e.id && e.inputHours)
.filter((e) => !e._isNew && !e._error && e.id)
.map(({ isPlanned, _error, _isNew, ...entry }) => ({
id: entry.id!,
inputHours: entry.inputHours!,
...entry,
})),
]);


+ 4
- 1
src/components/TimesheetTable/TimesheetTable.tsx Voir le fichier

@@ -75,7 +75,10 @@ const DayRow: React.FC<{
const dayJsObj = dayjs(day);
const [open, setOpen] = useState(false);

const totalHours = entries.reduce((acc, entry) => acc + entry.inputHours, 0);
const totalHours = entries.reduce(
(acc, entry) => acc + (entry.inputHours || 0) + (entry.otHours || 0),
0,
);

return (
<>


Chargement…
Annuler
Enregistrer