Quellcode durchsuchen

dashboard update

tags/Baseline_30082024_FRONTEND_UAT
MSI\User vor 1 Jahr
Ursprung
Commit
ebc49a8b36
3 geänderte Dateien mit 370 neuen und 310 gelöschten Zeilen
  1. +8
    -2
      .eslintrc.json
  2. +299
    -308
      src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx
  3. +63
    -0
      src/components/StaffUtilization/StaffUtilization.tsx

+ 8
- 2
.eslintrc.json Datei anzeigen

@@ -2,9 +2,15 @@
"extends": ["next/core-web-vitals", "plugin:@typescript-eslint/recommended", "prettier"],
"plugins": ["prettier", "@typescript-eslint"],
"rules": {
"prettier/prettier": "warn",
// "prettier/prettier": "warn",
"prettier/prettier": [
"error",
{
"endOfLine": "off"
}
],
"no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": ["off"],
// "@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/no-unused-vars": "warn"
}
}

+ 299
- 308
src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx Datei anzeigen

@@ -99,139 +99,29 @@ const ProjectFinancialSummary: React.FC = () => {
},
];

const rows0 = [
{
id: 1,
projectCode: "M1201",
projectName: "Consultancy Project C",
team: "XXX",
teamLeader: "XXX",
startDate: "01/08/2022",
targetEndDate: "01/05/2024",
client: "Client A",
subsidiary: "N/A",
},
{
id: 2,
projectCode: "M1321",
projectName: "Consultancy Project CCC",
team: "XXX",
teamLeader: "XXX",
startDate: "01/08/2022",
targetEndDate: "20/01/2024",
client: "Client E",
subsidiary: "Subsidiary B",
},
{
id: 3,
projectCode: "M1001",
projectName: "Consultancy Project A",
team: "YYY",
teamLeader: "YYY",
startDate: "01/07/2022",
targetEndDate: "01/04/2024",
client: "Client B",
subsidiary: "N/A",
},
{
id: 4,
projectCode: "M1301",
projectName: "Consultancy Project AAAA",
team: "YYY",
teamLeader: "YYY",
startDate: "01/09/2022",
targetEndDate: "20/02/2024",
client: "Client C",
subsidiary: "Subsidiary A",
},
{
id: 5,
projectCode: "M1354",
projectName: "Consultancy Project BBB",
team: "YYY",
teamLeader: "YYY",
startDate: "01/02/2023",
targetEndDate: "31/01/2024",
client: "Client D",
subsidiary: "Subsidiary C",
},
];
const rows0 = [{id: 1,projectCode:"M1201",projectName:"Consultancy Project C", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "01/05/2024", client:"Client A", subsidiary:"N/A"},
{id: 2,projectCode:"M1321",projectName:"Consultancy Project CCC", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "20/01/2024", client:"Client E", subsidiary:"Subsidiary B"},
{id: 3,projectCode:"M1001",projectName:"Consultancy Project A", team:"YYY", teamLeader:"YYY", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"},
{id: 4,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"YYY", teamLeader:"YYY", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"},
{id: 5,projectCode:"M1354",projectName:"Consultancy Project BBB", team:"YYY", teamLeader:"YYY", startDate:"01/02/2023", targetEndDate: "31/01/2024", client:"Client D", subsidiary:"Subsidiary C"}
]

const rows1 = [
{
id: 1,
projectCode: "M1201",
projectName: "Consultancy Project C",
team: "XXX",
teamLeader: "XXX",
startDate: "01/08/2022",
targetEndDate: "01/05/2024",
client: "Client A",
subsidiary: "N/A",
},
{
id: 2,
projectCode: "M1321",
projectName: "Consultancy Project CCC",
team: "XXX",
teamLeader: "XXX",
startDate: "01/08/2022",
targetEndDate: "20/01/2024",
client: "Client E",
subsidiary: "Subsidiary B",
},
];
const rows1 = [{id: 1,projectCode:"M1201",projectName:"Consultancy Project C", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "01/05/2024", client:"Client A", subsidiary:"N/A"},
{id: 2,projectCode:"M1321",projectName:"Consultancy Project CCC", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "20/01/2024", client:"Client E", subsidiary:"Subsidiary B"},
]

const rows2 = [
{
id: 3,
projectCode: "M1001",
projectName: "Consultancy Project A",
team: "YYY",
teamLeader: "YYY",
startDate: "01/07/2022",
targetEndDate: "01/04/2024",
client: "Client B",
subsidiary: "N/A",
},
{
id: 4,
projectCode: "M1301",
projectName: "Consultancy Project AAAA",
team: "YYY",
teamLeader: "YYY",
startDate: "01/09/2022",
targetEndDate: "20/02/2024",
client: "Client C",
subsidiary: "Subsidiary A",
},
{
id: 5,
projectCode: "M1354",
projectName: "Consultancy Project BBB",
team: "YYY",
teamLeader: "YYY",
startDate: "01/02/2023",
targetEndDate: "31/01/2024",
client: "Client D",
subsidiary: "Subsidiary C",
},
];
const rows2 = [{id: 3,projectCode:"M1001",projectName:"Consultancy Project A", team:"YYY", teamLeader:"YYY", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"},
{id: 4,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"YYY", teamLeader:"YYY", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"},
{id: 5,projectCode:"M1354",projectName:"Consultancy Project BBB", team:"YYY", teamLeader:"YYY", startDate:"01/02/2023", targetEndDate: "31/01/2024", client:"Client D", subsidiary:"Subsidiary C"}
]

const projectFinancialRows = [
{
id: 1,
cashFlowStatus: "Positive",
cpi: "1.25",
totalFees: "500,000.00",
totalBudget: "400,000.00",
totalCumulativeExpenditure: "280,000.00",
totalInvoicedAmount: "350,000.00",
totalUnInvoicedAmount: "150,000.00",
totalReceivedAmount: "350,000.00",
totalUnReceivedAmount: "0.00",
},
];
const projectFinancialRows = [{id: 1,projectCode:"M1354",projectName:"Consultanct Project BBB",clientName:"Client D",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}
]

const clientFinancialRows =[{id: 1,clientCode:"Cust-02",clientName:"Client B",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"},
{id: 2,clientCode:"Cust-03",clientName:"Client C",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"},
{id: 3,clientCode:"Cust-04",clientName:"Client D",totalProjectInvolved:"4",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}
]

const [isCardClickedIndex, setIsCardClickedIndex] = React.useState(0);

@@ -250,73 +140,210 @@ const ProjectFinancialSummary: React.FC = () => {

const columns = [
{
id: "projectCode",
field: "projectCode",
headerName: "Project Code",
flex: 1,
},
{
id: "projectName",
field: "projectName",
headerName: "Project Name",
flex: 1,
},
{
id: "team",
field: "team",
headerName: "Team",
flex: 1,
},
{
id: "teamLeader",
field: "teamLeader",
headerName: "Team Leader",
flex: 1,
},
{
id: "startDate",
field: "startDate",
headerName: "Start Date",
flex: 1,
},
{
id: "targetEndDate",
field: "targetEndDate",
headerName: "Target End Date",
flex: 1,
id: 'clientCode',
field: 'clientCode',
headerName: "Client Code",
flex: 0.7,
},
{
id: "client",
field: "client",
headerName: "Client",
id: 'clientName',
field: 'clientName',
headerName: "Client Name",
flex: 1,
},
{
id: "subsidiary",
field: "subsidiary",
headerName: "Subsidiary",
id: 'totalProjectInvolved',
field: 'totalProjectInvolved',
headerName: "Total Project Involved",
flex: 1,
},
];

const columns2 = [
{
id: "cashFlowStatus",
field: "cashFlowStatus",
id: 'cashFlowStatus',
field: 'cashFlowStatus',
headerName: "Cash Flow Status",
flex: 1,
renderCell: (params: any) => {
renderCell: (params:any) => {
if (params.row.cashFlowStatus === "Positive") {
return (
<span className="text-lime-500">{params.row.cashFlowStatus}</span>
);
)
} else if (params.row.cashFlowStatus === "Negative") {
return (
<span className="text-red-500">{params.row.cashFlowStatus}</span>
);
)
}
},
},
},
{
id: 'cpi',
field: 'cpi',
headerName: "CPI",
flex: 0.7,
renderCell: (params:any) => {
if (params.row.cpi >= 1) {
return (
<span className="text-lime-500">{params.row.cpi}</span>
)
} else if (params.row.cpi < 1) {
return (
<span className="text-red-500">{params.row.cpi}</span>
)
}
},
},
{
id: 'totalFees',
field: 'totalFees',
headerName: "Total Fees (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalFees}</span>
)
},
},
{
id: 'totalBudget',
field: 'totalBudget',
headerName: "Total Budget (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalBudget}</span>
)
},
},
{
id: 'totalCumulativeExpenditure',
field: 'totalCumulativeExpenditure',
headerName: "Total Cumulative Expenditure (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalCumulativeExpenditure}</span>
)
},
},
{
id: 'totalInvoicedAmount',
field: 'totalInvoicedAmount',
headerName: "Total Invoiced Amount (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalInvoicedAmount}</span>
)
},
},
{
id: 'totalUnInvoicedAmount',
field: 'totalUnInvoicedAmount',
headerName: "Total Un-invoiced Amount (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalUnInvoicedAmount}</span>
)
},
},
{
id: 'totalReceivedAmount',
field: 'totalReceivedAmount',
headerName: "Total Received Amount (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalReceivedAmount}</span>
)
},
},

// {
// id: 'projectCode',
// field: 'projectCode',
// headerName: "Project Code",
// flex: 1,
// },
// {
// id: 'projectName',
// field: 'projectName',
// headerName: "Project Name",
// flex: 1,
// },
// {
// id: 'team',
// field: 'team',
// headerName: "Team",
// flex: 1,
// },
// {
// id: 'teamLeader',
// field: 'teamLeader',
// headerName: "Team Leader",
// flex: 1,
// },
// {
// id: 'startDate',
// field: 'startDate',
// headerName: "Start Date",
// flex: 1,
// },
// {
// id: 'targetEndDate',
// field: 'targetEndDate',
// headerName: "Target End Date",
// flex: 1,
// },
// {
// id: 'client',
// field: 'client',
// headerName: "Client",
// flex: 1,
// },
// {
// id: 'subsidiary',
// field: 'subsidiary',
// headerName: "Subsidiary",
// flex: 1,
// },
];

const columns2 = [
{
id: 'projectCode',
field: 'projectCode',
headerName: "Project Code",
flex: 0.7,
},
{
id: 'projectName',
field: 'projectName',
headerName: "Project Name",
flex: 1,
},
{
id: 'clientName',
field: 'clientName',
headerName: "Client Name",
flex: 1,
},
{
id: 'cashFlowStatus',
field: 'cashFlowStatus',
headerName: "Cash Flow Status",
flex: 1,
renderCell: (params:any) => {
if (params.row.cashFlowStatus === "Positive") {
return (
<span className="text-lime-500">{params.row.cashFlowStatus}</span>
)
} else if (params.row.cashFlowStatus === "Negative") {
return (
<span className="text-red-500">{params.row.cashFlowStatus}</span>
)
}
},
},
{
id: "cpi",
field: "cpi",
@@ -330,70 +357,74 @@ const ProjectFinancialSummary: React.FC = () => {
}
},
},
{
id: "totalFees",
field: "totalFees",
headerName: "Total Fees (HKD)",
flex: 1,
renderCell: (params: any) => {
return <span>${params.row.totalFees}</span>;
},
},
{
id: "totalBudget",
field: "totalBudget",
headerName: "Total Budget (HKD)",
flex: 1,
renderCell: (params: any) => {
return <span>${params.row.totalBudget}</span>;
},
},
{
id: "totalCumulativeExpenditure",
field: "totalCumulativeExpenditure",
headerName: "Total Cumulative Expenditure (HKD)",
flex: 1,
renderCell: (params: any) => {
return <span>${params.row.totalCumulativeExpenditure}</span>;
},
},
{
id: "totalInvoicedAmount",
field: "totalInvoicedAmount",
headerName: "Total Invoiced Amount (HKD)",
flex: 1,
renderCell: (params: any) => {
return <span>${params.row.totalInvoicedAmount}</span>;
},
},
{
id: "totalUnInvoicedAmount",
field: "totalUnInvoicedAmount",
headerName: "Total Un-invoiced Amount (HKD)",
flex: 1,
renderCell: (params: any) => {
return <span>${params.row.totalUnInvoicedAmount}</span>;
},
},
{
id: "totalReceivedAmount",
field: "totalReceivedAmount",
headerName: "Total Received Amount (HKD)",
flex: 1,
renderCell: (params: any) => {
return <span>${params.row.totalReceivedAmount}</span>;
},
},
{
id: "totalUnReceivedAmount",
field: "totalUnReceivedAmount",
headerName: "Total Un-received Amount (HKD)",
flex: 1,
renderCell: (params: any) => {
return <span>${params.row.totalUnReceivedAmount}</span>;
},
},
];

{
id: 'totalFees',
field: 'totalFees',
headerName: "Total Fees (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalFees}</span>
)
},
},
{
id: 'totalBudget',
field: 'totalBudget',
headerName: "Total Budget (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalBudget}</span>
)
},
},
{
id: 'totalCumulativeExpenditure',
field: 'totalCumulativeExpenditure',
headerName: "Total Cumulative Expenditure (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalCumulativeExpenditure}</span>
)
},
},
{
id: 'totalInvoicedAmount',
field: 'totalInvoicedAmount',
headerName: "Total Invoiced Amount (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalInvoicedAmount}</span>
)
},
},
{
id: 'totalUnInvoicedAmount',
field: 'totalUnInvoicedAmount',
headerName: "Total Un-invoiced Amount (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalUnInvoicedAmount}</span>
)
},
},
{
id: 'totalReceivedAmount',
field: 'totalReceivedAmount',
headerName: "Total Received Amount (HKD)",
flex: 1,
renderCell: (params:any) => {
return (
<span>${params.row.totalReceivedAmount}</span>
)
},
},
];

const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => {
const selectedRowsData = selectedTeamData.filter((row: any) =>
@@ -403,71 +434,31 @@ const ProjectFinancialSummary: React.FC = () => {
};

return (
<Grid item sm>
<Card>
<CardHeader
className="text-slate-500"
title="Active Project Financial Status"
/>
<div
className="ml-10 mr-10"
style={{ display: "flex", flexWrap: "wrap", justifyContent: "start" }}
>
{projectFinancialData.map((record, index) => (
<div
className="hover:cursor-pointer ml-4 mt-5 mb-4 inline-block"
key={index}
onClick={(r) => handleCardClick(index)}
>
<ProjectFinancialCard
Title={record.title}
TotalActiveProjectNumber={record.activeProject}
TotalFees={record.fees}
TotalBudget={record.budget}
TotalCumulative={record.cumulativeExpenditure}
TotalInvoicedAmount={record.invoicedAmount}
TotalReceivedAmount={record.receivedAmount}
CashFlowStatus={record.cashFlowStatus}
CostPerformanceIndex={record.CPI}
ClickedIndex={isCardClickedIndex}
Index={index}
/>
</div>
))}
</div>
</Card>
<Card className="mt-5">
<CardHeader
className="text-slate-500"
title="Selected Team's Project"
/>
<div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}>
<CustomDatagrid
rows={selectedTeamData}
columns={columns}
columnWidth={200}
dataGridHeight={300}
checkboxSelection={true}
onRowSelectionModelChange={handleSelectionChange}
selectionModel={selectionModel}
/>
</div>
</Card>
<Card className="mt-5">
<CardHeader
className="text-slate-500"
title="Individual Project Financial Status"
/>
<div style={{ display: "inline-block", width: "99%", marginLeft: 10 }}>
<CustomDatagrid
rows={projectFinancialRows}
columns={columns2}
columnWidth={200}
dataGridHeight={300}
/>
</div>
</Card>
</Grid>
<Grid item sm>
<Card>
<CardHeader className="text-slate-500" title="Active Project Financial Status"/>
<div className="ml-10 mr-10" style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'start'}}>
{projectFinancialData.map((record, index) => (
<div className="hover:cursor-pointer ml-4 mt-5 mb-4 inline-block" key={index} onClick={(r) => handleCardClick(index)}>
<ProjectFinancialCard Title={record.title} TotalActiveProjectNumber={record.activeProject} TotalFees={record.fees} TotalBudget={record.budget} TotalCumulative={record.cumulativeExpenditure} TotalInvoicedAmount={record.invoicedAmount} TotalReceivedAmount={record.receivedAmount} CashFlowStatus={record.cashFlowStatus} CostPerformanceIndex={record.CPI} ClickedIndex={isCardClickedIndex} Index={index}/>
</div>
))}
</div>
</Card>
<Card className="mt-5">
<CardHeader className="text-slate-500" title="Selected Team's Project"/>
<div style={{display:"inline-block",width:"99%",marginLeft:10}}>
{/* <CustomDatagrid rows={clientFinancialRows} columns={columns} columnWidth={200} dataGridHeight={300} checkboxSelection={true} onRowSelectionModelChange={handleSelectionChange} selectionModel={selectionModel}/> */}
<CustomDatagrid rows={clientFinancialRows} columns={columns} columnWidth={200} dataGridHeight={300}/>
</div>
</Card>
<Card className="mt-5">
<CardHeader className="text-slate-500" title="Financial Status (by Project)"/>
<div style={{display:"inline-block",width:"99%",marginLeft:10}}>
<CustomDatagrid rows={projectFinancialRows} columns={columns2} columnWidth={200} dataGridHeight={300}/>
</div>
</Card>
</Grid>
);
};



+ 63
- 0
src/components/StaffUtilization/StaffUtilization.tsx Datei anzeigen

@@ -633,6 +633,59 @@ const StaffUtilization: React.FC = () => {
setIndividualStaffManhoursSpentPeriod(weekDates);
};

const options2: ApexOptions = {
chart: {
type: "donut",
},
colors: ['#f57f90','#94f7d6','#87c5f5','#ab95f5','#ab95f5'],
plotOptions: {
pie: {
donut: {
labels: {
show: true,
name: {
show: true,
},
value: {
show: false,
fontWeight: 500,
fontSize: "30px",
color: "#3e98c7",
},
total: {
show: false,
showAlways: true,
label: "Spent",
fontFamily: "sans-serif",
formatter: function (val) {
return val + "%";
},
},
},
},
},
},
series:[23.5,25.5,25.5,25.5],
labels: ["Consultancy Project 123","Consultancy Project ABC","Consultancy Project A","Consultancy Project B"],
legend: {
show: false,
},
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200,
},
legend: {
position: "bottom",
show: false,
},
},
},
],
};

return (
<>
<Grid item sm>
@@ -1129,6 +1182,16 @@ const StaffUtilization: React.FC = () => {
</Card>
</div>
</div>
<div style={{ display: "inline-block", width: "50%",verticalAlign:"top",marginTop:10}}>
<Card>
<CardHeader className="text-slat-500" title="Effort Proportion for individual Staff"/>
<ReactApexChart
options={options2}
series={options2.series}
type="donut"
/>
</Card>
</div>
</Card>
</Grid>
</div>


Laden…
Abbrechen
Speichern