소스 검색

Add PandL Report navigation

tags/Baseline_30082024_FRONTEND_UAT
MSI\2Fi 1 년 전
부모
커밋
1b12a18e3a
6개의 변경된 파일151개의 추가작업 그리고 1개의 파일을 삭제
  1. +30
    -0
      src/app/(main)/analytics/ProjectPandLReport/page.tsx
  2. +63
    -0
      src/components/GenerateProjectPandLReport/GenerateProjectPandLReport.tsx
  3. +38
    -0
      src/components/GenerateProjectPandLReport/GenerateProjectPandLReportLoading.tsx
  4. +18
    -0
      src/components/GenerateProjectPandLReport/GenerateProjectPandLReportWrapper.tsx
  5. +1
    -0
      src/components/GenerateProjectPandLReport/index.ts
  6. +1
    -1
      src/components/NavigationContent/NavigationContent.tsx

+ 30
- 0
src/app/(main)/analytics/ProjectPandLReport/page.tsx 파일 보기

@@ -0,0 +1,30 @@
import { Metadata } from "next";
import { Suspense } from "react";
import { I18nProvider, getServerI18n } from "@/i18n";
import { fetchProjects } from "@/app/api/projects";
import GenerateProjectPandLReport from "@/components/GenerateProjectPandLReport";
import { Typography } from "@mui/material";

export const metadata: Metadata = {
title: "Project Cash Flow Report",
};

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

return (
<>
<Typography variant="h4" marginInlineEnd={2}>
{t("Project P&L Report")}
</Typography>
<I18nProvider namespaces={["report", "common"]}>
<Suspense fallback={<GenerateProjectPandLReport.Loading />}>
<GenerateProjectPandLReport />
</Suspense>
</I18nProvider>
</>
);
};

export default ProjectPandLReport;

+ 63
- 0
src/components/GenerateProjectPandLReport/GenerateProjectPandLReport.tsx 파일 보기

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

import React, { useMemo } from "react";
import SearchBox, { Criterion } from "../SearchBox";
import { useTranslation } from "react-i18next";
import { ProjectResult } from "@/app/api/projects";
import { ProjectPandLReportFilter } from "@/app/api/reports";
import { fetchProjectPandLReport } from "@/app/api/reports/actions";
import { downloadFile } from "@/app/utils/commonUtil";
import { dateTypeCombo } from "@/app/utils/comboUtil";
import { FormHelperText } from "@mui/material";
import { errorDialog, errorDialogWithContent } from "../Swal/CustomAlerts";

interface Props {
projects: ProjectResult[];
}

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

const GenerateProjectPandLReport: React.FC<Props> = ({ projects }) => {
const { t } = useTranslation("report");
const projectCombo = projects.map(project => `${project.code} - ${project.name}`)

const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
() => [
{ label: t("Project *"), paramName: "project", type: "select", options: projectCombo, needAll: false},
{ label: t("Start Month *"), label2: t("End Month *"), paramName: "startMonth", type: "dateRange", needMonth: true },

],
[t],
);

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

if (query.project.length > 0 && query.project.toLocaleLowerCase() !== "all") {
const projectIndex = projectCombo.findIndex(project => project === query.project)
console.log(projects[projectIndex].id, query.startMonth, query.startMonthTo)
if(projects[projectIndex].id != null && query.startMonth != "" && query.startMonthTo != undefined){
const response = await fetchProjectPandLReport({ projectId: projects[projectIndex].id, startMonth: query.startMonth, endMonth: query.startMonthTo })
if (response) {
downloadFile(new Uint8Array(response.blobValue), response.filename!!)
}
}else{
errorDialogWithContent(t("Download Fail"),
t(`Please check the required field`), t)
.then(() => {
window.location.reload()
})
}
}
}}
formType={"download"}
/>
</>
);
};

export default GenerateProjectPandLReport;

+ 38
- 0
src/components/GenerateProjectPandLReport/GenerateProjectPandLReportLoading.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 GenerateProjectPandLReportLoading: 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 GenerateProjectPandLReportLoading;

+ 18
- 0
src/components/GenerateProjectPandLReport/GenerateProjectPandLReportWrapper.tsx 파일 보기

@@ -0,0 +1,18 @@
import React from "react";
import GenerateProjectPandLReportLoading from "./GenerateProjectPandLReportLoading";
import { fetchProjects } from "@/app/api/projects";
import GenerateProjectPandLReport from "./GenerateProjectPandLReport";

interface SubComponents {
Loading: typeof GenerateProjectPandLReportLoading;
}

const GenerateProjectPandLReportWrapper: React.FC & SubComponents = async () => {
const projects = await fetchProjects();

return <GenerateProjectPandLReport projects={projects} />;
};

GenerateProjectPandLReportWrapper.Loading = GenerateProjectPandLReportLoading;

export default GenerateProjectPandLReportWrapper;

+ 1
- 0
src/components/GenerateProjectPandLReport/index.ts 파일 보기

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

+ 1
- 1
src/components/NavigationContent/NavigationContent.tsx 파일 보기

@@ -175,7 +175,7 @@ const NavigationContent: React.FC<Props> = ({ abilities }) => {
{
icon: <Analytics />,
label: "Project P&L Report",
path: "/analytics/ProjectPLReport",
path: "/analytics/ProjectPandLReport",
},
{
icon: <Analytics />,


불러오는 중...
취소
저장