|
@@ -13,9 +13,10 @@ import { |
|
|
import { useTranslation } from "react-i18next"; |
|
|
import { useTranslation } from "react-i18next"; |
|
|
import { manhourFormatter } from "@/app/utils/formatUtil"; |
|
|
import { manhourFormatter } from "@/app/utils/formatUtil"; |
|
|
import { AssignedProject } from "@/app/api/projects"; |
|
|
import { AssignedProject } from "@/app/api/projects"; |
|
|
import { ViewList, ViewModule } from "@mui/icons-material"; |
|
|
|
|
|
|
|
|
import { TableRows, ViewModule, TableChart } from "@mui/icons-material"; |
|
|
|
|
|
import ProjectTable from "./ProjectTable"; |
|
|
|
|
|
|
|
|
interface Props { |
|
|
|
|
|
|
|
|
export interface Props { |
|
|
projects: AssignedProject[]; |
|
|
projects: AssignedProject[]; |
|
|
maintainNormalStaffWorkspaceAbility?: boolean; |
|
|
maintainNormalStaffWorkspaceAbility?: boolean; |
|
|
maintainManagementStaffWorkspaceAbility?: boolean; |
|
|
maintainManagementStaffWorkspaceAbility?: boolean; |
|
@@ -27,7 +28,7 @@ const ProjectGrid: React.FC<Props> = ({ |
|
|
maintainManagementStaffWorkspaceAbility, |
|
|
maintainManagementStaffWorkspaceAbility, |
|
|
}) => { |
|
|
}) => { |
|
|
const { t } = useTranslation("home"); |
|
|
const { t } = useTranslation("home"); |
|
|
const [view, setView] = useState<"grid" | "list">("grid"); |
|
|
|
|
|
|
|
|
const [view, setView] = useState<"grid" | "list" | "table">("grid"); |
|
|
|
|
|
|
|
|
const handleViewChange = useCallback< |
|
|
const handleViewChange = useCallback< |
|
|
NonNullable<ToggleButtonProps["onChange"]> |
|
|
NonNullable<ToggleButtonProps["onChange"]> |
|
@@ -53,44 +54,94 @@ const ProjectGrid: React.FC<Props> = ({ |
|
|
</ToggleButton> |
|
|
</ToggleButton> |
|
|
<ToggleButton value="list"> |
|
|
<ToggleButton value="list"> |
|
|
<Tooltip title={t("List view")}> |
|
|
<Tooltip title={t("List view")}> |
|
|
<ViewList /> |
|
|
|
|
|
|
|
|
<TableRows /> |
|
|
|
|
|
</Tooltip> |
|
|
|
|
|
</ToggleButton> |
|
|
|
|
|
<ToggleButton value="table"> |
|
|
|
|
|
<Tooltip title={t("Table view")}> |
|
|
|
|
|
<TableChart /> |
|
|
</Tooltip> |
|
|
</Tooltip> |
|
|
</ToggleButton> |
|
|
</ToggleButton> |
|
|
</ToggleButtonGroup> |
|
|
</ToggleButtonGroup> |
|
|
<Grid |
|
|
|
|
|
container |
|
|
|
|
|
columns={view === "list" ? 4 : { xs: 4, sm: 8, md: 12, lg: 16 }} |
|
|
|
|
|
spacing={2} |
|
|
|
|
|
alignItems="stretch" |
|
|
|
|
|
> |
|
|
|
|
|
{projects.map((project, idx) => ( |
|
|
|
|
|
<Grid key={`${project.code}${idx}`} item xs={4}> |
|
|
|
|
|
<Card sx={{ height: "100%" }}> |
|
|
|
|
|
<CardContent |
|
|
|
|
|
sx={{ |
|
|
|
|
|
display: "flex", |
|
|
|
|
|
flexDirection: "column", |
|
|
|
|
|
height: "100%", |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<Typography variant="overline">{project.code}</Typography> |
|
|
|
|
|
<Typography |
|
|
|
|
|
variant="h6" |
|
|
|
|
|
|
|
|
{view === "table" ? ( |
|
|
|
|
|
<ProjectTable |
|
|
|
|
|
projects={projects} |
|
|
|
|
|
maintainManagementStaffWorkspaceAbility={ |
|
|
|
|
|
maintainManagementStaffWorkspaceAbility |
|
|
|
|
|
} |
|
|
|
|
|
maintainNormalStaffWorkspaceAbility={ |
|
|
|
|
|
maintainNormalStaffWorkspaceAbility |
|
|
|
|
|
} |
|
|
|
|
|
/> |
|
|
|
|
|
) : ( |
|
|
|
|
|
<Grid |
|
|
|
|
|
container |
|
|
|
|
|
columns={view === "list" ? 4 : { xs: 4, sm: 8, md: 12, lg: 16 }} |
|
|
|
|
|
spacing={2} |
|
|
|
|
|
alignItems="stretch" |
|
|
|
|
|
> |
|
|
|
|
|
{projects.map((project, idx) => ( |
|
|
|
|
|
<Grid key={`${project.code}${idx}`} item xs={4}> |
|
|
|
|
|
<Card sx={{ height: "100%" }}> |
|
|
|
|
|
<CardContent |
|
|
sx={{ |
|
|
sx={{ |
|
|
marginBlockEnd: 3, |
|
|
|
|
|
|
|
|
display: "flex", |
|
|
|
|
|
flexDirection: "column", |
|
|
|
|
|
height: "100%", |
|
|
}} |
|
|
}} |
|
|
> |
|
|
> |
|
|
{project.name} |
|
|
|
|
|
</Typography> |
|
|
|
|
|
{/* Spacer */} |
|
|
|
|
|
<Box sx={{ flex: 1 }} /> |
|
|
|
|
|
{/* Hours Spent */} |
|
|
|
|
|
{(Boolean(maintainNormalStaffWorkspaceAbility) || |
|
|
|
|
|
Boolean(maintainManagementStaffWorkspaceAbility)) && ( |
|
|
|
|
|
<> |
|
|
|
|
|
<Typography variant="subtitle2"> |
|
|
|
|
|
{t("Hours Spent:")} |
|
|
|
|
|
</Typography> |
|
|
|
|
|
|
|
|
<Typography variant="overline">{project.code}</Typography> |
|
|
|
|
|
<Typography |
|
|
|
|
|
variant="h6" |
|
|
|
|
|
sx={{ |
|
|
|
|
|
marginBlockEnd: 3, |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
{project.name} |
|
|
|
|
|
</Typography> |
|
|
|
|
|
{/* Spacer */} |
|
|
|
|
|
<Box sx={{ flex: 1 }} /> |
|
|
|
|
|
{/* Hours Spent */} |
|
|
|
|
|
{(Boolean(maintainNormalStaffWorkspaceAbility) || |
|
|
|
|
|
Boolean(maintainManagementStaffWorkspaceAbility)) && ( |
|
|
|
|
|
<> |
|
|
|
|
|
<Typography variant="subtitle2"> |
|
|
|
|
|
{t("Hours Spent:")} |
|
|
|
|
|
</Typography> |
|
|
|
|
|
<Box |
|
|
|
|
|
sx={{ |
|
|
|
|
|
display: "flex", |
|
|
|
|
|
justifyContent: "space-between", |
|
|
|
|
|
alignItems: "baseline", |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<Typography variant="caption">{t("Normal")}</Typography> |
|
|
|
|
|
<Typography> |
|
|
|
|
|
{manhourFormatter.format( |
|
|
|
|
|
Boolean(maintainManagementStaffWorkspaceAbility) |
|
|
|
|
|
? project.hoursSpent |
|
|
|
|
|
: project.currentStaffHoursSpent, |
|
|
|
|
|
)} |
|
|
|
|
|
</Typography> |
|
|
|
|
|
</Box> |
|
|
|
|
|
<Box |
|
|
|
|
|
sx={{ |
|
|
|
|
|
display: "flex", |
|
|
|
|
|
justifyContent: "space-between", |
|
|
|
|
|
alignItems: "baseline", |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<Typography variant="caption">{t("Others")}</Typography> |
|
|
|
|
|
<Typography>{`${manhourFormatter.format( |
|
|
|
|
|
Boolean(maintainManagementStaffWorkspaceAbility) |
|
|
|
|
|
? project.hoursSpentOther |
|
|
|
|
|
: project.currentStaffHoursSpentOther, |
|
|
|
|
|
)}`}</Typography> |
|
|
|
|
|
</Box> |
|
|
|
|
|
</> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* Hours Allocated */} |
|
|
|
|
|
{Boolean(maintainManagementStaffWorkspaceAbility) && ( |
|
|
<Box |
|
|
<Box |
|
|
sx={{ |
|
|
sx={{ |
|
|
display: "flex", |
|
|
display: "flex", |
|
@@ -98,56 +149,23 @@ const ProjectGrid: React.FC<Props> = ({ |
|
|
alignItems: "baseline", |
|
|
alignItems: "baseline", |
|
|
}} |
|
|
}} |
|
|
> |
|
|
> |
|
|
<Typography variant="caption">{t("Normal")}</Typography> |
|
|
|
|
|
|
|
|
<Typography |
|
|
|
|
|
variant="subtitle2" |
|
|
|
|
|
sx={{ marginBlockStart: 2 }} |
|
|
|
|
|
> |
|
|
|
|
|
{t("Hours Allocated:")} |
|
|
|
|
|
</Typography> |
|
|
<Typography> |
|
|
<Typography> |
|
|
{manhourFormatter.format( |
|
|
|
|
|
Boolean(maintainManagementStaffWorkspaceAbility) |
|
|
|
|
|
? project.hoursSpent |
|
|
|
|
|
: project.currentStaffHoursSpent, |
|
|
|
|
|
)} |
|
|
|
|
|
|
|
|
{manhourFormatter.format(project.hoursAllocated)} |
|
|
</Typography> |
|
|
</Typography> |
|
|
</Box> |
|
|
</Box> |
|
|
<Box |
|
|
|
|
|
sx={{ |
|
|
|
|
|
display: "flex", |
|
|
|
|
|
justifyContent: "space-between", |
|
|
|
|
|
alignItems: "baseline", |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<Typography variant="caption">{t("Others")}</Typography> |
|
|
|
|
|
<Typography>{`${manhourFormatter.format( |
|
|
|
|
|
Boolean(maintainManagementStaffWorkspaceAbility) |
|
|
|
|
|
? project.hoursSpentOther |
|
|
|
|
|
: project.currentStaffHoursSpentOther, |
|
|
|
|
|
)}`}</Typography> |
|
|
|
|
|
</Box> |
|
|
|
|
|
</> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* Hours Allocated */} |
|
|
|
|
|
{Boolean(maintainManagementStaffWorkspaceAbility) && ( |
|
|
|
|
|
<Box |
|
|
|
|
|
sx={{ |
|
|
|
|
|
display: "flex", |
|
|
|
|
|
justifyContent: "space-between", |
|
|
|
|
|
alignItems: "baseline", |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<Typography |
|
|
|
|
|
variant="subtitle2" |
|
|
|
|
|
sx={{ marginBlockStart: 2 }} |
|
|
|
|
|
> |
|
|
|
|
|
{t("Hours Allocated:")} |
|
|
|
|
|
</Typography> |
|
|
|
|
|
<Typography> |
|
|
|
|
|
{manhourFormatter.format(project.hoursAllocated)} |
|
|
|
|
|
</Typography> |
|
|
|
|
|
</Box> |
|
|
|
|
|
)} |
|
|
|
|
|
</CardContent> |
|
|
|
|
|
</Card> |
|
|
|
|
|
</Grid> |
|
|
|
|
|
))} |
|
|
|
|
|
</Grid> |
|
|
|
|
|
|
|
|
)} |
|
|
|
|
|
</CardContent> |
|
|
|
|
|
</Card> |
|
|
|
|
|
</Grid> |
|
|
|
|
|
))} |
|
|
|
|
|
</Grid> |
|
|
|
|
|
)} |
|
|
</Box> |
|
|
</Box> |
|
|
); |
|
|
); |
|
|
}; |
|
|
}; |
|
|