import { MutableRefObject } from "react"; import { observer } from "mobx-react-lite"; import { GroupByColumnTypes, IGroupByColumn, TGroupedIssues, TIssue, IIssueDisplayProperties, IIssueMap, TSubGroupedIssues, TIssueKanbanFilters, TIssueGroupByOptions, TIssueOrderByOptions, } from "@plane/types"; // hooks import { useCycle, useLabel, useMember, useModule, useProject, useProjectState } from "@/hooks/store"; import { useIssueStoreType } from "@/hooks/use-issue-layout-store"; // components import { TRenderQuickActions } from "../list/list-view-types"; import { getGroupByColumns, isWorkspaceLevel, GroupDropLocation } from "../utils"; import { KanBan } from "./default"; import { HeaderGroupByCard } from "./headers/group-by-card"; import { HeaderSubGroupByCard } from "./headers/sub-group-by-card"; // types // constants interface ISubGroupSwimlaneHeader { getGroupIssueCount: ( groupId: string | undefined, subGroupId: string | undefined, isSubGroupCumulative: boolean ) => number | undefined; sub_group_by: TIssueGroupByOptions | undefined; group_by: TIssueGroupByOptions | undefined; list: IGroupByColumn[]; kanbanFilters: TIssueKanbanFilters; handleKanbanFilters: (toggle: "group_by" | "sub_group_by", value: string) => void; showEmptyGroup: boolean; } const visibilitySubGroupByGroupCount = (subGroupIssueCount: number, showEmptyGroup: boolean): boolean => { let subGroupHeaderVisibility = true; if (showEmptyGroup) subGroupHeaderVisibility = true; else { if (subGroupIssueCount > 0) subGroupHeaderVisibility = true; else subGroupHeaderVisibility = false; } return subGroupHeaderVisibility; }; const SubGroupSwimlaneHeader: React.FC = observer( ({ getGroupIssueCount, sub_group_by, group_by, list, kanbanFilters, handleKanbanFilters, showEmptyGroup }) => (
{list && list.length > 0 && list.map((_list: IGroupByColumn) => { const groupCount = getGroupIssueCount(_list?.id, undefined, false) ?? 0; const subGroupByVisibilityToggle = visibilitySubGroupByGroupCount(groupCount, showEmptyGroup); if (subGroupByVisibilityToggle === false) return <>; return (
); })}
) ); interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader { issuesMap: IIssueMap; groupedIssueIds: TGroupedIssues | TSubGroupedIssues; getGroupIssueCount: ( groupId: string | undefined, subGroupId: string | undefined, isSubGroupCumulative: boolean ) => number | undefined; showEmptyGroup: boolean; displayProperties: IIssueDisplayProperties | undefined; updateIssue: ((projectId: string | null, issueId: string, data: Partial) => Promise) | undefined; quickActions: TRenderQuickActions; kanbanFilters: TIssueKanbanFilters; handleKanbanFilters: (toggle: "group_by" | "sub_group_by", value: string) => void; handleOnDrop: (source: GroupDropLocation, destination: GroupDropLocation) => Promise; disableIssueCreation?: boolean; enableQuickIssueCreate: boolean; orderBy: TIssueOrderByOptions | undefined; canEditProperties: (projectId: string | undefined) => boolean; addIssuesToView?: (issueIds: string[]) => Promise; quickAddCallback?: (projectId: string | null | undefined, data: TIssue) => Promise; scrollableContainerRef?: MutableRefObject; loadMoreIssues: (groupId?: string, subGroupId?: string) => void; } const SubGroupSwimlane: React.FC = observer((props) => { const { issuesMap, groupedIssueIds, getGroupIssueCount, sub_group_by, group_by, list, updateIssue, quickActions, displayProperties, kanbanFilters, handleKanbanFilters, loadMoreIssues, showEmptyGroup, enableQuickIssueCreate, canEditProperties, addIssuesToView, quickAddCallback, scrollableContainerRef, handleOnDrop, orderBy, } = props; const visibilitySubGroupBy = ( _list: IGroupByColumn, subGroupCount: number ): { showGroup: boolean; showIssues: boolean } => { const subGroupVisibility = { showGroup: true, showIssues: true, }; if (showEmptyGroup) subGroupVisibility.showGroup = true; else { if (subGroupCount > 0) subGroupVisibility.showGroup = true; else subGroupVisibility.showGroup = false; } if (kanbanFilters?.sub_group_by.includes(_list.id)) subGroupVisibility.showIssues = false; return subGroupVisibility; }; return (
{list && list.length > 0 && list.map((_list: IGroupByColumn) => { const issueCount = getGroupIssueCount(undefined, _list.id, true) ?? 0; const subGroupByVisibilityToggle = visibilitySubGroupBy(_list, issueCount); if (subGroupByVisibilityToggle.showGroup === false) return <>; return (
{subGroupByVisibilityToggle.showIssues && (
getGroupIssueCount(groupByListId, _list.id, true) ?? 0 } />
)}
); })}
); }); export interface IKanBanSwimLanes { issuesMap: IIssueMap; groupedIssueIds: TGroupedIssues | TSubGroupedIssues; getGroupIssueCount: ( groupId: string | undefined, subGroupId: string | undefined, isSubGroupCumulative: boolean ) => number | undefined; displayProperties: IIssueDisplayProperties | undefined; sub_group_by: TIssueGroupByOptions | undefined; group_by: TIssueGroupByOptions | undefined; updateIssue: ((projectId: string | null, issueId: string, data: Partial) => Promise) | undefined; quickActions: TRenderQuickActions; kanbanFilters: TIssueKanbanFilters; handleKanbanFilters: (toggle: "group_by" | "sub_group_by", value: string) => void; loadMoreIssues: (groupId?: string, subGroupId?: string) => void; showEmptyGroup: boolean; handleOnDrop: (source: GroupDropLocation, destination: GroupDropLocation) => Promise; disableIssueCreation?: boolean; addIssuesToView?: (issueIds: string[]) => Promise; enableQuickIssueCreate: boolean; quickAddCallback?: (projectId: string | null | undefined, data: TIssue) => Promise; canEditProperties: (projectId: string | undefined) => boolean; scrollableContainerRef?: MutableRefObject; orderBy: TIssueOrderByOptions | undefined; } export const KanBanSwimLanes: React.FC = observer((props) => { const { issuesMap, groupedIssueIds, getGroupIssueCount, displayProperties, sub_group_by, group_by, orderBy, updateIssue, quickActions, kanbanFilters, handleKanbanFilters, loadMoreIssues, showEmptyGroup, handleOnDrop, disableIssueCreation, enableQuickIssueCreate, canEditProperties, addIssuesToView, quickAddCallback, scrollableContainerRef, } = props; const storeType = useIssueStoreType(); const member = useMember(); const project = useProject(); const label = useLabel(); const cycle = useCycle(); const projectModule = useModule(); const projectState = useProjectState(); const groupByList = getGroupByColumns( group_by as GroupByColumnTypes, project, cycle, projectModule, label, projectState, member, true, isWorkspaceLevel(storeType) ); const subGroupByList = getGroupByColumns( sub_group_by as GroupByColumnTypes, project, cycle, projectModule, label, projectState, member, true, isWorkspaceLevel(storeType) ); if (!groupByList || !subGroupByList) return null; return (
{sub_group_by && ( )}
); });