| @@ -281,6 +281,7 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| id: "budgetedManhour", | |||
| field: "budgetedManhour", | |||
| headerName: t("Budgeted Manhours"), | |||
| type: "number", | |||
| minWidth: 70, | |||
| renderCell: (params: any) => { | |||
| return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>; | |||
| @@ -290,6 +291,7 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| id: "spentManhour", | |||
| field: "spentManhour", | |||
| headerName: t("Spent Manhours"), | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| if (params.row.budgetedManhour - params.row.spentManhour <= 0) { | |||
| return ( | |||
| @@ -306,6 +308,7 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| id: "remainedManhour", | |||
| field: "remainedManhour", | |||
| headerName: t("Remained Manhours"), | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| if (params.row.budgetedManhour - params.row.spentManhour <= 0) { | |||
| return ( | |||
| @@ -378,6 +381,14 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| legend: { | |||
| show: false, | |||
| }, | |||
| tooltip: { | |||
| enabled: true, | |||
| y: { | |||
| formatter: function (val) { | |||
| return val.toFixed(1) + "%"; | |||
| } | |||
| } | |||
| }, | |||
| responsive: [ | |||
| { | |||
| breakpoint: 480, | |||
| @@ -412,11 +423,11 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| <div style="width: auto;"> | |||
| <span style="font-weight: bold;">${projectCode} - ${projectName}</span> | |||
| <br> | |||
| ${t("Budget Manhours")}: ${budgetManhours} hours | |||
| ${t("Budget Manhours")}: ${budgetManhours.toFixed(2)} hours | |||
| <br> | |||
| ${t("Spent Manhours")}: ${spentManhours} hours | |||
| ${t("Spent Manhours")}: ${spentManhours.toFixed(2)} hours | |||
| <br> | |||
| Percentage: ${value}% | |||
| Percentage: ${value.toFixed(1)}% | |||
| </div> | |||
| `; | |||
| @@ -674,9 +685,9 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{projectBudgetManhour}</span> | |||
| <span style={{ margin: "5%" }}>{projectBudgetManhour}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -685,13 +696,13 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{actualManhourSpent}</span> | |||
| <span style={{ margin: "5%" }}>{actualManhourSpent}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -700,13 +711,13 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Remained Manhours")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{remainedManhour}</span> | |||
| <span style={{ margin: "5%" }}>{remainedManhour}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -715,13 +726,13 @@ const ProgressByClient: React.FC<Props> = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Last Update")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Last Update")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 mb-5 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{lastUpdate}</span> | |||
| <span style={{ margin: "5%" }}>{lastUpdate}</span> | |||
| </div> | |||
| </div> | |||
| </Card> | |||
| @@ -322,6 +322,7 @@ const ProgressByTeam: React.FC = () => { | |||
| field: "budgetedManhour", | |||
| headerName: t("Budgeted Manhours"), | |||
| minWidth: 70, | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>; | |||
| } | |||
| @@ -330,6 +331,7 @@ const ProgressByTeam: React.FC = () => { | |||
| id: "spentManhour", | |||
| field: "spentManhour", | |||
| headerName: t("Spent Manhours"), | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| if (params.row.budgetedManhour - params.row.spentManhour <= 0) { | |||
| return ( | |||
| @@ -345,6 +347,7 @@ const ProgressByTeam: React.FC = () => { | |||
| id: "remainedManhour", | |||
| field: "remainedManhour", | |||
| headerName: t("Remained Manhours"), | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| if (params.row.budgetedManhour - params.row.spentManhour <= 0) { | |||
| return ( | |||
| @@ -461,6 +464,14 @@ const ProgressByTeam: React.FC = () => { | |||
| legend: { | |||
| show: false, | |||
| }, | |||
| tooltip: { | |||
| enabled: true, | |||
| y: { | |||
| formatter: function (val) { | |||
| return val.toFixed(1) + "%"; | |||
| } | |||
| } | |||
| }, | |||
| responsive: [ | |||
| { | |||
| breakpoint: 480, | |||
| @@ -494,12 +505,9 @@ const ProgressByTeam: React.FC = () => { | |||
| const tooltipContent = ` | |||
| <div style="width: auto;"> | |||
| <span style="font-weight: bold;">${projectCode} - ${projectName}</span> | |||
| <br> | |||
| ${t("Budget Manhours")}: ${budgetManhours} hours | |||
| <br> | |||
| ${t("Spent Manhours")}: ${spentManhours} hours | |||
| <br> | |||
| Percentage: ${value}% | |||
| <br>${t("Budget Manhours")}:${budgetManhours.toFixed(2)} hours | |||
| <br>${t("Spent Manhours")}:${spentManhours.toFixed(2)} hours | |||
| <br>Percentage:${value.toFixed(1)}% | |||
| </div> | |||
| `; | |||
| @@ -789,13 +797,13 @@ const ProgressByTeam: React.FC = () => { | |||
| className="mt-5 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Project Budget Manhours")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Project Budget Manhours")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{projectBudgetManhour}</span> | |||
| <span style={{ margin: "5%" }}>{projectBudgetManhour}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -804,13 +812,13 @@ const ProgressByTeam: React.FC = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{actualManhourSpent}</span> | |||
| <span style={{ margin: "5%" }}>{actualManhourSpent}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -819,13 +827,13 @@ const ProgressByTeam: React.FC = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Remained Manhours")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{remainedManhour}</span> | |||
| <span style={{ margin: "5%" }}>{remainedManhour}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -834,13 +842,13 @@ const ProgressByTeam: React.FC = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Last Update")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Last Update")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 mb-5 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{lastUpdate}</span> | |||
| <span style={{ margin: "5%" }}>{lastUpdate}</span> | |||
| </div> | |||
| </div> | |||
| </Card> | |||
| @@ -286,6 +286,7 @@ const ProjectCashFlow: React.FC = () => { | |||
| field: "expenditure", | |||
| headerName: t("Expenditure (HKD)"), | |||
| flex: 0.6, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.expenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -297,6 +298,7 @@ const ProjectCashFlow: React.FC = () => { | |||
| field: "income", | |||
| headerName: t("Income (HKD)"), | |||
| flex: 0.6, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.income.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -308,6 +310,7 @@ const ProjectCashFlow: React.FC = () => { | |||
| field: "balance", | |||
| headerName: t("Cash Flow Balance (HKD)"), | |||
| flex: 0.6, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| if (params.row.balance < 0) { | |||
| return ( | |||
| @@ -869,8 +872,8 @@ const ProjectCashFlow: React.FC = () => { | |||
| {t("Total Project Fee")} | |||
| </div> | |||
| <div | |||
| className="text-lg font-medium ml-5" | |||
| style={{ color: "#6b87cf" }} | |||
| className="text-lg font-medium mx-5" | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| ${totalFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} | |||
| </div> | |||
| @@ -882,8 +885,8 @@ const ProjectCashFlow: React.FC = () => { | |||
| {t("Total Invoiced Amount")} | |||
| </div> | |||
| <div | |||
| className="text-lg font-medium ml-5" | |||
| style={{ color: "#6b87cf" }} | |||
| className="text-lg font-medium mx-5" | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| ${totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} | |||
| </div> | |||
| @@ -895,8 +898,8 @@ const ProjectCashFlow: React.FC = () => { | |||
| {t("Total Received Amount")} | |||
| </div> | |||
| <div | |||
| className="text-lg font-medium ml-5" | |||
| style={{ color: "#6b87cf" }} | |||
| className="text-lg font-medium mx-5" | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| ${totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} | |||
| </div> | |||
| @@ -908,8 +911,8 @@ const ProjectCashFlow: React.FC = () => { | |||
| {t("Accounts Receivable")} | |||
| </div> | |||
| <div | |||
| className="text-lg font-medium ml-5 mb-2" | |||
| style={{ color: "#6b87cf" }} | |||
| className="text-lg font-medium mx-5 mb-2" | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| ${receivable.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} | |||
| </div> | |||
| @@ -944,8 +947,8 @@ const ProjectCashFlow: React.FC = () => { | |||
| {t("Total Budget")} | |||
| </div> | |||
| <div | |||
| className="text-lg font-medium ml-5" | |||
| style={{ color: "#6b87cf" }} | |||
| className="text-lg font-medium mx-5" | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| ${totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} | |||
| </div> | |||
| @@ -957,8 +960,8 @@ const ProjectCashFlow: React.FC = () => { | |||
| {t("Total Cumulative Expenditure")} | |||
| </div> | |||
| <div | |||
| className="text-lg font-medium ml-5" | |||
| style={{ color: "#6b87cf" }} | |||
| className="text-lg font-medium mx-5" | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| ${totalExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} | |||
| </div> | |||
| @@ -970,8 +973,8 @@ const ProjectCashFlow: React.FC = () => { | |||
| {t("Remaining Budget")} | |||
| </div> | |||
| <div | |||
| className="text-lg font-medium ml-5 mb-2" | |||
| style={{ color: "#6b87cf" }} | |||
| className="text-lg font-medium mx-5 mb-2" | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| ${expenditureReceivable.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} | |||
| </div> | |||
| @@ -199,6 +199,7 @@ const ProjectFinancialSummary: React.FC = () => { | |||
| field: 'totalFee', | |||
| headerName: t("Total Fees")+t("HKD"), | |||
| minWidth:50, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -210,6 +211,7 @@ const ProjectFinancialSummary: React.FC = () => { | |||
| field: 'totalBudget', | |||
| headerName: t("Total Budget")+t("HKD"), | |||
| minWidth:50, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -221,6 +223,7 @@ const ProjectFinancialSummary: React.FC = () => { | |||
| field: 'cumulativeExpenditure', | |||
| headerName: t("Total Cumulative Expenditure")+t("HKD"), | |||
| minWidth:280, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -232,6 +235,7 @@ const ProjectFinancialSummary: React.FC = () => { | |||
| field: 'totalInvoiced', | |||
| headerName: t("Total Invoiced Amount")+t("HKD"), | |||
| minWidth:250, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -243,6 +247,7 @@ const ProjectFinancialSummary: React.FC = () => { | |||
| field: 'totalUnInvoiced', | |||
| headerName: t("Total Un-Invoiced Amount")+t("HKD"), | |||
| minWidth:250, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -254,6 +259,7 @@ const ProjectFinancialSummary: React.FC = () => { | |||
| field: 'totalReceived', | |||
| headerName: t("Total Received Amount")+t("HKD"), | |||
| minWidth:250, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -404,6 +410,7 @@ const columns2 = [ | |||
| id: 'totalFees', | |||
| field: 'totalFees', | |||
| headerName: t("Total Fees")+t("HKD"), | |||
| type: "number", | |||
| minWidth:50, | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| @@ -416,6 +423,7 @@ const columns2 = [ | |||
| field: 'totalBudget', | |||
| headerName: t("Total Budget")+t("HKD"), | |||
| minWidth:50, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -427,6 +435,7 @@ const columns2 = [ | |||
| field: 'totalCumulativeExpenditure', | |||
| headerName: t("Total Cumulative Expenditure")+t("HKD"), | |||
| minWidth:250, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -438,6 +447,7 @@ const columns2 = [ | |||
| field: 'totalInvoicedAmount', | |||
| headerName: t("Total Invoiced Amount")+t("HKD"), | |||
| minWidth:250, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -449,6 +459,7 @@ const columns2 = [ | |||
| field: 'totalUnInvoicedAmount', | |||
| headerName: t("Total Un-Invoiced Amount")+t("HKD"), | |||
| minWidth:250, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -460,6 +471,7 @@ const columns2 = [ | |||
| field: 'totalReceivedAmount', | |||
| headerName: t("Total Received Amount") +t("HKD"), | |||
| minWidth:250, | |||
| type: "number", | |||
| renderCell: (params:any) => { | |||
| return ( | |||
| <span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> | |||
| @@ -408,6 +408,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| field: "budgetedManhour", | |||
| headerName: t("Budgeted Manhours"), | |||
| minWidth: 70, | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>; | |||
| } | |||
| @@ -416,6 +417,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| id: "spentManhour", | |||
| field: "spentManhour", | |||
| headerName: t("Spent Manhours"), | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| if (params.row.budgetedManhour - params.row.spentManhour <= 0) { | |||
| return ( | |||
| @@ -431,6 +433,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| id: "remainedManhour", | |||
| field: "remainedManhour", | |||
| headerName: t("Remained Manhours"), | |||
| type: "number", | |||
| renderCell: (params: any) => { | |||
| if (params.row.budgetedManhour - params.row.spentManhour <= 0) { | |||
| return ( | |||
| @@ -547,6 +550,14 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| legend: { | |||
| show: false, | |||
| }, | |||
| tooltip: { | |||
| enabled: true, | |||
| y: { | |||
| formatter: function (val) { | |||
| return val.toFixed(1) + "%"; | |||
| } | |||
| } | |||
| }, | |||
| responsive: [ | |||
| { | |||
| breakpoint: 480, | |||
| @@ -581,11 +592,11 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| <div style="width: 250px;"> | |||
| <span style="font-weight: bold;">${projectCode} - ${projectName}</span> | |||
| <br> | |||
| ${t("Budget Manhours")}: ${budgetManhours} ${t("hours")} | |||
| ${t("Budget Manhours")}: ${budgetManhours.toFixed(2)} ${t("hours")} | |||
| <br> | |||
| ${t("Spent Manhours")}: ${spentManhours} ${t("hours")} | |||
| ${t("Spent Manhours")}: ${spentManhours.toFixed(2)} ${t("hours")} | |||
| <br> | |||
| Percentage: ${value}% | |||
| Percentage: ${value.toFixed(1)}% | |||
| </div> | |||
| `; | |||
| @@ -909,13 +920,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| className="mt-5 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Project Budget Manhours")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Project Budget Manhours")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{projectBudgetManhour}</span> | |||
| <span style={{ margin: "5%" }}>{projectBudgetManhour}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -924,13 +935,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{actualManhourSpent}</span> | |||
| <span style={{ margin: "5%" }}>{actualManhourSpent}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -939,13 +950,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Remained Manhours")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{remainedManhour}</span> | |||
| <span style={{ margin: "5%" }}>{remainedManhour}</span> | |||
| </div> | |||
| </div> | |||
| <hr /> | |||
| @@ -954,13 +965,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => { | |||
| className="mt-2 text-lg font-medium" | |||
| style={{ color: "#898d8d" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{t("Last Update")}</span> | |||
| <span style={{ margin: "5%" }}>{t("Last Update")}</span> | |||
| </div> | |||
| <div | |||
| className="mt-2 mb-5 text-2xl font-extrabold" | |||
| style={{ color: "#6b87cf" }} | |||
| style={{ color: "#6b87cf", textAlign: "right" }} | |||
| > | |||
| <span style={{ marginLeft: "5%" }}>{lastUpdate}</span> | |||
| <span style={{ margin: "5%" }}>{lastUpdate}</span> | |||
| </div> | |||
| </div> | |||
| </Card> | |||
| @@ -234,6 +234,11 @@ const ProjectResourceSummary: React.FC = () => { | |||
| // createTaskData("1.1 Preparation of preliminary...","-","-","172.00","-","54.00","-","42.00","-","12.00","-","3.00","-","283.00"), | |||
| // ]; | |||
| const colBaseStyle:any = {fontSize:13, textAlign:"right"}; | |||
| const headerBaseStyle:any = {fontSize:11, minWidth:30, textAlign:"right"} | |||
| const infoHeaderStyle:any = { fontSize:"1em", fontWeight:"bold"};//, textAlign: "right"}; | |||
| const infoDataStyle:any = { fontSize:"1em"};//, textAlign: "right"}; | |||
| function Row(props:any) { | |||
| const { row } = props; | |||
| const [open, setOpen] = React.useState(false); | |||
| @@ -253,19 +258,19 @@ const ProjectResourceSummary: React.FC = () => { | |||
| )} | |||
| </TableCell> | |||
| <TableCell style={{fontSize:13}}>{row.stage}</TableCell> | |||
| <TableCell style={{fontSize:13}}>{row.taskCount}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#808aff"}}>{row.g1Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g1Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#808aff"}}>{row.g2Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g2Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#808aff"}}>{row.g3Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g3Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#808aff"}}>{row.g4Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g4Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#808aff"}}>{row.g5Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g5Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#808aff"}}>{row.totalPlanned.toFixed(2)}</TableCell> | |||
| <TableCell style={{fontSize:13, color:"#69dbac"}}>{row.totalActual.toFixed(2)}</TableCell> | |||
| <TableCell style={colBaseStyle}>{row.taskCount}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g1Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g1Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g2Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g2Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g3Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g3Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g4Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g4Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g5Planned.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g5Actual.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.totalPlanned.toFixed(2)}</TableCell> | |||
| <TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.totalActual.toFixed(2)}</TableCell> | |||
| </TableRow> | |||
| {row.task.map((taskRow:any) => ( | |||
| <TableRow key={taskRow[0]} style={{backgroundColor:"#f0f3f7"}} className="border-t-2 border-b-0 border-l-0 border-r-0 border-solid border-slate-300"> | |||
| @@ -622,92 +627,92 @@ const columns2 = [ | |||
| <CardHeader className="text-slate-500" title= {t("Project Information")}/> | |||
| <div className="ml-6 mr-6"> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Project")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| {projectName} | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Project Fee")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| HKD ${projectFee.toFixed(2)} | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Total Budget")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| HKD ${projectBudget.toFixed(2)} | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Cumulative Expenditure")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| HKD ${expenditure.toFixed(2)} | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Remaining Budget")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| HKD ${remainingBudget.toFixed(2)} | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Status")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| {t(status)} | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Planned Resources")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| {plannedResources.toFixed(2)} {t("Manhours")} | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Actual Resources Spent")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}}> | |||
| <div style={infoDataStyle}> | |||
| {(actualResourcesSpent ?? 0).toFixed(2)} {t("Manhours")} ({(actualResourcesSpent/plannedResources*100).toFixed(2)}%) | |||
| </div> | |||
| </div> | |||
| <div style={{ display: "inline-block", width: "33%"}}> | |||
| <div style={{ fontSize:"1em", fontWeight:"bold"}}> | |||
| <div style={infoHeaderStyle}> | |||
| <u> | |||
| {t("Remaining Resources")} | |||
| </u> | |||
| </div> | |||
| <div style={{fontSize:"1em"}} className={"mb-5"}> | |||
| <div style={infoDataStyle} className={"mb-5"}> | |||
| {(remainingResources ?? 0).toFixed(2)} {t("Manhours")} ({(remainingResources/plannedResources*100).toFixed(2)}%) | |||
| </div> | |||
| </div> | |||
| @@ -748,19 +753,19 @@ const columns2 = [ | |||
| <TableRow className="border-t-2 border-b-0 border-l-0 border-r-0 border-solid border-slate-300"> | |||
| <TableCell style={{minWidth:30}}/> | |||
| <TableCell style={{fontSize:11, minWidth:150}}>{t("Stage")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30}}>{t("Task Count")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={headerBaseStyle}>{t("Task Count")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell> | |||
| <TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell> | |||
| </TableRow> | |||
| </TableHead> | |||
| <TableBody> | |||