From 404f42abd52a953f31ee146efd8578df88ddaa71 Mon Sep 17 00:00:00 2001 From: "MSI\\2Fi" Date: Tue, 16 Jul 2024 12:11:18 +0800 Subject: [PATCH 1/7] fallback to 2 button --- src/components/InvoiceSearch/InvoiceSearch.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/InvoiceSearch/InvoiceSearch.tsx b/src/components/InvoiceSearch/InvoiceSearch.tsx index 0e1409a..f76db96 100644 --- a/src/components/InvoiceSearch/InvoiceSearch.tsx +++ b/src/components/InvoiceSearch/InvoiceSearch.tsx @@ -86,7 +86,7 @@ const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice, invoic const formData = new FormData(); formData.append('multipartFileList', file); - const response = await importInvoices(formData); + const response = await importIssuedInovice(formData); // response: status, message, projectList, emptyRowList, invoiceList console.log(response) @@ -271,8 +271,8 @@ const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice, invoic flexWrap="wrap" spacing={2} > - {/* */} - {/* */} - {/* */} - + + {/* + */} { // tabIndex == 0 && From d6d0092f109ff1ef5ba8a2399f82a6da1f03393a Mon Sep 17 00:00:00 2001 From: "MSI\\2Fi" Date: Tue, 16 Jul 2024 13:55:10 +0800 Subject: [PATCH 2/7] Update combined column field, updated display of settle Date and Amount received --- src/app/utils/formatUtil.ts | 3 +++ src/components/InvoiceSearch/InvoiceSearch.tsx | 2 +- src/components/InvoiceSearch/InvoiceSearchWrapper.tsx | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/app/utils/formatUtil.ts b/src/app/utils/formatUtil.ts index d5edb6f..32ccc76 100644 --- a/src/app/utils/formatUtil.ts +++ b/src/app/utils/formatUtil.ts @@ -131,6 +131,9 @@ export function convertLocaleStringToNumber(numberString: string): number { } export function timestampToDateString(timestamp: string): string { + if (timestamp === null){ + return "-" + } const date = new Date(timestamp); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); diff --git a/src/components/InvoiceSearch/InvoiceSearch.tsx b/src/components/InvoiceSearch/InvoiceSearch.tsx index f76db96..acc7b4a 100644 --- a/src/components/InvoiceSearch/InvoiceSearch.tsx +++ b/src/components/InvoiceSearch/InvoiceSearch.tsx @@ -236,7 +236,7 @@ const InvoiceSearch: React.FC = ({ issuedInvoice, receivedInvoice, invoic { name: "projectName", label: t("Project Name") }, { name: "team", label: t("Team") }, { name: "issuedDate", label: t("Issue Date") }, - { name: "receivedAmount", label: t("Amount (HKD)") }, + { name: "issuedAmount", label: t("Amount (HKD)") }, { name: "receiptDate", label: t("Settle Date") }, { name: "receivedAmount", label: t("Actual Received Amount (HKD)") }, ], diff --git a/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx b/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx index ad3c49c..f155c03 100644 --- a/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx +++ b/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx @@ -56,9 +56,9 @@ const InvoiceSearchWrapper: React.FC & SubComponents = async () => { projectName: invoice.projectName, team: invoice.team, issuedDate: timestampToDateString(invoice.invoiceDate)!!, - receiptDate: timestampToDateString(invoice.receiptDate??0)!!, + receiptDate: timestampToDateString(invoice.receiptDate??null)!!, issuedAmount: moneyFormatter.format(invoice.issueAmount), - receivedAmount: moneyFormatter.format(invoice.paidAmount) + receivedAmount: invoice.paidAmount === null ? "-" : moneyFormatter.format(invoice.paidAmount) } }) From 0deeda45a9296647422f5a49fcd5654a63cff046 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Tue, 16 Jul 2024 14:25:13 +0800 Subject: [PATCH 3/7] update cross team report (cherry picked from commit 13b6cc9f1205190872a2ebc0ca852ad7e89abb57) --- src/app/api/reports/index.ts | 2 + .../GenerateCrossTeamChargeReport.tsx | 22 +++++- .../GenerateCrossTeamChargeReportWrapper.tsx | 7 +- .../NavigationContent/NavigationContent.tsx | 54 ++++++++++++- src/middleware.ts | 76 ++++++++++++++++++- 5 files changed, 150 insertions(+), 11 deletions(-) diff --git a/src/app/api/reports/index.ts b/src/app/api/reports/index.ts index 934f02c..7db4809 100644 --- a/src/app/api/reports/index.ts +++ b/src/app/api/reports/index.ts @@ -120,8 +120,10 @@ export interface CostAndExpenseReportRequest { // - Cross Team Charge Report export interface CrossTeamChargeReportFilter { month: string; + team: string[]; } export interface CrossTeamChargeReportRequest { month: string; + teamId: number | "All"; } \ No newline at end of file diff --git a/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReport.tsx b/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReport.tsx index 2d7aaa4..683b701 100644 --- a/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReport.tsx +++ b/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReport.tsx @@ -6,15 +6,20 @@ import { useTranslation } from "react-i18next"; import { CrossTeamChargeReportFilter } from "@/app/api/reports"; import { fetchCrossTeamChargeReport } from "@/app/api/reports/actions"; import { downloadFile } from "@/app/utils/commonUtil"; +import { TeamResult } from "@/app/api/team"; +import { SessionStaff } from "@/config/authConfig"; interface Props { + teams: TeamResult[]; + userStaff: SessionStaff; } type SearchQuery = Partial>; type SearchParamNames = keyof SearchQuery; -const GenerateCrossTeamChargeReport: React.FC = () => { +const GenerateCrossTeamChargeReport: React.FC = ({ teams, userStaff }) => { const { t } = useTranslation("report"); + const teamCombo = teams.map(team => `${team.code} - ${team.name}`) const searchCriteria: Criterion[] = useMemo( () => [ @@ -23,6 +28,13 @@ const GenerateCrossTeamChargeReport: React.FC = () => { paramName: "month", type: "monthYear", }, + { + label: t("Team"), + paramName: "team", + type: "select", + options: teamCombo, + needAll: !Boolean(userStaff?.isTeamLead) + }, ], [t], ); @@ -33,10 +45,12 @@ const GenerateCrossTeamChargeReport: React.FC = () => { criteria={searchCriteria} onSearch={async (query) => { - console.log(query.month) - if (Boolean(query.month)) { + console.log(query) + if (Boolean(query.month) && Boolean(query.team)) { // const projectIndex = projectCombo.findIndex(({value}) => value === parseInt(query.project)) - const response = await fetchCrossTeamChargeReport({ month: query.month }) + const teamIndex = teamCombo.findIndex(team => team === query.team) + + const response = await fetchCrossTeamChargeReport({ month: query.month, teamId: teamIndex >= 0 ? teams[teamIndex].id : "All", }) if (response) { downloadFile(new Uint8Array(response.blobValue), response.filename!!) } diff --git a/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReportWrapper.tsx b/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReportWrapper.tsx index 5e7d2e5..a9aaea2 100644 --- a/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReportWrapper.tsx +++ b/src/components/GenerateCrossTeamChargeReport/GenerateCrossTeamChargeReportWrapper.tsx @@ -1,13 +1,18 @@ import React from "react"; import GenerateCrossTeamChargeReportLoading from "./GenerateCrossTeamChargeReportLoading"; import GenerateCrossTeamChargeReport from "./GenerateCrossTeamChargeReport"; +import { fetchTeam } from "@/app/api/team"; +import { getUserStaff } from "@/app/utils/commonUtil"; interface SubComponents { Loading: typeof GenerateCrossTeamChargeReportLoading; } const GenerateCrossTeamChargeReportWrapper: React.FC & SubComponents = async () => { - return ; + + const [teams, userStaff] = await Promise.all([fetchTeam(), getUserStaff()]) + + return team.id === userStaff?.teamId)} userStaff={userStaff}/>; }; GenerateCrossTeamChargeReportWrapper.Loading = GenerateCrossTeamChargeReportLoading; diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx index bab1493..83a5535 100644 --- a/src/components/NavigationContent/NavigationContent.tsx +++ b/src/components/NavigationContent/NavigationContent.tsx @@ -36,7 +36,6 @@ import ManageAccountsIcon from "@mui/icons-material/ManageAccounts"; import EmojiEventsIcon from "@mui/icons-material/EmojiEvents"; import FileUploadIcon from '@mui/icons-material/FileUpload'; import { - GENERATE_REPORTS, IMPORT_INVOICE, IMPORT_RECEIPT, MAINTAIN_PROJECT, @@ -68,6 +67,16 @@ import { MAINTAIN_GROUP, MAINTAIN_HOLIDAY, VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING, + GENERATE_LATE_START_REPORTS, + GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, + GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, + GENERATE_COST_ANT_EXPENSE_REPORT, + GENERATE_PROJECT_COMPLETION_REPORT, + GENERATE_PROJECT_PANDL_REPORT, + GENERATE_FINANCIAL_STATUS_REPORT, + GENERATE_PROJECT_CASH_FLOW_REPORT, + GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, + GENERATE_CROSS_TEAM_CHARGE_REPORT, } from "@/middleware"; import { SessionWithAbilities } from "../AppBar/NavigationToggle"; import { authOptions } from "@/config/authConfig"; @@ -180,7 +189,18 @@ const NavigationContent: React.FC = ({ abilities, username }) => { icon: , label: "Analysis Report", path: "", - isHidden: ![GENERATE_REPORTS].some((ability) => + isHidden: ![ + GENERATE_LATE_START_REPORTS, + GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, + GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, + GENERATE_COST_ANT_EXPENSE_REPORT, + GENERATE_PROJECT_COMPLETION_REPORT, + GENERATE_PROJECT_PANDL_REPORT, + GENERATE_FINANCIAL_STATUS_REPORT, + GENERATE_PROJECT_CASH_FLOW_REPORT, + GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, + GENERATE_CROSS_TEAM_CHARGE_REPORT, + ].some((ability) => abilities!.includes(ability), ), children: [ @@ -188,26 +208,41 @@ const NavigationContent: React.FC = ({ abilities, username }) => { icon: , label: "Late Start Report", path: "/analytics/LateStartReport", + isHidden: ![GENERATE_LATE_START_REPORTS].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Project Potential Delay Report", path: "/analytics/ProjectPotentialDelayReport", + isHidden: ![GENERATE_PROJECT_POTENTIAL_DELAY_REPORT].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Resource Overconsumption Report", path: "/analytics/ResourceOverconsumptionReport", + isHidden: ![GENERATE_RESOURCE_OVERCONSUMPTION_REPORT].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Cost and Expense Report", path: "/analytics/CostandExpenseReport", + isHidden: ![GENERATE_COST_ANT_EXPENSE_REPORT].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Project Completion Report", path: "/analytics/ProjectCompletionReport", + isHidden: ![GENERATE_PROJECT_COMPLETION_REPORT].some((ability) => + abilities!.includes(ability), + ), }, // { // icon: , @@ -223,26 +258,41 @@ const NavigationContent: React.FC = ({ abilities, username }) => { icon: , label: "Project P&L Report", path: "/analytics/ProjectPandLReport", + isHidden: ![GENERATE_PROJECT_COMPLETION_REPORT].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Financial Status Report", path: "/analytics/FinancialStatusReport", + isHidden: ![GENERATE_FINANCIAL_STATUS_REPORT].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Project Cash Flow Report", path: "/analytics/ProjectCashFlowReport", + isHidden: ![GENERATE_PROJECT_CASH_FLOW_REPORT].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Staff Monthly Work Hours Analysis Report", path: "/analytics/StaffMonthlyWorkHoursAnalysisReport", + isHidden: ![GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT].some((ability) => + abilities!.includes(ability), + ), }, { icon: , label: "Cross Team Charge Report", path: "/analytics/CrossTeamChargeReport", + isHidden: ![GENERATE_CROSS_TEAM_CHARGE_REPORT].some((ability) => + abilities!.includes(ability), + ), }, ], }, diff --git a/src/middleware.ts b/src/middleware.ts index cb48c5b..0448add 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -48,7 +48,6 @@ export const [ VIEW_DASHBOARD_SELF, VIEW_DASHBOARD_ALL, IMPORT_INVOICE, - GENERATE_REPORTS, VIEW_STAFF_PROFILE, IMPORT_RECEIPT, MAINTAIN_TASK_TEMPLATE, @@ -60,6 +59,16 @@ export const [ VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING, MAINTAIN_NORMAL_STAFF_WORKSPACE, MAINTAIN_MANAGEMENT_STAFF_WORKSPACE, + GENERATE_LATE_START_REPORTS, + GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, + GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, + GENERATE_COST_ANT_EXPENSE_REPORT, + GENERATE_PROJECT_COMPLETION_REPORT, + GENERATE_PROJECT_PANDL_REPORT, + GENERATE_FINANCIAL_STATUS_REPORT, + GENERATE_PROJECT_CASH_FLOW_REPORT, + GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, + GENERATE_CROSS_TEAM_CHARGE_REPORT, ] = [ 'MAINTAIN_USER', 'MAINTAIN_TIMESHEET', @@ -89,7 +98,6 @@ export const [ 'VIEW_DASHBOARD_SELF', 'VIEW_DASHBOARD_ALL', 'IMPORT_INVOICE', - 'GENERATE_REPORTS', 'VIEW_STAFF_PROFILE', 'IMPORT_RECEIPT', 'MAINTAIN_TASK_TEMPLATE', @@ -100,7 +108,17 @@ export const [ 'MAINTAIN_TIMESHEET_FAST_TIME_ENTRY', 'VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING', 'MAINTAIN_NORMAL_STAFF_WORKSPACE', - 'MAINTAIN_MANAGEMENT_STAFF_WORKSPACE' + 'MAINTAIN_MANAGEMENT_STAFF_WORKSPACE', + 'GENERATE_LATE_START_REPORTS', + 'GENERATE_PROJECT_POTENTIAL_DELAY_REPORT', + 'GENERATE_RESOURCE_OVERCONSUMPTION_REPORT', + 'GENERATE_COST_ANT_EXPENSE_REPORT', + 'GENERATE_PROJECT_COMPLETION_REPORT', + 'GENERATE_PROJECT_P&L_REPORT', + 'GENERATE_FINANCIAL_STATUS_REPORT', + 'GENERATE_PROJECT_CASH_FLOW_REPORT', + 'GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT', + 'GENERATE_CROSS_TEAM_CHARGE_REPORT', ] const PRIVATE_ROUTES = [ @@ -224,7 +242,57 @@ export default async function middleware( } if (req.nextUrl.pathname.startsWith('/analytics')) { - isAuth = [GENERATE_REPORTS].some((ability) => abilities.includes(ability)); + isAuth = [ + GENERATE_LATE_START_REPORTS, + GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, + GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, + GENERATE_COST_ANT_EXPENSE_REPORT, + GENERATE_PROJECT_COMPLETION_REPORT, + GENERATE_PROJECT_PANDL_REPORT, + GENERATE_FINANCIAL_STATUS_REPORT, + GENERATE_PROJECT_CASH_FLOW_REPORT, + GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, + GENERATE_CROSS_TEAM_CHARGE_REPORT,].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/LateStartReport')) { + isAuth = [GENERATE_LATE_START_REPORTS].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/ProjectPotentialDelayReport')) { + isAuth = [GENERATE_PROJECT_POTENTIAL_DELAY_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/ResourceOverconsumptionReport')) { + isAuth = [GENERATE_RESOURCE_OVERCONSUMPTION_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/CostandExpenseReport')) { + isAuth = [GENERATE_COST_ANT_EXPENSE_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/ProjectCompletionReport')) { + isAuth = [GENERATE_PROJECT_COMPLETION_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/ProjectPandLReport')) { + isAuth = [GENERATE_PROJECT_PANDL_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/FinancialStatusReport')) { + isAuth = [GENERATE_FINANCIAL_STATUS_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/ProjectCashFlowReport')) { + isAuth = [GENERATE_PROJECT_CASH_FLOW_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/StaffMonthlyWorkHoursAnalysisReport')) { + isAuth = [GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT].some((ability) => abilities.includes(ability)); + } + + if (req.nextUrl.pathname.startsWith('/analytics/CrossTeamChargeReport')) { + isAuth = [GENERATE_CROSS_TEAM_CHARGE_REPORT].some((ability) => abilities.includes(ability)); } if (req.nextUrl.pathname.startsWith('/settings/staff/edit')) { From 3f3de75fd12a4a0c33d92b6fe6100f6dfefedaaf Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Tue, 16 Jul 2024 16:35:16 +0800 Subject: [PATCH 4/7] update --- .../NavigationContent/NavigationContent.tsx | 10 +++++----- src/middleware.ts | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx index 83a5535..3203fa6 100644 --- a/src/components/NavigationContent/NavigationContent.tsx +++ b/src/components/NavigationContent/NavigationContent.tsx @@ -67,7 +67,7 @@ import { MAINTAIN_GROUP, MAINTAIN_HOLIDAY, VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING, - GENERATE_LATE_START_REPORTS, + GENERATE_LATE_START_REPORT, GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, GENERATE_COST_ANT_EXPENSE_REPORT, @@ -76,7 +76,7 @@ import { GENERATE_FINANCIAL_STATUS_REPORT, GENERATE_PROJECT_CASH_FLOW_REPORT, GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, - GENERATE_CROSS_TEAM_CHARGE_REPORT, + GENERATE_CROSS_TEAM_CHARGE_REPORT } from "@/middleware"; import { SessionWithAbilities } from "../AppBar/NavigationToggle"; import { authOptions } from "@/config/authConfig"; @@ -190,7 +190,7 @@ const NavigationContent: React.FC = ({ abilities, username }) => { label: "Analysis Report", path: "", isHidden: ![ - GENERATE_LATE_START_REPORTS, + GENERATE_LATE_START_REPORT, GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, GENERATE_COST_ANT_EXPENSE_REPORT, @@ -199,7 +199,7 @@ const NavigationContent: React.FC = ({ abilities, username }) => { GENERATE_FINANCIAL_STATUS_REPORT, GENERATE_PROJECT_CASH_FLOW_REPORT, GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, - GENERATE_CROSS_TEAM_CHARGE_REPORT, + GENERATE_CROSS_TEAM_CHARGE_REPORT ].some((ability) => abilities!.includes(ability), ), @@ -208,7 +208,7 @@ const NavigationContent: React.FC = ({ abilities, username }) => { icon: , label: "Late Start Report", path: "/analytics/LateStartReport", - isHidden: ![GENERATE_LATE_START_REPORTS].some((ability) => + isHidden: ![GENERATE_LATE_START_REPORT].some((ability) => abilities!.includes(ability), ), }, diff --git a/src/middleware.ts b/src/middleware.ts index 0448add..c9208df 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -59,7 +59,7 @@ export const [ VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING, MAINTAIN_NORMAL_STAFF_WORKSPACE, MAINTAIN_MANAGEMENT_STAFF_WORKSPACE, - GENERATE_LATE_START_REPORTS, + GENERATE_LATE_START_REPORT, GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, GENERATE_COST_ANT_EXPENSE_REPORT, @@ -68,7 +68,7 @@ export const [ GENERATE_FINANCIAL_STATUS_REPORT, GENERATE_PROJECT_CASH_FLOW_REPORT, GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, - GENERATE_CROSS_TEAM_CHARGE_REPORT, + GENERATE_CROSS_TEAM_CHARGE_REPORT ] = [ 'MAINTAIN_USER', 'MAINTAIN_TIMESHEET', @@ -109,7 +109,7 @@ export const [ 'VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING', 'MAINTAIN_NORMAL_STAFF_WORKSPACE', 'MAINTAIN_MANAGEMENT_STAFF_WORKSPACE', - 'GENERATE_LATE_START_REPORTS', + 'GENERATE_LATE_START_REPORT', 'GENERATE_PROJECT_POTENTIAL_DELAY_REPORT', 'GENERATE_RESOURCE_OVERCONSUMPTION_REPORT', 'GENERATE_COST_ANT_EXPENSE_REPORT', @@ -118,7 +118,7 @@ export const [ 'GENERATE_FINANCIAL_STATUS_REPORT', 'GENERATE_PROJECT_CASH_FLOW_REPORT', 'GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT', - 'GENERATE_CROSS_TEAM_CHARGE_REPORT', + 'GENERATE_CROSS_TEAM_CHARGE_REPORT' ] const PRIVATE_ROUTES = [ @@ -243,7 +243,7 @@ export default async function middleware( if (req.nextUrl.pathname.startsWith('/analytics')) { isAuth = [ - GENERATE_LATE_START_REPORTS, + GENERATE_LATE_START_REPORT, GENERATE_PROJECT_POTENTIAL_DELAY_REPORT, GENERATE_RESOURCE_OVERCONSUMPTION_REPORT, GENERATE_COST_ANT_EXPENSE_REPORT, @@ -252,11 +252,11 @@ export default async function middleware( GENERATE_FINANCIAL_STATUS_REPORT, GENERATE_PROJECT_CASH_FLOW_REPORT, GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, - GENERATE_CROSS_TEAM_CHARGE_REPORT,].some((ability) => abilities.includes(ability)); + GENERATE_CROSS_TEAM_CHARGE_REPORT].some((ability) => abilities.includes(ability)); } if (req.nextUrl.pathname.startsWith('/analytics/LateStartReport')) { - isAuth = [GENERATE_LATE_START_REPORTS].some((ability) => abilities.includes(ability)); + isAuth = [GENERATE_LATE_START_REPORT].some((ability) => abilities.includes(ability)); } if (req.nextUrl.pathname.startsWith('/analytics/ProjectPotentialDelayReport')) { From b4a611389d9f11aef354dec4359a271e5fc67a84 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Wed, 17 Jul 2024 11:50:20 +0800 Subject: [PATCH 5/7] update --- src/middleware.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/middleware.ts b/src/middleware.ts index c9208df..d2494d9 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -109,16 +109,16 @@ export const [ 'VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING', 'MAINTAIN_NORMAL_STAFF_WORKSPACE', 'MAINTAIN_MANAGEMENT_STAFF_WORKSPACE', - 'GENERATE_LATE_START_REPORT', - 'GENERATE_PROJECT_POTENTIAL_DELAY_REPORT', - 'GENERATE_RESOURCE_OVERCONSUMPTION_REPORT', - 'GENERATE_COST_ANT_EXPENSE_REPORT', - 'GENERATE_PROJECT_COMPLETION_REPORT', - 'GENERATE_PROJECT_P&L_REPORT', - 'GENERATE_FINANCIAL_STATUS_REPORT', - 'GENERATE_PROJECT_CASH_FLOW_REPORT', - 'GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT', - 'GENERATE_CROSS_TEAM_CHARGE_REPORT' + 'G_LATE_START_REPORT', + 'G_PROJECT_POTENTIAL_DELAY_REPORT', + 'G_RESOURCE_OVERCONSUMPTION_REPORT', + 'G_COST_AND_EXPENSE_REPORT', + 'G_PROJECT_COMPLETION_REPORT', + 'G_PROJECT_P&L_REPORT', + 'G_FINANCIAL_STATUS_REPORT', + 'G_PROJECT_CASH_FLOW_REPORT', + 'G_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT', + 'G_CROSS_TEAM_CHARGE_REPORT' ] const PRIVATE_ROUTES = [ @@ -252,7 +252,8 @@ export default async function middleware( GENERATE_FINANCIAL_STATUS_REPORT, GENERATE_PROJECT_CASH_FLOW_REPORT, GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT, - GENERATE_CROSS_TEAM_CHARGE_REPORT].some((ability) => abilities.includes(ability)); + GENERATE_CROSS_TEAM_CHARGE_REPORT + ].some((ability) => abilities.includes(ability)); } if (req.nextUrl.pathname.startsWith('/analytics/LateStartReport')) { From b925a8cdb4096c82056b02c2dd846bab06a64067 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Thu, 18 Jul 2024 17:16:33 +0800 Subject: [PATCH 6/7] update dashboard (fix bugs) --- src/components/CreateProject/ProjectClientDetails.tsx | 4 ++-- src/components/StaffUtilization/StaffUtilization.tsx | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/CreateProject/ProjectClientDetails.tsx b/src/components/CreateProject/ProjectClientDetails.tsx index e0333d4..7413f0a 100644 --- a/src/components/CreateProject/ProjectClientDetails.tsx +++ b/src/components/CreateProject/ProjectClientDetails.tsx @@ -344,7 +344,7 @@ const ProjectClientDetails: React.FC = ({ /> - + {/* = ({ {t("CLP Project")} - + */} diff --git a/src/components/StaffUtilization/StaffUtilization.tsx b/src/components/StaffUtilization/StaffUtilization.tsx index d432ca9..18049f4 100644 --- a/src/components/StaffUtilization/StaffUtilization.tsx +++ b/src/components/StaffUtilization/StaffUtilization.tsx @@ -362,7 +362,7 @@ const StaffUtilization: React.FC = ({ abilities, staff }) => { const startCount = weeklyPlanned[i].startCount const endCount = weeklyPlanned[i].endCount for (var j = 0; j < weeklyPlanned[i].searchDuration; j++) { - if (j >= startCount && j < endCount) { + if (j >= startCount && j <= endCount) { weeklyPlannedSubList.push(weeklyPlanned[i].AverageManhours) } else { weeklyPlannedSubList.push(0) @@ -503,7 +503,8 @@ const StaffUtilization: React.FC = ({ abilities, staff }) => { const fetchMonthlyUnsubmittedData = async () => { - const fetchResult = await fetchMonthlyUnsubmit(teamUnsubmitTeamId, unsubmitMonthlyFromValue.format('YYYY-MM-DD'), unsubmitMonthlyToValue.endOf('month').format('YYYY-MM-DD'), holidayDates); + const fetchResult = await fetchMonthlyUnsubmit(teamUnsubmitTeamId, unsubmitMonthlyFromValue.startOf('month').format('YYYY-MM-DD'), unsubmitMonthlyToValue.endOf('month').format('YYYY-MM-DD'), holidayDates); + const result = [] const staffList = [] var maxValue = 5 From be41356dff45008c3b1685a948b33cf2905c0d24 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Fri, 19 Jul 2024 12:08:11 +0800 Subject: [PATCH 7/7] update --- src/components/ProjectCashFlow/ProjectCashFlow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ProjectCashFlow/ProjectCashFlow.tsx b/src/components/ProjectCashFlow/ProjectCashFlow.tsx index 0fd9df5..737f6a6 100644 --- a/src/components/ProjectCashFlow/ProjectCashFlow.tsx +++ b/src/components/ProjectCashFlow/ProjectCashFlow.tsx @@ -954,7 +954,7 @@ const ProjectCashFlow: React.FC = () => { className="text-sm font-medium ml-5" style={{ color: "#898d8d" }} > - Accounts Receivable + Remaining Budget