mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix calendar pagination
This commit is contained in:
parent
57133122ec
commit
9b4176aa17
@ -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}
|
||||
|
@ -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>
|
||||
)}
|
||||
|
@ -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>
|
||||
)}
|
||||
|
@ -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"]
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user