Преглед на файлове

add project potential delay report

tags/Baseline_30082024_FRONTEND_UAT
cyril.tsui преди 1 година
родител
ревизия
9c054e030e
променени са 9 файла, в които са добавени 171 реда и са изтрити 28 реда
  1. +0
    -24
      src/app/(main)/analytics/DelayReport/page.tsx
  2. +33
    -0
      src/app/(main)/analytics/ProjectPotentialDelayReport/page.tsx
  3. +15
    -2
      src/app/api/reports/actions.ts
  4. +10
    -0
      src/app/api/reports/index.ts
  5. +53
    -0
      src/components/GenerateProjectPotentialDelayReport/GenerateProjectPotentialDelayReport.tsx
  6. +38
    -0
      src/components/GenerateProjectPotentialDelayReport/GenerateProjectPotentialDelayReportLoading.tsx
  7. +19
    -0
      src/components/GenerateProjectPotentialDelayReport/GenerateProjectPotentialDelayReportWrapper.tsx
  8. +1
    -0
      src/components/GenerateProjectPotentialDelayReport/index.ts
  9. +2
    -2
      src/components/NavigationContent/NavigationContent.tsx

+ 0
- 24
src/app/(main)/analytics/DelayReport/page.tsx Целия файл

@@ -1,24 +0,0 @@
//src\app\(main)\analytics\DelayReport\page.tsx
import { Metadata } from "next";
import { I18nProvider } from "@/i18n";
import Typography from "@mui/material/Typography";
import DelayReportComponent from "@/components/Report/DelayReport";

export const metadata: Metadata = {
title: "Delay Report",
};

const ProjectLateReport: React.FC = () => {
return (
<I18nProvider namespaces={["analytics"]}>
<Typography variant="h4" marginInlineEnd={2}>
Delay Report
</Typography>
{/* <Suspense fallback={<ProgressCashFlowSearch.Loading />}>
<ProgressCashFlowSearch/>
</Suspense> */}
<DelayReportComponent />
</I18nProvider>
);
};
export default ProjectLateReport;

+ 33
- 0
src/app/(main)/analytics/ProjectPotentialDelayReport/page.tsx Целия файл

@@ -0,0 +1,33 @@
//src\app\(main)\analytics\DelayReport\page.tsx
import { Metadata } from "next";
import { I18nProvider, getServerI18n } from "@/i18n";
import Typography from "@mui/material/Typography";;
import { fetchAllCustomers } from "@/app/api/customer";
import { fetchTeam } from "@/app/api/team";
import { Suspense } from "react";
import GenerateProjectPotentialDelayReport from "@/components/GenerateProjectPotentialDelayReport";

export const metadata: Metadata = {
title: "Project Potential Delay Report",
};

const ProjectPotentialDelayReport: React.FC = async () => {
const { t } = await getServerI18n("reports");

fetchAllCustomers()
fetchTeam()

return (
<>
<Typography variant="h4" marginInlineEnd={2}>
{t("Project Potential Delay Report")}
</Typography>
<I18nProvider namespaces={["report", "common"]}>
<Suspense fallback={<GenerateProjectPotentialDelayReport.Loading />}>
<GenerateProjectPotentialDelayReport />
</Suspense>
</I18nProvider>
</>
);
};
export default ProjectPotentialDelayReport;

+ 15
- 2
src/app/api/reports/actions.ts Целия файл

@@ -1,7 +1,7 @@
"use server";

import { serverFetchBlob, serverFetchJson } from "@/app/utils/fetchUtil";
import { MonthlyWorkHoursReportRequest, ProjectCashFlowReportRequest, LateStartReportRequest, ProjectResourceOverconsumptionReportRequest, ProjectPandLReportRequest, ProjectCompletionReportRequest } from ".";
import { serverFetchBlob } from "@/app/utils/fetchUtil";
import { MonthlyWorkHoursReportRequest, ProjectCashFlowReportRequest, LateStartReportRequest, ProjectResourceOverconsumptionReportRequest, ProjectPandLReportRequest, ProjectCompletionReportRequest, ProjectPotentialDelayReportRequest } from ".";
import { BASE_API_URL } from "@/config/api";

export interface FileResponse {
@@ -22,6 +22,19 @@ export const fetchProjectCashFlowReport = async (data: ProjectCashFlowReportRequ
return reportBlob
};

export const fetchProjectPotentialDelayReport = async (data: ProjectPotentialDelayReportRequest) => {
const reportBlob = await serverFetchBlob<FileResponse>(
`${BASE_API_URL}/reports/ProjectPotentialDelayReport`,
{
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
},
);

return reportBlob
};

export const fetchMonthlyWorkHoursReport = async (data: MonthlyWorkHoursReportRequest) => {
const reportBlob = await serverFetchBlob<FileResponse>(
`${BASE_API_URL}/reports/StaffMonthlyWorkHourAnalysisReport`,


+ 10
- 0
src/app/api/reports/index.ts Целия файл

@@ -28,6 +28,16 @@ export interface ProjectCashFlowReportRequest {
dateType: string;
}

// - Project Potential Delay Report
export interface ProjectPotentialDelayReportFilter {
team: string[];
client: string[];
}

export interface ProjectPotentialDelayReportRequest {
teamId: number | "All";
clientId: number | "All";
}

// - Monthly Work Hours Report
export interface MonthlyWorkHoursReportFilter {


+ 53
- 0
src/components/GenerateProjectPotentialDelayReport/GenerateProjectPotentialDelayReport.tsx Целия файл

@@ -0,0 +1,53 @@
"use client";

import React, { useMemo } from "react";
import SearchBox, { Criterion } from "../SearchBox";
import { useTranslation } from "react-i18next";
import { ProjectPotentialDelayReportFilter } from "@/app/api/reports";
import { fetchProjectCashFlowReport, fetchProjectPotentialDelayReport } from "@/app/api/reports/actions";
import { downloadFile } from "@/app/utils/commonUtil";
import { TeamResult } from "@/app/api/team";
import { Customer } from "@/app/api/customer";

interface Props {
teams: TeamResult[];
clients: Customer[];
}

type SearchQuery = Partial<Omit<ProjectPotentialDelayReportFilter, "id">>;
type SearchParamNames = keyof SearchQuery;

const GenerateProjectPotentialDelayReport: React.FC<Props> = ({ teams, clients }) => {
const { t } = useTranslation("report");
const teamCombo = teams.map(team => `${team.code} - ${team.name}`)
const clientCombo = clients.map(client => `${client.code} - ${client.name}`)

const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
() => [
{ label: t("Team"), paramName: "team", type: "select", options: teamCombo },
{ label: t("Client"), paramName: "client", type: "select", options: clientCombo },
],
[t],
);

return (
<>
<SearchBox
criteria={searchCriteria}
onSearch={async (query) => {

const teamIndex = teamCombo.findIndex(team => team === query.team)
const clientIndex = clientCombo.findIndex(client => client === query.client)
const response = await fetchProjectPotentialDelayReport({ teamId: teams[teamIndex]?.id ?? "All", clientId: clients[clientIndex]?.id ?? "All" })
if (response) {
downloadFile(new Uint8Array(response.blobValue), response.filename!!)
}
}}
formType={"download"}
/>
</>
);
};

export default GenerateProjectPotentialDelayReport;

+ 38
- 0
src/components/GenerateProjectPotentialDelayReport/GenerateProjectPotentialDelayReportLoading.tsx Целия файл

@@ -0,0 +1,38 @@
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Skeleton from "@mui/material/Skeleton";
import Stack from "@mui/material/Stack";
import React from "react";

// Can make this nicer
export const GenerateProjectPotentialDelayReportLoading: React.FC = () => {
return (
<>
<Card>
<CardContent>
<Stack spacing={2}>
<Skeleton variant="rounded" height={60} />
<Skeleton
variant="rounded"
height={50}
width={100}
sx={{ alignSelf: "flex-end" }}
/>
</Stack>
</CardContent>
</Card>
<Card>
<CardContent>
<Stack spacing={2}>
<Skeleton variant="rounded" height={40} />
<Skeleton variant="rounded" height={40} />
<Skeleton variant="rounded" height={40} />
<Skeleton variant="rounded" height={40} />
</Stack>
</CardContent>
</Card>
</>
);
};

export default GenerateProjectPotentialDelayReportLoading;

+ 19
- 0
src/components/GenerateProjectPotentialDelayReport/GenerateProjectPotentialDelayReportWrapper.tsx Целия файл

@@ -0,0 +1,19 @@
import React from "react";
import GenerateProjectPotentialDelayReportLoading from "./GenerateProjectPotentialDelayReportLoading";
import GenerateProjectPotentialDelayReport from "./GenerateProjectPotentialDelayReport";
import { fetchTeam } from "@/app/api/team";
import { fetchAllCustomers } from "@/app/api/customer";

interface SubComponents {
Loading: typeof GenerateProjectPotentialDelayReportLoading;
}

const GenerateProjectPotentialDelayReportWrapper: React.FC & SubComponents = async () => {
const [teams, clients] = await Promise.all([fetchTeam(), fetchAllCustomers()])

return <GenerateProjectPotentialDelayReport teams={teams} clients={clients}/>;
};

GenerateProjectPotentialDelayReportWrapper.Loading = GenerateProjectPotentialDelayReportLoading;

export default GenerateProjectPotentialDelayReportWrapper;

+ 1
- 0
src/components/GenerateProjectPotentialDelayReport/index.ts Целия файл

@@ -0,0 +1 @@
export { default } from "./GenerateProjectPotentialDelayReportWrapper";

+ 2
- 2
src/components/NavigationContent/NavigationContent.tsx Целия файл

@@ -144,8 +144,8 @@ const NavigationContent: React.FC<Props> = ({ abilities }) => {
},
{
icon: <Analytics />,
label: "Delay Report",
path: "/analytics/DelayReport",
label: "Project Potential Delay Report",
path: "/analytics/ProjectPotentialDelayReport",
},
{
icon: <Analytics />,


Зареждане…
Отказ
Запис