mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Virtualization like changes for list
This commit is contained in:
parent
ff14d037c6
commit
8a8e9caae9
@ -119,7 +119,6 @@ export const BaseListRoot = observer((props: IBaseListRoot) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<div className={`relative h-full w-full bg-custom-background-90`}>
|
<div className={`relative h-full w-full bg-custom-background-90`}>
|
||||||
<List
|
<List
|
||||||
issuesMap={issueMap}
|
issuesMap={issueMap}
|
||||||
@ -138,6 +137,5 @@ export const BaseListRoot = observer((props: IBaseListRoot) => {
|
|||||||
addIssuesToView={addIssuesToView}
|
addIssuesToView={addIssuesToView}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -48,15 +48,10 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
|
|||||||
const projectDetails = getProjectById(issue.project_id);
|
const projectDetails = getProjectById(issue.project_id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn("relative flex items-center gap-3 bg-custom-background-100 p-3 text-sm", {
|
||||||
"relative flex items-center gap-3 bg-custom-background-100 p-3 text-sm border border-transparent border-b-custom-border-200 last:border-b-transparent",
|
"border border-custom-primary-70 hover:border-custom-primary-70": peekIssue && peekIssue.issueId === issue.id,
|
||||||
{
|
})}
|
||||||
"border border-custom-primary-70 hover:border-custom-primary-70":
|
|
||||||
peekIssue && peekIssue.issueId === issue.id,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
{displayProperties && displayProperties?.key && (
|
{displayProperties && displayProperties?.key && (
|
||||||
<div className="flex-shrink-0 text-xs font-medium text-custom-text-300">
|
<div className="flex-shrink-0 text-xs font-medium text-custom-text-300">
|
||||||
@ -98,6 +93,5 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// components
|
// components
|
||||||
import { IssueBlocksList, ListQuickAddIssueForm } from "components/issues";
|
import { IssueBlock, IssueBlocksList, ListQuickAddIssueForm } from "components/issues";
|
||||||
// hooks
|
// hooks
|
||||||
import { useLabel, useMember, useProject, useProjectState } from "hooks/store";
|
import { useLabel, useMember, useProject, useProjectState } from "hooks/store";
|
||||||
// types
|
// types
|
||||||
@ -10,12 +10,15 @@ import {
|
|||||||
IIssueDisplayProperties,
|
IIssueDisplayProperties,
|
||||||
TIssueMap,
|
TIssueMap,
|
||||||
TUnGroupedIssues,
|
TUnGroupedIssues,
|
||||||
|
IIssueListRow,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
import { EIssueActions } from "../types";
|
import { EIssueActions } from "../types";
|
||||||
// constants
|
// constants
|
||||||
import { HeaderGroupByCard } from "./headers/group-by-card";
|
import { HeaderGroupByCard } from "./headers/group-by-card";
|
||||||
import { getGroupByColumns } from "../utils";
|
import { getGroupByColumns, getIssueFlatList } from "../utils";
|
||||||
import { TCreateModalStoreTypes } from "constants/issue";
|
import { EIssueListRow, TCreateModalStoreTypes } from "constants/issue";
|
||||||
|
import { useRef } from "react";
|
||||||
|
import RenderIfVisible from "components/core/render-if-visible-HOC";
|
||||||
|
|
||||||
export interface IGroupByList {
|
export interface IGroupByList {
|
||||||
issueIds: TGroupedIssues | TUnGroupedIssues | any;
|
issueIds: TGroupedIssues | TUnGroupedIssues | any;
|
||||||
@ -62,9 +65,11 @@ const GroupByList: React.FC<IGroupByList> = (props) => {
|
|||||||
const label = useLabel();
|
const label = useLabel();
|
||||||
const projectState = useProjectState();
|
const projectState = useProjectState();
|
||||||
|
|
||||||
const list = getGroupByColumns(group_by as GroupByColumnTypes, project, label, projectState, member, true);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
if (!list) return null;
|
const groups = getGroupByColumns(group_by as GroupByColumnTypes, project, label, projectState, member, true);
|
||||||
|
|
||||||
|
if (!groups) return null;
|
||||||
|
|
||||||
const prePopulateQuickAddData = (groupByKey: string | null, value: any) => {
|
const prePopulateQuickAddData = (groupByKey: string | null, value: any) => {
|
||||||
const defaultState = projectState.projectStates?.find((state) => state.default);
|
const defaultState = projectState.projectStates?.find((state) => state.default);
|
||||||
@ -91,59 +96,82 @@ const GroupByList: React.FC<IGroupByList> = (props) => {
|
|||||||
return preloadedData;
|
return preloadedData;
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateEmptyIssueGroups = (issues: TIssue[]) => {
|
const list = getIssueFlatList(groups, issueIds, !!showEmptyGroup);
|
||||||
const issuesCount = issues?.length || 0;
|
|
||||||
if (!showEmptyGroup && issuesCount <= 0) return false;
|
console.log(groups, issueIds, list);
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const is_list = group_by === null ? true : false;
|
const is_list = group_by === null ? true : false;
|
||||||
|
|
||||||
const isGroupByCreatedBy = group_by === "created_by";
|
const isGroupByCreatedBy = group_by === "created_by";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative h-full w-full">
|
<div ref={containerRef} className="relative overflow-auto h-full w-full">
|
||||||
{list &&
|
{list &&
|
||||||
list.length > 0 &&
|
list.length > 0 &&
|
||||||
list.map(
|
list.map((listRow: IIssueListRow) => {
|
||||||
(_list: any) =>
|
switch (listRow.type) {
|
||||||
validateEmptyIssueGroups(is_list ? issueIds : issueIds?.[_list.id]) && (
|
case EIssueListRow.HEADER:
|
||||||
<div key={_list.id} className={`flex flex-shrink-0 flex-col`}>
|
return (
|
||||||
<div className="sticky top-0 z-[2] w-full flex-shrink-0 border-b border-custom-border-200 bg-custom-background-90 px-3 py-1">
|
<div
|
||||||
|
key={listRow.id}
|
||||||
|
className="sticky top-0 z-[2] w-full flex-shrink-0 border-b border-custom-border-200 bg-custom-background-90 px-3 py-1"
|
||||||
|
>
|
||||||
<HeaderGroupByCard
|
<HeaderGroupByCard
|
||||||
icon={_list.icon}
|
icon={listRow.icon}
|
||||||
title={_list.name || ""}
|
title={listRow?.name || ""}
|
||||||
count={is_list ? issueIds?.length || 0 : issueIds?.[_list.id]?.length || 0}
|
count={is_list ? issueIds?.length || 0 : issueIds?.[listRow.id]?.length || 0}
|
||||||
issuePayload={_list.payload}
|
issuePayload={listRow.payload || {}}
|
||||||
disableIssueCreation={disableIssueCreation || isGroupByCreatedBy}
|
disableIssueCreation={disableIssueCreation || isGroupByCreatedBy}
|
||||||
storeType={storeType}
|
storeType={storeType}
|
||||||
addIssuesToView={addIssuesToView}
|
addIssuesToView={addIssuesToView}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
{issueIds && (
|
case EIssueListRow.QUICK_ADD:
|
||||||
<IssueBlocksList
|
if (enableIssueQuickAdd && !disableIssueCreation && !isGroupByCreatedBy)
|
||||||
issueIds={is_list ? issueIds || 0 : issueIds?.[_list.id] || 0}
|
return (
|
||||||
issuesMap={issuesMap}
|
<div
|
||||||
handleIssues={handleIssues}
|
key={`${listRow.id}_${EIssueListRow.QUICK_ADD}`}
|
||||||
quickActions={quickActions}
|
className="sticky bottom-0 z-[1] w-full flex-shrink-0"
|
||||||
displayProperties={displayProperties}
|
>
|
||||||
canEditProperties={canEditProperties}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{enableIssueQuickAdd && !disableIssueCreation && !isGroupByCreatedBy && (
|
|
||||||
<div className="sticky bottom-0 z-[1] w-full flex-shrink-0">
|
|
||||||
<ListQuickAddIssueForm
|
<ListQuickAddIssueForm
|
||||||
prePopulatedData={prePopulateQuickAddData(group_by, _list.id)}
|
prePopulatedData={prePopulateQuickAddData(group_by, listRow.id)}
|
||||||
quickAddCallback={quickAddCallback}
|
quickAddCallback={quickAddCallback}
|
||||||
viewId={viewId}
|
viewId={viewId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
);
|
||||||
|
else return null;
|
||||||
|
case EIssueListRow.NO_ISSUES:
|
||||||
|
const noIssuesRow = listRow as IIssueListRow;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={`${noIssuesRow.id}_${EIssueListRow.NO_ISSUES}`}
|
||||||
|
className="bg-custom-background-100 p-3 text-sm text-custom-text-400"
|
||||||
|
>
|
||||||
|
No issues
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
)}
|
case EIssueListRow.ISSUE:
|
||||||
|
return (
|
||||||
|
<RenderIfVisible
|
||||||
|
key={`${listRow.id}_${listRow.groupId}`}
|
||||||
|
defaultHeight={45}
|
||||||
|
root={containerRef}
|
||||||
|
classNames={"relative border border-transparent border-b-custom-border-200 last:border-b-transparent"}
|
||||||
|
>
|
||||||
|
<IssueBlock
|
||||||
|
issueId={listRow.id}
|
||||||
|
issuesMap={issuesMap}
|
||||||
|
handleIssues={handleIssues}
|
||||||
|
quickActions={quickActions}
|
||||||
|
canEditProperties={canEditProperties}
|
||||||
|
displayProperties={displayProperties}
|
||||||
|
/>
|
||||||
|
</RenderIfVisible>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -209,3 +237,5 @@ export const List: React.FC<IList> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user