diff --git a/apps/app/components/notifications/notification-card.tsx b/apps/app/components/notifications/notification-card.tsx index fd1d5b629..787ad50c0 100644 --- a/apps/app/components/notifications/notification-card.tsx +++ b/apps/app/components/notifications/notification-card.tsx @@ -39,8 +39,6 @@ export const NotificationCard: React.FC = (props) => { const { setToastAlert } = useToast(); - if (notification.data.issue_activity.field === "None") return null; - return (
= (props) => { {notification.data.issue_activity.field !== "comment" && notification.data.issue_activity.verb}{" "} - {notification.data.issue_activity.field !== "comment" - ? replaceUnderscoreIfSnakeCase(notification.data.issue_activity.field) - : "commented"}{" "} - {notification.data.issue_activity.field !== "comment" ? "to" : ""} + {notification.data.issue_activity.field === "comment" + ? "commented" + : notification.data.issue_activity.field === "None" + ? null + : replaceUnderscoreIfSnakeCase(notification.data.issue_activity.field)}{" "} + {notification.data.issue_activity.field !== "comment" && + notification.data.issue_activity.field !== "None" + ? "to" + : ""} {" "} - {notification.data.issue_activity.field !== "comment" ? ( - notification.data.issue_activity.field === "target_date" ? ( - renderShortDateWithYearFormat(notification.data.issue_activity.new_value) - ) : notification.data.issue_activity.field === "attachment" ? ( - "the issue" - ) : stripHTML(notification.data.issue_activity.new_value).length > 55 ? ( - stripHTML(notification.data.issue_activity.new_value).slice(0, 50) + "..." + {notification.data.issue_activity.field !== "None" ? ( + notification.data.issue_activity.field !== "comment" ? ( + notification.data.issue_activity.field === "target_date" ? ( + renderShortDateWithYearFormat(notification.data.issue_activity.new_value) + ) : notification.data.issue_activity.field === "attachment" ? ( + "the issue" + ) : stripHTML(notification.data.issue_activity.new_value).length > 55 ? ( + stripHTML(notification.data.issue_activity.new_value).slice(0, 50) + "..." + ) : ( + stripHTML(notification.data.issue_activity.new_value) + ) ) : ( - stripHTML(notification.data.issue_activity.new_value) + + {`"`} + {notification.data.issue_activity.new_value.length > 55 + ? notification?.data?.issue_activity?.issue_comment?.slice(0, 50) + "..." + : notification.data.issue_activity.issue_comment} + {`"`} + ) ) : ( - - {`"`} - {notification.data.issue_activity.new_value.length > 55 - ? notification?.data?.issue_activity?.issue_comment?.slice(0, 50) + "..." - : notification.data.issue_activity.issue_comment} - {`"`} - + "the issue and assigned it to you." )}

diff --git a/apps/app/components/notifications/notification-popover.tsx b/apps/app/components/notifications/notification-popover.tsx index fb79b5a5d..7da63fb97 100644 --- a/apps/app/components/notifications/notification-popover.tsx +++ b/apps/app/components/notifications/notification-popover.tsx @@ -5,7 +5,7 @@ import Image from "next/image"; // hooks import useTheme from "hooks/use-theme"; -import { Popover, Transition, Menu } from "@headlessui/react"; +import { Popover, Transition } from "@headlessui/react"; // hooks import useUserNotification from "hooks/use-user-notifications"; @@ -14,27 +14,12 @@ import useUserNotification from "hooks/use-user-notifications"; import { Spinner, Icon } from "components/ui"; import { SnoozeNotificationModal, NotificationCard } from "components/notifications"; +// helpers +import { getNumberCount } from "helpers/string.helper"; + // type import type { NotificationType } from "types"; -const notificationTabs: Array<{ - label: string; - value: NotificationType; -}> = [ - { - label: "My Issues", - value: "assigned", - }, - { - label: "Created by me", - value: "created", - }, - { - label: "Subscribed", - value: "watching", - }, -]; - export const NotificationPopover = () => { const { notifications, @@ -52,11 +37,35 @@ export const NotificationPopover = () => { markNotificationArchivedStatus, markNotificationReadStatus, markSnoozeNotification, + notificationCount, + totalNotificationCount, } = useUserNotification(); // theme context const { collapsed: sidebarCollapse } = useTheme(); + const notificationTabs: Array<{ + label: string; + value: NotificationType; + unreadCount?: number; + }> = [ + { + label: "My Issues", + value: "assigned", + unreadCount: notificationCount?.my_issues, + }, + { + label: "Created by me", + value: "created", + unreadCount: notificationCount?.created_issues, + }, + { + label: "Subscribed", + value: "watching", + unreadCount: notificationCount?.watching_notifications, + }, + ]; + return ( <> { > {sidebarCollapse ? null : Notifications} + {totalNotificationCount && totalNotificationCount > 0 ? ( + + {getNumberCount(totalNotificationCount)} + + ) : null} { }`} > {tab.label} + {tab.unreadCount && tab.unreadCount > 0 ? ( + + {getNumberCount(tab.unreadCount)} + + ) : null} ))} diff --git a/apps/app/constants/fetch-keys.ts b/apps/app/constants/fetch-keys.ts index 5da215add..d0e9a0e19 100644 --- a/apps/app/constants/fetch-keys.ts +++ b/apps/app/constants/fetch-keys.ts @@ -241,3 +241,6 @@ export const USER_WORKSPACE_NOTIFICATIONS_DETAILS = ( notificationId: string ) => `USER_WORKSPACE_NOTIFICATIONS_DETAILS_${workspaceSlug.toUpperCase()}_${notificationId.toUpperCase()}`; + +export const UNREAD_NOTIFICATIONS_COUNT = (workspaceSlug: string) => + `UNREAD_NOTIFICATIONS_COUNT_${workspaceSlug.toUpperCase()}`; diff --git a/apps/app/helpers/string.helper.ts b/apps/app/helpers/string.helper.ts index 2436a8d12..ae78d6f97 100644 --- a/apps/app/helpers/string.helper.ts +++ b/apps/app/helpers/string.helper.ts @@ -134,3 +134,20 @@ export const stripHTML = (html: string) => { tmp.innerHTML = html; return tmp.textContent || tmp.innerText || ""; }; + +/** + * @description: This function return number count in string if number is more than 100 then it will return 99+ + * @param {number} number + * @return {string} + * @example: + * const number = 100; + * const text = getNumberCount(number); + * console.log(text); // 99+ + */ + +export const getNumberCount = (number: number): string => { + if (number > 99) { + return "99+"; + } + return number.toString(); +}; diff --git a/apps/app/hooks/use-user-notifications.tsx b/apps/app/hooks/use-user-notifications.tsx index 948d48280..4de9d296c 100644 --- a/apps/app/hooks/use-user-notifications.tsx +++ b/apps/app/hooks/use-user-notifications.tsx @@ -9,7 +9,7 @@ import useSWR from "swr"; import userNotificationServices from "services/notifications.service"; // fetch-keys -import { USER_WORKSPACE_NOTIFICATIONS } from "constants/fetch-keys"; +import { UNREAD_NOTIFICATIONS_COUNT, USER_WORKSPACE_NOTIFICATIONS } from "constants/fetch-keys"; // type import type { NotificationType } from "types"; @@ -46,6 +46,14 @@ const useUserNotification = () => { : null ); + const { data: notificationCount, mutate: mutateNotificationCount } = useSWR( + workspaceSlug ? UNREAD_NOTIFICATIONS_COUNT(workspaceSlug.toString()) : null, + () => + workspaceSlug + ? userNotificationServices.getUnreadNotificationsCount(workspaceSlug.toString()) + : null + ); + const markNotificationReadStatus = async (notificationId: string) => { if (!workspaceSlug) return; const isRead = @@ -66,6 +74,7 @@ const useUserNotification = () => { return prevNotification; }) ); + mutateNotificationCount(); }) .catch(() => { throw new Error("Something went wrong"); @@ -85,6 +94,7 @@ const useUserNotification = () => { return prevNotification; }) ); + mutateNotificationCount(); }) .catch(() => { throw new Error("Something went wrong"); @@ -164,6 +174,13 @@ const useUserNotification = () => { setSelectedNotificationForSnooze, selectedTab, setSelectedTab, + totalNotificationCount: notificationCount + ? notificationCount.created_issues + + notificationCount.watching_notifications + + notificationCount.my_issues + : null, + notificationCount, + mutateNotificationCount, }; }; diff --git a/apps/app/services/notifications.service.ts b/apps/app/services/notifications.service.ts index 8a9cc8e4c..f2b49b954 100644 --- a/apps/app/services/notifications.service.ts +++ b/apps/app/services/notifications.service.ts @@ -155,6 +155,18 @@ class UserNotificationsServices extends APIService { throw error?.response?.data; }); } + + async getUnreadNotificationsCount(workspaceSlug: string): Promise<{ + created_issues: number; + my_issues: number; + watching_notifications: number; + }> { + return this.get(`/api/workspaces/${workspaceSlug}/users/notifications/unread/`) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } } const userNotificationServices = new UserNotificationsServices();