|
- "use client";
-
- import { ProjectCategory, ProjectResult } from "@/app/api/projects";
- import React, { useCallback, useEffect, useMemo, useState } from "react";
- import SearchBox, { Criterion } from "../SearchBox";
- import { useTranslation } from "react-i18next";
- import SearchResults, { Column } from "../SearchResults";
- import EditNote from "@mui/icons-material/EditNote";
- import uniq from "lodash/uniq";
- import { useRouter, useSearchParams } from "next/navigation";
- import { MAINTAIN_PROJECT } from "@/middleware";
- import { reverse, uniqBy } from "lodash";
- import { loadDrafts } from "@/app/utils/draftUtils";
- import { TeamResult } from "@/app/api/team";
- import { Customer } from "@/app/api/customer";
- import ContentCopyIcon from '@mui/icons-material/ContentCopy';
- import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline';
-
- type ProjectResultOrDraft = ProjectResult & { isDraft?: boolean };
-
- interface Props {
- projects: ProjectResult[];
- projectCategories: ProjectCategory[];
- abilities: string[];
- teams: TeamResult[];
- customers: Customer[];
- }
-
- type SearchQuery = Partial<Omit<ProjectResult, "id">>;
- type SearchParamNames = keyof SearchQuery;
-
- const ProjectSearch: React.FC<Props> = ({
- projects,
- projectCategories,
- abilities,
- teams,
- customers,
- }) => {
- const router = useRouter();
- const { t } = useTranslation("projects");
-
- const [draftProjects, setDraftProjects] = useState<ProjectResultOrDraft[]>(
- [],
- );
-
- useEffect(() => {
- const drafts = reverse(loadDrafts());
- setDraftProjects(
- drafts.map(([id, inputs]) => {
- const team = teams.find(
- (team) => team.teamLead === inputs.projectLeadId,
- );
- return {
- isDraft: true,
- id: parseInt(id),
- code: inputs.projectCode || "",
- name: inputs.projectName || t("Draft Project"),
- category:
- projectCategories.find((cat) => cat.id === inputs.projectCategoryId)
- ?.name || "",
- team: team?.code || "",
- client:
- customers.find((customer) => customer.id === inputs.clientId)
- ?.name || "",
- status: t("Draft"),
- teamCodeName: team?.code || "",
- teamId: team?.teamId || 0,
- mainProject: "",
- };
- }),
- );
- }, [projectCategories, t, teams, customers]);
-
- const [filteredProjects, setFilteredProjects] = useState(projects);
-
- const draftAndFilterdProjects = useMemo<ProjectResultOrDraft[]>(
- () => [...draftProjects, ...filteredProjects],
- [draftProjects, filteredProjects],
- );
-
- const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
- () => [
- { label: t("Project Code"), paramName: "code", type: "text" },
- { label: t("Project Name"), paramName: "name", type: "text" },
- {
- label: t("Client Name"),
- paramName: "client",
- type: "autocomplete",
- options: uniqBy(
- projects.map((project) => ({
- value: project.client,
- label: project.client,
- })),
- "value",
- ).sort((a, b) => (a.value >= b.value ? 1 : -1)),
- },
- {
- label: t("Project Category"),
- paramName: "category",
- type: "select",
- options: projectCategories.map((category) => category.name),
- },
- {
- label: t("Team"),
- paramName: "team",
- type: "select",
- options: uniq(projects.map((project) => project.teamCodeName)),
- },
- {
- label: t("Status"),
- paramName: "status",
- type: "select",
- options: uniq(projects.map((project) => project.status)),
- },
- ],
- [t, projectCategories, projects],
- );
-
- const onReset = useCallback(() => {
- setFilteredProjects(projects);
- }, [projects]);
-
- const onProjectClick = useCallback(
- (project: ProjectResultOrDraft) => {
- if (project.isDraft && project.id) {
- router.push(`/projects/create?draftId=${project.id}`);
- } else if (Boolean(project.mainProject)) {
- router.push(`/projects/editSub?id=${project.id}`);
- } else router.push(`/projects/edit?id=${project.id}`);
- },
- [router],
- );
-
- const onProjectCopyClick = useCallback(
- (project: ProjectResultOrDraft) => {
- if (!project.isDraft) {
- if (Boolean(project.mainProject)) {
- router.push(`/projects/copySub?id=${project.id}`);
- } else router.push(`/projects/copy?id=${project.id}`);
- }
- },
- [router],
- );
-
- const onProjectStatusClick = useCallback(
- (project: ProjectResultOrDraft) => {
- const status = project.status.toLocaleLowerCase()
- console.log(status)
-
- if (status && statusList.includes(status)) {
- /* switch (status) {
- case "pending to start":
- router.push(`/projects/edit?id=${project.id}&autoClick=start`);
- break;
- case "on-going":
- router.push(`/projects/edit?id=${project.id}&autoClick=complete`);
- break;
- case "completed":
- router.push(`/projects/edit?id=${project.id}&autoClick=reopen`);
- break;
- } */
- router.push(`/projects/edit?id=${project.id}&autoClick=true`);
- }
- },
- [router],
- );
-
- const statusList = ["pending to start", "on-going","completed"]
- const ignoreStatusList = ["draft", "deleted"]
-
- const columns = useMemo<Column<ProjectResult>[]>(
- () => [
- {
- name: "id",
- label: t("Details"),
- onClick: onProjectClick,
- buttonIcon: <EditNote />,
- disabled: !abilities.includes(MAINTAIN_PROJECT),
- },
- {
- name: "id",
- label: t("Copy"),
- onClick: onProjectCopyClick,
- buttonIcon: <ContentCopyIcon />,
- disabled: !abilities.includes(MAINTAIN_PROJECT),
- disabledRows: {
- status: ["Draft"]
- }
- },
- { name: "code", label: t("Project Code") },
- { name: "name", label: t("Project Name") },
- { name: "category", label: t("Project Category") },
- { name: "team", label: t("Team") },
- { name: "client", label: t("Client") },
- {
- name: "status",
- label: t("Status"),
- // type: "link",
- // onClick: onProjectStatusClick,
- // underlines: ignoreStatusList.reduce((acc, cur) => ({...acc, [cur]: "none"}), {}),
- // colors: ignoreStatusList.reduce((acc, cur) => ({...acc, [cur]: "inherit"}), {}),
- },
- // {
- // name: "status",
- // label: t("Status"),
- // type: "button",
- // onClick: onProjectStatusClick,
- // variants: ignoreStatusList.reduce((acc, cur) => ({...acc, [cur]: "text"}), {}),
- // colors: ignoreStatusList.reduce((acc, cur) => ({...acc, [cur]: "inherit"}), {}),
- // }
- {
- name: "status",
- label: t(""),
- onClick: onProjectStatusClick,
- buttonIcon: <PlayCircleOutlineIcon />,
- disabled: !abilities.includes(MAINTAIN_PROJECT),
- disabledRows: {
- status: ignoreStatusList
- }
- },
- ],
- [t, onProjectClick],
- );
-
- return (
- <>
- <SearchBox
- criteria={searchCriteria}
- onSearch={(query) => {
- setFilteredProjects(
- projects.filter(
- (p) =>
- p.code.toLowerCase().includes(query.code.toLowerCase()) &&
- p.name.toLowerCase().includes(query.name.toLowerCase()) &&
- (query.client === "All" || p.client === query.client) &&
- (query.category === "All" || p.category === query.category) &&
- // (query.team === "All" || p.team === query.team) &&
- (query.team === "All" ||
- query.team.toLowerCase().includes(p.team.toLowerCase())) &&
- (query.status === "All" || p.status === query.status),
- ),
- );
- }}
- onReset={onReset}
- />
- <SearchResults<ProjectResult>
- items={draftAndFilterdProjects}
- columns={columns}
- />
- </>
- );
- };
-
- export default ProjectSearch;
|