Explorar el Código

Merge branch 'main' of https://git.2fi-solutions.com/wayne.lee/tsms

tags/Baseline_30082024_FRONTEND_UAT
MSI\2Fi hace 1 año
padre
commit
2f078fd2f0
Se han modificado 4 ficheros con 127 adiciones y 104 borrados
  1. +7
    -2
      src/components/AppBar/AppBar.tsx
  2. +13
    -3
      src/components/AppBar/NavigationToggle.tsx
  3. +104
    -97
      src/components/NavigationContent/NavigationContent.tsx
  4. +3
    -2
      src/middleware.ts

+ 7
- 2
src/components/AppBar/AppBar.tsx Ver fichero

@@ -5,18 +5,23 @@ import Profile from "./Profile";
import Box from "@mui/material/Box";
import NavigationToggle from "./NavigationToggle";
import { I18nProvider } from "@/i18n";
import { authOptions } from "@/config/authConfig";
import { getServerSession } from "next-auth";

export interface AppBarProps {
avatarImageSrc?: string;
profileName: string;
}

const AppBar: React.FC<AppBarProps> = ({ avatarImageSrc, profileName }) => {
const AppBar: React.FC<AppBarProps> = async ({ avatarImageSrc, profileName }) => {
const session = await getServerSession(authOptions) as any;
const abilities: string[] = session.abilities
console.log(abilities)
return (
<I18nProvider namespaces={["common"]}>
<MUIAppBar position="sticky" color="default" elevation={4}>
<Toolbar>
<NavigationToggle />
<NavigationToggle abilities={abilities}/>
<Box
sx={{ flexGrow: 1, display: "flex", justifyContent: "flex-end" }}
>


+ 13
- 3
src/components/AppBar/NavigationToggle.tsx Ver fichero

@@ -4,8 +4,18 @@ import MenuIcon from "@mui/icons-material/Menu";
import NavigationContent from "../NavigationContent";
import React from "react";
import Drawer from "@mui/material/Drawer";
import { Session } from "inspector";
import { authOptions } from "@/config/authConfig";
import { getServerSession } from "next-auth";
export interface SessionWithAbilities extends Session {
abilities?: string[]
}

const NavigationToggle: React.FC = () => {
interface Props {
abilities?: string[]
}

const NavigationToggle: React.FC<Props> = ({ abilities }) => {
const [isOpened, setIsOpened] = React.useState(false);

const openNavigation = () => {
@@ -18,7 +28,7 @@ const NavigationToggle: React.FC = () => {
return (
<>
<Drawer variant="permanent" sx={{ display: { xs: "none", xl: "block" } }}>
<NavigationContent />
<NavigationContent abilities={abilities}/>
</Drawer>
<Drawer
sx={{ display: { xl: "none" } }}
@@ -28,7 +38,7 @@ const NavigationToggle: React.FC = () => {
keepMounted: true,
}}
>
<NavigationContent />
<NavigationContent abilities={abilities}/>
</Drawer>
<IconButton
sx={{ display: { xl: "none" } }}


+ 104
- 97
src/components/NavigationContent/NavigationContent.tsx Ver fichero

@@ -35,114 +35,121 @@ import BusinessIcon from '@mui/icons-material/Business';
import ViewWeekIcon from '@mui/icons-material/ViewWeek';
import ManageAccountsIcon from '@mui/icons-material/ManageAccounts';
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';

import { GENERATE_REPORTS, MAINTAIN_MASTERDATA, MAINTAIN_USER, VIEW_MASTERDATA, VIEW_USER } from "@/middleware";
import { SessionWithAbilities } from "../AppBar/NavigationToggle";
import { authOptions } from "@/config/authConfig";
import { getServerSession } from "next-auth";
interface NavigationItem {
icon: React.ReactNode;
label: string;
path: string;
isHidden?: boolean;
children?: NavigationItem[];
}

const navigationItems: NavigationItem[] = [
{ icon: <WorkHistory />, label: "User Workspace", path: "/home" },
{
icon: <Dashboard />,
label: "Dashboard",
path: "",
children: [
{
icon: <SummarizeIcon />,
label: "Financial Summary",
path: "/dashboard/ProjectFinancialSummary",
},
{
icon: <PaymentsIcon />,
label: "Company / Team Cash Flow",
path: "/dashboard/CompanyTeamCashFlow",
},
{
icon: <PaymentsIcon />,
label: "Project Cash Flow",
path: "/dashboard/ProjectCashFlow",
},
{
icon: <AccountTreeIcon />,
label: "Project Status by Client",
path: "/dashboard/ProjectStatusByClient",
},
{
icon: <AccountTreeIcon />,
label: "Project Status by Team",
path: "/dashboard/ProjectStatusByTeam",
},
{
icon: <PeopleIcon />,
label: "Staff Utilization",
path: "/dashboard/StaffUtilization",
},
{
icon: <ViewWeekIcon />,
label: "Project Resource Summary",
path: "/dashboard/ProjectResourceSummary",
}
],
},
{
icon: <RequestQuote />,
label: "Staff Reimbursement",
path: "/staffReimbursement",
children: [
{
icon: <RequestQuote />,
label: "Claim Approval",
path: "/staffReimbursement/ClaimApproval",
},
{
icon: <RequestQuote />,
label: "Claim Summary",
path: "/staffReimbursement/ClaimSummary",
},
],
},
{ icon: <Assignment />, label: "Project Management", path: "/projects" },
{ icon: <Task />, label: "Task Template", path: "/tasks" },
{ icon: <Payments />, label: "Invoice", path: "/invoice" },
{ icon: <Analytics />, label: "Analysis Report", path: "",
children: [
{icon: <Analytics />, label:"Late Start Report", path: "/analytics/LateStartReport"},
{icon: <Analytics />, label:"Delay Report", path: "/analytics/DelayReport"},
{icon: <Analytics />, label:"Resource Overconsumption Report", path: "/analytics/ResourceOverconsumptionReport"},
{icon: <Analytics />, label:"Cost and Expense Report", path: "/analytics/CostandExpenseReport"},
{icon: <Analytics />, label:"Completion Report", path: "/analytics/ProjectCompletionReport"},
{icon: <Analytics />, label:"Completion Report with Outstanding Un-billed Hours Report", path: "/analytics/ProjectCompletionReportWO"},
{icon: <Analytics />, label:"Project Claims Report", path: "/analytics/ProjectClaimsReport"},
{icon: <Analytics />, label:"Project P&L Report", path: "/analytics/ProjectPLReport"},
{icon: <Analytics />, label:"Financial Status Report", path: "/analytics/FinancialStatusReport"},
{icon: <Analytics />, label:"Project Cash Flow Report", path: "/analytics/ProjectCashFlowReport"},
],
},
{
icon: <Settings />, label: "Setting", path: "",
children: [
{ icon: <GroupIcon />, label: "Client", path: "/settings/customer" },
{ icon: <BusinessIcon />, label: "Subsidiary", path: "/settings/subsidiary" },
{ icon: <Staff />, label: "Staff", path: "/settings/staff" },
{ icon: <Company />, label: "Company", path: "/settings/company" },
{ icon: <EmojiEventsIcon />, label: "Skill", path: "/settings/skill" },
{ icon: <Department />, label: "Department", path: "/settings/department" },
{ icon: <Position />, label: "Position", path: "/settings/position" },
{ icon: <Salary />, label: "Salary", path: "/settings/salary" },
{ icon: <Team />, label: "Team", path: "/settings/team" },
{ icon: <ManageAccountsIcon />, label: "User", path: "/settings/user" },
{ icon: <Holiday />, label: "Holiday", path: "/settings/holiday" },
interface Props {
abilities?: string[]
}

const NavigationContent: React.FC<Props> = ({ abilities }) => {
const navigationItems: NavigationItem[] = [
{ icon: <WorkHistory />, label: "User Workspace", path: "/home" },
{
icon: <Dashboard />,
label: "Dashboard",
path: "",
children: [
{
icon: <SummarizeIcon />,
label: "Financial Summary",
path: "/dashboard/ProjectFinancialSummary",
},
{
icon: <PaymentsIcon />,
label: "Company / Team Cash Flow",
path: "/dashboard/CompanyTeamCashFlow",
},
{
icon: <PaymentsIcon />,
label: "Project Cash Flow",
path: "/dashboard/ProjectCashFlow",
},
{
icon: <AccountTreeIcon />,
label: "Project Status by Client",
path: "/dashboard/ProjectStatusByClient",
},
{
icon: <AccountTreeIcon />,
label: "Project Status by Team",
path: "/dashboard/ProjectStatusByTeam",
},
{
icon: <PeopleIcon />,
label: "Staff Utilization",
path: "/dashboard/StaffUtilization",
},
{
icon: <ViewWeekIcon />,
label: "Project Resource Summary",
path: "/dashboard/ProjectResourceSummary",
}
],
},
{
icon: <RequestQuote />,
label: "Staff Reimbursement",
path: "/staffReimbursement",
children: [
{
icon: <RequestQuote />,
label: "Claim Approval",
path: "/staffReimbursement/ClaimApproval",
},
{
icon: <RequestQuote />,
label: "Claim Summary",
path: "/staffReimbursement/ClaimSummary",
},
],
},
{ icon: <Assignment />, label: "Project Management", path: "/projects" },
{ icon: <Task />, label: "Task Template", path: "/tasks" },
{ icon: <Payments />, label: "Invoice", path: "/invoice" },
{ icon: <Analytics />, label: "Analysis Report", path: "", isHidden: ![GENERATE_REPORTS].some((ability) => abilities!!.includes(ability)),
children: [
{icon: <Analytics />, label:"Late Start Report", path: "/analytics/LateStartReport"},
{icon: <Analytics />, label:"Delay Report", path: "/analytics/DelayReport"},
{icon: <Analytics />, label:"Resource Overconsumption Report", path: "/analytics/ResourceOverconsumptionReport"},
{icon: <Analytics />, label:"Cost and Expense Report", path: "/analytics/CostandExpenseReport"},
{icon: <Analytics />, label:"Completion Report", path: "/analytics/ProjectCompletionReport"},
{icon: <Analytics />, label:"Completion Report with Outstanding Un-billed Hours Report", path: "/analytics/ProjectCompletionReportWO"},
{icon: <Analytics />, label:"Project Claims Report", path: "/analytics/ProjectClaimsReport"},
{icon: <Analytics />, label:"Project P&L Report", path: "/analytics/ProjectPLReport"},
{icon: <Analytics />, label:"Financial Status Report", path: "/analytics/FinancialStatusReport"},
{icon: <Analytics />, label:"EX02 - Project Cash Flow Report", path: "/analytics/EX02ProjectCashFlowReport"},
],
},
];
{
icon: <Settings />, label: "Setting", path: "", isHidden: ![VIEW_MASTERDATA, MAINTAIN_MASTERDATA].some((ability) => abilities!!.includes(ability)),
children: [
{ icon: <GroupIcon />, label: "Client", path: "/settings/customer" },
{ icon: <BusinessIcon />, label: "Subsidiary", path: "/settings/subsidiary" },
{ icon: <Staff />, label: "Staff", path: "/settings/staff" },
{ icon: <Company />, label: "Company", path: "/settings/company" },
{ icon: <EmojiEventsIcon />, label: "Skill", path: "/settings/skill" },
{ icon: <Department />, label: "Department", path: "/settings/department" },
{ icon: <Position />, label: "Position", path: "/settings/position" },
{ icon: <Salary />, label: "Salary", path: "/settings/salary" },
{ icon: <Team />, label: "Team", path: "/settings/team" },
{ icon: <ManageAccountsIcon />, label: "User", path: "/settings/user" },
{ icon: <Holiday />, label: "Holiday", path: "/settings/holiday" },
],
},
];

const NavigationContent: React.FC = () => {
const { t } = useTranslation("common");
const pathname = usePathname();

const [openItems, setOpenItems] = React.useState<string[]>([]);
const toggleItem = (label: string) => {
setOpenItems((prevOpenItems) =>
@@ -188,7 +195,7 @@ const NavigationContent: React.FC = () => {
</Box>
<Divider />
<List component="nav">
{navigationItems.map((item) => renderNavigationItem(item))}
{navigationItems.filter(item => item.isHidden !== true).map((item) => renderNavigationItem(item))}
{/* {navigationItems.map(({ icon, label, path }, index) => {
return (
<Box


+ 3
- 2
src/middleware.ts Ver fichero

@@ -2,8 +2,6 @@ import { NextRequestWithAuth, withAuth } from "next-auth/middleware";
import { ability, authOptions } from "@/config/authConfig";
import { NextFetchEvent, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";
import { ConnectingAirportsOutlined } from "@mui/icons-material";
import { getServerSession } from "next-auth";

// abilities
export const [
@@ -86,6 +84,9 @@ export default async function middleware(
callbacks: {
authorized: ({req, token}) => {
let isAuth = Boolean(token);
if (!Boolean(token)) {
return Boolean(token)
}
if (req.nextUrl.pathname.startsWith('/settings')) {
isAuth = [VIEW_MASTERDATA, MAINTAIN_MASTERDATA].some((ability) => abilities.includes(ability));
}


Cargando…
Cancelar
Guardar