1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-09 01:17:06 +02:00

feat: add user created by (#3235)

Adds the user created by avatar and name to the notification.
This commit is contained in:
Fredrik Strand Oseberg 2023-03-01 16:05:39 +01:00 committed by GitHub
parent c37453f4b5
commit 7c988a063a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 15 deletions

View File

@ -1,5 +1,11 @@
import { ListItemButton, useTheme } from '@mui/material'; import {
import { Box, Typography, styled } from '@mui/material'; Box,
Typography,
styled,
Avatar,
ListItemButton,
useTheme,
} from '@mui/material';
import { import {
NotificationsSchemaItem, NotificationsSchemaItem,
NotificationsSchemaItemNotificationType, NotificationsSchemaItemNotificationType,
@ -7,6 +13,7 @@ import {
import { ReactComponent as ChangesAppliedIcon } from 'assets/icons/merge.svg'; import { ReactComponent as ChangesAppliedIcon } from 'assets/icons/merge.svg';
import TimeAgo from 'react-timeago'; import TimeAgo from 'react-timeago';
import { ToggleOffOutlined } from '@mui/icons-material'; import { ToggleOffOutlined } from '@mui/icons-material';
import { flexRow } from 'themes/themeStyles';
const StyledContainerBox = styled(Box, { const StyledContainerBox = styled(Box, {
shouldForwardProp: prop => prop !== 'readAt', shouldForwardProp: prop => prop !== 'readAt',
@ -45,8 +52,9 @@ const StyledNotificationMessageBox = styled(Box)(({ theme }) => ({
const StyledSecondaryInfoBox = styled(Box)(({ theme }) => ({ const StyledSecondaryInfoBox = styled(Box)(({ theme }) => ({
display: 'flex', display: 'flex',
justifyContent: 'flex-end', justifyContent: 'space-between',
margin: theme.spacing(1, 0, 1, 0), alignItems: 'center',
margin: theme.spacing(1.5, 0, 1.5, 0),
})); }));
const StyledMessageTypography = styled(Typography, { const StyledMessageTypography = styled(Typography, {
@ -63,6 +71,21 @@ const StyledTimeAgoTypography = styled(Typography)(({ theme }) => ({
color: theme.palette.neutral.main, 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 { interface INotificationProps {
notification: NotificationsSchemaItem; notification: NotificationsSchemaItem;
onNotificationClick: (notification: NotificationsSchemaItem) => void; onNotificationClick: (notification: NotificationsSchemaItem) => void;
@ -116,6 +139,15 @@ export const Notification = ({
{notification.message} {notification.message}
</StyledMessageTypography> </StyledMessageTypography>
<StyledSecondaryInfoBox> <StyledSecondaryInfoBox>
<StyledUserContainer>
<StyledAvatar
src={notification.createdBy.imageUrl || ''}
/>
<StyledCreatedBy>
Created by {notification.createdBy.username}
</StyledCreatedBy>
</StyledUserContainer>
<StyledTimeAgoTypography> <StyledTimeAgoTypography>
<TimeAgo date={new Date(notification.createdAt)} /> <TimeAgo date={new Date(notification.createdAt)} />
</StyledTimeAgoTypography> </StyledTimeAgoTypography>

View File

@ -82,7 +82,9 @@ export const Notifications = () => {
const { trackEvent } = usePlausibleTracker(); const { trackEvent } = usePlausibleTracker();
const [showUnread, setShowUnread] = useState(false); const [showUnread, setShowUnread] = useState(false);
const onNotificationClick = (notification: NotificationsSchemaItem) => { const onNotificationClick = async (
notification: NotificationsSchemaItem
) => {
if (notification.link) { if (notification.link) {
navigate(notification.link); navigate(notification.link);
} }
@ -95,22 +97,21 @@ export const Notifications = () => {
setShowNotifications(false); 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 { try {
markAsRead({ await markAsRead({
notifications: [notification.id], notifications: [notification.id],
}); });
refetchNotifications();
} catch (e) { } catch (e) {
// No need to display this in the UI. Minor inconvinence if this call fails. // No need to display this in the UI. Minor inconvinence if this call fails.
console.error('Error marking notification as read: ', e); console.error('Error marking notification as read: ', e);
} }
}; };
const onMarkAllAsRead = () => { const onMarkAllAsRead = async () => {
try { try {
if (notifications && notifications.length > 0) { if (notifications && notifications.length > 0) {
markAsRead({ await markAsRead({
notifications: notifications.map( notifications: notifications.map(
notification => notification.id notification => notification.id
), ),
@ -155,6 +156,10 @@ export const Notifications = () => {
/> />
)); ));
const shouldShowFeedback = Boolean(
notifications && notifications.length > 0 && !showUnread
);
return ( return (
<StyledPrimaryContainerBox> <StyledPrimaryContainerBox>
<IconButton <IconButton
@ -215,11 +220,7 @@ export const Notifications = () => {
{notificationComponents} {notificationComponents}
</NotificationsList> </NotificationsList>
<ConditionallyRender <ConditionallyRender
condition={Boolean( condition={shouldShowFeedback}
notifications &&
notifications.length > 0 &&
!showUnread
)}
show={ show={
<> <>
<Feedback <Feedback

View File

@ -21,6 +21,7 @@ export const useNotifications = (options: SWRConfiguration = {}) => {
error, error,
loading: !error && !data, loading: !error && !data,
refetchNotifications, refetchNotifications,
mutateNotifications: mutate,
}; };
}; };