/** * Copyright (c) 2023-present Plane Software, Inc. and contributors * SPDX-License-Identifier: AGPL-3.0-only * See the LICENSE file for details. */ import { useCallback, useEffect } from "react"; import { observer } from "mobx-react"; import { PanelLeft } from "lucide-react"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { IconButton } from "@plane/propel/icon-button"; import { ChevronDownIcon, ChevronUpIcon, LinkIcon, NewTabIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TExternalContourRequest, TNameDescriptionLoader } from "@plane/types"; import { ControlLink, Header, Row } from "@plane/ui"; import { copyUrlToClipboard, generateWorkItemLink } from "@plane/utils"; import { NameDescriptionUpdateStatus } from "@/components/issues/issue-update-status"; import { useProject } from "@/hooks/store/use-project"; import { useProjectExternalContours } from "@/hooks/store/use-project-external-contours"; import { useAppRouter } from "@/hooks/use-app-router"; import { ExternalContourStatePill } from "./state-pill"; type Props = { workspaceSlug: string; sourceProjectId: string; contourRequest: TExternalContourRequest; isSubmitting: TNameDescriptionLoader; isMobileSidebar: boolean; setIsMobileSidebar: (value: boolean) => void; }; export const ExternalContoursIssueActionsHeader = observer(function ExternalContoursIssueActionsHeader(props: Props) { const { workspaceSlug, sourceProjectId, contourRequest, isSubmitting, isMobileSidebar, setIsMobileSidebar } = props; const { t } = useTranslation(); const router = useAppRouter(); const { currentTab, filteredRequestIds } = useProjectExternalContours(); const { getProjectById } = useProject(); const issue = contourRequest.issue; const currentRequestId = contourRequest.id; const redirectToRelativeIssue = useCallback( (direction: "next" | "prev") => { if (!filteredRequestIds || !currentRequestId) return; const currentIssueIndex = filteredRequestIds.findIndex((requestId) => requestId === currentRequestId); const nextIssueIndex = direction === "next" ? (currentIssueIndex + 1) % filteredRequestIds.length : (currentIssueIndex - 1 + filteredRequestIds.length) % filteredRequestIds.length; const nextIssueId = filteredRequestIds[nextIssueIndex]; if (!nextIssueId) return; router.push(`/${workspaceSlug}/projects/${sourceProjectId}/external-contours?currentTab=${currentTab}&inboxIssueId=${nextIssueId}`); }, [currentRequestId, currentTab, filteredRequestIds, router, sourceProjectId, workspaceSlug] ); useEffect(() => { const onKeyDown = (event: KeyboardEvent) => { if (event.key === "ArrowUp") redirectToRelativeIssue("prev"); if (event.key === "ArrowDown") redirectToRelativeIssue("next"); }; document.addEventListener("keydown", onKeyDown); return () => document.removeEventListener("keydown", onKeyDown); }, [redirectToRelativeIssue]); const targetProjectIdentifier = issue.project_detail?.identifier || getProjectById(issue.project_id || "")?.identifier; const workItemLink = generateWorkItemLink({ workspaceSlug: workspaceSlug?.toString(), projectId: issue.project_id, issueId: issue.id, projectIdentifier: targetProjectIdentifier, sequenceId: issue.sequence_id, }); const handleCopyLink = () => copyUrlToClipboard(workItemLink).then(() => setToast({ type: TOAST_TYPE.SUCCESS, title: t("common.link_copied"), message: t("common.copied_to_clipboard"), }) ); return ( <> {issue?.project_id && issue.sequence_id && ( {targetProjectIdentifier}-{issue.sequence_id} )} redirectToRelativeIssue("prev")} /> redirectToRelativeIssue("next")} /> } onClick={handleCopyLink}> {t("external_contours_page.actions.copy")} router.push(workItemLink)} target="_self"> }> {t("external_contours_page.actions.open")} setIsMobileSidebar(!isMobileSidebar)} className={`my-auto mr-2 h-4 w-4 flex-shrink-0 ${isMobileSidebar ? "text-accent-primary" : "text-secondary"}`} /> router.push(workItemLink)} target="_self"> {t("external_contours_page.actions.open")} > ); });