"use client"; import React, { useRef, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // plane imports import { Plus, Search } from "lucide-react"; import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { Tooltip } from "@plane/propel/tooltip"; import { copyUrlToClipboard, orderJoinedProjects } from "@plane/utils"; // components import { CreateProjectModal } from "@/components/project/create-project-modal"; import { SidebarProjectsListItem } from "@/components/workspace/sidebar/projects-list-item"; // hooks import { useAppTheme } from "@/hooks/store/use-app-theme"; import { useProject } from "@/hooks/store/use-project"; import { useUserPermissions } from "@/hooks/store/user"; import type { TProject } from "@/plane-web/types"; import { ExtendedSidebarWrapper } from "./extended-sidebar-wrapper"; export const ExtendedProjectSidebar = observer(() => { // refs const extendedProjectSidebarRef = useRef(null); const [searchQuery, setSearchQuery] = useState(""); // states const [isProjectModalOpen, setIsProjectModalOpen] = useState(false); // routers const { workspaceSlug } = useParams(); // store hooks const { t } = useTranslation(); const { isExtendedProjectSidebarOpened, toggleExtendedProjectSidebar } = useAppTheme(); const { getPartialProjectById, joinedProjectIds: joinedProjects, updateProjectView } = useProject(); const { allowPermissions } = useUserPermissions(); const handleOnProjectDrop = ( sourceId: string | undefined, destinationId: string | undefined, shouldDropAtEnd: boolean ) => { if (!sourceId || !destinationId || !workspaceSlug) return; if (sourceId === destinationId) return; const joinedProjectsList: TProject[] = []; joinedProjects.map((projectId) => { const projectDetails = getPartialProjectById(projectId); if (projectDetails) joinedProjectsList.push(projectDetails); }); const sourceIndex = joinedProjects.indexOf(sourceId); const destinationIndex = shouldDropAtEnd ? joinedProjects.length : joinedProjects.indexOf(destinationId); if (joinedProjectsList.length <= 0) return; const updatedSortOrder = orderJoinedProjects(sourceIndex, destinationIndex, sourceId, joinedProjectsList); if (updatedSortOrder != undefined) updateProjectView(workspaceSlug.toString(), sourceId, { sort_order: updatedSortOrder }).catch(() => { setToast({ type: TOAST_TYPE.ERROR, title: t("error"), message: t("something_went_wrong"), }); }); }; // filter projects based on search query const filteredProjects = joinedProjects.filter((projectId) => { const project = getPartialProjectById(projectId); if (!project) return false; return project.name.toLowerCase().includes(searchQuery.toLowerCase()) || project.identifier.includes(searchQuery); }); // auth const isAuthorizedUser = allowPermissions( [EUserPermissions.ADMIN, EUserPermissions.MEMBER], EUserPermissionsLevel.WORKSPACE ); const handleClose = () => toggleExtendedProjectSidebar(false); const handleCopyText = (projectId: string) => { copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/issues`).then(() => { setToast({ type: TOAST_TYPE.SUCCESS, title: t("link_copied"), message: t("project_link_copied_to_clipboard"), }); }); }; return ( <> {workspaceSlug && ( setIsProjectModalOpen(false)} setToFavorite={false} workspaceSlug={workspaceSlug.toString()} /> )}
Projects {isAuthorizedUser && ( )}
setSearchQuery(e.target.value)} />
{filteredProjects.map((projectId, index) => ( handleCopyText(projectId)} projectListType={"JOINED"} disableDrag={false} disableDrop={false} isLastChild={index === joinedProjects.length - 1} handleOnProjectDrop={handleOnProjectDrop} renderInExtendedSidebar /> ))}
); });