[WEB-1624] chore: add un-snooze option and minor fixes in inbox issue (#4854)

* [WEB-1624] chore: add option to un-snooze inbox issue.

* [WEB-1605] fix: inbox issues snooze till date consistency.

* chore: update snooze/ un-snooze logic for issues for which snoozed till date is passed.
This commit is contained in:
Prateek Shourya 2024-06-18 19:59:28 +05:30 committed by GitHub
parent 135024a940
commit 8155d9a3ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 33 additions and 15 deletions

View file

@ -81,7 +81,7 @@ export type TInboxDuplicateIssueDetails = {
export type TInboxIssue = {
id: string;
status: TInboxIssueStatus;
snoozed_till: Date | undefined;
snoozed_till: Date | null;
duplicate_to: string | undefined;
source: string;
issue: TIssue;

View file

@ -28,6 +28,7 @@ import { IssueUpdateStatus } from "@/components/issues";
// constants
import { EUserProjectRoles } from "@/constants/project";
// helpers
import { findHowManyDaysLeft } from "@/helpers/date-time.helper";
import { EInboxIssueStatus } from "@/helpers/inbox.helper";
import { copyUrlToClipboard } from "@/helpers/string.helper";
// hooks
@ -71,6 +72,8 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p
const canMarkAsDeclined = isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
const canDelete = isAllowed || inboxIssue?.created_by === currentUser?.id;
const isAcceptedOrDeclined = inboxIssue?.status ? [-1, 1, 2].includes(inboxIssue.status) : undefined;
// days left for snooze
const numberOfDaysLeft = findHowManyDaysLeft(inboxIssue?.snoozed_till);
const currentInboxIssueId = inboxIssue?.issue?.id;
@ -109,7 +112,7 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p
handleRedirection(nextOrPreviousIssueId);
};
const handleInboxSIssueSnooze = async (date: Date) => {
const handleInboxIssueSnooze = async (date: Date) => {
const nextOrPreviousIssueId = redirectIssue();
await inboxIssue?.updateInboxIssueSnoozeTill(date);
setIsSnoozeDateModalOpen(false);
@ -127,6 +130,16 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p
});
};
const handleIssueSnoozeAction = async () => {
if (inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0) {
const nextOrPreviousIssueId = redirectIssue();
await inboxIssue?.updateInboxIssueSnoozeTill(undefined);
handleRedirection(nextOrPreviousIssueId);
} else {
setIsSnoozeDateModalOpen(true);
}
};
const handleCopyIssueLink = () =>
copyUrlToClipboard(issueLink).then(() =>
setToast({
@ -209,7 +222,7 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p
isOpen={isSnoozeDateModalOpen}
handleClose={() => setIsSnoozeDateModalOpen(false)}
value={inboxIssue?.snoozed_till}
onConfirm={handleInboxSIssueSnooze}
onConfirm={handleInboxIssueSnooze}
/>
</>
@ -299,10 +312,12 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p
{isAllowed && (
<CustomMenu verticalEllipsis placement="bottom-start">
{canMarkAsAccepted && (
<CustomMenu.MenuItem onClick={() => setIsSnoozeDateModalOpen(true)}>
<CustomMenu.MenuItem onClick={handleIssueSnoozeAction}>
<div className="flex items-center gap-2">
<Clock size={14} strokeWidth={2} />
Snooze
{inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0
? "Un-snooze"
: "Snooze"}
</div>
</CustomMenu.MenuItem>
)}
@ -337,7 +352,7 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p
handleCopyIssueLink={handleCopyIssueLink}
setAcceptIssueModal={setAcceptIssueModal}
setDeclineIssueModal={setDeclineIssueModal}
setIsSnoozeDateModalOpen={setIsSnoozeDateModalOpen}
handleIssueSnoozeAction={handleIssueSnoozeAction}
setSelectDuplicateIssue={setSelectDuplicateIssue}
setDeleteIssueModal={setDeleteIssueModal}
canMarkAsAccepted={canMarkAsAccepted}

View file

@ -20,6 +20,7 @@ import { InboxIssueStatus } from "@/components/inbox";
import { IssueUpdateStatus } from "@/components/issues";
// helpers
import { cn } from "@/helpers/common.helper";
import { findHowManyDaysLeft } from "@/helpers/date-time.helper";
// hooks
import { useAppRouter } from "@/hooks/use-app-router";
// store types
@ -38,7 +39,7 @@ type Props = {
setAcceptIssueModal: (value: boolean) => void;
setDeclineIssueModal: (value: boolean) => void;
setDeleteIssueModal: (value: boolean) => void;
setIsSnoozeDateModalOpen: (value: boolean) => void;
handleIssueSnoozeAction: () => Promise<void>;
setSelectDuplicateIssue: (value: boolean) => void;
handleCopyIssueLink: () => void;
isMobileSidebar: boolean;
@ -59,7 +60,7 @@ export const InboxIssueActionsMobileHeader: React.FC<Props> = observer((props) =
setAcceptIssueModal,
setDeclineIssueModal,
setDeleteIssueModal,
setIsSnoozeDateModalOpen,
handleIssueSnoozeAction,
setSelectDuplicateIssue,
handleCopyIssueLink,
isMobileSidebar,
@ -68,6 +69,8 @@ export const InboxIssueActionsMobileHeader: React.FC<Props> = observer((props) =
const router = useAppRouter();
const issue = inboxIssue?.issue;
const currentInboxIssueId = issue?.id;
// days left for snooze
const numberOfDaysLeft = findHowManyDaysLeft(inboxIssue?.snoozed_till);
if (!issue || !inboxIssue) return null;
@ -126,10 +129,10 @@ export const InboxIssueActionsMobileHeader: React.FC<Props> = observer((props) =
</CustomMenu.MenuItem>
)}
{canMarkAsAccepted && !isAcceptedOrDeclined && (
<CustomMenu.MenuItem onClick={() => setIsSnoozeDateModalOpen(true)}>
<CustomMenu.MenuItem onClick={handleIssueSnoozeAction}>
<div className="flex items-center gap-2">
<Clock size={14} strokeWidth={2} />
Snooze
{inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0 ? "Un-snooze" : "Snooze"}
</div>
</CustomMenu.MenuItem>
)}

View file

@ -22,7 +22,7 @@ export interface IInboxIssueStore {
// actions
updateInboxIssueStatus: (status: TInboxIssueStatus) => Promise<void>; // accept, decline
updateInboxIssueDuplicateTo: (issueId: string) => Promise<void>; // connecting the inbox issue to the project existing issue
updateInboxIssueSnoozeTill: (date: Date) => Promise<void>; // snooze the issue
updateInboxIssueSnoozeTill: (date: Date | undefined) => Promise<void>; // snooze the issue
updateIssue: (issue: Partial<TIssue>) => Promise<void>; // updating the issue
updateProjectIssue: (issue: Partial<TIssue>) => Promise<void>; // updating the issue
fetchIssueActivity: () => Promise<void>; // fetching the issue activity
@ -53,7 +53,7 @@ export class InboxIssueStore implements IInboxIssueStore {
this.id = data.id;
this.status = data.status;
this.issue = data?.issue;
this.snoozed_till = data?.snoozed_till ? new Date(data.snoozed_till) : undefined;
this.snoozed_till = data?.snoozed_till || undefined;
this.duplicate_to = data?.duplicate_to || undefined;
this.created_by = data?.created_by || undefined;
this.duplicate_issue_detail = data?.duplicate_issue_detail || undefined;
@ -124,8 +124,8 @@ export class InboxIssueStore implements IInboxIssueStore {
}
};
updateInboxIssueSnoozeTill = async (date: Date) => {
const inboxStatus = EInboxIssueStatus.SNOOZED;
updateInboxIssueSnoozeTill = async (date: Date | undefined) => {
const inboxStatus = date ? EInboxIssueStatus.SNOOZED : EInboxIssueStatus.PENDING;
const previousData: Partial<TInboxIssue> = {
status: this.status,
snoozed_till: this.snoozed_till,
@ -134,7 +134,7 @@ export class InboxIssueStore implements IInboxIssueStore {
if (!this.issue.id) return;
const inboxIssue = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, {
status: inboxStatus,
snoozed_till: new Date(date),
snoozed_till: date ? new Date(date) : null,
});
runInAction(() => {
set(this, "status", inboxIssue?.status);