diff --git a/apps/app/components/inbox/decline-issue-modal.tsx b/apps/app/components/inbox/decline-issue-modal.tsx index 64fe1682a..941841659 100644 --- a/apps/app/components/inbox/decline-issue-modal.tsx +++ b/apps/app/components/inbox/decline-issue-modal.tsx @@ -1,102 +1,33 @@ -import React, { useEffect, useState } from "react"; - -import { useRouter } from "next/router"; - -import { mutate } from "swr"; +import React, { useState } from "react"; // headless ui import { Dialog, Transition } from "@headlessui/react"; -// services -import inboxServices from "services/inbox.service"; -// hooks -import useToast from "hooks/use-toast"; -import useInboxView from "hooks/use-inbox-view"; -import useUser from "hooks/use-user"; // icons import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; // ui import { SecondaryButton, DangerButton } from "components/ui"; // types -import type { IInboxIssue, ICurrentUserResponse, IInboxIssueDetail } from "types"; -// fetch-keys -import { INBOX_ISSUES, INBOX_ISSUE_DETAILS } from "constants/fetch-keys"; +import type { IInboxIssue } from "types"; type Props = { isOpen: boolean; handleClose: () => void; data: IInboxIssue | undefined; + onSubmit: () => Promise; }; -export const DeclineIssueModal: React.FC = ({ isOpen, handleClose, data }) => { +export const DeclineIssueModal: React.FC = ({ isOpen, handleClose, data, onSubmit }) => { const [isDeclining, setIsDeclining] = useState(false); - const router = useRouter(); - const { workspaceSlug, projectId, inboxId } = router.query; - - const { user } = useUser(); - const { setToastAlert } = useToast(); - const { params } = useInboxView(); - const onClose = () => { setIsDeclining(false); handleClose(); }; const handleDecline = () => { - if (!workspaceSlug || !projectId || !inboxId || !data) return; - setIsDeclining(true); - inboxServices - .markInboxStatus( - workspaceSlug.toString(), - projectId.toString(), - inboxId.toString(), - data.bridge_id, - { - status: -1, - }, - user - ) - .then(() => { - mutate( - INBOX_ISSUE_DETAILS(inboxId.toString(), data.bridge_id), - (prevData) => { - if (!prevData) return prevData; - - return { - ...prevData, - issue_inbox: [{ ...prevData.issue_inbox[0], status: -1 }], - }; - }, - false - ); - mutate( - INBOX_ISSUES(inboxId.toString(), params), - (prevData) => - prevData?.map((i) => - i.bridge_id === data.bridge_id - ? { ...i, issue_inbox: [{ ...i.issue_inbox[0], status: -1 }] } - : i - ), - false - ); - - setToastAlert({ - type: "success", - title: "Success!", - message: "Issue declined successfully.", - }); - onClose(); - }) - .catch(() => - setToastAlert({ - type: "error", - title: "Error!", - message: "Issue could not be declined. Please try again.", - }) - ) - .finally(() => setIsDeclining(false)); + onSubmit().finally(() => setIsDeclining(false)); }; return ( diff --git a/apps/app/components/inbox/delete-issue-modal.tsx b/apps/app/components/inbox/delete-issue-modal.tsx index 46ba1ebdd..c6f5320a2 100644 --- a/apps/app/components/inbox/delete-issue-modal.tsx +++ b/apps/app/components/inbox/delete-issue-modal.tsx @@ -130,7 +130,8 @@ export const DeleteIssueModal: React.FC = ({ isOpen, handleClose, data }) {data?.project_detail?.identifier}-{data?.sequence_id} - {""}? This action cannot be undone. + {""}? The issue will only be deleted from the inbox and this action cannot be + undone.

diff --git a/apps/app/components/inbox/filters-dropdown.tsx b/apps/app/components/inbox/filters-dropdown.tsx index 938e4fc01..b567baed0 100644 --- a/apps/app/components/inbox/filters-dropdown.tsx +++ b/apps/app/components/inbox/filters-dropdown.tsx @@ -6,7 +6,7 @@ import { getPriorityIcon } from "components/icons"; import { IInboxFilterOptions } from "types"; // constants import { PRIORITIES } from "constants/project"; -import { STATUS } from "constants/inbox"; +import { INBOX_STATUS } from "constants/inbox"; type Props = { filters: Partial; @@ -45,16 +45,16 @@ export const FiltersDropdown: React.FC = ({ filters, onSelect, direction, { id: "inbox_status", label: "Status", - value: Object.values(STATUS), + value: INBOX_STATUS.map((status) => status.value), children: [ - ...Object.keys(STATUS).map((status) => ({ - id: status, - label: status, + ...INBOX_STATUS.map((status) => ({ + id: status.key, + label: status.label, value: { key: "inbox_status", - value: STATUS[status], + value: status.value, }, - selected: filters?.inbox_status?.includes(STATUS[status]), + selected: filters?.inbox_status?.includes(status.value), })), ], }, diff --git a/apps/app/components/inbox/filters-list.tsx b/apps/app/components/inbox/filters-list.tsx new file mode 100644 index 000000000..aa8213b2f --- /dev/null +++ b/apps/app/components/inbox/filters-list.tsx @@ -0,0 +1,126 @@ +// hooks +import useInboxView from "hooks/use-inbox-view"; +// icons +import { XMarkIcon } from "@heroicons/react/24/outline"; +import { getPriorityIcon } from "components/icons"; +// helpers +import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper"; +// constants +import { INBOX_STATUS } from "constants/inbox"; + +export const InboxFiltersList = () => { + const { filters, setFilters, clearAllFilters, filtersLength } = useInboxView(); + + if (filtersLength <= 0) return <>; + + return ( +
+ {Object.keys(filters).map((key) => { + const filterKey = key as keyof typeof filters; + + if (filters[filterKey] !== null) + return ( +
+ + {replaceUnderscoreIfSnakeCase(key)}: + + {filters[filterKey] === null || (filters[filterKey]?.length ?? 0) <= 0 ? ( + None + ) : ( +
+ {filterKey === "priority" ? ( +
+ {filters.priority?.map((priority) => ( +
+ {getPriorityIcon(priority)} + +
+ ))} + +
+ ) : filterKey === "inbox_status" ? ( +
+ {filters.inbox_status?.map((status) => ( +
+ {INBOX_STATUS.find((s) => s.value === status)?.label} + +
+ ))} + +
+ ) : ( + (filters[filterKey] as any)?.join(", ") + )} +
+ )} +
+ ); + })} + +
+ ); +}; diff --git a/apps/app/components/inbox/inbox-action-headers.tsx b/apps/app/components/inbox/inbox-action-headers.tsx index 8be550d98..5ceaa8f2c 100644 --- a/apps/app/components/inbox/inbox-action-headers.tsx +++ b/apps/app/components/inbox/inbox-action-headers.tsx @@ -76,6 +76,11 @@ export const InboxActionHeader: React.FC = (props) => { const issueStatus = issue?.issue_inbox[0].status; const isAllowed = memberRole.isMember || memberRole.isOwner; + const today = new Date(); + const tomorrow = new Date(today); + + tomorrow.setDate(today.getDate() + 1); + return (
@@ -142,12 +147,20 @@ export const InboxActionHeader: React.FC = (props) => {
{isAllowed && ( -
+
- + @@ -165,6 +178,7 @@ export const InboxActionHeader: React.FC = (props) => { setDate(val); }} dateFormat="dd-MM-yyyy" + minDate={tomorrow} inline /> = (props) => { )} +
+ )} + {isAllowed && ( +
= (props) => {
{issue.issue_inbox[0].snoozed_till && ( -
+
Snoozed till {renderShortNumericDateFormat(issue.issue_inbox[0].snoozed_till)} diff --git a/apps/app/components/inbox/inbox-main-content.tsx b/apps/app/components/inbox/inbox-main-content.tsx index 1bf330e5e..83948495c 100644 --- a/apps/app/components/inbox/inbox-main-content.tsx +++ b/apps/app/components/inbox/inbox-main-content.tsx @@ -36,7 +36,7 @@ import { renderShortNumericDateFormat } from "helpers/date-time.helper"; // types import type { IInboxIssue, IIssue } from "types"; // fetch-keys -import { INBOX_ISSUES, INBOX_ISSUE_DETAILS } from "constants/fetch-keys"; +import { INBOX_ISSUES, INBOX_ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; const defaultValues = { name: "", @@ -129,6 +129,7 @@ export const InboxMainContent: React.FC = () => { .then(() => { mutateIssueDetails(); mutate(INBOX_ISSUES(inboxId.toString(), params)); + mutate(PROJECT_ISSUES_ACTIVITY(issueDetails.id)); }); }, [ @@ -157,7 +158,9 @@ export const InboxMainContent: React.FC = () => { : issueStatus === -1 ? "text-red-500 border-red-500 bg-red-500/10" : issueStatus === 0 - ? "text-blue-500 border-blue-500 bg-blue-500/10" + ? new Date(issueDetails.issue_inbox[0].snoozed_till ?? "") < new Date() + ? "text-red-500 border-red-500 bg-red-500/10" + : "text-blue-500 border-blue-500 bg-blue-500/10" : issueStatus === 1 ? "text-green-500 border-green-500 bg-green-500/10" : issueStatus === 2 @@ -178,10 +181,19 @@ export const InboxMainContent: React.FC = () => { ) : issueStatus === 0 ? ( <> -

- This issue has been snoozed till{" "} - {renderShortNumericDateFormat(issueDetails.issue_inbox[0].snoozed_till ?? "")}. -

+ {new Date(issueDetails.issue_inbox[0].snoozed_till ?? "") < new Date() ? ( +

+ This issue was snoozed till{" "} + {renderShortNumericDateFormat(issueDetails.issue_inbox[0].snoozed_till ?? "")} + . +

+ ) : ( +

+ This issue has been snoozed till{" "} + {renderShortNumericDateFormat(issueDetails.issue_inbox[0].snoozed_till ?? "")} + . +

+ )} ) : issueStatus === 1 ? ( <> diff --git a/apps/app/components/inbox/index.ts b/apps/app/components/inbox/index.ts index 3f66790bc..7cdd8ee9d 100644 --- a/apps/app/components/inbox/index.ts +++ b/apps/app/components/inbox/index.ts @@ -1,6 +1,7 @@ export * from "./decline-issue-modal"; export * from "./delete-issue-modal"; export * from "./filters-dropdown"; +export * from "./filters-list"; export * from "./inbox-action-headers"; export * from "./inbox-issue-card"; export * from "./inbox-main-content"; diff --git a/apps/app/components/inbox/issues-list-sidebar.tsx b/apps/app/components/inbox/issues-list-sidebar.tsx index 02181c02a..9f5c85db1 100644 --- a/apps/app/components/inbox/issues-list-sidebar.tsx +++ b/apps/app/components/inbox/issues-list-sidebar.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; // hooks import useInboxView from "hooks/use-inbox-view"; // components -import { InboxIssueCard } from "components/inbox"; +import { InboxIssueCard, InboxFiltersList } from "components/inbox"; // ui import { Loader } from "components/ui"; @@ -14,10 +14,11 @@ export const IssuesListSidebar = () => { const { issues: inboxIssues } = useInboxView(); return ( - <> +
+ {inboxIssues ? ( inboxIssues.length > 0 ? ( -
+
{inboxIssues.map((issue) => ( { )} - +
); }; diff --git a/apps/app/components/inbox/select-duplicate.tsx b/apps/app/components/inbox/select-duplicate.tsx index fdf7034df..74409a57f 100644 --- a/apps/app/components/inbox/select-duplicate.tsx +++ b/apps/app/components/inbox/select-duplicate.tsx @@ -76,7 +76,7 @@ export const SelectDuplicateInboxIssueModal: React.FC = (props) => { return ( setQuery("")} appear> -
+
= ({ {issueDetail?.project_detail?.identifier}-{issueDetail?.sequence_id}
- + {(fieldsToShow.includes("all") || fieldsToShow.includes("link")) && ( + + )} {!isNotAllowed && (fieldsToShow.includes("all") || fieldsToShow.includes("delete")) && (