[WEB-5599] refactor: enhance Kanban swimlane components with improved props and structure (#8262)
This commit is contained in:
parent
f41e121e58
commit
316856a555
1 changed files with 68 additions and 57 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import type { MutableRefObject } from "react";
|
import type { MutableRefObject } from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
|
// plane imports
|
||||||
import type {
|
import type {
|
||||||
GroupByColumnTypes,
|
GroupByColumnTypes,
|
||||||
IGroupByColumn,
|
IGroupByColumn,
|
||||||
|
|
@ -12,33 +13,32 @@ import type {
|
||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
TIssueOrderByOptions,
|
TIssueOrderByOptions,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
// UI
|
|
||||||
import { Row } from "@plane/ui";
|
import { Row } from "@plane/ui";
|
||||||
// hooks
|
// hooks
|
||||||
import { useIssueStoreType } from "@/hooks/use-issue-layout-store";
|
import { useIssueStoreType } from "@/hooks/use-issue-layout-store";
|
||||||
// components
|
// plane web imports
|
||||||
import { useWorkFlowFDragNDrop } from "@/plane-web/components/workflow";
|
import { useWorkFlowFDragNDrop } from "@/plane-web/components/workflow";
|
||||||
|
// local imports
|
||||||
import type { TRenderQuickActions } from "../list/list-view-types";
|
import type { TRenderQuickActions } from "../list/list-view-types";
|
||||||
import type { GroupDropLocation } from "../utils";
|
import type { GroupDropLocation } from "../utils";
|
||||||
import { getGroupByColumns, isWorkspaceLevel } from "../utils";
|
import { getGroupByColumns, isWorkspaceLevel } from "../utils";
|
||||||
import { KanBan } from "./default";
|
import { KanBan } from "./default";
|
||||||
import { HeaderGroupByCard } from "./headers/group-by-card";
|
import { HeaderGroupByCard } from "./headers/group-by-card";
|
||||||
import { HeaderSubGroupByCard } from "./headers/sub-group-by-card";
|
import { HeaderSubGroupByCard } from "./headers/sub-group-by-card";
|
||||||
// types
|
|
||||||
// constants
|
|
||||||
|
|
||||||
interface ISubGroupSwimlaneHeader {
|
interface ISubGroupSwimlaneHeader {
|
||||||
|
collapsedGroups: TIssueKanbanFilters;
|
||||||
|
group_by: TIssueGroupByOptions | undefined;
|
||||||
getGroupIssueCount: (
|
getGroupIssueCount: (
|
||||||
groupId: string | undefined,
|
groupId: string | undefined,
|
||||||
subGroupId: string | undefined,
|
subGroupId: string | undefined,
|
||||||
isSubGroupCumulative: boolean
|
isSubGroupCumulative: boolean
|
||||||
) => number | undefined;
|
) => number | undefined;
|
||||||
sub_group_by: TIssueGroupByOptions | undefined;
|
|
||||||
group_by: TIssueGroupByOptions | undefined;
|
|
||||||
list: IGroupByColumn[];
|
|
||||||
collapsedGroups: TIssueKanbanFilters;
|
|
||||||
handleCollapsedGroups: (toggle: "group_by" | "sub_group_by", value: string) => void;
|
handleCollapsedGroups: (toggle: "group_by" | "sub_group_by", value: string) => void;
|
||||||
|
isEpic?: boolean;
|
||||||
|
list: IGroupByColumn[];
|
||||||
showEmptyGroup: boolean;
|
showEmptyGroup: boolean;
|
||||||
|
sub_group_by: TIssueGroupByOptions | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const visibilitySubGroupByGroupCount = (subGroupIssueCount: number, showEmptyGroup: boolean): boolean => {
|
const visibilitySubGroupByGroupCount = (subGroupIssueCount: number, showEmptyGroup: boolean): boolean => {
|
||||||
|
|
@ -54,13 +54,14 @@ const visibilitySubGroupByGroupCount = (subGroupIssueCount: number, showEmptyGro
|
||||||
};
|
};
|
||||||
|
|
||||||
const SubGroupSwimlaneHeader = observer(function SubGroupSwimlaneHeader({
|
const SubGroupSwimlaneHeader = observer(function SubGroupSwimlaneHeader({
|
||||||
getGroupIssueCount,
|
|
||||||
sub_group_by,
|
|
||||||
group_by,
|
|
||||||
list,
|
|
||||||
collapsedGroups,
|
collapsedGroups,
|
||||||
|
getGroupIssueCount,
|
||||||
|
group_by,
|
||||||
handleCollapsedGroups,
|
handleCollapsedGroups,
|
||||||
|
isEpic = false,
|
||||||
|
list,
|
||||||
showEmptyGroup,
|
showEmptyGroup,
|
||||||
|
sub_group_by,
|
||||||
}: ISubGroupSwimlaneHeader) {
|
}: ISubGroupSwimlaneHeader) {
|
||||||
const { getIsWorkflowWorkItemCreationDisabled } = useWorkFlowFDragNDrop(group_by, sub_group_by);
|
const { getIsWorkflowWorkItemCreationDisabled } = useWorkFlowFDragNDrop(group_by, sub_group_by);
|
||||||
|
|
||||||
|
|
@ -88,6 +89,7 @@ const SubGroupSwimlaneHeader = observer(function SubGroupSwimlaneHeader({
|
||||||
handleCollapsedGroups={handleCollapsedGroups}
|
handleCollapsedGroups={handleCollapsedGroups}
|
||||||
issuePayload={_list.payload}
|
issuePayload={_list.payload}
|
||||||
disableIssueCreation={getIsWorkflowWorkItemCreationDisabled(_list.id)}
|
disableIssueCreation={getIsWorkflowWorkItemCreationDisabled(_list.id)}
|
||||||
|
isEpic={isEpic}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -97,53 +99,55 @@ const SubGroupSwimlaneHeader = observer(function SubGroupSwimlaneHeader({
|
||||||
});
|
});
|
||||||
|
|
||||||
interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader {
|
interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader {
|
||||||
issuesMap: IIssueMap;
|
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
|
||||||
groupedIssueIds: TGroupedIssues | TSubGroupedIssues;
|
canEditProperties: (projectId: string | undefined) => boolean;
|
||||||
|
collapsedGroups: TIssueKanbanFilters;
|
||||||
|
disableIssueCreation?: boolean;
|
||||||
|
displayProperties: IIssueDisplayProperties | undefined;
|
||||||
|
enableQuickIssueCreate: boolean;
|
||||||
getGroupIssueCount: (
|
getGroupIssueCount: (
|
||||||
groupId: string | undefined,
|
groupId: string | undefined,
|
||||||
subGroupId: string | undefined,
|
subGroupId: string | undefined,
|
||||||
isSubGroupCumulative: boolean
|
isSubGroupCumulative: boolean
|
||||||
) => number | undefined;
|
) => number | undefined;
|
||||||
showEmptyGroup: boolean;
|
groupedIssueIds: TGroupedIssues | TSubGroupedIssues;
|
||||||
displayProperties: IIssueDisplayProperties | undefined;
|
|
||||||
updateIssue: ((projectId: string | null, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
|
||||||
quickActions: TRenderQuickActions;
|
|
||||||
collapsedGroups: TIssueKanbanFilters;
|
|
||||||
handleCollapsedGroups: (toggle: "group_by" | "sub_group_by", value: string) => void;
|
handleCollapsedGroups: (toggle: "group_by" | "sub_group_by", value: string) => void;
|
||||||
handleOnDrop: (source: GroupDropLocation, destination: GroupDropLocation) => Promise<void>;
|
handleOnDrop: (source: GroupDropLocation, destination: GroupDropLocation) => Promise<void>;
|
||||||
disableIssueCreation?: boolean;
|
isEpic?: boolean;
|
||||||
enableQuickIssueCreate: boolean;
|
issuesMap: IIssueMap;
|
||||||
|
loadMoreIssues: (groupId?: string, subGroupId?: string) => void;
|
||||||
orderBy: TIssueOrderByOptions | undefined;
|
orderBy: TIssueOrderByOptions | undefined;
|
||||||
canEditProperties: (projectId: string | undefined) => boolean;
|
quickActions: TRenderQuickActions;
|
||||||
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
|
|
||||||
quickAddCallback?: (projectId: string | null | undefined, data: TIssue) => Promise<TIssue | undefined>;
|
quickAddCallback?: (projectId: string | null | undefined, data: TIssue) => Promise<TIssue | undefined>;
|
||||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||||
loadMoreIssues: (groupId?: string, subGroupId?: string) => void;
|
showEmptyGroup: boolean;
|
||||||
|
updateIssue: ((projectId: string | null, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SubGroupSwimlane = observer(function SubGroupSwimlane(props: ISubGroupSwimlane) {
|
const SubGroupSwimlane = observer(function SubGroupSwimlane(props: ISubGroupSwimlane) {
|
||||||
const {
|
const {
|
||||||
issuesMap,
|
|
||||||
groupedIssueIds,
|
|
||||||
getGroupIssueCount,
|
|
||||||
sub_group_by,
|
|
||||||
group_by,
|
|
||||||
list,
|
|
||||||
updateIssue,
|
|
||||||
quickActions,
|
|
||||||
displayProperties,
|
|
||||||
collapsedGroups,
|
|
||||||
handleCollapsedGroups,
|
|
||||||
loadMoreIssues,
|
|
||||||
showEmptyGroup,
|
|
||||||
enableQuickIssueCreate,
|
|
||||||
disableIssueCreation,
|
|
||||||
canEditProperties,
|
|
||||||
addIssuesToView,
|
addIssuesToView,
|
||||||
|
canEditProperties,
|
||||||
|
collapsedGroups,
|
||||||
|
disableIssueCreation,
|
||||||
|
displayProperties,
|
||||||
|
enableQuickIssueCreate,
|
||||||
|
getGroupIssueCount,
|
||||||
|
group_by,
|
||||||
|
groupedIssueIds,
|
||||||
|
handleCollapsedGroups,
|
||||||
|
handleOnDrop,
|
||||||
|
isEpic = false,
|
||||||
|
issuesMap,
|
||||||
|
list,
|
||||||
|
loadMoreIssues,
|
||||||
|
orderBy,
|
||||||
|
quickActions,
|
||||||
quickAddCallback,
|
quickAddCallback,
|
||||||
scrollableContainerRef,
|
scrollableContainerRef,
|
||||||
handleOnDrop,
|
showEmptyGroup,
|
||||||
orderBy,
|
sub_group_by,
|
||||||
|
updateIssue,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const visibilitySubGroupBy = (
|
const visibilitySubGroupBy = (
|
||||||
|
|
@ -214,6 +218,7 @@ const SubGroupSwimlane = observer(function SubGroupSwimlane(props: ISubGroupSwim
|
||||||
orderBy={orderBy}
|
orderBy={orderBy}
|
||||||
isDropDisabled={_list.isDropDisabled}
|
isDropDisabled={_list.isDropDisabled}
|
||||||
dropErrorMessage={_list.dropErrorMessage}
|
dropErrorMessage={_list.dropErrorMessage}
|
||||||
|
isEpic={isEpic}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -225,30 +230,31 @@ const SubGroupSwimlane = observer(function SubGroupSwimlane(props: ISubGroupSwim
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface IKanBanSwimLanes {
|
export interface IKanBanSwimLanes {
|
||||||
issuesMap: IIssueMap;
|
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
|
||||||
groupedIssueIds: TGroupedIssues | TSubGroupedIssues;
|
canEditProperties: (projectId: string | undefined) => boolean;
|
||||||
|
collapsedGroups: TIssueKanbanFilters;
|
||||||
|
disableIssueCreation?: boolean;
|
||||||
|
displayProperties: IIssueDisplayProperties | undefined;
|
||||||
|
enableQuickIssueCreate: boolean;
|
||||||
getGroupIssueCount: (
|
getGroupIssueCount: (
|
||||||
groupId: string | undefined,
|
groupId: string | undefined,
|
||||||
subGroupId: string | undefined,
|
subGroupId: string | undefined,
|
||||||
isSubGroupCumulative: boolean
|
isSubGroupCumulative: boolean
|
||||||
) => number | undefined;
|
) => number | undefined;
|
||||||
displayProperties: IIssueDisplayProperties | undefined;
|
|
||||||
sub_group_by: TIssueGroupByOptions | undefined;
|
|
||||||
group_by: TIssueGroupByOptions | undefined;
|
group_by: TIssueGroupByOptions | undefined;
|
||||||
updateIssue: ((projectId: string | null, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
groupedIssueIds: TGroupedIssues | TSubGroupedIssues;
|
||||||
quickActions: TRenderQuickActions;
|
|
||||||
collapsedGroups: TIssueKanbanFilters;
|
|
||||||
handleCollapsedGroups: (toggle: "group_by" | "sub_group_by", value: string) => void;
|
handleCollapsedGroups: (toggle: "group_by" | "sub_group_by", value: string) => void;
|
||||||
loadMoreIssues: (groupId?: string, subGroupId?: string) => void;
|
|
||||||
showEmptyGroup: boolean;
|
|
||||||
handleOnDrop: (source: GroupDropLocation, destination: GroupDropLocation) => Promise<void>;
|
handleOnDrop: (source: GroupDropLocation, destination: GroupDropLocation) => Promise<void>;
|
||||||
disableIssueCreation?: boolean;
|
isEpic?: boolean;
|
||||||
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
|
issuesMap: IIssueMap;
|
||||||
enableQuickIssueCreate: boolean;
|
loadMoreIssues: (groupId?: string, subGroupId?: string) => void;
|
||||||
quickAddCallback?: (projectId: string | null | undefined, data: TIssue) => Promise<TIssue | undefined>;
|
|
||||||
canEditProperties: (projectId: string | undefined) => boolean;
|
|
||||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
|
||||||
orderBy: TIssueOrderByOptions | undefined;
|
orderBy: TIssueOrderByOptions | undefined;
|
||||||
|
quickActions: TRenderQuickActions;
|
||||||
|
quickAddCallback?: (projectId: string | null | undefined, data: TIssue) => Promise<TIssue | undefined>;
|
||||||
|
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||||
|
showEmptyGroup: boolean;
|
||||||
|
sub_group_by: TIssueGroupByOptions | undefined;
|
||||||
|
updateIssue: ((projectId: string | null, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const KanBanSwimLanes = observer(function KanBanSwimLanes(props: IKanBanSwimLanes) {
|
export const KanBanSwimLanes = observer(function KanBanSwimLanes(props: IKanBanSwimLanes) {
|
||||||
|
|
@ -273,6 +279,7 @@ export const KanBanSwimLanes = observer(function KanBanSwimLanes(props: IKanBanS
|
||||||
addIssuesToView,
|
addIssuesToView,
|
||||||
quickAddCallback,
|
quickAddCallback,
|
||||||
scrollableContainerRef,
|
scrollableContainerRef,
|
||||||
|
isEpic = false,
|
||||||
} = props;
|
} = props;
|
||||||
// store hooks
|
// store hooks
|
||||||
const storeType = useIssueStoreType();
|
const storeType = useIssueStoreType();
|
||||||
|
|
@ -281,11 +288,13 @@ export const KanBanSwimLanes = observer(function KanBanSwimLanes(props: IKanBanS
|
||||||
groupBy: group_by as GroupByColumnTypes,
|
groupBy: group_by as GroupByColumnTypes,
|
||||||
includeNone: true,
|
includeNone: true,
|
||||||
isWorkspaceLevel: isWorkspaceLevel(storeType),
|
isWorkspaceLevel: isWorkspaceLevel(storeType),
|
||||||
|
isEpic: isEpic,
|
||||||
});
|
});
|
||||||
const subGroupByList = getGroupByColumns({
|
const subGroupByList = getGroupByColumns({
|
||||||
groupBy: sub_group_by as GroupByColumnTypes,
|
groupBy: sub_group_by as GroupByColumnTypes,
|
||||||
includeNone: true,
|
includeNone: true,
|
||||||
isWorkspaceLevel: isWorkspaceLevel(storeType),
|
isWorkspaceLevel: isWorkspaceLevel(storeType),
|
||||||
|
isEpic: isEpic,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!groupByList || !subGroupByList) return null;
|
if (!groupByList || !subGroupByList) return null;
|
||||||
|
|
@ -301,6 +310,7 @@ export const KanBanSwimLanes = observer(function KanBanSwimLanes(props: IKanBanS
|
||||||
handleCollapsedGroups={handleCollapsedGroups}
|
handleCollapsedGroups={handleCollapsedGroups}
|
||||||
list={groupByList}
|
list={groupByList}
|
||||||
showEmptyGroup={showEmptyGroup}
|
showEmptyGroup={showEmptyGroup}
|
||||||
|
isEpic={isEpic}
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
|
|
@ -327,6 +337,7 @@ export const KanBanSwimLanes = observer(function KanBanSwimLanes(props: IKanBanS
|
||||||
canEditProperties={canEditProperties}
|
canEditProperties={canEditProperties}
|
||||||
quickAddCallback={quickAddCallback}
|
quickAddCallback={quickAddCallback}
|
||||||
scrollableContainerRef={scrollableContainerRef}
|
scrollableContainerRef={scrollableContainerRef}
|
||||||
|
isEpic={isEpic}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue