mirror of
https://github.com/makeplane/plane.git
synced 2025-12-25 16:19:43 +01:00
[WEB-1603] fix: load more issues when issues are deleted (#4830)
* fix load more issues when issues are deleted * fix build
This commit is contained in:
@@ -17,6 +17,7 @@ import { EInboxIssueCurrentTab } from "@/helpers/inbox.helper";
|
||||
// hooks
|
||||
import { useProject, useProjectInbox } from "@/hooks/store";
|
||||
import { useIntersectionObserver } from "@/hooks/use-intersection-observer";
|
||||
import { useIssuesStore } from "@/hooks/use-issue-layout-store";
|
||||
|
||||
type IInboxSidebarProps = {
|
||||
workspaceSlug: string;
|
||||
@@ -51,6 +52,9 @@ export const InboxSidebar: FC<IInboxSidebarProps> = observer((props) => {
|
||||
fetchInboxPaginationIssues,
|
||||
getAppliedFiltersCount,
|
||||
} = useProjectInbox();
|
||||
const {
|
||||
issues: { getIssueLoader },
|
||||
} = useIssuesStore();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
@@ -59,8 +63,10 @@ export const InboxSidebar: FC<IInboxSidebarProps> = observer((props) => {
|
||||
fetchInboxPaginationIssues(workspaceSlug.toString(), projectId.toString());
|
||||
}, [workspaceSlug, projectId, fetchInboxPaginationIssues]);
|
||||
|
||||
const isPaginating = !!getIssueLoader();
|
||||
|
||||
// page observer
|
||||
useIntersectionObserver(containerRef, elementRef, fetchNextPages, "20%");
|
||||
useIntersectionObserver(containerRef, isPaginating ? null : elementRef, fetchNextPages, "20%");
|
||||
|
||||
return (
|
||||
<div className="bg-custom-background-100 flex-shrink-0 w-full h-full border-r border-custom-border-300 ">
|
||||
|
||||
@@ -91,9 +91,15 @@ export const KanbanGroup = observer((props: IKanbanGroup) => {
|
||||
loadMoreIssues(groupId, sub_group_id === "null"? undefined: sub_group_id)
|
||||
}, [loadMoreIssues, groupId, sub_group_id])
|
||||
|
||||
useIntersectionObserver(containerRef, intersectionElement, loadMoreIssuesInThisGroup, `0% 100% 100% 100%`);
|
||||
const [isDraggingOverColumn, setIsDraggingOverColumn] = useState(false);
|
||||
const isPaginating = !!getIssueLoader(groupId);
|
||||
|
||||
useIntersectionObserver(
|
||||
containerRef,
|
||||
isPaginating ? null : intersectionElement,
|
||||
loadMoreIssuesInThisGroup,
|
||||
`0% 100% 100% 100%`
|
||||
);
|
||||
const [isDraggingOverColumn, setIsDraggingOverColumn] = useState(false);
|
||||
|
||||
// Enable Kanban Columns as Drop Targets
|
||||
useEffect(() => {
|
||||
@@ -216,7 +222,6 @@ export const KanbanGroup = observer((props: IKanbanGroup) => {
|
||||
|
||||
const nextPageResults = getPaginationData(groupId, sub_group_id)?.nextPageResults;
|
||||
|
||||
const isPaginating = !!getIssueLoader(groupId, sub_group_id);
|
||||
|
||||
const loadMore = isPaginating ? (
|
||||
<KanbanIssueBlockLoader />
|
||||
|
||||
@@ -98,12 +98,12 @@ export const ListGroup = observer((props: Props) => {
|
||||
|
||||
const [intersectionElement, setIntersectionElement] = useState<HTMLDivElement | null>(null);
|
||||
|
||||
useIntersectionObserver(containerRef, intersectionElement, loadMoreIssues, `50% 0% 50% 0%`);
|
||||
|
||||
const groupIssueCount = getGroupIssueCount(group.id, undefined, false) ?? 0;
|
||||
const nextPageResults = getPaginationData(group.id, undefined)?.nextPageResults;
|
||||
const isPaginating = !!getIssueLoader(group.id);
|
||||
|
||||
useIntersectionObserver(containerRef, isPaginating ? null : intersectionElement, loadMoreIssues, `50% 0% 50% 0%`);
|
||||
|
||||
const shouldLoadMore =
|
||||
nextPageResults === undefined && groupIssueCount !== undefined && groupIssueIds
|
||||
? groupIssueIds.length < groupIssueCount
|
||||
|
||||
@@ -5,6 +5,7 @@ import { IIssueDisplayFilterOptions, IIssueDisplayProperties, TIssue } from "@pl
|
||||
import { SpreadsheetIssueRowLoader } from "@/components/ui/loader";
|
||||
//hooks
|
||||
import { useIntersectionObserver } from "@/hooks/use-intersection-observer";
|
||||
import { useIssuesStore } from "@/hooks/use-issue-layout-store";
|
||||
import { TSelectionHelper } from "@/hooks/use-multiple-select";
|
||||
import { useTableKeyboardNavigation } from "@/hooks/use-table-keyboard-navigation";
|
||||
// components
|
||||
@@ -52,6 +53,10 @@ export const SpreadsheetTable = observer((props: Props) => {
|
||||
const isScrolled = useRef(false);
|
||||
const [intersectionElement, setIntersectionElement] = useState<HTMLTableSectionElement | null>(null);
|
||||
|
||||
const {
|
||||
issues: { getIssueLoader },
|
||||
} = useIssuesStore();
|
||||
|
||||
const handleScroll = useCallback(() => {
|
||||
if (!containerRef.current) return;
|
||||
const scrollLeft = containerRef.current.scrollLeft;
|
||||
@@ -85,7 +90,9 @@ export const SpreadsheetTable = observer((props: Props) => {
|
||||
};
|
||||
}, [handleScroll, containerRef]);
|
||||
|
||||
useIntersectionObserver(containerRef, intersectionElement, loadMoreIssues, `50% 0% 50% 0%`);
|
||||
const isPaginating = !!getIssueLoader();
|
||||
|
||||
useIntersectionObserver(containerRef, isPaginating ? null : intersectionElement, loadMoreIssues, `50% 0% 50% 0%`);
|
||||
|
||||
const handleKeyBoardNavigation = useTableKeyboardNavigation();
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ export class ArchivedIssues extends BaseIssuesStore implements IArchivedIssues {
|
||||
// get params from stored pagination options
|
||||
const params = this.issueFilterStore?.getFilterParams(
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
@@ -205,7 +205,7 @@ export class CycleIssues extends BaseIssuesStore implements ICycleIssues {
|
||||
// get params from stored pagination options
|
||||
const params = this.issueFilterStore?.getFilterParams(
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
@@ -129,7 +129,7 @@ export class DraftIssues extends BaseIssuesStore implements IDraftIssues {
|
||||
// get params from stored pagination options
|
||||
const params = this.issueFilterStore?.getFilterParams(
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
@@ -305,8 +305,9 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
|
||||
const subGroupBy = displayFilters?.sub_group_by;
|
||||
const groupBy = displayFilters?.group_by;
|
||||
|
||||
if (!groupBy && !subGroupBy && Array.isArray(groupedIssueIds)) {
|
||||
return groupedIssueIds as string[];
|
||||
const allIssues = groupedIssueIds[ALL_ISSUES];
|
||||
if (!groupBy && !subGroupBy && allIssues && Array.isArray(allIssues)) {
|
||||
return allIssues as string[];
|
||||
}
|
||||
|
||||
if (groupBy && groupId && groupedIssueIds?.[groupId] && Array.isArray(groupedIssueIds[groupId])) {
|
||||
@@ -314,7 +315,7 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
|
||||
}
|
||||
|
||||
if (groupBy && subGroupBy && groupId && subGroupId) {
|
||||
return (groupedIssueIds as TSubGroupedIssues)?.[subGroupId]?.[groupId] as string[];
|
||||
return (groupedIssueIds as TSubGroupedIssues)?.[groupId]?.[subGroupId] as string[];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -421,6 +422,24 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets the next page cursor based on number of issues currently available
|
||||
* @param groupId groupId for the cursor
|
||||
* @param subGroupId subgroupId for cursor
|
||||
* @returns next page cursor or undefined
|
||||
*/
|
||||
getNextCursor = (groupId: string | undefined, subGroupId: string | undefined): string | undefined => {
|
||||
const groupedIssues = this.getIssueIds(groupId, subGroupId) ?? [];
|
||||
const currentIssueCount = groupedIssues.length;
|
||||
|
||||
if (!this.paginationOptions) return;
|
||||
|
||||
const { perPageCount } = this.paginationOptions;
|
||||
const nextPage = Math.floor(currentIssueCount / perPageCount);
|
||||
|
||||
return `${perPageCount}:${nextPage}:0`;
|
||||
};
|
||||
|
||||
/**
|
||||
* This Method is called after fetching the first paginated issues
|
||||
*
|
||||
|
||||
@@ -160,7 +160,7 @@ export class ModuleIssues extends BaseIssuesStore implements IModuleIssues {
|
||||
// get params from stored pagination options
|
||||
const params = this.issueFilterStore?.getFilterParams(
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
@@ -167,7 +167,7 @@ export class ProfileIssues extends BaseIssuesStore implements IProfileIssues {
|
||||
// get params from stored pagination options
|
||||
let params = this.issueFilterStore?.getFilterParams(
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
@@ -127,7 +127,7 @@ export class ProjectViewIssues extends BaseIssuesStore implements IProjectViewIs
|
||||
// get params from stored pagination options
|
||||
const params = this.issueFilterStore?.getFilterParams(
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
@@ -130,7 +130,7 @@ export class ProjectIssues extends BaseIssuesStore implements IProjectIssues {
|
||||
// get params from stored pagination options
|
||||
const params = this.issueFilterStore?.getFilterParams(
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
@@ -130,7 +130,7 @@ export class WorkspaceIssues extends BaseIssuesStore implements IWorkspaceIssues
|
||||
const params = this.issueFilterStore?.getFilterParams(
|
||||
viewId,
|
||||
this.paginationOptions,
|
||||
cursorObject?.nextCursor,
|
||||
this.getNextCursor(groupId, subGroupId),
|
||||
groupId,
|
||||
subGroupId
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user