mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
fix: notification items are now real links (#2039)
Replace UnstyledButton with UnstyledButton component={Link} so each
notification renders as a real anchor element. Regular left-clicks use
SPA navigation and close the popover; Ctrl/Cmd/middle-click open the
page in a new tab. All click types mark the notification as read.
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
|||||||
import { CustomAvatar } from "@/components/ui/custom-avatar";
|
import { CustomAvatar } from "@/components/ui/custom-avatar";
|
||||||
import { INotification } from "../types/notification.types";
|
import { INotification } from "../types/notification.types";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useMarkReadMutation } from "../queries/notification-query";
|
import { useMarkReadMutation } from "../queries/notification-query";
|
||||||
import { buildPageUrl } from "@/features/page/page.utils";
|
import { buildPageUrl } from "@/features/page/page.utils";
|
||||||
@@ -30,7 +30,6 @@ export function NotificationItem({
|
|||||||
onNavigate,
|
onNavigate,
|
||||||
}: NotificationItemProps) {
|
}: NotificationItemProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
|
||||||
const markRead = useMarkReadMutation();
|
const markRead = useMarkReadMutation();
|
||||||
const [hovered, setHovered] = useState(false);
|
const [hovered, setHovered] = useState(false);
|
||||||
|
|
||||||
@@ -55,32 +54,39 @@ export function NotificationItem({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = () => {
|
const pageUrl =
|
||||||
if (notification.page && notification.space) {
|
notification.page && notification.space
|
||||||
if (isUnread) {
|
? buildPageUrl(
|
||||||
markRead.mutate([notification.id]);
|
|
||||||
}
|
|
||||||
navigate(
|
|
||||||
buildPageUrl(
|
|
||||||
notification.space.slug,
|
notification.space.slug,
|
||||||
notification.page.slugId,
|
notification.page.slugId,
|
||||||
notification.page.title,
|
notification.page.title,
|
||||||
),
|
)
|
||||||
);
|
: undefined;
|
||||||
onNavigate();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleMarkRead = (e: React.MouseEvent) => {
|
const markReadIfNeeded = () => {
|
||||||
e.stopPropagation();
|
|
||||||
if (isUnread) {
|
if (isUnread) {
|
||||||
markRead.mutate([notification.id]);
|
markRead.mutate([notification.id]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
markReadIfNeeded();
|
||||||
|
onNavigate();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMarkRead = (e: React.MouseEvent) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
markReadIfNeeded();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UnstyledButton
|
<UnstyledButton
|
||||||
|
component={Link}
|
||||||
|
to={pageUrl ?? ""}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
// auxclick fires for all non-primary buttons; guard to middle-click only (button 1)
|
||||||
|
// so that right-click (button 2, context menu) does not mark as read
|
||||||
|
onAuxClick={(e: React.MouseEvent) => e.button === 1 && markReadIfNeeded()}
|
||||||
onMouseEnter={() => setHovered(true)}
|
onMouseEnter={() => setHovered(true)}
|
||||||
onMouseLeave={() => setHovered(false)}
|
onMouseLeave={() => setHovered(false)}
|
||||||
w="100%"
|
w="100%"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
.notificationItem {
|
.notificationItem {
|
||||||
|
display: block;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
Reference in New Issue
Block a user