From bd604063e62987d6ca3e57023105e41320b42669 Mon Sep 17 00:00:00 2001 From: Kristina <7614497+khjrtbrg@users.noreply.github.com> Date: Thu, 7 May 2026 10:37:36 +0200 Subject: [PATCH] [web] add preferences to control all implemented notifications (#33320) * feat: add granular controls for other features * feat: add filtering to notifications that were missing them * refactor: rm duplicate thread fetches * fix: reduce permissions to fit spec (all === new comments/tracked changes, replies === only if also a participant) * fix: include mentions in types GitOrigin-RevId: b4a09ef59e5cf4de2e07d5b9a13c31fc1cf81a31 --- .../use-project-notification-preferences.ts | 46 +++++++++++------- .../project-notifications-setting.test.tsx | 47 ++++++++++++------- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/services/web/frontend/js/features/settings/hooks/use-project-notification-preferences.ts b/services/web/frontend/js/features/settings/hooks/use-project-notification-preferences.ts index a82eed216e..479bc38aa3 100644 --- a/services/web/frontend/js/features/settings/hooks/use-project-notification-preferences.ts +++ b/services/web/frontend/js/features/settings/hooks/use-project-notification-preferences.ts @@ -22,36 +22,45 @@ function levelToPreferences( switch (level) { case 'all': return { - trackedChangesOnOwnProject: true, - trackedChangesOnInvitedProject: true, commentOnOwnProject: true, commentOnInvitedProject: true, - repliesOnOwnProject: true, - repliesOnInvitedProject: true, repliesOnAuthoredThread: true, repliesOnParticipatingThread: true, + commentResolvedOnAuthoredThread: true, + commentResolvedOnParticipatingThread: true, + commentReopenedOnAuthoredThread: true, + commentReopenedOnParticipatingThread: true, + trackedChangesOnOwnProject: true, + trackedChangesOnInvitedProject: true, + trackChangesAcceptedOnAuthoredChange: true, } case 'replies': return { - trackedChangesOnOwnProject: false, - trackedChangesOnInvitedProject: false, commentOnOwnProject: false, commentOnInvitedProject: false, - repliesOnOwnProject: false, - repliesOnInvitedProject: false, repliesOnAuthoredThread: true, repliesOnParticipatingThread: true, + commentResolvedOnAuthoredThread: true, + commentResolvedOnParticipatingThread: true, + commentReopenedOnAuthoredThread: true, + commentReopenedOnParticipatingThread: true, + trackedChangesOnOwnProject: false, + trackedChangesOnInvitedProject: false, + trackChangesAcceptedOnAuthoredChange: true, } case 'off': return { - trackedChangesOnOwnProject: false, - trackedChangesOnInvitedProject: false, commentOnOwnProject: false, commentOnInvitedProject: false, - repliesOnOwnProject: false, - repliesOnInvitedProject: false, repliesOnAuthoredThread: false, repliesOnParticipatingThread: false, + commentResolvedOnAuthoredThread: false, + commentResolvedOnParticipatingThread: false, + commentReopenedOnAuthoredThread: false, + commentReopenedOnParticipatingThread: false, + trackedChangesOnOwnProject: false, + trackedChangesOnInvitedProject: false, + trackChangesAcceptedOnAuthoredChange: false, } } } @@ -76,15 +85,16 @@ function preferencesToLevel( const projectTrackedChanges = isOwner ? preferences.trackedChangesOnOwnProject : preferences.trackedChangesOnInvitedProject - const projectReplies = isOwner - ? preferences.repliesOnOwnProject - : preferences.repliesOnInvitedProject - const anyProjectNotifications = - projectComments || projectTrackedChanges || projectReplies + const anyProjectNotifications = projectComments || projectTrackedChanges const anyParticipantNotifications = preferences.repliesOnAuthoredThread || - preferences.repliesOnParticipatingThread + preferences.repliesOnParticipatingThread || + preferences.trackChangesAcceptedOnAuthoredChange || + preferences.commentResolvedOnAuthoredThread || + preferences.commentResolvedOnParticipatingThread || + preferences.commentReopenedOnAuthoredThread || + preferences.commentReopenedOnParticipatingThread if (!anyProjectNotifications && !anyParticipantNotifications) { return 'off' diff --git a/services/web/test/frontend/features/settings-modal/settings/project-notifications-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/project-notifications-setting.test.tsx index ab5ab40a40..680062e466 100644 --- a/services/web/test/frontend/features/settings-modal/settings/project-notifications-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/project-notifications-setting.test.tsx @@ -9,25 +9,31 @@ import ProjectNotificationsSetting from '@/features/settings/components/editor-s const preferencesUrl = `/notifications/preferences/project/${PROJECT_ID}` const allNotificationsOn = { - trackedChangesOnOwnProject: true, - trackedChangesOnInvitedProject: true, commentOnOwnProject: true, commentOnInvitedProject: true, - repliesOnOwnProject: true, - repliesOnInvitedProject: true, repliesOnAuthoredThread: true, repliesOnParticipatingThread: true, + commentResolvedOnAuthoredThread: true, + commentResolvedOnParticipatingThread: true, + commentReopenedOnAuthoredThread: true, + commentReopenedOnParticipatingThread: true, + trackedChangesOnOwnProject: true, + trackedChangesOnInvitedProject: true, + trackChangesAcceptedOnAuthoredChange: true, } const repliesOnlyPreferences = { - trackedChangesOnOwnProject: false, - trackedChangesOnInvitedProject: false, commentOnOwnProject: false, commentOnInvitedProject: false, - repliesOnOwnProject: false, - repliesOnInvitedProject: false, repliesOnAuthoredThread: true, repliesOnParticipatingThread: true, + commentResolvedOnAuthoredThread: true, + commentResolvedOnParticipatingThread: true, + commentReopenedOnAuthoredThread: true, + commentReopenedOnParticipatingThread: true, + trackedChangesOnOwnProject: false, + trackedChangesOnInvitedProject: false, + trackChangesAcceptedOnAuthoredChange: true, } const globallyMutedPreferences = { @@ -35,22 +41,28 @@ const globallyMutedPreferences = { trackedChangesOnInvitedProject: false, commentOnOwnProject: false, commentOnInvitedProject: false, - repliesOnOwnProject: false, - repliesOnInvitedProject: false, repliesOnAuthoredThread: false, repliesOnParticipatingThread: false, muteAllNotifications: true, + commentResolvedOnAuthoredThread: false, + commentResolvedOnParticipatingThread: false, + commentReopenedOnAuthoredThread: false, + commentReopenedOnParticipatingThread: false, + trackChangesAcceptedOnAuthoredChange: false, } const allNotificationsOff = { - trackedChangesOnOwnProject: false, - trackedChangesOnInvitedProject: false, commentOnOwnProject: false, commentOnInvitedProject: false, - repliesOnOwnProject: false, - repliesOnInvitedProject: false, repliesOnAuthoredThread: false, repliesOnParticipatingThread: false, + commentResolvedOnAuthoredThread: false, + commentResolvedOnParticipatingThread: false, + commentReopenedOnAuthoredThread: false, + commentReopenedOnParticipatingThread: false, + trackedChangesOnOwnProject: false, + trackedChangesOnInvitedProject: false, + trackChangesAcceptedOnAuthoredChange: false, } const defaultPreferences = { @@ -58,11 +70,14 @@ const defaultPreferences = { trackedChangesOnInvitedProject: false, commentOnOwnProject: true, commentOnInvitedProject: false, - repliesOnOwnProject: false, - repliesOnInvitedProject: false, repliesOnAuthoredThread: true, repliesOnParticipatingThread: true, muteAllNotifications: false, + commentResolvedOnAuthoredThread: true, + commentResolvedOnParticipatingThread: true, + commentReopenedOnAuthoredThread: true, + commentReopenedOnParticipatingThread: true, + trackChangesAcceptedOnAuthoredChange: true, } function renderComponent(props: { permissionsLevel?: string } = {}) {