Browse Source

david pending tasks

tags/Baseline_30082024_FRONTEND_UAT
Mac\David 1 year ago
parent
commit
96e5757559
5 changed files with 114 additions and 29 deletions
  1. +14
    -1
      src/app/api/financialsummary/actions.ts
  2. +5
    -5
      src/components/ProgressByClient/ProgressByClient.tsx
  3. +5
    -5
      src/components/ProgressByTeam/ProgressByTeam.tsx
  4. +85
    -13
      src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx
  5. +5
    -5
      src/components/ProjectResourceConsumptionRanking/ProjectResourceConsumptionRanking.tsx

+ 14
- 1
src/app/api/financialsummary/actions.ts View File

@@ -54,7 +54,20 @@ export const searchFinancialSummaryByClient = cache(async (teamId?: number) => {
}); });


export const searchFinancialSummaryByProject = cache(async (teamId?: number, customerId?:number) => {
export const searchFinancialSummaryByProject = cache(async (teamId?: number) => {
if (teamId === undefined) {
return serverFetchJson<FinancialSummaryByProjectResult[]>(
`${BASE_API_URL}/dashboard/searchFinancialSummaryByProject`
);
} else {
return serverFetchJson<FinancialSummaryByProjectResult[]>(
`${BASE_API_URL}/dashboard/searchFinancialSummaryByProject?teamId=${teamId}`
);
}
});

export const searchFinancialSummaryByProjectOld = cache(async (teamId?: number, customerId?:number) => {
if (teamId === undefined) { if (teamId === undefined) {
return serverFetchJson<FinancialSummaryByProjectResult[]>( return serverFetchJson<FinancialSummaryByProjectResult[]>(
`${BASE_API_URL}/dashboard/searchFinancialSummaryByProject` `${BASE_API_URL}/dashboard/searchFinancialSummaryByProject`


+ 5
- 5
src/components/ProgressByClient/ProgressByClient.tsx View File

@@ -572,19 +572,19 @@ const ProgressByClient: React.FC<Props> = () => {
</div> </div>
<div className="ml-6 mb-2"> <div className="ml-6 mb-2">
<button onClick={() => {setTableSorting('PercentageASC')}} <button onClick={() => {setTableSorting('PercentageASC')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Percentage ASC
{`Percentage (Ascending Order)`}
</button> </button>
<button <button
onClick={() => {setTableSorting('PercentageDESC')}} onClick={() => {setTableSorting('PercentageDESC')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Percentage DESC
{`Percentage (Descending Order)`}
</button> </button>
<button <button
onClick={() => {setTableSorting('ProjectName')}} onClick={() => {setTableSorting('ProjectName')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Project Name Project Name
</button> </button>


+ 5
- 5
src/components/ProgressByTeam/ProgressByTeam.tsx View File

@@ -663,19 +663,19 @@ const ProgressByTeam: React.FC = () => {
</div> </div>
<div className="ml-6 mb-2"> <div className="ml-6 mb-2">
<button onClick={() => {setTableSorting('PercentageASC')}} <button onClick={() => {setTableSorting('PercentageASC')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Percentage ASC
{`Percentage (Ascending Order)`}
</button> </button>
<button <button
onClick={() => {setTableSorting('PercentageDESC')}} onClick={() => {setTableSorting('PercentageDESC')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Percentage DESC
{`Percentage (Descending Order)`}
</button> </button>
<button <button
onClick={() => {setTableSorting('ProjectName')}} onClick={() => {setTableSorting('ProjectName')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Project Name Project Name
</button> </button>


+ 85
- 13
src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx View File

@@ -19,11 +19,16 @@ import SearchBox, { Criterion } from "../SearchBox";
import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import ProgressByClientSearch from "@/components/ProgressByClientSearch";
import { Suspense } from "react"; import { Suspense } from "react";
import { fetchFinancialSummaryCard } from "@/app/api/financialsummary"; import { fetchFinancialSummaryCard } from "@/app/api/financialsummary";
import { exportFinancialSummaryByClientExcel, exportFinancialSummaryByProjectExcel, searchFinancialSummaryByClient,searchFinancialSummaryByProject } from "@/app/api/financialsummary/actions";
import { exportFinancialSummaryByClientExcel, exportFinancialSummaryByProjectExcel, FinancialSummaryByProjectResult, FinancialSummaryByClientResult, searchFinancialSummaryByClient,searchFinancialSummaryByProject } from "@/app/api/financialsummary/actions";
import ProjectFinancialCard from "./ProjectFinancialCard"; import ProjectFinancialCard from "./ProjectFinancialCard";
import VisibilityIcon from '@mui/icons-material/Visibility'; import VisibilityIcon from '@mui/icons-material/Visibility';
import { downloadFile } from "@/app/utils/commonUtil"; import { downloadFile } from "@/app/utils/commonUtil";


type SearchProjectQuery = Partial<Omit<FinancialSummaryByProjectResult, "id">>;
type SearchClientQuery = Partial<Omit<FinancialSummaryByClientResult, "id">>;
type SearchProjectParamNames = keyof SearchProjectQuery;
type SearchClientParamNames = keyof SearchClientQuery;

const ProjectFinancialSummary: React.FC = () => { const ProjectFinancialSummary: React.FC = () => {
const [SearchCriteria, setSearchCriteria] = React.useState({}); const [SearchCriteria, setSearchCriteria] = React.useState({});
const { t } = useTranslation("dashboard"); const { t } = useTranslation("dashboard");
@@ -31,6 +36,24 @@ const ProjectFinancialSummary: React.FC = () => {
const [projectFinancialData, setProjectFinancialData]: any[] = React.useState([]); const [projectFinancialData, setProjectFinancialData]: any[] = React.useState([]);
const [clientFinancialRows, setClientFinancialRows]: any[] = React.useState([]); const [clientFinancialRows, setClientFinancialRows]: any[] = React.useState([]);
const [projectFinancialRows, setProjectFinancialRows]: any[] = React.useState([]); const [projectFinancialRows, setProjectFinancialRows]: any[] = React.useState([]);
const [filteredProjectResult, setFilteredProjectResult]:any[] = useState([]);
const [filteredClientResult, setFilteredClientResult]:any[] = useState([]);

const projectSearchCriteria: Criterion<SearchProjectParamNames>[] = useMemo(
() => [
{ label: "Project Code", paramName: "projectCode", type: "text" },
{ label: "Project Name", paramName: "projectName", type: "text" },
],
[t],
);
const clientSearchCriteria: Criterion<SearchClientParamNames>[] = useMemo(
() => [
{ label: "Client Code", paramName: "customerCode", type: "text" },
{ label: "Client Name", paramName: "customerName", type: "text" },
],
[t],
);

const fetchData = async () => { const fetchData = async () => {
const financialSummaryCard = await fetchFinancialSummaryCard(); const financialSummaryCard = await fetchFinancialSummaryCard();
setProjectFinancialData(financialSummaryCard) setProjectFinancialData(financialSummaryCard)
@@ -41,10 +64,11 @@ const ProjectFinancialSummary: React.FC = () => {
console.log(financialSummaryByClient) console.log(financialSummaryByClient)
// console.log(financialSummaryByProject) // console.log(financialSummaryByProject)
setClientFinancialRows(financialSummaryByClient) setClientFinancialRows(financialSummaryByClient)
setFilteredClientResult(financialSummaryByClient)
} }
useEffect(() => { useEffect(() => {
fetchData() fetchData()
fetchTableData(undefined)
// fetchTableData(undefined)
}, []); }, []);


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"}, 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"},
@@ -77,6 +101,7 @@ const ProjectFinancialSummary: React.FC = () => {


const handleCardClick = (r: any, index:any) => { const handleCardClick = (r: any, index:any) => {
fetchTableData(r.teamId) fetchTableData(r.teamId)
fetchProjectTableData(r.teamId)
setIsCardClickedIndex(index) setIsCardClickedIndex(index)
}; };


@@ -450,13 +475,14 @@ const columns2 = [
}; };
const fetchProjectTableData = async (teamId?:any,customerId?:any) => { const fetchProjectTableData = async (teamId?:any,customerId?:any) => {
const financialSummaryByProject = await searchFinancialSummaryByProject(teamId,customerId);
const financialSummaryByProject = await searchFinancialSummaryByProject(teamId);
setProjectFinancialRows(financialSummaryByProject) setProjectFinancialRows(financialSummaryByProject)
setFilteredProjectResult(financialSummaryByProject)
} }


const handleRowClick = (params:any) => { const handleRowClick = (params:any) => {
console.log(params.row.teamId); console.log(params.row.teamId);
fetchProjectTableData(params.row.teamId,params.row.cid)
// fetchProjectTableData(params.row.teamId,params.row.cid)
}; };


const handleExportByClient = async () => { const handleExportByClient = async () => {
@@ -486,37 +512,83 @@ const columns2 = [
</div> </div>
))} ))}
</div> </div>
<hr></hr>
<div className="ml-10 text-base"><strong>-Formula-</strong></div>
<div className="ml-10 text-sm"><strong>CPI:</strong> Invoiced Amount / Cumulative Expenditure</div>
<div className="ml-10 text-sm"><strong>Cash Flow Status: </strong>{`Positive when CPI >= 1`}</div>
<div className="ml-10 text-sm"><strong>Projected CPI:</strong> Project Fee / Cumulative Expenditure</div>
<div className="ml-10 text-sm mb-5"><strong>Cash Flow Status: </strong>{`Positive when Projected CPI >= 1`}</div>
</Card> </Card>
<Card className="mt-5"> <Card className="mt-5">
<div style={{display:"inline-block"}}> <div style={{display:"inline-block"}}>
<CardHeader className="text-slate-500" title="Financial Status (by Client)"/>
<CardHeader className="text-slate-500" title="Financial Status (by Project)"/>
</div> </div>
<div style={{display:"inline-block"}}> <div style={{display:"inline-block"}}>
{clientFinancialRows.length > 0 && (
<button onClick={handleExportByClient} className="hover:cursor-pointer hover:bg-violet-50 text-base bg-transparent border-violet-500 text-violet-500 border-solid rounded-md w-36">
{projectFinancialRows.length > 0 && (
<button onClick={handleExportByProject} className="hover:cursor-pointer hover:bg-violet-50 text-base bg-transparent border-violet-500 text-violet-500 border-solid rounded-md w-36">
Export Excel Export Excel
</button> </button>
)} )}
</div> </div>
{projectFinancialRows.length > 0 && (
<SearchBox
criteria={projectSearchCriteria}
onSearch={(query) => {
setFilteredProjectResult(
projectFinancialRows.filter(
(cp:any) =>
cp.projectCode.toLowerCase().includes(query.projectCode.toLowerCase()) &&
cp.projectName.toLowerCase().includes(query.projectName.toLowerCase())
),
);
}}
/>
)}
<div style={{display:"inline-block",width:"99%",marginLeft:10}}> <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 onRowClick={handleRowClick} rows={clientFinancialRows} columns={columns} columnWidth={200} dataGridHeight={300}/>
<CustomDatagrid rows={filteredProjectResult} columns={columns2} columnWidth={200} dataGridHeight={300}/>
</div> </div>
<hr></hr>
<div className="ml-10 text-base"><strong>-Formula-</strong></div>
<div className="ml-10 text-sm"><strong>CPI:</strong> Invoiced Amount / Cumulative Expenditure</div>
<div className="ml-10 text-sm"><strong>Cash Flow Status: </strong>{`Positive when CPI >= 1`}</div>
<div className="ml-10 text-sm"><strong>Projected CPI:</strong> Project Fee / Cumulative Expenditure</div>
<div className="ml-10 text-sm mb-5"><strong>Cash Flow Status: </strong>{`Positive when Projected CPI >= 1`}</div>
</Card> </Card>
<Card className="mt-5"> <Card className="mt-5">
<div style={{display:"inline-block"}}> <div style={{display:"inline-block"}}>
<CardHeader className="text-slate-500" title="Financial Status (by Project)"/>
<CardHeader className="text-slate-500" title="Financial Status (by Client)"/>
</div> </div>
<div style={{display:"inline-block"}}> <div style={{display:"inline-block"}}>
{projectFinancialRows.length > 0 && (
<button onClick={handleExportByProject} className="hover:cursor-pointer hover:bg-violet-50 text-base bg-transparent border-violet-500 text-violet-500 border-solid rounded-md w-36">
{clientFinancialRows.length > 0 && (
<button onClick={handleExportByClient} className="hover:cursor-pointer hover:bg-violet-50 text-base bg-transparent border-violet-500 text-violet-500 border-solid rounded-md w-36">
Export Excel Export Excel
</button> </button>
)} )}
</div> </div>
{clientFinancialRows.length > 0 && (
<SearchBox
criteria={clientSearchCriteria}
onSearch={(query) => {
setFilteredClientResult(
clientFinancialRows.filter(
(cp:any) =>
cp.customerCode.toLowerCase().includes(query.customerCode.toLowerCase()) &&
cp.customerName.toLowerCase().includes(query.customerName.toLowerCase())
),
);
}}
/>
)}
<div style={{display:"inline-block",width:"99%",marginLeft:10}}> <div style={{display:"inline-block",width:"99%",marginLeft:10}}>
<CustomDatagrid rows={projectFinancialRows} columns={columns2} columnWidth={200} dataGridHeight={300}/>
{/* <CustomDatagrid rows={clientFinancialRows} columns={columns} columnWidth={200} dataGridHeight={300} checkboxSelection={true} onRowSelectionModelChange={handleSelectionChange} selectionModel={selectionModel}/> */}
<CustomDatagrid onRowClick={handleRowClick} rows={filteredClientResult} columns={columns} columnWidth={200} dataGridHeight={300}/>
</div> </div>
<hr></hr>
<div className="ml-10 text-base"><strong>-Formula-</strong></div>
<div className="ml-10 text-sm"><strong>CPI:</strong> Invoiced Amount / Cumulative Expenditure</div>
<div className="ml-10 text-sm"><strong>Cash Flow Status: </strong>{`Positive when CPI >= 1`}</div>
<div className="ml-10 text-sm"><strong>Projected CPI:</strong> Project Fee / Cumulative Expenditure</div>
<div className="ml-10 text-sm mb-5"><strong>Cash Flow Status: </strong>{`Positive when Projected CPI >= 1`}</div>
</Card> </Card>
</Grid> </Grid>
); );


+ 5
- 5
src/components/ProjectResourceConsumptionRanking/ProjectResourceConsumptionRanking.tsx View File

@@ -788,19 +788,19 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
</div> </div>
<div className="ml-6 mb-2"> <div className="ml-6 mb-2">
<button onClick={() => {setTableSorting('PercentageASC')}} <button onClick={() => {setTableSorting('PercentageASC')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Percentage ASC
{`Percentage (Ascending Order)`}
</button> </button>
<button <button
onClick={() => {setTableSorting('PercentageDESC')}} onClick={() => {setTableSorting('PercentageDESC')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Percentage DESC
{`Percentage (Descending Order)`}
</button> </button>
<button <button
onClick={() => {setTableSorting('ProjectName')}} onClick={() => {setTableSorting('ProjectName')}}
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-36"
className="hover:cursor-pointer hover:bg-violet-50 text-sm bg-transparent border-violet-500 text-violet-500 border-solid w-50"
> >
Project Name Project Name
</button> </button>


Loading…
Cancel
Save