浏览代码

update dashboard

tags/Baseline_30082024_FRONTEND_UAT
Mac\David 1年前
父节点
当前提交
c69363baab
共有 3 个文件被更改,包括 427 次插入55 次删除
  1. +2
    -0
      src/app/(main)/dashboard/StaffUtilization/page.tsx
  2. +58
    -0
      src/app/api/staffUtilization/index.ts
  3. +367
    -55
      src/components/StaffUtilization/StaffUtilization.tsx

+ 2
- 0
src/app/(main)/dashboard/StaffUtilization/page.tsx 查看文件

@@ -8,12 +8,14 @@ import Tabs, { TabsProps } from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import Typography from "@mui/material/Typography";
import StaffUtilizationComponent from "@/components/StaffUtilization";
import { preloadClientProjects } from "@/app/api/clientprojects";

export const metadata: Metadata = {
title: "Staff Utilization",
};

const StaffUtilization: React.FC = () => {
preloadClientProjects();
return (
<I18nProvider namespaces={["dashboard"]}>
<Typography variant="h4" marginInlineEnd={2}>


+ 58
- 0
src/app/api/staffUtilization/index.ts 查看文件

@@ -0,0 +1,58 @@
"use server";
import { cache } from "react";
import { serverFetchJson } from "@/app/utils/fetchUtil";
import { BASE_API_URL } from "@/config/api";

export interface comboProp {
id: any;
label: string;
}

export interface teamCombo {
records: comboProp[];
}

export interface weeklyTeamTotalManhoursSpentResult {
weeklyActualTeamTotalManhoursSpent: any[];
weeklyPlannedTeamTotalManhoursSpent: any[];
}

export interface monthlyTeamTotalManhoursSpentResult {
monthlyActualTeamTotalManhoursSpent: any[];
monthlyPlannedTeamTotalManhoursSpent: any[];
}

export interface totalManhourByGradeResult {
staffGradeTotalManhours: any[];
staffGradeTotalPlannedManhours: any[];
}

export interface weeklyUnsubmitResult {
id: number;
name: string;
teamId: number;
UnsubmittedCount: number;
}

export const fetchTeamCombo = cache(async () => {
return serverFetchJson<teamCombo>(`${BASE_API_URL}/team/combo`);
});

export const fetchweeklyTeamTotalManhours = cache(async (teamId: number, startdate:string) => {
return serverFetchJson<weeklyTeamTotalManhoursSpentResult[]>(`${BASE_API_URL}/dashboard/searchWeeklyActualTeamTotalManhoursSpent?teamId=${teamId}&startdate=${startdate}`);
});

export const fetchmonthlyTeamTotalManhours = cache(async (teamId: number, startdate:string, enddate:string) => {
return serverFetchJson<monthlyTeamTotalManhoursSpentResult[]>(`${BASE_API_URL}/dashboard/searchMonthlyActualTeamTotalManhoursSpent?teamId=${teamId}&startdate=${startdate}&enddate=${enddate}`);
});

export const fetchTotalManhoursByGrade = cache(async (startdate:string, enddate:string) => {
return serverFetchJson<totalManhourByGradeResult[]>(`${BASE_API_URL}/dashboard/searchTotalManhoursSpentByStaffGrade?startdate=${startdate}&enddate=${enddate}`);
});

export const fetchWeeklyUnsubmit = cache(async (teamId:number,startdate:string, publicHolidayList:string) => {
return serverFetchJson<weeklyUnsubmitResult[]>(`${BASE_API_URL}/dashboard/searchWeeklyUnsubmittedTimeSheet?teamId=${teamId}&startdate=${startdate}&publicHolidayList=${publicHolidayList}`);
});
export const fetchMonthlyUnsubmit = cache(async (teamId:number,startdate:string, enddate:string, publicHolidayList:string) => {
return serverFetchJson<weeklyUnsubmitResult[]>(`${BASE_API_URL}/dashboard/searchMonthlyUnsubmittedTimeSheet?teamId=${teamId}&startdate=${startdate}&enddate=${enddate}&publicHolidayList=${publicHolidayList}`);
});

+ 367
- 55
src/components/StaffUtilization/StaffUtilization.tsx 查看文件

@@ -29,6 +29,9 @@ import dayjs, { Dayjs } from "dayjs";
import isBetweenPlugin from "dayjs/plugin/isBetween";
import { PickersDay, PickersDayProps } from "@mui/x-date-pickers/PickersDay";
import { styled } from "@mui/material/styles";
import Holidays from "date-holidays";
import moment from "moment";
import {fetchTeamCombo, fetchweeklyTeamTotalManhours, fetchmonthlyTeamTotalManhours,fetchTotalManhoursByGrade,fetchWeeklyUnsubmit,fetchMonthlyUnsubmit} from "@/app/api/staffUtilization";

dayjs.extend(isBetweenPlugin);
interface CustomPickerDayProps extends PickersDayProps<Dayjs> {
@@ -174,25 +177,31 @@ const StaffUtilization: React.FC = () => {
const [
teamTotalManhoursSpentPlanData,
setTeamTotalManhoursSpentPlanData,
]: any[] = React.useState([42, 42, 42, 42, 42, 0, 0]);
]: any[] = React.useState([0, 0, 0, 0, 0, 0, 0]);
const [
teamTotalManhoursSpentActualData,
setTeamTotalManhoursSpentActualData,
]: any[] = React.useState([45, 42, 60, 42, 58, 0, 0]);
]: any[] = React.useState([0, 0, 0, 0, 0, 0, 0]);
const [hoveredDay, setHoveredDay] = React.useState<Dayjs | null>(null);
const [value, setValue] = React.useState<Dayjs | null>(dayjs());
const [value, setValue] = React.useState<Dayjs>(dayjs().startOf('week'));
const [weeklyValueByStaffGrade, setWeeklyValueByStaffGrade] =
React.useState<Dayjs | null>(dayjs());
React.useState<Dayjs>(dayjs().startOf('week'));
const [weeklyToValueByStaffGrade, setWeeklyToValueByStaffGrade] =
React.useState<Dayjs>(dayjs().startOf('week').add(6, 'day'));
const [weeklyValueByIndividualStaff, setWeeklyValueByIndividualStaff] =
React.useState<Dayjs | null>(dayjs());
React.useState<Dayjs>(dayjs().startOf('week'));
const [weeklyUnsubmittedTimeSheet, setWeeklyUnsubmittedTimeSheet ] =
React.useState<Dayjs | null>(dayjs());
React.useState<Dayjs>(dayjs().startOf('week'));
const [staffGradeManhoursSpentValue, setStaffGradeManhoursSpentValue] =
React.useState<Dayjs | null>(dayjs());
React.useState<Dayjs>(dayjs());
const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] =
React.useState<Dayjs>(dayjs(new Date()).subtract(6, "month"));
const [totalManHoursMonthlyToValue, setTotalManHoursMonthlyToValue] =
React.useState<Dayjs>(dayjs());
const [unsubmitMonthlyFromValue, setUnsubmitMonthlyFromValue] =
React.useState<Dayjs>(dayjs(new Date()).subtract(6, "month"));
const [unsubmitMonthlyToValue, setUnsubmitMonthlyToValue] =
React.useState<Dayjs>(dayjs());
const [
totalManHoursByStaffGradeMonthlyFromValue,
setTotalManHoursByStaffGradeMonthlyFromValue,
@@ -217,7 +226,284 @@ const StaffUtilization: React.FC = () => {
totalManHoursByIndividualStaffDailyToValue,
setTotalManHoursByIndividualStaffDailyToValue,
] = React.useState<Dayjs>(dayjs());
const [totalManHoursMaxValue, setTotalManHoursMaxValue] = React.useState(75);
const hd = new Holidays('HK');
const currentYear = new Date().getFullYear();
const years = [currentYear -2, currentYear - 1, currentYear, currentYear + 1, currentYear + 2];
let allHolidays: any[] = [];
years.forEach(year => {
const holidays = hd.getHolidays(year);
allHolidays = allHolidays.concat(holidays);
});
const holidayDates = allHolidays.map(holiday => moment(holiday.date).format('YYYY-MM-DD')).join(',');
const [totalManHoursMaxValue, setTotalManHoursMaxValue] = React.useState(5);
const [totalManHoursByGradeMaxValue, setTotalManHoursByGradeMaxValue] = React.useState(5);
const [totalManhourByGradeActualManhours, setTotalManhourByGradeActualManhours]:any[] = React.useState([]);
const [totalManhourByGradePlannedManhours, setTotalManhourByGradePlannedManhours]:any[] = React.useState([]);
const [gradeNameList, setGradeNameList]:any[] = React.useState([]);
const [teamManhoursTeamOptions, setTeamManhoursTeamOptions]: any[] = React.useState([]);
const [teamManhoursTeamId, setTeamManhoursTeamId]: any[] = React.useState(0);
const [teamUnsubmitTeamId, setTeamUnsubmitTeamId]: any[] = React.useState(0);
const [unsubmitCount, setUnsubmitCount]: any[] = React.useState([]);
const [unsubmitStaffList, setUnsubmitStaffList]: any[] = React.useState([]);
const fetchComboData = async () => {
const teamComboList = []
const teamCombo = await fetchTeamCombo();
for (var i = 0; i < teamCombo.records.length; i++) {
teamComboList.push({value: teamCombo.records[i].id, label: teamCombo.records[i].label})
}
setTeamManhoursTeamOptions(teamComboList)
}

const fetchWeeklyTeamManhourSpentData = async () => {
const fetchResult = await fetchweeklyTeamTotalManhours(teamManhoursTeamId,value.format('YYYY-MM-DD'));
const weeklyActual = fetchResult[0].weeklyActualTeamTotalManhoursSpent
const weeklyPlanned = fetchResult[0].weeklyPlannedTeamTotalManhoursSpent
const weeklyActualList = []
const weeklyPlannedList = []
var chartMax = 5
for (var i = 0; i < weeklyActual.length; i++) {
if (chartMax < weeklyActual[i].TotalManhourConsumed) {
chartMax = weeklyActual[i].TotalManhourConsumed
}
weeklyActualList.push(weeklyActual[i].TotalManhourConsumed)
}
if (weekDates.length > 0) {
for (var i = 0; i < weeklyPlanned.length; i++) {
const weeklyPlannedSubList = []
const startCount = weeklyPlanned[i].startCount
const endCount = weeklyPlanned[i].endCount
for (var j = 0; j < weeklyPlanned[i].searchDuration; j++) {
if (j >= startCount && j < endCount) {
weeklyPlannedSubList.push(weeklyPlanned[i].AverageManhours)
} else {
weeklyPlannedSubList.push(0)
}
}
weeklyPlannedList.push(weeklyPlannedSubList)
}
if (weeklyPlannedList.length > 0) {
const result = new Array(weeklyPlannedList[0].length).fill(0);
for (const arr of weeklyPlannedList) {
for (let i = 0; i < arr.length; i++) {
result[i] += arr[i];
if (chartMax < result[i]) {
chartMax = result[i]
}
}
}
setTeamTotalManhoursSpentPlanData(result)
}
}
setTeamTotalManhoursSpentActualData(weeklyActualList);
setTotalManHoursMaxValue(chartMax)
}
const fetchMonthlyTeamManhourSpentData = async () => {
const fetchResult = await fetchmonthlyTeamTotalManhours(teamManhoursTeamId, totalManHoursMonthlyFromValue.format('YYYY-MM-DD'), totalManHoursMonthlyToValue.endOf('month').format('YYYY-MM-DD'));
const weeklyActual = fetchResult[0].monthlyActualTeamTotalManhoursSpent
const weeklyPlanned = fetchResult[0].monthlyPlannedTeamTotalManhoursSpent
const weeklyActualList = []
const weeklyPlannedList = []
var chartMax = 5
for (var i = 0; i < weeklyActual.length; i++) {
if (chartMax < weeklyActual[i].TotalManhourConsumed) {
chartMax = weeklyActual[i].TotalManhourConsumed
}
weeklyActualList.push(weeklyActual[i].TotalManhourConsumed)
}
if (weekDates.length > 0) {
for (var i = 0; i < weeklyPlanned.length; i++) {
const weeklyPlannedSubList = []
const startCount = weeklyPlanned[i].startCount
const endCount = weeklyPlanned[i].endCount
for (var j = 0; j < weeklyPlanned[i].searchDuration; j++) {
if (j >= startCount && j < endCount) {
weeklyPlannedSubList.push(weeklyPlanned[i].AverageManhours)
} else {
weeklyPlannedSubList.push(0)
}
}
weeklyPlannedList.push(weeklyPlannedSubList)
}
if (weeklyPlannedList.length > 0) {
const result = new Array(weeklyPlannedList[0].length).fill(0);
for (const arr of weeklyPlannedList) {
for (let i = 0; i < arr.length; i++) {
result[i] += arr[i];
if (chartMax < result[i]) {
chartMax = result[i]
}
}
}
setTeamTotalManhoursSpentPlanData(result)
}
}
setTeamTotalManhoursSpentActualData(weeklyActualList);
setTotalManHoursMaxValue(chartMax)
}

const fetchTotalManhoursByGradeData = async () => {
const fetchResult = await fetchTotalManhoursByGrade(weeklyValueByStaffGrade.format('YYYY-MM-DD'), weeklyToValueByStaffGrade.format('YYYY-MM-DD'));
const actualManhours = fetchResult[0].staffGradeTotalManhours
const plannedManhours = fetchResult[0].staffGradeTotalPlannedManhours
var chartMax = 5
const gradeList = []
const actualList = []
const plannedList = []
var manhours = 0
for (var i = 0; i < actualManhours.length; i++) {
actualList.push(actualManhours[i].manhours.toFixed(2))
gradeList.push(actualManhours[i].gradeName)
if (chartMax < actualManhours[i].manhours) {
chartMax = actualManhours[i].manhours
}
}
if (plannedManhours.length > 0) {
var gradeId = plannedManhours[0].id
for (var i = 0; i < plannedManhours.length; i++) {
if (plannedManhours[i].id === gradeId) {
manhours += (plannedManhours[i].searchDuration - plannedManhours[i].startDiff - plannedManhours[i].endDiff) * plannedManhours[i].avgGradeManhour
if (chartMax < manhours) {
chartMax = manhours
}
if (i === plannedManhours.length - 1) {
plannedList.push(manhours.toFixed(2))
}
} else {
plannedList.push(manhours.toFixed(2))
manhours = 0
gradeId = plannedManhours[i].id
manhours += (plannedManhours[i].searchDuration - plannedManhours[i].startDiff - plannedManhours[i].endDiff) * plannedManhours[i].avgGradeManhour
if (chartMax < manhours) {
chartMax = manhours
}
if (i === plannedManhours.length - 1) {
plannedList.push(manhours.toFixed(2))
}
}
}
}
setGradeNameList(gradeList)
setTotalManhourByGradePlannedManhours(plannedList)
setTotalManhourByGradeActualManhours(actualList);
setTotalManHoursByGradeMaxValue(chartMax)
}
const fetchMonthlyTotalManhoursByGradeData = async () => {
const fetchResult = await fetchTotalManhoursByGrade(totalManHoursMonthlyFromValue.format('YYYY-MM-DD'), totalManHoursMonthlyToValue.endOf('month').format('YYYY-MM-DD'));
const actualManhours = fetchResult[0].staffGradeTotalManhours
const plannedManhours = fetchResult[0].staffGradeTotalPlannedManhours
var chartMax = 5
const gradeList = []
const actualList = []
const plannedList = []
var manhours = 0
for (var i = 0; i < actualManhours.length; i++) {
actualList.push(actualManhours[i].manhours.toFixed(2))
gradeList.push(actualManhours[i].gradeName)
if (chartMax < actualManhours[i].manhours) {
chartMax = actualManhours[i].manhours
}
}
if (plannedManhours.length > 0) {
var gradeId = plannedManhours[0].id
for (var i = 0; i < plannedManhours.length; i++) {
if (plannedManhours[i].id === gradeId) {
manhours += (plannedManhours[i].searchDuration - plannedManhours[i].startDiff - plannedManhours[i].endDiff) * plannedManhours[i].avgGradeManhour
if (chartMax < manhours) {
chartMax = manhours
}
if (i === plannedManhours.length - 1) {
plannedList.push(manhours.toFixed(2))
}
} else {
plannedList.push(manhours.toFixed(2))
manhours = 0
gradeId = plannedManhours[i].id
manhours += (plannedManhours[i].searchDuration - plannedManhours[i].startDiff - plannedManhours[i].endDiff) * plannedManhours[i].avgGradeManhour
if (chartMax < manhours) {
chartMax = manhours
}
if (i === plannedManhours.length - 1) {
plannedList.push(manhours.toFixed(2))
}
}
}
}
setGradeNameList(gradeList)
setTotalManhourByGradePlannedManhours(plannedList)
setTotalManhourByGradeActualManhours(actualList);
setTotalManHoursByGradeMaxValue(chartMax)
}
const fetchWeeklyUnsubmittedData = async () => {
const fetchResult = await fetchWeeklyUnsubmit(teamUnsubmitTeamId, weeklyUnsubmittedTimeSheet.format('YYYY-MM-DD'), holidayDates);
const result = []
const staffList = []
for (var i = 0; i < fetchResult.length; i++) {
result.push(fetchResult[i].UnsubmittedCount)
staffList.push(fetchResult[i].name)
}
setUnsubmitCount(result)
setUnsubmitStaffList(staffList)
}
const fetchMonthlyUnsubmittedData = async () => {
const fetchResult = await fetchMonthlyUnsubmit(teamUnsubmitTeamId, unsubmitMonthlyFromValue.format('YYYY-MM-DD'), unsubmitMonthlyToValue.endOf('month').format('YYYY-MM-DD'), holidayDates);
console.log(fetchResult)
const result = []
const staffList = []
for (var i = 0; i < fetchResult.length; i++) {
result.push(fetchResult[i].UnsubmittedCount)
staffList.push(fetchResult[i].name)
}
setUnsubmitCount(result)
setUnsubmitStaffList(staffList)
}



useEffect(() => {
fetchComboData()
}, []);

useEffect(() => {
if (teamTotalManhoursSpentSelect === "Weekly"){
fetchWeeklyTeamManhourSpentData()
}
}, [value,teamManhoursTeamId]);

useEffect(() => {
if (teamTotalManhoursSpentSelect === "Monthly"){
fetchMonthlyTeamManhourSpentData()
}
}, [totalManHoursMonthlyFromValue,totalManHoursMonthlyToValue,teamManhoursTeamId]);

useEffect(() => {
if (staffGradeManhoursSpentSelect === "Weekly"){
fetchTotalManhoursByGradeData()
}
}, [weeklyValueByStaffGrade,weeklyToValueByStaffGrade]);

useEffect(() => {
if (staffGradeManhoursSpentSelect === "Monthly"){
fetchMonthlyTotalManhoursByGradeData()
}
}, [totalManHoursMonthlyFromValue,totalManHoursMonthlyToValue]);

useEffect(() => {
if (unsubmittedTimeSheetSelect === "Weekly"){
fetchWeeklyUnsubmittedData()
}
}, [teamUnsubmitTeamId, weeklyUnsubmittedTimeSheet]);

useEffect(() => {
if (unsubmittedTimeSheetSelect === "Monthly"){
fetchMonthlyUnsubmittedData()
}
}, [unsubmitMonthlyFromValue, unsubmitMonthlyToValue]);



const teamOptions = [
{ value: 1, label: "XXX Team" },
@@ -344,13 +630,7 @@ const StaffUtilization: React.FC = () => {
enabled: true,
},
xaxis: {
categories: [
"Grade 1: A. QS / QS Trainee",
"Grade 2: QS",
"Grade 3: Senior QS",
"Grade 4: Manager",
"Grade 5: Director",
],
categories: gradeNameList,
},
yaxis: [
{
@@ -358,7 +638,7 @@ const StaffUtilization: React.FC = () => {
text: "Staff Grade",
},
min: 0,
max: 60,
max: totalManHoursByGradeMaxValue,
tickAmount: 5,
},
],
@@ -371,13 +651,13 @@ const StaffUtilization: React.FC = () => {
name: "Planned",
type: "bar",
color: "#efbe7d",
data: [35, 45, 35, 20, 10],
data: totalManhourByGradePlannedManhours,
},
{
name: "Actual",
type: "bar",
color: "#00acb1",
data: [25, 26, 33, 20, 11],
data: totalManhourByGradeActualManhours,
},
],
};
@@ -450,13 +730,7 @@ const StaffUtilization: React.FC = () => {
enabled: true,
},
xaxis: {
categories: [
"001-Staff A",
"002-Staff B",
"005-Staff E",
"006-Staff F",
"007-Staff G",
],
categories: unsubmitStaffList,
},
yaxis: [
{
@@ -464,7 +738,7 @@ const StaffUtilization: React.FC = () => {
text: "Staff",
},
min: 0,
max: 12,
max: 5,
tickAmount: 5,
},
],
@@ -477,7 +751,7 @@ const StaffUtilization: React.FC = () => {
name: "Unsubmitted Time Sheet",
type: "bar",
color: "#00acb1",
data: [2, 2, 1, 5, 1],
data: unsubmitCount,
},
],
};
@@ -485,16 +759,12 @@ const StaffUtilization: React.FC = () => {
const teamTotalManhoursSpentOnClick = (r: any) => {
setTeamTotalManhoursSpentSelect(r);
if (r === "Weekly") {
setValue(dayjs(new Date()));
fetchWeeklyTeamManhourSpentData()
setValue(dayjs().startOf('week'));
setTeamTotalManhoursSpentPeriod(weekDates);
setTeamTotalManhoursSpentPlanData([42, 42, 42, 42, 42, 0, 0]);
setTeamTotalManhoursSpentActualData([45, 42, 60, 42, 58, 0, 0]);
setTotalManHoursMaxValue(75);
} else if (r === "Monthly") {
fetchMonthlyTeamManhourSpentData()
setTeamTotalManhoursSpentPeriod(monthDates);
setTeamTotalManhoursSpentPlanData([840, 840, 840, 840, 840, 840]);
setTeamTotalManhoursSpentActualData([900, 840, 1200, 840, 1160, 840]);
setTotalManHoursMaxValue(1250);
}
};

@@ -520,9 +790,10 @@ const StaffUtilization: React.FC = () => {

const selectWeeklyPeriod = (r: any) => {
const selectDate = new Date(r);
const firstDayOfWeek = new Date();
const firstDayOfWeek = selectDate;
firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
const weekDates: any[] = [];
const weekFirstDate = new Date(firstDayOfWeek);
for (let i = 0; i < 7; i++) {
const currentDate = new Date(firstDayOfWeek);
currentDate.setDate(firstDayOfWeek.getDate() + i);
@@ -535,7 +806,7 @@ const StaffUtilization: React.FC = () => {

const selectWeeklyPeriodByStaffGrade = (r: any) => {
const selectDate = new Date(r);
const firstDayOfWeek = new Date();
const firstDayOfWeek = selectDate
firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
const weekDates: any[] = [];
for (let i = 0; i < 7; i++) {
@@ -546,11 +817,12 @@ const StaffUtilization: React.FC = () => {
}
setTeamTotalManhoursByStaffGrade(weekDates);
setWeeklyValueByStaffGrade(dayjs(firstDayOfWeek));
setWeeklyToValueByStaffGrade(dayjs(firstDayOfWeek).add(6, 'day'))
};

const selectWeeklyPeriodUnsubmittedTimeSheet = (r: any) => {
const selectDate = new Date(r);
const firstDayOfWeek = new Date();
const firstDayOfWeek = selectDate;
firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
const weekDates: any[] = [];
for (let i = 0; i < 7; i++) {
@@ -579,6 +851,7 @@ const StaffUtilization: React.FC = () => {
};

const selectMonthlyPeriodFrom = (r: any) => {
setTotalManHoursMonthlyFromValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
@@ -601,6 +874,7 @@ const StaffUtilization: React.FC = () => {
};

const selectMonthlyPeriodTo = (r: any) => {
setTotalManHoursMonthlyToValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
@@ -623,6 +897,7 @@ const StaffUtilization: React.FC = () => {
};

const selectStaffGradeMonthlyPeriodFrom = (r: any) => {
setTotalManHoursMonthlyFromValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
@@ -645,6 +920,7 @@ const StaffUtilization: React.FC = () => {
};

const selectStaffGradeMonthlyPeriodTo = (r: any) => {
setTotalManHoursMonthlyToValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
@@ -667,20 +943,21 @@ const StaffUtilization: React.FC = () => {
};

const selectUnsubmittedTimeSheetMonthlyPeriodFrom = (r: any) => {
setUnsubmitMonthlyFromValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
const selectFromDate = dayjs(r);
for (
let date = selectFromDate.clone();
date.isBefore(totalManHoursMonthlyToValue, "month");
date.isBefore(unsubmitMonthlyToValue, "month");
date = date.add(1, "month")
) {
monthDates.push(date.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
}
monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
monthDates.push(selectFromDate.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
// setTeamTotalManhoursSpentPlanData(monthPlanData)
@@ -689,6 +966,7 @@ const StaffUtilization: React.FC = () => {
};

const selectIndividualStaffMonthlyPeriodFrom = (r: any) => {
setTotalManHoursMonthlyFromValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
@@ -699,24 +977,25 @@ const StaffUtilization: React.FC = () => {
date = date.add(1, "month")
) {
monthDates.push(date.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
// monthPlanData.push(840);
// monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
}
monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
monthDates.push(selectFromDate.format("MM-YYYY"));
// monthPlanData.push(840);
// monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
// setTeamTotalManhoursSpentPlanData(monthPlanData)
// setTeamTotalManhoursSpentActualData(monthActualData)
setIndividualStaffManhoursSpentPeriod(weekDates);
};

const selectUnsubmittedTimeSheetMonthlyPeriodTo = (r: any) => {
setUnsubmitMonthlyToValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
const selectToDate = dayjs(r);
for (
let date = totalManHoursMonthlyFromValue.clone();
let date = unsubmitMonthlyFromValue.clone();
date.isBefore(selectToDate, "month");
date = date.add(1, "month")
) {
@@ -733,6 +1012,7 @@ const StaffUtilization: React.FC = () => {
};

const selectIndividualStaffMonthlyPeriodTo = (r: any) => {
setTotalManHoursMonthlyToValue(r)
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
@@ -859,9 +1139,16 @@ const StaffUtilization: React.FC = () => {
</div>
<div className="inline-block ml-1 w-60">
<Select
placeholder="All Team"
options={teamOptions}
placeholder="Please select a team"
options={teamManhoursTeamOptions}
isClearable={true}
onChange={(selectedOption:any) => {
if (selectedOption === null) {
setTeamManhoursTeamId(null);
} else {
setTeamManhoursTeamId(selectedOption.value);
}
}}
/>
</div>
<div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>
@@ -875,9 +1162,10 @@ const StaffUtilization: React.FC = () => {
label="Period:"
value={value}
format="DD-MM-YYYY"
onChange={(newValue) =>
onChange={(newValue) => {
selectWeeklyPeriod(newValue)
}
}
showDaysOutsideCurrentMonth
displayWeekNumber
slots={{ day: Day }}
@@ -944,8 +1232,10 @@ const StaffUtilization: React.FC = () => {
Weekly
</button>
<button
onClick={() =>
onClick={() => {
setStaffGradeManhoursSpentSelect("Monthly")
fetchMonthlyTotalManhoursByGradeData()
}
}
className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-48"
>
@@ -956,8 +1246,10 @@ const StaffUtilization: React.FC = () => {
{staffGradeManhoursSpentSelect === "Monthly" && (
<>
<button
onClick={() =>
onClick={() => {
setStaffGradeManhoursSpentSelect("Weekly")
fetchTotalManhoursByGradeData()
}
}
className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-l-md w-32"
>
@@ -976,7 +1268,7 @@ const StaffUtilization: React.FC = () => {
<DatePicker
className="w-72 h-10 align-top"
label="Period:"
value={value}
value={weeklyValueByStaffGrade}
format="DD-MM-YYYY"
onChange={(newValue) =>
selectWeeklyPeriodByStaffGrade(newValue)
@@ -1069,7 +1361,10 @@ const StaffUtilization: React.FC = () => {
</button>
<button
onClick={() =>
{
unsubmittedTimeSheetOnClick("Monthly")
fetchMonthlyUnsubmittedData()
}
}
className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-32"
>
@@ -1081,7 +1376,10 @@ const StaffUtilization: React.FC = () => {
<>
<button
onClick={() =>
{
unsubmittedTimeSheetOnClick("Weekly")
fetchWeeklyUnsubmittedData()
}
}
className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid w-32"
>
@@ -1101,9 +1399,16 @@ const StaffUtilization: React.FC = () => {
</div>
<div className="inline-block ml-1 w-60">
<Select
placeholder="Team"
options={teamOptions}
placeholder="Please select a team"
options={teamManhoursTeamOptions}
isClearable={true}
onChange={(selectedOption:any) => {
if (selectedOption === null) {
setTeamUnsubmitTeamId(null);
} else {
setTeamUnsubmitTeamId(selectedOption.value);
}
}}
/>
</div>
<div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>
@@ -1259,9 +1564,16 @@ const StaffUtilization: React.FC = () => {
</div>
<div className="inline-block ml-1 w-60">
<Select
placeholder="00338-Chris Wong"
options={teamOptions}
placeholder="Please select a team"
options={teamManhoursTeamOptions}
isClearable={true}
onChange={(selectedOption:any) => {
if (selectedOption === null) {
setTeamUnsubmitTeamId(null);
} else {
setTeamUnsubmitTeamId(selectedOption.value);
}
}}
/>
</div>
<div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>


正在加载...
取消
保存