mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge branch 'feat/pagination' of github.com:makeplane/plane into feat/pagination
This commit is contained in:
commit
19fa1c28b9
8
packages/types/src/view-props.d.ts
vendored
8
packages/types/src/view-props.d.ts
vendored
@ -27,10 +27,10 @@ export type TIssueOrderByOptions =
|
|||||||
| "-assignees__first_name"
|
| "-assignees__first_name"
|
||||||
| "labels__name"
|
| "labels__name"
|
||||||
| "-labels__name"
|
| "-labels__name"
|
||||||
| "modules__name"
|
| "issue_module__module__name"
|
||||||
| "-modules__name"
|
| "-issue_module__module__name"
|
||||||
| "cycle__name"
|
| "issue_cycle__cycle__name"
|
||||||
| "-cycle__name"
|
| "-issue_cycle__cycle__name"
|
||||||
| "target_date"
|
| "target_date"
|
||||||
| "-target_date"
|
| "-target_date"
|
||||||
| "estimate_point"
|
| "estimate_point"
|
||||||
|
@ -24,7 +24,7 @@ const RenderIfVisible: React.FC<Props> = (props) => {
|
|||||||
as = "div",
|
as = "div",
|
||||||
children,
|
children,
|
||||||
classNames = "",
|
classNames = "",
|
||||||
alwaysRender = false, //render the children even if it is not visble in root
|
alwaysRender = false, //render the children even if it is not visible in root
|
||||||
placeholderChildren = null, //placeholder children
|
placeholderChildren = null, //placeholder children
|
||||||
pauseHeightUpdateWhileRendering = false, //while this is true the height of the blocks are maintained
|
pauseHeightUpdateWhileRendering = false, //while this is true the height of the blocks are maintained
|
||||||
changingReference, //This is to force render when this reference is changed
|
changingReference, //This is to force render when this reference is changed
|
||||||
@ -48,7 +48,7 @@ const RenderIfVisible: React.FC<Props> = (props) => {
|
|||||||
// } else {
|
// } else {
|
||||||
// setShouldVisible(entries[0].isIntersecting);
|
// setShouldVisible(entries[0].isIntersecting);
|
||||||
// }
|
// }
|
||||||
setShouldVisible(entries[0].isIntersecting);
|
setShouldVisible(entries[entries.length - 1].isIntersecting);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
root: root?.current,
|
root: root?.current,
|
||||||
@ -63,7 +63,7 @@ const RenderIfVisible: React.FC<Props> = (props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [intersectionRef, children, changingReference, root, verticalOffset, horizontalOffset]);
|
}, [intersectionRef, children, root, verticalOffset, horizontalOffset]);
|
||||||
|
|
||||||
//Set height after render
|
//Set height after render
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -179,17 +179,18 @@ export const KanbanGroup = observer((props: IKanbanGroup) => {
|
|||||||
|
|
||||||
{provided.placeholder}
|
{provided.placeholder}
|
||||||
|
|
||||||
{shouldLoadMore && isSubGroup ? (
|
{shouldLoadMore &&
|
||||||
<div
|
(isSubGroup ? (
|
||||||
className="w-full sticky bottom-0 p-3 text-sm text-custom-primary-100 hover:underline cursor-pointer"
|
<div
|
||||||
onClick={() => loadMoreIssues(groupId, sub_group_id)}
|
className="w-full sticky bottom-0 p-3 text-sm text-custom-primary-100 hover:underline cursor-pointer"
|
||||||
>
|
onClick={() => loadMoreIssues(groupId, sub_group_id)}
|
||||||
{" "}
|
>
|
||||||
Load more ↓
|
{" "}
|
||||||
</div>
|
Load more ↓
|
||||||
) : (
|
</div>
|
||||||
<KanbanIssueBlockLoader ref={intersectionRef} />
|
) : (
|
||||||
)}
|
<KanbanIssueBlockLoader ref={intersectionRef} />
|
||||||
|
))}
|
||||||
|
|
||||||
{enableQuickIssueCreate && !disableIssueCreation && (
|
{enableQuickIssueCreate && !disableIssueCreation && (
|
||||||
<div className="w-full bg-custom-background-90 py-0.5 sticky bottom-0">
|
<div className="w-full bg-custom-background-90 py-0.5 sticky bottom-0">
|
||||||
|
@ -83,27 +83,27 @@ export const SPREADSHEET_PROPERTY_DETAILS: {
|
|||||||
},
|
},
|
||||||
modules: {
|
modules: {
|
||||||
title: "Modules",
|
title: "Modules",
|
||||||
ascendingOrderKey: "modules__name",
|
ascendingOrderKey: "issue_module__module__name",
|
||||||
ascendingOrderTitle: "A",
|
ascendingOrderTitle: "A",
|
||||||
descendingOrderKey: "-modules__name",
|
descendingOrderKey: "-issue_module__module__name",
|
||||||
descendingOrderTitle: "Z",
|
descendingOrderTitle: "Z",
|
||||||
icon: DiceIcon,
|
icon: DiceIcon,
|
||||||
Column: SpreadsheetModuleColumn,
|
Column: SpreadsheetModuleColumn,
|
||||||
},
|
},
|
||||||
cycle: {
|
cycle: {
|
||||||
title: "Cycle",
|
title: "Cycle",
|
||||||
ascendingOrderKey: "cycle__name",
|
ascendingOrderKey: "issue_cycle__cycle__name",
|
||||||
ascendingOrderTitle: "A",
|
ascendingOrderTitle: "A",
|
||||||
descendingOrderKey: "-cycle__name",
|
descendingOrderKey: "-issue_cycle__cycle__name",
|
||||||
descendingOrderTitle: "Z",
|
descendingOrderTitle: "Z",
|
||||||
icon: ContrastIcon,
|
icon: ContrastIcon,
|
||||||
Column: SpreadsheetCycleColumn,
|
Column: SpreadsheetCycleColumn,
|
||||||
},
|
},
|
||||||
priority: {
|
priority: {
|
||||||
title: "Priority",
|
title: "Priority",
|
||||||
ascendingOrderKey: "priority",
|
ascendingOrderKey: "-priority",
|
||||||
ascendingOrderTitle: "None",
|
ascendingOrderTitle: "None",
|
||||||
descendingOrderKey: "-priority",
|
descendingOrderKey: "priority",
|
||||||
descendingOrderTitle: "Urgent",
|
descendingOrderTitle: "Urgent",
|
||||||
icon: Signal,
|
icon: Signal,
|
||||||
Column: SpreadsheetPriorityColumn,
|
Column: SpreadsheetPriorityColumn,
|
||||||
|
@ -39,9 +39,9 @@ import isEqual from "date-fns/isEqual";
|
|||||||
export type TIssueDisplayFilterOptions = Exclude<TIssueGroupByOptions, null> | "target_date";
|
export type TIssueDisplayFilterOptions = Exclude<TIssueGroupByOptions, null> | "target_date";
|
||||||
|
|
||||||
export enum EIssueGroupedAction {
|
export enum EIssueGroupedAction {
|
||||||
ADD,
|
ADD = "ADD",
|
||||||
DELETE,
|
DELETE = "DELETE",
|
||||||
REORDER,
|
REORDER = "REORDER",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ALL_ISSUES = "All Issues";
|
export const ALL_ISSUES = "All Issues";
|
||||||
@ -95,10 +95,10 @@ const ISSUE_ORDERBY_KEY: Record<TIssueOrderByOptions, keyof TIssue> = {
|
|||||||
"-assignees__first_name": "assignee_ids",
|
"-assignees__first_name": "assignee_ids",
|
||||||
labels__name: "label_ids",
|
labels__name: "label_ids",
|
||||||
"-labels__name": "label_ids",
|
"-labels__name": "label_ids",
|
||||||
modules__name: "module_ids",
|
issue_module__module__name: "module_ids",
|
||||||
"-modules__name": "module_ids",
|
"-issue_module__module__name": "module_ids",
|
||||||
cycle__name: "cycle_id",
|
issue_cycle__cycle__name: "cycle_id",
|
||||||
"-cycle__name": "cycle_id",
|
"-issue_cycle__cycle__name": "cycle_id",
|
||||||
target_date: "target_date",
|
target_date: "target_date",
|
||||||
"-target_date": "target_date",
|
"-target_date": "target_date",
|
||||||
estimate_point: "estimate_point",
|
estimate_point: "estimate_point",
|
||||||
@ -154,9 +154,14 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
onfetchNexIssues: action.bound,
|
onfetchNexIssues: action.bound,
|
||||||
clear: action.bound,
|
clear: action.bound,
|
||||||
getPaginationData: action.bound,
|
getPaginationData: action.bound,
|
||||||
|
addIssue: action.bound,
|
||||||
|
removeIssueFromList: action.bound,
|
||||||
|
|
||||||
createIssue: action,
|
createIssue: action,
|
||||||
updateIssue: action,
|
updateIssue: action,
|
||||||
|
createDraftIssue: action,
|
||||||
|
updateDraftIssue: action,
|
||||||
|
issueQuickAdd: action.bound,
|
||||||
removeIssue: action,
|
removeIssue: action,
|
||||||
archiveIssue: action,
|
archiveIssue: action,
|
||||||
removeBulkIssues: action,
|
removeBulkIssues: action,
|
||||||
@ -661,7 +666,8 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
|
|
||||||
getDifference = (
|
getDifference = (
|
||||||
current: string[],
|
current: string[],
|
||||||
previous: string[]
|
previous: string[],
|
||||||
|
action?: EIssueGroupedAction.ADD | EIssueGroupedAction.DELETE
|
||||||
): { [EIssueGroupedAction.ADD]: string[]; [EIssueGroupedAction.DELETE]: string[] } => {
|
): { [EIssueGroupedAction.ADD]: string[]; [EIssueGroupedAction.DELETE]: string[] } => {
|
||||||
const ADD = [];
|
const ADD = [];
|
||||||
const DELETE = [];
|
const DELETE = [];
|
||||||
@ -675,7 +681,11 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
DELETE.push(previousValue);
|
DELETE.push(previousValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { [EIssueGroupedAction.ADD]: ADD, [EIssueGroupedAction.DELETE]: DELETE };
|
if (!action) return { [EIssueGroupedAction.ADD]: ADD, [EIssueGroupedAction.DELETE]: DELETE };
|
||||||
|
|
||||||
|
if (action === EIssueGroupedAction.ADD)
|
||||||
|
return { [EIssueGroupedAction.ADD]: [...ADD, ...DELETE], [EIssueGroupedAction.DELETE]: [] };
|
||||||
|
else return { [EIssueGroupedAction.DELETE]: [...ADD, ...DELETE], [EIssueGroupedAction.ADD]: [] };
|
||||||
};
|
};
|
||||||
|
|
||||||
issueDisplayFiltersDefaultData = (groupBy: string | null): string[] => {
|
issueDisplayFiltersDefaultData = (groupBy: string | null): string[] => {
|
||||||
@ -783,7 +793,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
|
|
||||||
issuesSortWithOrderBy = (issueIds: string[], key: TIssueOrderByOptions | undefined): string[] => {
|
issuesSortWithOrderBy = (issueIds: string[], key: TIssueOrderByOptions | undefined): string[] => {
|
||||||
const issues = this.rootIssueStore.issues.getIssuesByIds(issueIds, this.isArchived ? "archived" : "un-archived");
|
const issues = this.rootIssueStore.issues.getIssuesByIds(issueIds, this.isArchived ? "archived" : "un-archived");
|
||||||
const array = orderBy(issues, "created_at", ["asc"]);
|
const array = orderBy(issues, "created_at", ["desc"]);
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "sort_order":
|
case "sort_order":
|
||||||
@ -834,13 +844,13 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
// custom
|
// custom
|
||||||
case "priority": {
|
case "priority": {
|
||||||
const sortArray = ISSUE_PRIORITIES.map((i) => i.key);
|
const sortArray = ISSUE_PRIORITIES.map((i) => i.key);
|
||||||
return this.getIssueIds(
|
return this.getIssueIds(orderBy(array, (currentIssue: TIssue) => indexOf(sortArray, currentIssue.priority)));
|
||||||
orderBy(array, (currentIssue: TIssue) => indexOf(sortArray, currentIssue.priority), ["desc"])
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
case "-priority": {
|
case "-priority": {
|
||||||
const sortArray = ISSUE_PRIORITIES.map((i) => i.key);
|
const sortArray = ISSUE_PRIORITIES.map((i) => i.key);
|
||||||
return this.getIssueIds(orderBy(array, (currentIssue: TIssue) => indexOf(sortArray, currentIssue.priority)));
|
return this.getIssueIds(
|
||||||
|
orderBy(array, (currentIssue: TIssue) => indexOf(sortArray, currentIssue.priority), ["desc"])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// number
|
// number
|
||||||
@ -892,14 +902,14 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
case "modules__name":
|
case "issue_module__module__name":
|
||||||
return this.getIssueIds(
|
return this.getIssueIds(
|
||||||
orderBy(array, [
|
orderBy(array, [
|
||||||
this.getSortOrderToFilterEmptyValues.bind(null, "module_ids"), //preferring sorting based on empty values to always keep the empty values below
|
this.getSortOrderToFilterEmptyValues.bind(null, "module_ids"), //preferring sorting based on empty values to always keep the empty values below
|
||||||
(issue) => this.populateIssueDataForSorting("module_ids", issue["module_ids"], "asc"),
|
(issue) => this.populateIssueDataForSorting("module_ids", issue["module_ids"], "asc"),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
case "-modules__name":
|
case "-issue_module__module__name":
|
||||||
return this.getIssueIds(
|
return this.getIssueIds(
|
||||||
orderBy(
|
orderBy(
|
||||||
array,
|
array,
|
||||||
@ -911,14 +921,14 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
case "cycle__name":
|
case "issue_cycle__cycle__name":
|
||||||
return this.getIssueIds(
|
return this.getIssueIds(
|
||||||
orderBy(array, [
|
orderBy(array, [
|
||||||
this.getSortOrderToFilterEmptyValues.bind(null, "cycle_id"), //preferring sorting based on empty values to always keep the empty values below
|
this.getSortOrderToFilterEmptyValues.bind(null, "cycle_id"), //preferring sorting based on empty values to always keep the empty values below
|
||||||
(issue) => this.populateIssueDataForSorting("cycle_id", issue["cycle_id"], "asc"),
|
(issue) => this.populateIssueDataForSorting("cycle_id", issue["cycle_id"], "asc"),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
case "-cycle__name":
|
case "-issue_cycle__cycle__name":
|
||||||
return this.getIssueIds(
|
return this.getIssueIds(
|
||||||
orderBy(
|
orderBy(
|
||||||
array,
|
array,
|
||||||
@ -1073,7 +1083,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getGroupKey(groupId?: string, subGroupId?: string) {
|
getGroupKey(groupId?: string, subGroupId?: string) {
|
||||||
if (groupId && subGroupId) return `${groupId}_${subGroupId}`;
|
if (groupId && subGroupId && subGroupId !== "null") return `${groupId}_${subGroupId}`;
|
||||||
|
|
||||||
if (groupId) return groupId;
|
if (groupId) return groupId;
|
||||||
|
|
||||||
@ -1099,6 +1109,8 @@ export class BaseIssuesStore implements IBaseIssuesStore {
|
|||||||
for (const groupKey of groupIssuesKeys) {
|
for (const groupKey of groupIssuesKeys) {
|
||||||
if (groupKey.includes(subGroupId)) subGroupCumulativeCount += this.groupedIssueCount[groupKey];
|
if (groupKey.includes(subGroupId)) subGroupCumulativeCount += this.groupedIssueCount[groupKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return subGroupCumulativeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
return get(this.groupedIssueCount, [this.getGroupKey(groupId, subGroupId)]);
|
return get(this.groupedIssueCount, [this.getGroupKey(groupId, subGroupId)]);
|
||||||
|
Loading…
Reference in New Issue
Block a user