fix calendar pagination

This commit is contained in:
rahulramesha 2024-03-27 16:38:12 +05:30
parent 57133122ec
commit 9b4176aa17
4 changed files with 42 additions and 58 deletions

View File

@ -106,7 +106,7 @@ export const CalendarChart: React.FC<Props> = observer((props) => {
</div>
);
const issueIdList = groupedIssueIds ? groupedIssueIds[formattedDatePayload] : null;
const issueIdList = groupedIssueIds ? groupedIssueIds[formattedDatePayload] : [];
return (
<>
@ -182,6 +182,9 @@ export const CalendarChart: React.FC<Props> = observer((props) => {
date={selectedDate}
issues={issues}
issueIdList={issueIdList}
loadMoreIssues={loadMoreIssues}
getPaginationData={getPaginationData}
getGroupIssueCount={getGroupIssueCount}
quickActions={quickActions}
enableQuickIssueCreate
disableIssueCreation={!enableIssueCreation || !isEditingAllowed}

View File

@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
// types
import { TGroupedIssues, TIssue, TIssueMap, TPaginationData } from "@plane/types";
// components
import { CalendarIssueBlocks, ICalendarDate, CalendarQuickAddIssueForm } from "@/components/issues";
import { CalendarIssueBlocks, ICalendarDate } from "@/components/issues";
// helpers
import { MONTHS_LIST } from "@/constants/calendar";
import { cn } from "@/helpers/common.helper";
@ -63,11 +63,6 @@ export const CalendarDayTile: React.FC<Props> = observer((props) => {
const formattedDatePayload = renderFormattedPayloadDate(date.date);
if (!formattedDatePayload) return null;
const issueIds = groupedIssueIds?.[formattedDatePayload];
const dayIssueCount = getGroupIssueCount(formattedDatePayload);
const nextPageResults = getPaginationData(formattedDatePayload)?.nextPageResults;
const shouldLoadMore =
nextPageResults === undefined && dayIssueCount !== undefined ? issueIds?.length < dayIssueCount : !!nextPageResults;
const isToday = date.date.toDateString() === new Date().toDateString();
const isSelectedDate = date.date.toDateString() == selectedDate.toDateString();
@ -117,6 +112,9 @@ export const CalendarDayTile: React.FC<Props> = observer((props) => {
issues={issues}
issueIdList={issueIds ?? []}
quickActions={quickActions}
loadMoreIssues={loadMoreIssues}
getPaginationData={getPaginationData}
getGroupIssueCount={getGroupIssueCount}
isDragDisabled={readOnly}
addIssuesToView={addIssuesToView}
disableIssueCreation={disableIssueCreation}
@ -126,33 +124,6 @@ export const CalendarDayTile: React.FC<Props> = observer((props) => {
readOnly={readOnly}
/>
{enableQuickIssueCreate && !disableIssueCreation && !readOnly && (
<div className="px-2 py-1">
<CalendarQuickAddIssueForm
formKey="target_date"
groupId={formattedDatePayload}
prePopulatedData={{
target_date: renderFormattedPayloadDate(date.date) ?? undefined,
}}
quickAddCallback={quickAddCallback}
addIssuesToView={addIssuesToView}
viewId={viewId}
/>
</div>
)}
{shouldLoadMore && (
<div className="flex items-center px-2.5 py-1">
<button
type="button"
className="w-min whitespace-nowrap rounded text-xs px-1.5 py-1 text-custom-text-400 font-medium hover:bg-custom-background-80 hover:text-custom-text-300"
onClick={() => loadMoreIssues(formattedDatePayload)}
>
Load More
</button>
</div>
)}
{provided.placeholder}
</div>
)}

View File

@ -1,8 +1,7 @@
import { useState } from "react";
import { Draggable } from "@hello-pangea/dnd";
import { Placement } from "@popperjs/core";
import { observer } from "mobx-react-lite";
import { TIssue, TIssueMap } from "@plane/types";
import { TIssue, TIssueMap, TPaginationData } from "@plane/types";
// components
import { CalendarQuickAddIssueForm, CalendarIssueBlockRoot } from "@/components/issues";
// helpers
@ -12,8 +11,11 @@ import { renderFormattedPayloadDate } from "@/helpers/date-time.helper";
type Props = {
date: Date;
issues: TIssueMap | undefined;
issueIdList: string[] | null;
issueIdList: string[];
quickActions: (issue: TIssue, customActionButton?: React.ReactElement, placement?: Placement) => React.ReactNode;
loadMoreIssues: (dateString: string) => void;
getPaginationData: (groupId: string | undefined) => TPaginationData | undefined;
getGroupIssueCount: (groupId: string | undefined) => number | undefined;
isDragDisabled?: boolean;
enableQuickIssueCreate?: boolean;
disableIssueCreation?: boolean;
@ -35,6 +37,9 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
issues,
issueIdList,
quickActions,
loadMoreIssues,
getPaginationData,
getGroupIssueCount,
isDragDisabled = false,
enableQuickIssueCreate,
disableIssueCreation,
@ -45,13 +50,18 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
isMobileView = false,
} = props;
// states
const [showAllIssues, setShowAllIssues] = useState(false);
const formattedDatePayload = renderFormattedPayloadDate(date);
const totalIssues = issueIdList?.length ?? 0;
if (!formattedDatePayload) return null;
const dayIssueCount = getGroupIssueCount(formattedDatePayload);
const nextPageResults = getPaginationData(formattedDatePayload)?.nextPageResults;
const shouldLoadMore =
nextPageResults === undefined && dayIssueCount !== undefined
? issueIdList?.length < dayIssueCount
: !!nextPageResults;
return (
<>
{issueIdList?.map((issueId, index) =>
@ -79,7 +89,7 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
)}
{enableQuickIssueCreate && !disableIssueCreation && !readOnly && (
<div className="px-1 md:px-2 py-1 border-custom-border-200 border-b md:border-none">
<div className="px-1 md:px-2 py-1 border-custom-border-200 border-b md:border-none md:hidden group-hover:block">
<CalendarQuickAddIssueForm
formKey="target_date"
groupId={formattedDatePayload}
@ -89,18 +99,18 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
quickAddCallback={quickAddCallback}
addIssuesToView={addIssuesToView}
viewId={viewId}
onOpen={() => setShowAllIssues(true)}
/>
</div>
)}
{totalIssues > 4 && (
<div className="hidden md:flex items-center px-2.5 py-1">
{shouldLoadMore && (
<div className="flex items-center px-2.5 py-1">
<button
type="button"
className="w-min whitespace-nowrap rounded text-xs px-1.5 py-1 text-custom-text-400 font-medium hover:bg-custom-background-80 hover:text-custom-text-300"
onClick={() => setShowAllIssues(!showAllIssues)}
onClick={() => loadMoreIssues(formattedDatePayload)}
>
{showAllIssues ? "Hide" : totalIssues - 4 + " more"}
Load More
</button>
</div>
)}

View File

@ -800,11 +800,11 @@ export class BaseIssuesStore implements IBaseIssuesStore {
return this.getIssueIds(orderBy(array, "sort_order"));
case "state__name":
return this.getIssueIds(
orderBy(array, (issue) => this.populateIssueDataForSorting("state_id", issue["state_id"]))
orderBy(array, (issue) => this.populateIssueDataForSorting("state_id", issue?.["state_id"]))
);
case "-state__name":
return this.getIssueIds(
orderBy(array, (issue) => this.populateIssueDataForSorting("state_id", issue["state_id"]), ["desc"])
orderBy(array, (issue) => this.populateIssueDataForSorting("state_id", issue?.["state_id"]), ["desc"])
);
// dates
case "created_at":
@ -844,12 +844,12 @@ export class BaseIssuesStore implements IBaseIssuesStore {
// custom
case "priority": {
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)));
}
case "-priority": {
const sortArray = ISSUE_PRIORITIES.map((i) => i.key);
return this.getIssueIds(
orderBy(array, (currentIssue: TIssue) => indexOf(sortArray, currentIssue.priority), ["desc"])
orderBy(array, (currentIssue: TIssue) => indexOf(sortArray, currentIssue?.priority), ["desc"])
);
}
@ -887,7 +887,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
return this.getIssueIds(
orderBy(array, [
this.getSortOrderToFilterEmptyValues.bind(null, "label_ids"), //preferring sorting based on empty values to always keep the empty values below
(issue) => this.populateIssueDataForSorting("label_ids", issue["label_ids"], "asc"),
(issue) => this.populateIssueDataForSorting("label_ids", issue?.["label_ids"], "asc"),
])
);
case "-labels__name":
@ -896,7 +896,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
array,
[
this.getSortOrderToFilterEmptyValues.bind(null, "label_ids"), //preferring sorting based on empty values to always keep the empty values below
(issue) => this.populateIssueDataForSorting("label_ids", issue["label_ids"], "desc"),
(issue) => this.populateIssueDataForSorting("label_ids", issue?.["label_ids"], "desc"),
],
["asc", "desc"]
)
@ -906,7 +906,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
return this.getIssueIds(
orderBy(array, [
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 "-issue_module__module__name":
@ -915,7 +915,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
array,
[
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"], "desc"),
(issue) => this.populateIssueDataForSorting("module_ids", issue?.["module_ids"], "desc"),
],
["asc", "desc"]
)
@ -925,7 +925,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
return this.getIssueIds(
orderBy(array, [
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 "-issue_cycle__cycle__name":
@ -934,7 +934,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
array,
[
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"], "desc"),
(issue) => this.populateIssueDataForSorting("cycle_id", issue?.["cycle_id"], "desc"),
],
["asc", "desc"]
)
@ -944,7 +944,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
return this.getIssueIds(
orderBy(array, [
this.getSortOrderToFilterEmptyValues.bind(null, "assignee_ids"), //preferring sorting based on empty values to always keep the empty values below
(issue) => this.populateIssueDataForSorting("assignee_ids", issue["assignee_ids"], "asc"),
(issue) => this.populateIssueDataForSorting("assignee_ids", issue?.["assignee_ids"], "asc"),
])
);
case "-assignees__first_name":
@ -953,7 +953,7 @@ export class BaseIssuesStore implements IBaseIssuesStore {
array,
[
this.getSortOrderToFilterEmptyValues.bind(null, "assignee_ids"), //preferring sorting based on empty values to always keep the empty values below
(issue) => this.populateIssueDataForSorting("assignee_ids", issue["assignee_ids"], "desc"),
(issue) => this.populateIssueDataForSorting("assignee_ids", issue?.["assignee_ids"], "desc"),
],
["asc", "desc"]
)