forked from github/plane
chore: optimised issue loaders and added enum for issue status and current tab (#4164)
This commit is contained in:
parent
7aa1d750ea
commit
cfbc1a91af
17
packages/types/src/inbox.d.ts
vendored
17
packages/types/src/inbox.d.ts
vendored
@ -2,9 +2,22 @@ import { TPaginationInfo } from "./common";
|
|||||||
import { TIssuePriorities } from "./issues";
|
import { TIssuePriorities } from "./issues";
|
||||||
import { TIssue } from "./issues/base";
|
import { TIssue } from "./issues/base";
|
||||||
|
|
||||||
export type TInboxIssueCurrentTab = "open" | "closed";
|
enum EInboxIssueCurrentTab {
|
||||||
|
OPEN = "open",
|
||||||
|
CLOSED = "closed",
|
||||||
|
}
|
||||||
|
|
||||||
export type TInboxIssueStatus = -2 | -1 | 0 | 1 | 2;
|
enum EInboxIssueStatus {
|
||||||
|
PENDING = -2,
|
||||||
|
DECLINED = -1,
|
||||||
|
SNOOZED = 0,
|
||||||
|
ACCEPTED = 1,
|
||||||
|
DUPLICATE = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TInboxIssueCurrentTab = EInboxIssueCurrentTab;
|
||||||
|
|
||||||
|
export type TInboxIssueStatus = EInboxIssueStatus;
|
||||||
|
|
||||||
// filters
|
// filters
|
||||||
export type TInboxIssueFilterMemberKeys = "assignee" | "created_by";
|
export type TInboxIssueFilterMemberKeys = "assignee" | "created_by";
|
||||||
|
@ -16,6 +16,7 @@ import { IssueUpdateStatus } from "@/components/issues";
|
|||||||
// constants
|
// constants
|
||||||
import { EUserProjectRoles } from "@/constants/project";
|
import { EUserProjectRoles } from "@/constants/project";
|
||||||
// helpers
|
// helpers
|
||||||
|
import { EInboxIssueStatus } from "@/helpers/inbox.helper";
|
||||||
import { copyUrlToClipboard } from "@/helpers/string.helper";
|
import { copyUrlToClipboard } from "@/helpers/string.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useUser, useProjectInbox, useProject } from "@/hooks/store";
|
import { useUser, useProjectInbox, useProject } from "@/hooks/store";
|
||||||
@ -60,27 +61,27 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p
|
|||||||
const issueLink = `${workspaceSlug}/projects/${issue?.project_id}/issues/${currentInboxIssueId}`;
|
const issueLink = `${workspaceSlug}/projects/${issue?.project_id}/issues/${currentInboxIssueId}`;
|
||||||
|
|
||||||
const handleInboxIssueAccept = async () => {
|
const handleInboxIssueAccept = async () => {
|
||||||
inboxIssue?.updateInboxIssueStatus(1);
|
await inboxIssue?.updateInboxIssueStatus(EInboxIssueStatus.ACCEPTED);
|
||||||
setAcceptIssueModal(false);
|
setAcceptIssueModal(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInboxIssueDecline = async () => {
|
const handleInboxIssueDecline = async () => {
|
||||||
inboxIssue?.updateInboxIssueStatus(-1);
|
await inboxIssue?.updateInboxIssueStatus(EInboxIssueStatus.DECLINED);
|
||||||
setDeclineIssueModal(false);
|
setDeclineIssueModal(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInboxIssueDuplicate = (issueId: string) => {
|
const handleInboxIssueDuplicate = async (issueId: string) => {
|
||||||
inboxIssue?.updateInboxIssueDuplicateTo(issueId);
|
await inboxIssue?.updateInboxIssueDuplicateTo(issueId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInboxSIssueSnooze = async (date: Date) => {
|
const handleInboxSIssueSnooze = async (date: Date) => {
|
||||||
inboxIssue?.updateInboxIssueSnoozeTill(date);
|
await inboxIssue?.updateInboxIssueSnoozeTill(date);
|
||||||
setIsSnoozeDateModalOpen(false);
|
setIsSnoozeDateModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInboxIssueDelete = async () => {
|
const handleInboxIssueDelete = async () => {
|
||||||
if (!inboxIssue || !currentInboxIssueId) return;
|
if (!inboxIssue || !currentInboxIssueId) return;
|
||||||
deleteInboxIssue(workspaceSlug, projectId, currentInboxIssueId).finally(() => {
|
await deleteInboxIssue(workspaceSlug, projectId, currentInboxIssueId).finally(() => {
|
||||||
router.push(`/${workspaceSlug}/projects/${projectId}/inbox`);
|
router.push(`/${workspaceSlug}/projects/${projectId}/inbox`);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -52,7 +52,7 @@ export const CreateInboxIssueModal: React.FC<Props> = observer((props) => {
|
|||||||
const workspaceStore = useWorkspace();
|
const workspaceStore = useWorkspace();
|
||||||
const workspaceId = workspaceStore.getWorkspaceBySlug(workspaceSlug as string)?.id as string;
|
const workspaceId = workspaceStore.getWorkspaceBySlug(workspaceSlug as string)?.id as string;
|
||||||
// store hooks
|
// store hooks
|
||||||
const { createInboxIssue, handleCurrentTab } = useProjectInbox();
|
const { createInboxIssue } = useProjectInbox();
|
||||||
const {
|
const {
|
||||||
config: { envConfig },
|
config: { envConfig },
|
||||||
} = useApplication();
|
} = useApplication();
|
||||||
@ -80,7 +80,6 @@ export const CreateInboxIssueModal: React.FC<Props> = observer((props) => {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!createMore) {
|
if (!createMore) {
|
||||||
router.push(`/${workspaceSlug}/projects/${projectId}/inbox/?currentTab=open&inboxIssueId=${res?.issue?.id}`);
|
router.push(`/${workspaceSlug}/projects/${projectId}/inbox/?currentTab=open&inboxIssueId=${res?.issue?.id}`);
|
||||||
handleCurrentTab("open");
|
|
||||||
handleClose();
|
handleClose();
|
||||||
} else {
|
} else {
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
|
@ -25,8 +25,11 @@ export const InboxIssueRoot: FC<TInboxIssueRoot> = observer((props) => {
|
|||||||
|
|
||||||
useSWR(
|
useSWR(
|
||||||
inboxAccessible && workspaceSlug && projectId ? `PROJECT_INBOX_ISSUES_${workspaceSlug}_${projectId}` : null,
|
inboxAccessible && workspaceSlug && projectId ? `PROJECT_INBOX_ISSUES_${workspaceSlug}_${projectId}` : null,
|
||||||
() => {
|
async () => {
|
||||||
inboxAccessible && workspaceSlug && projectId && fetchInboxIssues(workspaceSlug.toString(), projectId.toString());
|
inboxAccessible &&
|
||||||
|
workspaceSlug &&
|
||||||
|
projectId &&
|
||||||
|
(await fetchInboxIssues(workspaceSlug.toString(), projectId.toString()));
|
||||||
},
|
},
|
||||||
{ revalidateOnFocus: false, revalidateIfStale: false }
|
{ revalidateOnFocus: false, revalidateIfStale: false }
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FC, MouseEvent, useEffect } from "react";
|
import { FC, MouseEvent } from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
@ -32,19 +32,6 @@ export const InboxIssueListItem: FC<InboxIssueListItemProps> = observer((props)
|
|||||||
const { isMobile } = usePlatformOS();
|
const { isMobile } = usePlatformOS();
|
||||||
const issue = inboxIssue.issue;
|
const issue = inboxIssue.issue;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (issue.id === inboxIssueId) {
|
|
||||||
setTimeout(() => {
|
|
||||||
const issueItemCard = document.getElementById(`inbox-issue-list-item-${issue.id}`);
|
|
||||||
if (issueItemCard)
|
|
||||||
issueItemCard.scrollIntoView({
|
|
||||||
behavior: "smooth",
|
|
||||||
block: "center",
|
|
||||||
});
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
}, [inboxIssueId, issue.id]);
|
|
||||||
|
|
||||||
const handleIssueRedirection = (event: MouseEvent, currentIssueId: string | undefined) => {
|
const handleIssueRedirection = (event: MouseEvent, currentIssueId: string | undefined) => {
|
||||||
if (inboxIssueId === currentIssueId) event.preventDefault();
|
if (inboxIssueId === currentIssueId) event.preventDefault();
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,6 @@ export const InboxIssueList: FC<InboxIssueListProps> = observer((props) => {
|
|||||||
{inboxIssues.map((inboxIssue) => (
|
{inboxIssues.map((inboxIssue) => (
|
||||||
<Fragment key={inboxIssue.id}>
|
<Fragment key={inboxIssue.id}>
|
||||||
<InboxIssueListItem
|
<InboxIssueListItem
|
||||||
key={inboxIssue.id}
|
|
||||||
workspaceSlug={workspaceSlug}
|
workspaceSlug={workspaceSlug}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
projectIdentifier={projectIdentifier}
|
projectIdentifier={projectIdentifier}
|
||||||
|
@ -11,6 +11,7 @@ import { InboxSidebarLoader } from "@/components/ui";
|
|||||||
import { EmptyStateType } from "@/constants/empty-state";
|
import { EmptyStateType } from "@/constants/empty-state";
|
||||||
// helpers
|
// helpers
|
||||||
import { cn } from "@/helpers/common.helper";
|
import { cn } from "@/helpers/common.helper";
|
||||||
|
import { EInboxIssueCurrentTab } from "@/helpers/inbox.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useProject, useProjectInbox } from "@/hooks/store";
|
import { useProject, useProjectInbox } from "@/hooks/store";
|
||||||
import { useIntersectionObserver } from "@/hooks/use-intersection-observer";
|
import { useIntersectionObserver } from "@/hooks/use-intersection-observer";
|
||||||
@ -22,11 +23,11 @@ type IInboxSidebarProps = {
|
|||||||
|
|
||||||
const tabNavigationOptions: { key: TInboxIssueCurrentTab; label: string }[] = [
|
const tabNavigationOptions: { key: TInboxIssueCurrentTab; label: string }[] = [
|
||||||
{
|
{
|
||||||
key: "open",
|
key: EInboxIssueCurrentTab.OPEN,
|
||||||
label: "Open",
|
label: "Open",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "closed",
|
key: EInboxIssueCurrentTab.CLOSED,
|
||||||
label: "Closed",
|
label: "Closed",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -99,7 +100,7 @@ export const InboxSidebar: FC<IInboxSidebarProps> = observer((props) => {
|
|||||||
|
|
||||||
<InboxIssueAppliedFilters />
|
<InboxIssueAppliedFilters />
|
||||||
|
|
||||||
{isLoading === "filter-loading" && !inboxIssuePaginationInfo?.next_page_results ? (
|
{isLoading != undefined && isLoading === "filter-loading" && !inboxIssuePaginationInfo?.next_page_results ? (
|
||||||
<InboxSidebarLoader />
|
<InboxSidebarLoader />
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
@ -119,7 +120,7 @@ export const InboxSidebar: FC<IInboxSidebarProps> = observer((props) => {
|
|||||||
type={
|
type={
|
||||||
getAppliedFiltersCount > 0
|
getAppliedFiltersCount > 0
|
||||||
? EmptyStateType.INBOX_SIDEBAR_FILTER_EMPTY_STATE
|
? EmptyStateType.INBOX_SIDEBAR_FILTER_EMPTY_STATE
|
||||||
: currentTab === "open"
|
: currentTab === EInboxIssueCurrentTab.OPEN
|
||||||
? EmptyStateType.INBOX_SIDEBAR_OPEN_TAB
|
? EmptyStateType.INBOX_SIDEBAR_OPEN_TAB
|
||||||
: EmptyStateType.INBOX_SIDEBAR_CLOSED_TAB
|
: EmptyStateType.INBOX_SIDEBAR_CLOSED_TAB
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { AlertTriangle, CheckCircle2, Clock, Copy, LucideIcon, XCircle } from "l
|
|||||||
import { TInboxIssueSortingOrderByKeys, TInboxIssueSortingSortByKeys, TInboxIssueStatus } from "@plane/types";
|
import { TInboxIssueSortingOrderByKeys, TInboxIssueSortingSortByKeys, TInboxIssueStatus } from "@plane/types";
|
||||||
// helpers
|
// helpers
|
||||||
import { findHowManyDaysLeft } from "@/helpers/date-time.helper";
|
import { findHowManyDaysLeft } from "@/helpers/date-time.helper";
|
||||||
|
import { EInboxIssueStatus } from "@/helpers/inbox.helper";
|
||||||
|
|
||||||
export const INBOX_STATUS: {
|
export const INBOX_STATUS: {
|
||||||
key: string;
|
key: string;
|
||||||
@ -16,7 +17,7 @@ export const INBOX_STATUS: {
|
|||||||
}[] = [
|
}[] = [
|
||||||
{
|
{
|
||||||
key: "pending",
|
key: "pending",
|
||||||
status: -2,
|
status: EInboxIssueStatus.PENDING,
|
||||||
icon: AlertTriangle,
|
icon: AlertTriangle,
|
||||||
title: "Pending",
|
title: "Pending",
|
||||||
description: () => `Pending`,
|
description: () => `Pending`,
|
||||||
@ -25,7 +26,7 @@ export const INBOX_STATUS: {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "declined",
|
key: "declined",
|
||||||
status: -1,
|
status: EInboxIssueStatus.DECLINED,
|
||||||
icon: XCircle,
|
icon: XCircle,
|
||||||
title: "Declined",
|
title: "Declined",
|
||||||
description: () => `Declined`,
|
description: () => `Declined`,
|
||||||
@ -34,7 +35,7 @@ export const INBOX_STATUS: {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "snoozed",
|
key: "snoozed",
|
||||||
status: 0,
|
status: EInboxIssueStatus.SNOOZED,
|
||||||
icon: Clock,
|
icon: Clock,
|
||||||
title: "Snoozed",
|
title: "Snoozed",
|
||||||
description: (snoozedTillDate: Date = new Date()) => `${findHowManyDaysLeft(snoozedTillDate)} days to go`,
|
description: (snoozedTillDate: Date = new Date()) => `${findHowManyDaysLeft(snoozedTillDate)} days to go`,
|
||||||
@ -43,7 +44,7 @@ export const INBOX_STATUS: {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "accepted",
|
key: "accepted",
|
||||||
status: 1,
|
status: EInboxIssueStatus.ACCEPTED,
|
||||||
icon: CheckCircle2,
|
icon: CheckCircle2,
|
||||||
title: "Accepted",
|
title: "Accepted",
|
||||||
description: () => `Accepted`,
|
description: () => `Accepted`,
|
||||||
@ -52,7 +53,7 @@ export const INBOX_STATUS: {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "duplicate",
|
key: "duplicate",
|
||||||
status: 2,
|
status: EInboxIssueStatus.DUPLICATE,
|
||||||
icon: Copy,
|
icon: Copy,
|
||||||
title: "Duplicate",
|
title: "Duplicate",
|
||||||
description: () => `Duplicate`,
|
description: () => `Duplicate`,
|
||||||
|
@ -1,6 +1,19 @@
|
|||||||
import { subDays } from "date-fns";
|
import { subDays } from "date-fns";
|
||||||
import { renderFormattedPayloadDate } from "./date-time.helper";
|
import { renderFormattedPayloadDate } from "./date-time.helper";
|
||||||
|
|
||||||
|
export enum EInboxIssueCurrentTab {
|
||||||
|
OPEN = "open",
|
||||||
|
CLOSED = "closed",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EInboxIssueStatus {
|
||||||
|
PENDING = -2,
|
||||||
|
DECLINED = -1,
|
||||||
|
SNOOZED = 0,
|
||||||
|
ACCEPTED = 1,
|
||||||
|
DUPLICATE = 2,
|
||||||
|
}
|
||||||
|
|
||||||
export enum EPastDurationFilters {
|
export enum EPastDurationFilters {
|
||||||
TODAY = "today",
|
TODAY = "today",
|
||||||
YESTERDAY = "yesterday",
|
YESTERDAY = "yesterday",
|
||||||
|
@ -8,6 +8,8 @@ import { ProjectInboxHeader } from "@/components/headers";
|
|||||||
import { InboxIssueRoot } from "@/components/inbox";
|
import { InboxIssueRoot } from "@/components/inbox";
|
||||||
// constants
|
// constants
|
||||||
import { EmptyStateType } from "@/constants/empty-state";
|
import { EmptyStateType } from "@/constants/empty-state";
|
||||||
|
// helpers
|
||||||
|
import { EInboxIssueCurrentTab } from "@/helpers/inbox.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useProject, useProjectInbox } from "@/hooks/store";
|
import { useProject, useProjectInbox } from "@/hooks/store";
|
||||||
// layouts
|
// layouts
|
||||||
@ -40,7 +42,8 @@ const ProjectInboxPage: NextPageWithLayout = observer(() => {
|
|||||||
const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - Inbox` : "Plane - Inbox";
|
const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - Inbox` : "Plane - Inbox";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (navigationTab && currentTab != navigationTab) handleCurrentTab(navigationTab === "open" ? "open" : "closed");
|
if (navigationTab && currentTab != navigationTab)
|
||||||
|
handleCurrentTab(navigationTab === "open" ? EInboxIssueCurrentTab.OPEN : EInboxIssueCurrentTab.CLOSED);
|
||||||
}, [currentTab, navigationTab, handleCurrentTab]);
|
}, [currentTab, navigationTab, handleCurrentTab]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import set from "lodash/set";
|
import set from "lodash/set";
|
||||||
import { makeObservable, observable, runInAction, action } from "mobx";
|
import { makeObservable, observable, runInAction, action } from "mobx";
|
||||||
import { TIssue, TInboxIssue, TInboxIssueStatus, TInboxDuplicateIssueDetails } from "@plane/types";
|
import { TIssue, TInboxIssue, TInboxIssueStatus, TInboxDuplicateIssueDetails } from "@plane/types";
|
||||||
|
// helpers
|
||||||
|
import { EInboxIssueStatus } from "@/helpers/inbox.helper";
|
||||||
// services
|
// services
|
||||||
import { InboxIssueService } from "@/services/inbox";
|
import { InboxIssueService } from "@/services/inbox";
|
||||||
// root store
|
// root store
|
||||||
@ -26,7 +28,7 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||||||
// observables
|
// observables
|
||||||
isLoading: boolean = false;
|
isLoading: boolean = false;
|
||||||
id: string;
|
id: string;
|
||||||
status: TInboxIssueStatus = -2;
|
status: TInboxIssueStatus = EInboxIssueStatus.PENDING;
|
||||||
issue: Partial<TIssue> = {};
|
issue: Partial<TIssue> = {};
|
||||||
snoozed_till: Date | undefined;
|
snoozed_till: Date | undefined;
|
||||||
duplicate_to: string | undefined;
|
duplicate_to: string | undefined;
|
||||||
@ -82,7 +84,8 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
updateInboxIssueDuplicateTo = async (issueId: string) => {
|
updateInboxIssueDuplicateTo = async (issueId: string) => {
|
||||||
const inboxStatus = 2;
|
const inboxStatus = EInboxIssueStatus.DUPLICATE;
|
||||||
|
|
||||||
const previousData: Partial<TInboxIssue> = {
|
const previousData: Partial<TInboxIssue> = {
|
||||||
status: this.status,
|
status: this.status,
|
||||||
duplicate_to: this.duplicate_to,
|
duplicate_to: this.duplicate_to,
|
||||||
@ -108,7 +111,8 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
updateInboxIssueSnoozeTill = async (date: Date) => {
|
updateInboxIssueSnoozeTill = async (date: Date) => {
|
||||||
const inboxStatus = 0;
|
const inboxStatus = EInboxIssueStatus.SNOOZED;
|
||||||
|
|
||||||
const previousData: Partial<TInboxIssue> = {
|
const previousData: Partial<TInboxIssue> = {
|
||||||
status: this.status,
|
status: this.status,
|
||||||
snoozed_till: this.snoozed_till,
|
snoozed_till: this.snoozed_till,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import isEmpty from "lodash/isEmpty";
|
import isEmpty from "lodash/isEmpty";
|
||||||
import omit from "lodash/omit";
|
import omit from "lodash/omit";
|
||||||
|
import orderBy from "lodash/orderBy";
|
||||||
|
import reverse from "lodash/reverse";
|
||||||
import set from "lodash/set";
|
import set from "lodash/set";
|
||||||
import { action, computed, makeObservable, observable, runInAction } from "mobx";
|
import { action, computed, makeObservable, observable, runInAction } from "mobx";
|
||||||
import { computedFn } from "mobx-utils";
|
import { computedFn } from "mobx-utils";
|
||||||
@ -13,19 +15,26 @@ import {
|
|||||||
TInboxIssueSortingOrderByQueryParam,
|
TInboxIssueSortingOrderByQueryParam,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
// helpers
|
// helpers
|
||||||
import { EPastDurationFilters, getCustomDates } from "@/helpers/inbox.helper";
|
import { EInboxIssueCurrentTab, EInboxIssueStatus, EPastDurationFilters, getCustomDates } from "@/helpers/inbox.helper";
|
||||||
// services
|
// services
|
||||||
import { InboxIssueService } from "@/services/inbox";
|
import { InboxIssueService } from "@/services/inbox";
|
||||||
// root store
|
// root store
|
||||||
import { IInboxIssueStore, InboxIssueStore } from "@/store/inbox/inbox-issue.store";
|
import { IInboxIssueStore, InboxIssueStore } from "@/store/inbox/inbox-issue.store";
|
||||||
import { RootStore } from "@/store/root.store";
|
import { RootStore } from "@/store/root.store";
|
||||||
|
|
||||||
type TLoader = "init-loading" | "filter-loading" | "pagination-loading" | "issue-loading" | undefined;
|
type TLoader =
|
||||||
|
| "init-loading"
|
||||||
|
| "mutation-loading"
|
||||||
|
| "filter-loading"
|
||||||
|
| "pagination-loading"
|
||||||
|
| "issue-loading"
|
||||||
|
| undefined;
|
||||||
|
|
||||||
export interface IProjectInboxStore {
|
export interface IProjectInboxStore {
|
||||||
currentTab: TInboxIssueCurrentTab;
|
currentTab: TInboxIssueCurrentTab;
|
||||||
isLoading: TLoader;
|
isLoading: TLoader;
|
||||||
error: { message: string; status: "init-error" | "pagination-error" } | undefined;
|
error: { message: string; status: "init-error" | "pagination-error" } | undefined;
|
||||||
|
currentInboxProjectId: string;
|
||||||
inboxFilters: Partial<TInboxIssueFilter>;
|
inboxFilters: Partial<TInboxIssueFilter>;
|
||||||
inboxSorting: Partial<TInboxIssueSorting>;
|
inboxSorting: Partial<TInboxIssueSorting>;
|
||||||
inboxIssuePaginationInfo: TInboxIssuePaginationInfo | undefined;
|
inboxIssuePaginationInfo: TInboxIssuePaginationInfo | undefined;
|
||||||
@ -35,6 +44,7 @@ export interface IProjectInboxStore {
|
|||||||
inboxIssuesArray: IInboxIssueStore[];
|
inboxIssuesArray: IInboxIssueStore[];
|
||||||
// helper actions
|
// helper actions
|
||||||
getIssueInboxByIssueId: (issueId: string) => IInboxIssueStore | undefined;
|
getIssueInboxByIssueId: (issueId: string) => IInboxIssueStore | undefined;
|
||||||
|
inboxIssueSorting: (issues: IInboxIssueStore[]) => IInboxIssueStore[];
|
||||||
inboxIssueQueryParams: (
|
inboxIssueQueryParams: (
|
||||||
inboxFilters: Partial<TInboxIssueFilter>,
|
inboxFilters: Partial<TInboxIssueFilter>,
|
||||||
inboxSorting: Partial<TInboxIssueSorting>,
|
inboxSorting: Partial<TInboxIssueSorting>,
|
||||||
@ -60,11 +70,12 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
// constants
|
// constants
|
||||||
PER_PAGE_COUNT = 10;
|
PER_PAGE_COUNT = 10;
|
||||||
// observables
|
// observables
|
||||||
currentTab: TInboxIssueCurrentTab = "open";
|
currentTab: TInboxIssueCurrentTab = EInboxIssueCurrentTab.OPEN;
|
||||||
isLoading: TLoader = undefined;
|
isLoading: TLoader = "init-loading";
|
||||||
error: { message: string; status: "init-error" | "pagination-error" } | undefined = undefined;
|
error: { message: string; status: "init-error" | "pagination-error" } | undefined = undefined;
|
||||||
|
currentInboxProjectId: string = "";
|
||||||
inboxFilters: Partial<TInboxIssueFilter> = {
|
inboxFilters: Partial<TInboxIssueFilter> = {
|
||||||
status: [-2],
|
status: [EInboxIssueStatus.PENDING],
|
||||||
};
|
};
|
||||||
inboxSorting: Partial<TInboxIssueSorting> = {
|
inboxSorting: Partial<TInboxIssueSorting> = {
|
||||||
order_by: "issue__created_at",
|
order_by: "issue__created_at",
|
||||||
@ -79,6 +90,8 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
currentTab: observable.ref,
|
currentTab: observable.ref,
|
||||||
isLoading: observable.ref,
|
isLoading: observable.ref,
|
||||||
|
error: observable,
|
||||||
|
currentInboxProjectId: observable.ref,
|
||||||
inboxFilters: observable,
|
inboxFilters: observable,
|
||||||
inboxSorting: observable,
|
inboxSorting: observable,
|
||||||
inboxIssuePaginationInfo: observable,
|
inboxIssuePaginationInfo: observable,
|
||||||
@ -111,13 +124,40 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get inboxIssuesArray() {
|
get inboxIssuesArray() {
|
||||||
return Object.values(this.inboxIssues || {}).filter((inbox) =>
|
return this.inboxIssueSorting(
|
||||||
(this.currentTab === "open" ? [-2, 0] : [-1, 1, 2]).includes(inbox.status)
|
Object.values(this.inboxIssues || {}).filter((inbox) =>
|
||||||
|
(this.currentTab === EInboxIssueCurrentTab.OPEN
|
||||||
|
? [EInboxIssueStatus.PENDING, EInboxIssueStatus.SNOOZED]
|
||||||
|
: [EInboxIssueStatus.ACCEPTED, EInboxIssueStatus.DECLINED, EInboxIssueStatus.DUPLICATE]
|
||||||
|
).includes(inbox.status)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getIssueInboxByIssueId = computedFn((issueId: string) => this.inboxIssues?.[issueId] || undefined);
|
getIssueInboxByIssueId = computedFn((issueId: string) => this.inboxIssues?.[issueId] || undefined);
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
inboxIssueSorting = (issues: IInboxIssueStore[]) => {
|
||||||
|
console.log("issues", issues);
|
||||||
|
let inboxIssues: IInboxIssueStore[] = [];
|
||||||
|
if (this.inboxSorting?.order_by && this.inboxSorting?.sort_by) {
|
||||||
|
switch (this.inboxSorting.order_by) {
|
||||||
|
case "issue__created_at":
|
||||||
|
if (this.inboxSorting.sort_by === "desc") inboxIssues = orderBy(issues, ["issue", "created_at"]);
|
||||||
|
else inboxIssues = reverse(orderBy(issues, ["issue", "created_at"]));
|
||||||
|
case "issue__updated_at":
|
||||||
|
if (this.inboxSorting.sort_by === "desc") inboxIssues = orderBy(issues, ["issue", "updated_at"]);
|
||||||
|
else inboxIssues = reverse(orderBy(issues, ["issue", "updated_at"]));
|
||||||
|
case "issue__sequence_id":
|
||||||
|
if (this.inboxSorting.sort_by === "desc") inboxIssues = orderBy(issues, ["issue", "sequence_id"]);
|
||||||
|
else inboxIssues = reverse(orderBy(issues, ["issue", "sequence_id"]));
|
||||||
|
default:
|
||||||
|
inboxIssues = orderBy(issues, ["issue", "created_at"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inboxIssues;
|
||||||
|
};
|
||||||
|
|
||||||
inboxIssueQueryParams = (
|
inboxIssueQueryParams = (
|
||||||
inboxFilters: Partial<TInboxIssueFilter>,
|
inboxFilters: Partial<TInboxIssueFilter>,
|
||||||
inboxSorting: Partial<TInboxIssueSorting>,
|
inboxSorting: Partial<TInboxIssueSorting>,
|
||||||
@ -177,6 +217,8 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
set(this, "inboxFilters", undefined);
|
set(this, "inboxFilters", undefined);
|
||||||
set(this, ["inboxSorting", "order_by"], "issue__created_at");
|
set(this, ["inboxSorting", "order_by"], "issue__created_at");
|
||||||
set(this, ["inboxSorting", "sort_by"], "desc");
|
set(this, ["inboxSorting", "sort_by"], "desc");
|
||||||
|
set(this, ["inboxIssues"], {});
|
||||||
|
set(this, ["inboxIssuePaginationInfo"], undefined);
|
||||||
if (tab === "closed") set(this, ["inboxFilters", "status"], [-1, 1, 2]);
|
if (tab === "closed") set(this, ["inboxFilters", "status"], [-1, 1, 2]);
|
||||||
else set(this, ["inboxFilters", "status"], [-2]);
|
else set(this, ["inboxFilters", "status"], [-2]);
|
||||||
const { workspaceSlug, projectId } = this.store.app.router;
|
const { workspaceSlug, projectId } = this.store.app.router;
|
||||||
@ -185,12 +227,16 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
|
|
||||||
handleInboxIssueFilters = <T extends keyof TInboxIssueFilter>(key: T, value: TInboxIssueFilter[T]) => {
|
handleInboxIssueFilters = <T extends keyof TInboxIssueFilter>(key: T, value: TInboxIssueFilter[T]) => {
|
||||||
set(this.inboxFilters, key, value);
|
set(this.inboxFilters, key, value);
|
||||||
|
set(this, ["inboxIssues"], {});
|
||||||
|
set(this, ["inboxIssuePaginationInfo"], undefined);
|
||||||
const { workspaceSlug, projectId } = this.store.app.router;
|
const { workspaceSlug, projectId } = this.store.app.router;
|
||||||
if (workspaceSlug && projectId) this.fetchInboxIssues(workspaceSlug, projectId, "filter-loading");
|
if (workspaceSlug && projectId) this.fetchInboxIssues(workspaceSlug, projectId, "filter-loading");
|
||||||
};
|
};
|
||||||
|
|
||||||
handleInboxIssueSorting = <T extends keyof TInboxIssueSorting>(key: T, value: TInboxIssueSorting[T]) => {
|
handleInboxIssueSorting = <T extends keyof TInboxIssueSorting>(key: T, value: TInboxIssueSorting[T]) => {
|
||||||
set(this.inboxSorting, key, value);
|
set(this.inboxSorting, key, value);
|
||||||
|
set(this, ["inboxIssues"], {});
|
||||||
|
set(this, ["inboxIssuePaginationInfo"], undefined);
|
||||||
const { workspaceSlug, projectId } = this.store.app.router;
|
const { workspaceSlug, projectId } = this.store.app.router;
|
||||||
if (workspaceSlug && projectId) this.fetchInboxIssues(workspaceSlug, projectId, "filter-loading");
|
if (workspaceSlug && projectId) this.fetchInboxIssues(workspaceSlug, projectId, "filter-loading");
|
||||||
};
|
};
|
||||||
@ -202,10 +248,14 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
*/
|
*/
|
||||||
fetchInboxIssues = async (workspaceSlug: string, projectId: string, loadingType: TLoader = undefined) => {
|
fetchInboxIssues = async (workspaceSlug: string, projectId: string, loadingType: TLoader = undefined) => {
|
||||||
try {
|
try {
|
||||||
if (loadingType) this.isLoading = loadingType;
|
if (this.currentInboxProjectId != projectId) {
|
||||||
else if (Object.keys(this.inboxIssues).length === 0) this.isLoading = "init-loading";
|
set(this, ["currentInboxProjectId"], projectId);
|
||||||
set(this, ["inboxIssues"], {});
|
set(this, ["inboxIssues"], {});
|
||||||
set(this, ["inboxIssuePaginationInfo"], undefined);
|
set(this, ["inboxIssuePaginationInfo"], undefined);
|
||||||
|
}
|
||||||
|
if (Object.keys(this.inboxIssues).length === 0) this.isLoading = "init-loading";
|
||||||
|
else this.isLoading = "mutation-loading";
|
||||||
|
if (loadingType) this.isLoading = loadingType;
|
||||||
|
|
||||||
const queryParams = this.inboxIssueQueryParams(
|
const queryParams = this.inboxIssueQueryParams(
|
||||||
this.inboxFilters,
|
this.inboxFilters,
|
||||||
@ -247,9 +297,10 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
fetchInboxPaginationIssues = async (workspaceSlug: string, projectId: string) => {
|
fetchInboxPaginationIssues = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
!this.inboxIssuePaginationInfo?.total_results ||
|
this.inboxIssuePaginationInfo &&
|
||||||
|
(!this.inboxIssuePaginationInfo?.total_results ||
|
||||||
(this.inboxIssuePaginationInfo?.total_results &&
|
(this.inboxIssuePaginationInfo?.total_results &&
|
||||||
this.inboxIssuesArray.length < this.inboxIssuePaginationInfo?.total_results)
|
this.inboxIssuesArray.length < this.inboxIssuePaginationInfo?.total_results))
|
||||||
) {
|
) {
|
||||||
this.isLoading = "pagination-loading";
|
this.isLoading = "pagination-loading";
|
||||||
|
|
||||||
@ -299,15 +350,15 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||||||
const issueId = inboxIssue?.issue?.id || undefined;
|
const issueId = inboxIssue?.issue?.id || undefined;
|
||||||
|
|
||||||
if (inboxIssue && issueId) {
|
if (inboxIssue && issueId) {
|
||||||
|
runInAction(() => {
|
||||||
|
set(this.inboxIssues, [issueId], new InboxIssueStore(workspaceSlug, projectId, inboxIssue, this.store));
|
||||||
|
});
|
||||||
// fetching reactions
|
// fetching reactions
|
||||||
await this.store.issue.issueDetail.fetchReactions(workspaceSlug, projectId, issueId);
|
await this.store.issue.issueDetail.fetchReactions(workspaceSlug, projectId, issueId);
|
||||||
// fetching activity
|
// fetching activity
|
||||||
await this.store.issue.issueDetail.fetchActivities(workspaceSlug, projectId, issueId);
|
await this.store.issue.issueDetail.fetchActivities(workspaceSlug, projectId, issueId);
|
||||||
// fetching comments
|
// fetching comments
|
||||||
await this.store.issue.issueDetail.fetchComments(workspaceSlug, projectId, issueId);
|
await this.store.issue.issueDetail.fetchComments(workspaceSlug, projectId, issueId);
|
||||||
runInAction(() => {
|
|
||||||
set(this.inboxIssues, [issueId], new InboxIssueStore(workspaceSlug, projectId, inboxIssue, this.store));
|
|
||||||
});
|
|
||||||
this.isLoading = undefined;
|
this.isLoading = undefined;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
Loading…
Reference in New Issue
Block a user