diff --git a/web/components/issues/issue-layouts/calendar/calendar.tsx b/web/components/issues/issue-layouts/calendar/calendar.tsx index c1b8ffa97..7b14f7a8e 100644 --- a/web/components/issues/issue-layouts/calendar/calendar.tsx +++ b/web/components/issues/issue-layouts/calendar/calendar.tsx @@ -106,7 +106,7 @@ export const CalendarChart: React.FC = observer((props) => { ); - const issueIdList = groupedIssueIds ? groupedIssueIds[formattedDatePayload] : null; + const issueIdList = groupedIssueIds ? groupedIssueIds[formattedDatePayload] : []; return ( <> @@ -182,6 +182,9 @@ export const CalendarChart: React.FC = observer((props) => { date={selectedDate} issues={issues} issueIdList={issueIdList} + loadMoreIssues={loadMoreIssues} + getPaginationData={getPaginationData} + getGroupIssueCount={getGroupIssueCount} quickActions={quickActions} enableQuickIssueCreate disableIssueCreation={!enableIssueCreation || !isEditingAllowed} diff --git a/web/components/issues/issue-layouts/calendar/day-tile.tsx b/web/components/issues/issue-layouts/calendar/day-tile.tsx index 3945816be..9f4986b2f 100644 --- a/web/components/issues/issue-layouts/calendar/day-tile.tsx +++ b/web/components/issues/issue-layouts/calendar/day-tile.tsx @@ -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 = 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 = 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 = observer((props) => { readOnly={readOnly} /> - {enableQuickIssueCreate && !disableIssueCreation && !readOnly && ( -
- -
- )} - - {shouldLoadMore && ( -
- -
- )} - {provided.placeholder} )} diff --git a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx index e660e3f60..f6108bc3e 100644 --- a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx +++ b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx @@ -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 = observer((props) => { issues, issueIdList, quickActions, + loadMoreIssues, + getPaginationData, + getGroupIssueCount, isDragDisabled = false, enableQuickIssueCreate, disableIssueCreation, @@ -45,13 +50,18 @@ export const CalendarIssueBlocks: React.FC = 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 = observer((props) => { )} {enableQuickIssueCreate && !disableIssueCreation && !readOnly && ( -
+
= observer((props) => { quickAddCallback={quickAddCallback} addIssuesToView={addIssuesToView} viewId={viewId} - onOpen={() => setShowAllIssues(true)} />
)} - {totalIssues > 4 && ( -
+ + {shouldLoadMore && ( +
)} diff --git a/web/store/issue/helpers/base-issues.store.ts b/web/store/issue/helpers/base-issues.store.ts index 9def82375..f90107cf8 100644 --- a/web/store/issue/helpers/base-issues.store.ts +++ b/web/store/issue/helpers/base-issues.store.ts @@ -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"] )