diff --git a/frontend/src/component/common/Notifications/Notification.tsx b/frontend/src/component/common/Notifications/Notification.tsx index 9df5175d8e0..06db8c5d686 100644 --- a/frontend/src/component/common/Notifications/Notification.tsx +++ b/frontend/src/component/common/Notifications/Notification.tsx @@ -1,5 +1,11 @@ -import { ListItemButton, useTheme } from '@mui/material'; -import { Box, Typography, styled } from '@mui/material'; +import { + Box, + Typography, + styled, + Avatar, + ListItemButton, + useTheme, +} from '@mui/material'; import { NotificationsSchemaItem, NotificationsSchemaItemNotificationType, @@ -7,6 +13,7 @@ import { import { ReactComponent as ChangesAppliedIcon } from 'assets/icons/merge.svg'; import TimeAgo from 'react-timeago'; import { ToggleOffOutlined } from '@mui/icons-material'; +import { flexRow } from 'themes/themeStyles'; const StyledContainerBox = styled(Box, { shouldForwardProp: prop => prop !== 'readAt', @@ -45,8 +52,9 @@ const StyledNotificationMessageBox = styled(Box)(({ theme }) => ({ const StyledSecondaryInfoBox = styled(Box)(({ theme }) => ({ display: 'flex', - justifyContent: 'flex-end', - margin: theme.spacing(1, 0, 1, 0), + justifyContent: 'space-between', + alignItems: 'center', + margin: theme.spacing(1.5, 0, 1.5, 0), })); const StyledMessageTypography = styled(Typography, { @@ -63,6 +71,21 @@ const StyledTimeAgoTypography = styled(Typography)(({ theme }) => ({ color: theme.palette.neutral.main, })); +const StyledUserContainer = styled(Box)(({ theme }) => ({ + ...flexRow, +})); + +const StyledAvatar = styled(Avatar)(({ theme }) => ({ + width: '18px', + height: '18px', +})); + +const StyledCreatedBy = styled(Typography)(({ theme }) => ({ + fontSize: theme.fontSizes.smallerBody, + color: theme.palette.neutral.main, + marginLeft: theme.spacing(1), +})); + interface INotificationProps { notification: NotificationsSchemaItem; onNotificationClick: (notification: NotificationsSchemaItem) => void; @@ -116,6 +139,15 @@ export const Notification = ({ {notification.message} + + + + Created by {notification.createdBy.username} + + + diff --git a/frontend/src/component/common/Notifications/Notifications.tsx b/frontend/src/component/common/Notifications/Notifications.tsx index 9e9e9c4b539..862d86d1f7d 100644 --- a/frontend/src/component/common/Notifications/Notifications.tsx +++ b/frontend/src/component/common/Notifications/Notifications.tsx @@ -82,7 +82,9 @@ export const Notifications = () => { const { trackEvent } = usePlausibleTracker(); const [showUnread, setShowUnread] = useState(false); - const onNotificationClick = (notification: NotificationsSchemaItem) => { + const onNotificationClick = async ( + notification: NotificationsSchemaItem + ) => { if (notification.link) { navigate(notification.link); } @@ -95,22 +97,21 @@ export const Notifications = () => { setShowNotifications(false); - // Intentionally not wait for this request. We don't want to hold the user back - // only to mark a notification as read. try { - markAsRead({ + await markAsRead({ notifications: [notification.id], }); + refetchNotifications(); } catch (e) { // No need to display this in the UI. Minor inconvinence if this call fails. console.error('Error marking notification as read: ', e); } }; - const onMarkAllAsRead = () => { + const onMarkAllAsRead = async () => { try { if (notifications && notifications.length > 0) { - markAsRead({ + await markAsRead({ notifications: notifications.map( notification => notification.id ), @@ -155,6 +156,10 @@ export const Notifications = () => { /> )); + const shouldShowFeedback = Boolean( + notifications && notifications.length > 0 && !showUnread + ); + return ( { {notificationComponents} 0 && - !showUnread - )} + condition={shouldShowFeedback} show={ <> { error, loading: !error && !data, refetchNotifications, + mutateNotifications: mutate, }; };