import React, { useRef } from "react"; import { observer } from "mobx-react-lite"; // types import { TIssue, IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types"; // components import { LogoSpinner } from "@/components/common"; import { MultipleSelectGroup } from "@/components/core"; import { IssueBulkOperationsRoot, SpreadsheetQuickAddIssueForm } from "@/components/issues"; // constants import { SPREADSHEET_PROPERTY_LIST, SPREADSHEET_SELECT_GROUP } from "@/constants/spreadsheet"; // hooks import { useProject } from "@/hooks/store"; // types import { TRenderQuickActions } from "../list/list-view-types"; import { SpreadsheetTable } from "./spreadsheet-table"; type Props = { displayProperties: IIssueDisplayProperties; displayFilters: IIssueDisplayFilterOptions; handleDisplayFilterUpdate: (data: Partial<IIssueDisplayFilterOptions>) => void; issueIds: string[] | undefined; quickActions: TRenderQuickActions; updateIssue: ((projectId: string | null, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined; openIssuesListModal?: (() => void) | null; quickAddCallback?: (projectId: string | null | undefined, data: TIssue) => Promise<TIssue | undefined>; canEditProperties: (projectId: string | undefined) => boolean; canLoadMoreIssues: boolean; loadMoreIssues: () => void; enableQuickCreateIssue?: boolean; disableIssueCreation?: boolean; isWorkspaceLevel?: boolean; }; export const SpreadsheetView: React.FC<Props> = observer((props) => { const { displayProperties, displayFilters, handleDisplayFilterUpdate, issueIds, quickActions, updateIssue, quickAddCallback, canEditProperties, enableQuickCreateIssue, disableIssueCreation, canLoadMoreIssues, loadMoreIssues, isWorkspaceLevel = false, } = props; // refs const containerRef = useRef<HTMLTableElement | null>(null); const portalRef = useRef<HTMLDivElement | null>(null); const { currentProjectDetails } = useProject(); const isEstimateEnabled: boolean = currentProjectDetails?.estimate !== null; const spreadsheetColumnsList = isWorkspaceLevel ? SPREADSHEET_PROPERTY_LIST : SPREADSHEET_PROPERTY_LIST.filter((property) => { if (property === "cycle" && !currentProjectDetails?.cycle_view) return false; if (property === "modules" && !currentProjectDetails?.module_view) return false; return true; }); if (!issueIds || issueIds.length === 0) return ( <div className="grid h-full w-full place-items-center"> <LogoSpinner /> </div> ); return ( <div className="relative flex h-full w-full flex-col overflow-x-hidden whitespace-nowrap rounded-lg bg-custom-background-200 text-custom-text-200"> <div ref={portalRef} className="spreadsheet-menu-portal" /> <MultipleSelectGroup containerRef={containerRef} entities={{ [SPREADSHEET_SELECT_GROUP]: issueIds, }} disabled > {(helpers) => ( <> <div ref={containerRef} className="vertical-scrollbar horizontal-scrollbar scrollbar-lg h-full w-full"> <SpreadsheetTable displayProperties={displayProperties} displayFilters={displayFilters} handleDisplayFilterUpdate={handleDisplayFilterUpdate} issueIds={issueIds} isEstimateEnabled={isEstimateEnabled} portalElement={portalRef} quickActions={quickActions} updateIssue={updateIssue} canEditProperties={canEditProperties} containerRef={containerRef} canLoadMoreIssues={canLoadMoreIssues} loadMoreIssues={loadMoreIssues} spreadsheetColumnsList={spreadsheetColumnsList} selectionHelpers={helpers} /> </div> <div className="border-t border-custom-border-100"> <div className="z-5 sticky bottom-0 left-0 mb-3"> {enableQuickCreateIssue && !disableIssueCreation && ( <SpreadsheetQuickAddIssueForm formKey="name" quickAddCallback={quickAddCallback}/> )} </div> </div> <IssueBulkOperationsRoot selectionHelpers={helpers} /> </> )} </MultipleSelectGroup> </div> ); });