feat: implement notification inbox system

- Add API methods for getting notifications and marking them as read
- Add TypeScript types for the notification inbox API
- Update notification components to use the official API types
- Integrate NotificationsInbox component into the navbar

Closes #16804

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Coder User
2025-03-13 03:03:57 +00:00
parent f6382fde22
commit 380bf63f51
4 changed files with 48 additions and 11 deletions

View File

@ -2388,6 +2388,22 @@ class ApiMethods {
);
return res.data;
};
// Notification inbox API methods
getUserNotifications = async () => {
const response = await this.axios.get<TypesGen.UserNotificationsResponse>(
"/api/v2/users/me/notifications"
);
return response.data;
};
markAllNotificationsAsRead = async (): Promise<void> => {
await this.axios.post("/api/v2/users/me/notifications/read");
};
markNotificationAsRead = async (notificationId: string): Promise<void> => {
await this.axios.post(`/api/v2/users/me/notifications/${notificationId}/read`);
};
}
// This is a hard coded CSRF token/cookie pair for local development. In prod,

View File

@ -1237,6 +1237,24 @@ export interface NotificationMethodsResponse {
readonly default: string;
}
// From codersdk/notifications.go
export interface InboxNotification {
readonly id: string;
readonly read_status: "read" | "unread";
readonly content: string;
readonly created_at: string;
readonly actions: {
readonly label: string;
readonly url: string;
}[];
}
// From codersdk/notifications.go
export interface UserNotificationsResponse {
readonly notifications: InboxNotification[];
readonly unread_count: number;
}
// From codersdk/notifications.go
export interface NotificationPreference {
readonly id: string;

View File

@ -1,7 +1,9 @@
import { API } from "api/api";
import type * as TypesGen from "api/typesGenerated";
import { ExternalImage } from "components/ExternalImage/ExternalImage";
import { CoderIcon } from "components/Icons/CoderIcon";
import type { ProxyContextValue } from "contexts/ProxyContext";
import { NotificationsInbox } from "modules/notifications/NotificationsInbox/NotificationsInbox";
import type { FC } from "react";
import { NavLink, useLocation } from "react-router-dom";
import { cn } from "utils/cn";
@ -57,6 +59,14 @@ export const NavbarView: FC<NavbarViewProps> = ({
{proxyContextValue && (
<ProxyMenu proxyContextValue={proxyContextValue} />
)}
{user && (
<NotificationsInbox
fetchNotifications={API.getUserNotifications}
markAllAsRead={API.markAllNotificationsAsRead}
markNotificationAsRead={API.markNotificationAsRead}
/>
)}
<DeploymentDropdown
canViewAuditLog={canViewAuditLog}

View File

@ -1,12 +1,5 @@
// TODO: Remove this file when the types from API are available
// This file uses the official API types
import type { InboxNotification } from "api/typesGenerated";
export type Notification = {
id: string;
read_status: "read" | "unread";
content: string;
created_at: string;
actions: {
label: string;
url: string;
}[];
};
// Reexport the InboxNotification type for backward compatibility
export type Notification = InboxNotification;