plane/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx
Prateek Shourya 53367a6bc4
[WEB-570] chore: toast refactor (#3836)
* new toast setup

* chore: new toast implementation.

* chore: move toast component to ui package.

* chore: replace `setToast` with `setPromiseToast` in required places for better UX.
* chore: code cleanup.

* chore: update theme.

* fix: theme switching issue.

* chore: remove toast from issue update operations.

* chore: add promise toast for add/ remove issue to cycle/ module and remove local spinners.

---------

Co-authored-by: rahulramesha <rahulramesham@gmail.com>
2024-03-06 14:18:41 +05:30

140 lines
5.1 KiB
TypeScript

import { FC, useCallback } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { DragDropContext, DropResult } from "@hello-pangea/dnd";
// components
import { CalendarChart } from "components/issues";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
// types
import { TGroupedIssues, TIssue } from "@plane/types";
import { IQuickActionProps } from "../list/list-view-types";
import { EIssueActions } from "../types";
import { handleDragDrop } from "./utils";
import { useIssues, useUser } from "hooks/store";
import { ICycleIssues, ICycleIssuesFilter } from "store/issue/cycle";
import { IModuleIssues, IModuleIssuesFilter } from "store/issue/module";
import { IProjectIssues, IProjectIssuesFilter } from "store/issue/project";
import { IProjectViewIssues, IProjectViewIssuesFilter } from "store/issue/project-views";
import { EUserProjectRoles } from "constants/project";
interface IBaseCalendarRoot {
issueStore: IProjectIssues | IModuleIssues | ICycleIssues | IProjectViewIssues;
issuesFilterStore: IProjectIssuesFilter | IModuleIssuesFilter | ICycleIssuesFilter | IProjectViewIssuesFilter;
QuickActions: FC<IQuickActionProps>;
issueActions: {
[EIssueActions.DELETE]: (issue: TIssue) => Promise<void>;
[EIssueActions.UPDATE]?: (issue: TIssue) => Promise<void>;
[EIssueActions.REMOVE]?: (issue: TIssue) => Promise<void>;
[EIssueActions.ARCHIVE]?: (issue: TIssue) => Promise<void>;
[EIssueActions.RESTORE]?: (issue: TIssue) => Promise<void>;
};
viewId?: string;
isCompletedCycle?: boolean;
}
export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => {
const { issueStore, issuesFilterStore, QuickActions, issueActions, viewId, isCompletedCycle = false } = props;
// router
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// hooks
const { issueMap } = useIssues();
const {
membership: { currentProjectRole },
} = useUser();
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
const displayFilters = issuesFilterStore.issueFilters?.displayFilters;
const groupedIssueIds = (issueStore.groupedIssueIds ?? {}) as TGroupedIssues;
const onDragEnd = async (result: DropResult) => {
if (!result) return;
// return if not dropped on the correct place
if (!result.destination) return;
// return if dropped on the same date
if (result.destination.droppableId === result.source.droppableId) return;
if (handleDragDrop) {
await handleDragDrop(
result.source,
result.destination,
workspaceSlug?.toString(),
projectId?.toString(),
issueStore,
issueMap,
groupedIssueIds,
viewId
).catch((err) => {
setToast({
title: "Error",
type: TOAST_TYPE.ERROR,
message: err.detail ?? "Failed to perform this action",
});
});
}
};
const handleIssues = useCallback(
async (date: string, issue: TIssue, action: EIssueActions) => {
if (issueActions[action]) {
await issueActions[action]!(issue);
}
},
[issueActions]
);
return (
<>
<div className="h-full w-full overflow-hidden bg-custom-background-100 pt-4">
<DragDropContext onDragEnd={onDragEnd}>
<CalendarChart
issuesFilterStore={issuesFilterStore}
issues={issueMap}
groupedIssueIds={groupedIssueIds}
layout={displayFilters?.calendar?.layout}
showWeekends={displayFilters?.calendar?.show_weekends ?? false}
quickActions={(issue, customActionButton) => (
<QuickActions
customActionButton={customActionButton}
issue={issue}
handleDelete={async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.DELETE)}
handleUpdate={
issueActions[EIssueActions.UPDATE]
? async (data) => handleIssues(issue.target_date ?? "", data, EIssueActions.UPDATE)
: undefined
}
handleRemoveFromView={
issueActions[EIssueActions.REMOVE]
? async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.REMOVE)
: undefined
}
handleArchive={
issueActions[EIssueActions.ARCHIVE]
? async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.ARCHIVE)
: undefined
}
handleRestore={
issueActions[EIssueActions.RESTORE]
? async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.RESTORE)
: undefined
}
readOnly={!isEditingAllowed || isCompletedCycle}
/>
)}
quickAddCallback={issueStore.quickAddIssue}
viewId={viewId}
readOnly={!isEditingAllowed || isCompletedCycle}
/>
</DragDropContext>
</div>
</>
);
});