import { useRef, useState } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; // icons import { ChevronRight, MoreHorizontal } from "lucide-react"; // constants import { SPREADSHEET_PROPERTY_DETAILS, SPREADSHEET_PROPERTY_LIST } from "constants/spreadsheet"; // components import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; // ui import { ControlLink, Tooltip } from "@plane/ui"; // hooks import useOutsideClickDetector from "hooks/use-outside-click-detector"; import { useEventTracker, useIssueDetail, useProject } from "hooks/store"; // helper import { cn } from "helpers/common.helper"; // types import { IIssueDisplayProperties, TIssue } from "@plane/types"; import { EIssueActions } from "../types"; interface Props { displayProperties: IIssueDisplayProperties; isEstimateEnabled: boolean; quickActions: ( issue: TIssue, customActionButton?: React.ReactElement, portalElement?: HTMLDivElement | null ) => React.ReactNode; canEditProperties: (projectId: string | undefined) => boolean; handleIssues: (issue: TIssue, action: EIssueActions) => Promise; portalElement: React.MutableRefObject; nestingLevel: number; issueId: string; } export const SpreadsheetIssueRow = observer((props: Props) => { const { displayProperties, issueId, isEstimateEnabled, nestingLevel, portalElement, handleIssues, quickActions, canEditProperties, } = props; // router const router = useRouter(); const { workspaceSlug } = router.query; //hooks const { getProjectById } = useProject(); const { peekIssue, setPeekIssue } = useIssueDetail(); const { captureIssueEvent } = useEventTracker(); // states const [isMenuActive, setIsMenuActive] = useState(false); const [isExpanded, setExpanded] = useState(false); const menuActionRef = useRef(null); const handleIssuePeekOverview = (issue: TIssue) => { if (workspaceSlug && issue && issue.project_id && issue.id) setPeekIssue({ workspaceSlug: workspaceSlug.toString(), projectId: issue.project_id, issueId: issue.id }); }; const { subIssues: subIssuesStore, issue } = useIssueDetail(); const issueDetail = issue.getIssueById(issueId); const subIssues = subIssuesStore.subIssuesByIssueId(issueId); const paddingLeft = `${nestingLevel * 54}px`; useOutsideClickDetector(menuActionRef, () => setIsMenuActive(false)); const handleToggleExpand = () => { setExpanded((prevState) => { if (!prevState && workspaceSlug && issueDetail) subIssuesStore.fetchSubIssues(workspaceSlug.toString(), issueDetail.project_id, issueDetail.id); return !prevState; }); }; const customActionButton = (
setIsMenuActive(!isMenuActive)} >
); if (!issueDetail) return null; const disableUserActions = !canEditProperties(issueDetail.project_id); return ( <> {/* first column/ issue name and key column */}
{getProjectById(issueDetail.project_id)?.identifier}-{issueDetail.sequence_id} {canEditProperties(issueDetail.project_id) && ( )}
{issueDetail.sub_issues_count > 0 && (
)}
handleIssuePeekOverview(issueDetail)} className="w-full line-clamp-1 cursor-pointer text-sm text-custom-text-100" >
{issueDetail.name}
{/* Rest of the columns */} {SPREADSHEET_PROPERTY_LIST.map((property) => { const { Column } = SPREADSHEET_PROPERTY_DETAILS[property]; const shouldRenderProperty = property === "estimate" ? isEstimateEnabled : true; return ( , updates: any) => handleIssues({ ...issue, ...data }, EIssueActions.UPDATE).then(() => { captureIssueEvent({ eventName: "Issue updated", payload: { ...issue, ...data, element: "Spreadsheet layout", }, updates: updates, path: router.asPath, }); }) } disabled={disableUserActions} /> ); })} {isExpanded && subIssues && subIssues.length > 0 && subIssues.map((subIssueId: string) => ( ))} ); });