Skip to content

Commit 8568812

Browse files
committed
feat: turn off notification via email
1 parent e65eb03 commit 8568812

File tree

7 files changed

+55
-18
lines changed

7 files changed

+55
-18
lines changed

coderd/database/queries.sql.go

Lines changed: 10 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/notifications.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
-- name: FetchNewMessageMetadata :one
22
-- This is used to build up the notification_message's JSON payload.
33
SELECT nt.name AS notification_name,
4+
nt.id AS notification_template_id,
45
nt.actions AS actions,
56
nt.method AS custom_method,
67
u.id AS user_id,

coderd/notifications/dispatch/smtp/html.gotmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<div style="border-top: 1px solid #e2e8f0; color: #475569; font-size: 12px; margin-top: 64px; padding-top: 24px; line-height: 1.6;">
2727
<p>&copy;&nbsp;{{ current_year }}&nbsp;Coder. All rights reserved&nbsp;-&nbsp;<a href="{{ base_url }}" style="color: #2563eb; text-decoration: none;">{{ base_url }}</a></p>
2828
<p><a href="{{ base_url }}/settings/notifications" style="color: #2563eb; text-decoration: none;">Click here to manage your notification settings</a></p>
29+
<p><a href="{{ base_url }}/settings/notifications?unsubscribe={{ .NotificationTemplateID }}" style="color: #2563eb; text-decoration: none;">Stop receiving emails like this</a></p>
2930
</div>
3031
</div>
3132
</body>

coderd/notifications/enqueuer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ func (s *StoreEnqueuer) buildPayload(metadata database.FetchNewMessageMetadataRo
123123
payload := types.MessagePayload{
124124
Version: "1.0",
125125

126-
NotificationName: metadata.NotificationName,
126+
NotificationName: metadata.NotificationName,
127+
NotificationTemplateID: metadata.NotificationTemplateID.String(),
127128

128129
UserID: metadata.UserID.String(),
129130
UserEmail: metadata.UserEmail,

coderd/notifications/render/gotmpl_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ func TestGoTemplate(t *testing.T) {
5656
"url": "https://mocked-server-address/@johndoe/my-workspace"
5757
}]`,
5858
},
59+
{
60+
name: "render notification template ID",
61+
in: `{{ .NotificationTemplateID }}`,
62+
payload: types.MessagePayload{
63+
NotificationTemplateID: "4e19c0ac-94e1-4532-9515-d1801aa283b2",
64+
},
65+
expectedOutput: "4e19c0ac-94e1-4532-9515-d1801aa283b2",
66+
expectedErr: nil,
67+
},
5968
}
6069

6170
for _, tc := range tests {

coderd/notifications/types/payload.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ package types
77
type MessagePayload struct {
88
Version string `json:"_version"`
99

10-
NotificationName string `json:"notification_name"`
11-
12-
UserID string `json:"user_id"`
13-
UserEmail string `json:"user_email"`
14-
UserName string `json:"user_name"`
15-
UserUsername string `json:"user_username"`
16-
17-
Actions []TemplateAction `json:"actions"`
18-
Labels map[string]string `json:"labels"`
10+
NotificationName string `json:"notification_name"`
11+
NotificationTemplateID string `json:"notification_template_id"`
12+
UserID string `json:"user_id"`
13+
UserEmail string `json:"user_email"`
14+
UserName string `json:"user_name"`
15+
UserUsername string `json:"user_username"`
16+
Actions []TemplateAction `json:"actions"`
17+
Labels map[string]string `json:"labels"`
1918
}

site/src/pages/UserSettingsPage/NotificationsPage/NotificationsPage.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import type {
1818
NotificationPreference,
1919
NotificationTemplate,
2020
} from "api/typesGenerated";
21-
import { displaySuccess } from "components/GlobalSnackbar/utils";
21+
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
2222
import { Loader } from "components/Loader/Loader";
2323
import { Stack } from "components/Stack/Stack";
2424
import { useAuthenticated } from "contexts/auth/RequireAuth";
@@ -28,8 +28,10 @@ import {
2828
methodLabels,
2929
} from "modules/notifications/utils";
3030
import { type FC, Fragment } from "react";
31+
import { useEffect } from "react";
3132
import { Helmet } from "react-helmet-async";
3233
import { useMutation, useQueries, useQueryClient } from "react-query";
34+
import { useSearchParams } from "react-router-dom";
3335
import { pageTitle } from "utils/page";
3436
import { Section } from "../Section";
3537

@@ -60,6 +62,27 @@ export const NotificationsPage: FC = () => {
6062
const updatePreferences = useMutation(
6163
updateUserNotificationPreferences(user.id, queryClient),
6264
);
65+
const [searchParams] = useSearchParams();
66+
const unsubscribeTemplateId = searchParams.get("unsubscribe");
67+
68+
useEffect(() => {
69+
if (unsubscribeTemplateId) {
70+
handleUnsubscribe(unsubscribeTemplateId);
71+
}
72+
}, [unsubscribeTemplateId]);
73+
74+
const handleUnsubscribe = async (templateId: string) => {
75+
await updatePreferences.mutateAsync({
76+
template_disabled_map: {
77+
[templateId]: true,
78+
},
79+
});
80+
displaySuccess("Notification preferences updated");
81+
queryClient.invalidateQueries(
82+
userNotificationPreferences(user.id).queryKey,
83+
);
84+
};
85+
6386
const ready =
6487
disabledPreferences.data && templatesByGroup.data && dispatchMethods.data;
6588

0 commit comments

Comments
 (0)