[WEB-1764] chore: revamp workspace notifications (#4947)
* chore: Initialised store and updated the components * chore: updated store and types * chore: updated notifications in the side and updated store * chore: handled notification center * chore: updates store request * chore: notifications filter changed * chore: updated filter logic and handled bulk read * chore: handled filter dropdown * chore: handled ui * chore: resolved build error * chore: implemented applied filters * chore: removed old notifications * chore: added redirection from sidebar * chore: updated notification as read when we see the notification preview * chore: updated read and unread validation * chore: handled custom snooze dropdown * chore: resolved git comments * chore: updated structure and typos * chore: import and prop changes * chore: updated avatar props * chore: updated avatar * chore: notification unread count on the app sidebar --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
This commit is contained in:
parent
8d5d0422e9
commit
209dc57307
59 changed files with 2337 additions and 1623 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { linearGradientDef } from "@nivo/core";
|
||||
// icons
|
||||
import { BarChart2, Briefcase, CheckCircle, Home, Settings } from "lucide-react";
|
||||
import { BarChart2, Bell, Briefcase, CheckCircle, Home, Settings } from "lucide-react";
|
||||
// types
|
||||
import { TIssuesListTypes, TStateGroups } from "@plane/types";
|
||||
// ui
|
||||
|
|
@ -317,4 +317,12 @@ export const SIDEBAR_USER_MENU_ITEMS: {
|
|||
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/`,
|
||||
Icon: Home,
|
||||
},
|
||||
{
|
||||
key: "notifications",
|
||||
label: "Notifications",
|
||||
href: `/notifications`,
|
||||
access: EUserWorkspaceRoles.GUEST,
|
||||
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/notifications`,
|
||||
Icon: Bell,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ export enum EmptyStateType {
|
|||
ISSUE_RELATION_EMPTY_STATE = "issue-relation-empty-state",
|
||||
ISSUE_COMMENT_EMPTY_STATE = "issue-comment-empty-state",
|
||||
|
||||
NOTIFICATION_ALL_EMPTY_STATE = "notification-all-empty-state",
|
||||
NOTIFICATION_MENTIONS_EMPTY_STATE = "notification-mentions-empty-state",
|
||||
NOTIFICATION_MY_ISSUE_EMPTY_STATE = "notification-my-issues-empty-state",
|
||||
NOTIFICATION_CREATED_EMPTY_STATE = "notification-created-empty-state",
|
||||
NOTIFICATION_SUBSCRIBED_EMPTY_STATE = "notification-subscribed-empty-state",
|
||||
|
|
@ -593,13 +595,24 @@ const emptyStateDetails = {
|
|||
path: "/empty-state/search/comments",
|
||||
},
|
||||
|
||||
[EmptyStateType.NOTIFICATION_ALL_EMPTY_STATE]: {
|
||||
key: EmptyStateType.NOTIFICATION_ALL_EMPTY_STATE,
|
||||
title: "No issues assigned",
|
||||
description: "Updates for issues assigned to you can be \n seen here",
|
||||
path: "/empty-state/search/notification",
|
||||
},
|
||||
[EmptyStateType.NOTIFICATION_MENTIONS_EMPTY_STATE]: {
|
||||
key: EmptyStateType.NOTIFICATION_MENTIONS_EMPTY_STATE,
|
||||
title: "No issues assigned",
|
||||
description: "Updates for issues assigned to you can be \n seen here",
|
||||
path: "/empty-state/search/notification",
|
||||
},
|
||||
[EmptyStateType.NOTIFICATION_MY_ISSUE_EMPTY_STATE]: {
|
||||
key: EmptyStateType.NOTIFICATION_MY_ISSUE_EMPTY_STATE,
|
||||
title: "No issues assigned",
|
||||
description: "Updates for issues assigned to you can be \n seen here",
|
||||
path: "/empty-state/search/notification",
|
||||
},
|
||||
|
||||
[EmptyStateType.NOTIFICATION_CREATED_EMPTY_STATE]: {
|
||||
key: EmptyStateType.NOTIFICATION_CREATED_EMPTY_STATE,
|
||||
title: "No updates to issues",
|
||||
|
|
@ -630,6 +643,7 @@ const emptyStateDetails = {
|
|||
description: "Any notification you archive will be \n available here to help you focus",
|
||||
path: "/empty-state/search/archive",
|
||||
},
|
||||
|
||||
[EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE]: {
|
||||
key: EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE,
|
||||
title: "Add issues to the cycle to view it's \n progress",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { IAnalyticsParams, IJiraMetadata, INotificationParams } from "@plane/types";
|
||||
import { objToQueryParams } from "@/helpers/string.helper";
|
||||
import { IAnalyticsParams, IJiraMetadata } from "@plane/types";
|
||||
|
||||
const paramsToKey = (params: any) => {
|
||||
const {
|
||||
|
|
@ -246,41 +245,6 @@ export const ANALYTICS = (workspaceSlug: string, params: IAnalyticsParams) =>
|
|||
export const DEFAULT_ANALYTICS = (workspaceSlug: string, params?: Partial<IAnalyticsParams>) =>
|
||||
`DEFAULT_ANALYTICS_${workspaceSlug.toUpperCase()}_${params?.project?.toString()}_${params?.cycle}_${params?.module}`;
|
||||
|
||||
// notifications
|
||||
export const USER_WORKSPACE_NOTIFICATIONS = (workspaceSlug: string, params: INotificationParams) => {
|
||||
const { type, snoozed, archived, read } = params;
|
||||
|
||||
return `USER_WORKSPACE_NOTIFICATIONS_${workspaceSlug?.toUpperCase()}_TYPE_${(
|
||||
type ?? "assigned"
|
||||
)?.toUpperCase()}_SNOOZED_${snoozed}_ARCHIVED_${archived}_READ_${read}`;
|
||||
};
|
||||
|
||||
export const USER_WORKSPACE_NOTIFICATIONS_DETAILS = (workspaceSlug: string, notificationId: string) =>
|
||||
`USER_WORKSPACE_NOTIFICATIONS_DETAILS_${workspaceSlug?.toUpperCase()}_${notificationId?.toUpperCase()}`;
|
||||
|
||||
export const UNREAD_NOTIFICATIONS_COUNT = (workspaceSlug: string) =>
|
||||
`UNREAD_NOTIFICATIONS_COUNT_${workspaceSlug?.toUpperCase()}`;
|
||||
|
||||
export const getPaginatedNotificationKey = (index: number, prevData: any, workspaceSlug: string, params: any) => {
|
||||
if (prevData && !prevData?.results?.length) return null;
|
||||
|
||||
if (index === 0)
|
||||
return `/api/workspaces/${workspaceSlug}/users/notifications?${objToQueryParams({
|
||||
...params,
|
||||
cursor: "30:0:0",
|
||||
})}`;
|
||||
|
||||
const cursor = prevData?.next_cursor;
|
||||
const nextPageResults = prevData?.next_page_results;
|
||||
|
||||
if (!nextPageResults) return null;
|
||||
|
||||
return `/api/workspaces/${workspaceSlug}/users/notifications?${objToQueryParams({
|
||||
...params,
|
||||
cursor,
|
||||
})}`;
|
||||
};
|
||||
|
||||
// profile
|
||||
export const USER_PROFILE_DATA = (workspaceSlug: string, userId: string) =>
|
||||
`USER_PROFILE_ACTIVITY_${workspaceSlug.toUpperCase()}_${userId.toUpperCase()}`;
|
||||
|
|
|
|||
|
|
@ -1,27 +1,101 @@
|
|||
export const snoozeOptions = [
|
||||
export enum ENotificationTab {
|
||||
ALL = "all",
|
||||
MENTIONS = "mentions",
|
||||
}
|
||||
|
||||
export enum ENotificationFilterType {
|
||||
CREATED = "created",
|
||||
ASSIGNED = "assigned",
|
||||
SUBSCRIBED = "subscribed",
|
||||
}
|
||||
|
||||
export enum ENotificationLoader {
|
||||
INIT_LOADER = "init-loader",
|
||||
MUTATION_LOADER = "mutation-loader",
|
||||
PAGINATION_LOADER = "pagination-loader",
|
||||
REFRESH = "refresh",
|
||||
MARK_ALL_AS_READY = "mark-all-as-read",
|
||||
}
|
||||
|
||||
export enum ENotificationQueryParamType {
|
||||
INIT = "init",
|
||||
CURRENT = "current",
|
||||
NEXT = "next",
|
||||
}
|
||||
|
||||
export type TNotificationTab = ENotificationTab.ALL | ENotificationTab.MENTIONS;
|
||||
|
||||
export const NOTIFICATION_TABS = [
|
||||
{
|
||||
label: "All",
|
||||
value: ENotificationTab.ALL,
|
||||
},
|
||||
// {
|
||||
// label: "Mentions",
|
||||
// value: ENotificationTab.MENTIONS,
|
||||
// },
|
||||
];
|
||||
|
||||
export const FILTER_TYPE_OPTIONS = [
|
||||
{
|
||||
label: "Assigned to me",
|
||||
value: ENotificationFilterType.ASSIGNED,
|
||||
},
|
||||
{
|
||||
label: "Created by me",
|
||||
value: ENotificationFilterType.CREATED,
|
||||
},
|
||||
{
|
||||
label: "Subscribed by me",
|
||||
value: ENotificationFilterType.SUBSCRIBED,
|
||||
},
|
||||
];
|
||||
|
||||
export const NOTIFICATION_SNOOZE_OPTIONS = [
|
||||
{
|
||||
key: "1_day",
|
||||
label: "1 day",
|
||||
value: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
return new Date(date.getTime() + 24 * 60 * 60 * 1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "3_days",
|
||||
label: "3 days",
|
||||
value: new Date(new Date().getTime() + 3 * 24 * 60 * 60 * 1000),
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
return new Date(date.getTime() + 3 * 24 * 60 * 60 * 1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "5_days",
|
||||
label: "5 days",
|
||||
value: new Date(new Date().getTime() + 5 * 24 * 60 * 60 * 1000),
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
return new Date(date.getTime() + 5 * 24 * 60 * 60 * 1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "1_week",
|
||||
label: "1 week",
|
||||
value: new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000),
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
return new Date(date.getTime() + 7 * 24 * 60 * 60 * 1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "2_weeks",
|
||||
label: "2 weeks",
|
||||
value: new Date(new Date().getTime() + 14 * 24 * 60 * 60 * 1000),
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
return new Date(date.getTime() + 14 * 24 * 60 * 60 * 1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "custom",
|
||||
label: "Custom",
|
||||
value: null,
|
||||
value: undefined,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue