瀏覽代碼

update number digit alignment

tags/Baseline_30082024_FRONTEND_UAT
kelvinsuen 1 年之前
父節點
當前提交
959a768485
共有 6 個檔案被更改,包括 155 行新增105 行删除
  1. +25
    -14
      src/components/ProgressByClient/ProgressByClient.tsx
  2. +26
    -18
      src/components/ProgressByTeam/ProgressByTeam.tsx
  3. +17
    -14
      src/components/ProjectCashFlow/ProjectCashFlow.tsx
  4. +12
    -0
      src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx
  5. +26
    -15
      src/components/ProjectResourceConsumptionRanking/ProjectResourceConsumptionRanking.tsx
  6. +49
    -44
      src/components/ProjectResourceSummary/ProjectResourceSummary.tsx

+ 25
- 14
src/components/ProgressByClient/ProgressByClient.tsx 查看文件

@@ -281,6 +281,7 @@ const ProgressByClient: React.FC<Props> = () => {
id: "budgetedManhour", id: "budgetedManhour",
field: "budgetedManhour", field: "budgetedManhour",
headerName: t("Budgeted Manhours"), headerName: t("Budgeted Manhours"),
type: "number",
minWidth: 70, minWidth: 70,
renderCell: (params: any) => { renderCell: (params: any) => {
return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>; return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>;
@@ -290,6 +291,7 @@ const ProgressByClient: React.FC<Props> = () => {
id: "spentManhour", id: "spentManhour",
field: "spentManhour", field: "spentManhour",
headerName: t("Spent Manhours"), headerName: t("Spent Manhours"),
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) { if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return ( return (
@@ -306,6 +308,7 @@ const ProgressByClient: React.FC<Props> = () => {
id: "remainedManhour", id: "remainedManhour",
field: "remainedManhour", field: "remainedManhour",
headerName: t("Remained Manhours"), headerName: t("Remained Manhours"),
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) { if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return ( return (
@@ -378,6 +381,14 @@ const ProgressByClient: React.FC<Props> = () => {
legend: { legend: {
show: false, show: false,
}, },
tooltip: {
enabled: true,
y: {
formatter: function (val) {
return val.toFixed(1) + "%";
}
}
},
responsive: [ responsive: [
{ {
breakpoint: 480, breakpoint: 480,
@@ -412,11 +423,11 @@ const ProgressByClient: React.FC<Props> = () => {
<div style="width: auto;"> <div style="width: auto;">
<span style="font-weight: bold;">${projectCode} - ${projectName}</span> <span style="font-weight: bold;">${projectCode} - ${projectName}</span>
<br> <br>
${t("Budget Manhours")}: ${budgetManhours} hours
${t("Budget Manhours")}: ${budgetManhours.toFixed(2)} hours
<br> <br>
${t("Spent Manhours")}: ${spentManhours} hours
${t("Spent Manhours")}: ${spentManhours.toFixed(2)} hours
<br> <br>
Percentage: ${value}%
Percentage: ${value.toFixed(1)}%
</div> </div>
`; `;


@@ -674,9 +685,9 @@ const ProgressByClient: React.FC<Props> = () => {
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -685,13 +696,13 @@ const ProgressByClient: React.FC<Props> = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span>
<span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -700,13 +711,13 @@ const ProgressByClient: React.FC<Props> = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Remained Manhours")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -715,13 +726,13 @@ const ProgressByClient: React.FC<Props> = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Last Update")}</span>
<span style={{ margin: "5%" }}>{t("Last Update")}</span>
</div> </div>
<div <div
className="mt-2 mb-5 text-2xl font-extrabold" 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>
</div> </div>
</Card> </Card>


+ 26
- 18
src/components/ProgressByTeam/ProgressByTeam.tsx 查看文件

@@ -322,6 +322,7 @@ const ProgressByTeam: React.FC = () => {
field: "budgetedManhour", field: "budgetedManhour",
headerName: t("Budgeted Manhours"), headerName: t("Budgeted Manhours"),
minWidth: 70, minWidth: 70,
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>; return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>;
} }
@@ -330,6 +331,7 @@ const ProgressByTeam: React.FC = () => {
id: "spentManhour", id: "spentManhour",
field: "spentManhour", field: "spentManhour",
headerName: t("Spent Manhours"), headerName: t("Spent Manhours"),
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) { if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return ( return (
@@ -345,6 +347,7 @@ const ProgressByTeam: React.FC = () => {
id: "remainedManhour", id: "remainedManhour",
field: "remainedManhour", field: "remainedManhour",
headerName: t("Remained Manhours"), headerName: t("Remained Manhours"),
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) { if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return ( return (
@@ -461,6 +464,14 @@ const ProgressByTeam: React.FC = () => {
legend: { legend: {
show: false, show: false,
}, },
tooltip: {
enabled: true,
y: {
formatter: function (val) {
return val.toFixed(1) + "%";
}
}
},
responsive: [ responsive: [
{ {
breakpoint: 480, breakpoint: 480,
@@ -494,12 +505,9 @@ const ProgressByTeam: React.FC = () => {
const tooltipContent = ` const tooltipContent = `
<div style="width: auto;"> <div style="width: auto;">
<span style="font-weight: bold;">${projectCode} - ${projectName}</span> <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> </div>
`; `;


@@ -789,13 +797,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-5 text-lg font-medium" className="mt-5 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Project Budget Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Project Budget Manhours")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -804,13 +812,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span>
<span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -819,13 +827,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Remained Manhours")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -834,13 +842,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Last Update")}</span>
<span style={{ margin: "5%" }}>{t("Last Update")}</span>
</div> </div>
<div <div
className="mt-2 mb-5 text-2xl font-extrabold" 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>
</div> </div>
</Card> </Card>


+ 17
- 14
src/components/ProjectCashFlow/ProjectCashFlow.tsx 查看文件

@@ -286,6 +286,7 @@ const ProjectCashFlow: React.FC = () => {
field: "expenditure", field: "expenditure",
headerName: t("Expenditure (HKD)"), headerName: t("Expenditure (HKD)"),
flex: 0.6, flex: 0.6,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.expenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.expenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -297,6 +298,7 @@ const ProjectCashFlow: React.FC = () => {
field: "income", field: "income",
headerName: t("Income (HKD)"), headerName: t("Income (HKD)"),
flex: 0.6, flex: 0.6,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.income.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.income.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -308,6 +310,7 @@ const ProjectCashFlow: React.FC = () => {
field: "balance", field: "balance",
headerName: t("Cash Flow Balance (HKD)"), headerName: t("Cash Flow Balance (HKD)"),
flex: 0.6, flex: 0.6,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
if (params.row.balance < 0) { if (params.row.balance < 0) {
return ( return (
@@ -869,8 +872,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Project Fee")} {t("Total Project Fee")}
</div> </div>
<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 })} ${totalFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div> </div>
@@ -882,8 +885,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Invoiced Amount")} {t("Total Invoiced Amount")}
</div> </div>
<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 })} ${totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div> </div>
@@ -895,8 +898,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Received Amount")} {t("Total Received Amount")}
</div> </div>
<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 })} ${totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div> </div>
@@ -908,8 +911,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Accounts Receivable")} {t("Accounts Receivable")}
</div> </div>
<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 })} ${receivable.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div> </div>
@@ -944,8 +947,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Budget")} {t("Total Budget")}
</div> </div>
<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 })} ${totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div> </div>
@@ -957,8 +960,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Cumulative Expenditure")} {t("Total Cumulative Expenditure")}
</div> </div>
<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 })} ${totalExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div> </div>
@@ -970,8 +973,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Remaining Budget")} {t("Remaining Budget")}
</div> </div>
<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 })} ${expenditureReceivable.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div> </div>


+ 12
- 0
src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx 查看文件

@@ -199,6 +199,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalFee', field: 'totalFee',
headerName: t("Total Fees")+t("HKD"), headerName: t("Total Fees")+t("HKD"),
minWidth:50, minWidth:50,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -210,6 +211,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalBudget', field: 'totalBudget',
headerName: t("Total Budget")+t("HKD"), headerName: t("Total Budget")+t("HKD"),
minWidth:50, minWidth:50,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -221,6 +223,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'cumulativeExpenditure', field: 'cumulativeExpenditure',
headerName: t("Total Cumulative Expenditure")+t("HKD"), headerName: t("Total Cumulative Expenditure")+t("HKD"),
minWidth:280, minWidth:280,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -232,6 +235,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalInvoiced', field: 'totalInvoiced',
headerName: t("Total Invoiced Amount")+t("HKD"), headerName: t("Total Invoiced Amount")+t("HKD"),
minWidth:250, minWidth:250,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -243,6 +247,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalUnInvoiced', field: 'totalUnInvoiced',
headerName: t("Total Un-Invoiced Amount")+t("HKD"), headerName: t("Total Un-Invoiced Amount")+t("HKD"),
minWidth:250, minWidth:250,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -254,6 +259,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalReceived', field: 'totalReceived',
headerName: t("Total Received Amount")+t("HKD"), headerName: t("Total Received Amount")+t("HKD"),
minWidth:250, minWidth:250,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -404,6 +410,7 @@ const columns2 = [
id: 'totalFees', id: 'totalFees',
field: 'totalFees', field: 'totalFees',
headerName: t("Total Fees")+t("HKD"), headerName: t("Total Fees")+t("HKD"),
type: "number",
minWidth:50, minWidth:50,
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
@@ -416,6 +423,7 @@ const columns2 = [
field: 'totalBudget', field: 'totalBudget',
headerName: t("Total Budget")+t("HKD"), headerName: t("Total Budget")+t("HKD"),
minWidth:50, minWidth:50,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -427,6 +435,7 @@ const columns2 = [
field: 'totalCumulativeExpenditure', field: 'totalCumulativeExpenditure',
headerName: t("Total Cumulative Expenditure")+t("HKD"), headerName: t("Total Cumulative Expenditure")+t("HKD"),
minWidth:250, minWidth:250,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -438,6 +447,7 @@ const columns2 = [
field: 'totalInvoicedAmount', field: 'totalInvoicedAmount',
headerName: t("Total Invoiced Amount")+t("HKD"), headerName: t("Total Invoiced Amount")+t("HKD"),
minWidth:250, minWidth:250,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -449,6 +459,7 @@ const columns2 = [
field: 'totalUnInvoicedAmount', field: 'totalUnInvoicedAmount',
headerName: t("Total Un-Invoiced Amount")+t("HKD"), headerName: t("Total Un-Invoiced Amount")+t("HKD"),
minWidth:250, minWidth:250,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -460,6 +471,7 @@ const columns2 = [
field: 'totalReceivedAmount', field: 'totalReceivedAmount',
headerName: t("Total Received Amount") +t("HKD"), headerName: t("Total Received Amount") +t("HKD"),
minWidth:250, minWidth:250,
type: "number",
renderCell: (params:any) => { renderCell: (params:any) => {
return ( return (
<span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span> <span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>


+ 26
- 15
src/components/ProjectResourceConsumptionRanking/ProjectResourceConsumptionRanking.tsx 查看文件

@@ -408,6 +408,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
field: "budgetedManhour", field: "budgetedManhour",
headerName: t("Budgeted Manhours"), headerName: t("Budgeted Manhours"),
minWidth: 70, minWidth: 70,
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>; return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>;
} }
@@ -416,6 +417,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
id: "spentManhour", id: "spentManhour",
field: "spentManhour", field: "spentManhour",
headerName: t("Spent Manhours"), headerName: t("Spent Manhours"),
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) { if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return ( return (
@@ -431,6 +433,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
id: "remainedManhour", id: "remainedManhour",
field: "remainedManhour", field: "remainedManhour",
headerName: t("Remained Manhours"), headerName: t("Remained Manhours"),
type: "number",
renderCell: (params: any) => { renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) { if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return ( return (
@@ -547,6 +550,14 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
legend: { legend: {
show: false, show: false,
}, },
tooltip: {
enabled: true,
y: {
formatter: function (val) {
return val.toFixed(1) + "%";
}
}
},
responsive: [ responsive: [
{ {
breakpoint: 480, breakpoint: 480,
@@ -581,11 +592,11 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
<div style="width: 250px;"> <div style="width: 250px;">
<span style="font-weight: bold;">${projectCode} - ${projectName}</span> <span style="font-weight: bold;">${projectCode} - ${projectName}</span>
<br> <br>
${t("Budget Manhours")}: ${budgetManhours} ${t("hours")}
${t("Budget Manhours")}: ${budgetManhours.toFixed(2)} ${t("hours")}
<br> <br>
${t("Spent Manhours")}: ${spentManhours} ${t("hours")}
${t("Spent Manhours")}: ${spentManhours.toFixed(2)} ${t("hours")}
<br> <br>
Percentage: ${value}%
Percentage: ${value.toFixed(1)}%
</div> </div>
`; `;


@@ -909,13 +920,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-5 text-lg font-medium" className="mt-5 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Project Budget Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Project Budget Manhours")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -924,13 +935,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span>
<span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -939,13 +950,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Remained Manhours")}</span>
</div> </div>
<div <div
className="mt-2 text-2xl font-extrabold" 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>
</div> </div>
<hr /> <hr />
@@ -954,13 +965,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-2 text-lg font-medium" className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }} style={{ color: "#898d8d" }}
> >
<span style={{ marginLeft: "5%" }}>{t("Last Update")}</span>
<span style={{ margin: "5%" }}>{t("Last Update")}</span>
</div> </div>
<div <div
className="mt-2 mb-5 text-2xl font-extrabold" 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>
</div> </div>
</Card> </Card>


+ 49
- 44
src/components/ProjectResourceSummary/ProjectResourceSummary.tsx 查看文件

@@ -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"), // 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) { function Row(props:any) {
const { row } = props; const { row } = props;
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
@@ -253,19 +258,19 @@ const ProjectResourceSummary: React.FC = () => {
)} )}
</TableCell> </TableCell>
<TableCell style={{fontSize:13}}>{row.stage}</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> </TableRow>
{row.task.map((taskRow:any) => ( {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"> <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")}/> <CardHeader className="text-slate-500" title= {t("Project Information")}/>
<div className="ml-6 mr-6"> <div className="ml-6 mr-6">
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Project")} {t("Project")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{projectName} {projectName}
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Project Fee")} {t("Project Fee")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${projectFee.toFixed(2)} HKD ${projectFee.toFixed(2)}
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Total Budget")} {t("Total Budget")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${projectBudget.toFixed(2)} HKD ${projectBudget.toFixed(2)}
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Cumulative Expenditure")} {t("Cumulative Expenditure")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${expenditure.toFixed(2)} HKD ${expenditure.toFixed(2)}
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Remaining Budget")} {t("Remaining Budget")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${remainingBudget.toFixed(2)} HKD ${remainingBudget.toFixed(2)}
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Status")} {t("Status")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{t(status)} {t(status)}
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Planned Resources")} {t("Planned Resources")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{plannedResources.toFixed(2)} {t("Manhours")} {plannedResources.toFixed(2)} {t("Manhours")}
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Actual Resources Spent")} {t("Actual Resources Spent")}
</u> </u>
</div> </div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{(actualResourcesSpent ?? 0).toFixed(2)} {t("Manhours")} ({(actualResourcesSpent/plannedResources*100).toFixed(2)}%) {(actualResourcesSpent ?? 0).toFixed(2)} {t("Manhours")} ({(actualResourcesSpent/plannedResources*100).toFixed(2)}%)
</div> </div>
</div> </div>
<div style={{ display: "inline-block", width: "33%"}}> <div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u> <u>
{t("Remaining Resources")} {t("Remaining Resources")}
</u> </u>
</div> </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)}%) {(remainingResources ?? 0).toFixed(2)} {t("Manhours")} ({(remainingResources/plannedResources*100).toFixed(2)}%)
</div> </div>
</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"> <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={{minWidth:30}}/>
<TableCell style={{fontSize:11, minWidth:150}}>{t("Stage")}</TableCell> <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> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>


Loading…
取消
儲存