diff --git a/frontend/src/component/common/Notifications/EmptyNotifications.tsx b/frontend/src/component/common/Notifications/EmptyNotifications.tsx
index 691077575f..24206d0a74 100644
--- a/frontend/src/component/common/Notifications/EmptyNotifications.tsx
+++ b/frontend/src/component/common/Notifications/EmptyNotifications.tsx
@@ -16,11 +16,15 @@ const StyledNotificationsIcon = styled(NotificationsIcon)(({ theme }) => ({
marginBottom: theme.spacing(1),
}));
-export const EmptyNotifications = () => {
+interface IEmptyNotificationsProps {
+ text: string;
+}
+
+export const EmptyNotifications = ({ text }: IEmptyNotificationsProps) => {
return (
- No new notifications
+ {text}
);
};
diff --git a/frontend/src/component/common/Notifications/Notification.tsx b/frontend/src/component/common/Notifications/Notification.tsx
index cafd4ce4b4..9df5175d8e 100644
--- a/frontend/src/component/common/Notifications/Notification.tsx
+++ b/frontend/src/component/common/Notifications/Notification.tsx
@@ -1,5 +1,5 @@
-import { useTheme } from '@mui/material';
-import { Box, ListItem, Typography, styled } from '@mui/material';
+import { ListItemButton, useTheme } from '@mui/material';
+import { Box, Typography, styled } from '@mui/material';
import {
NotificationsSchemaItem,
NotificationsSchemaItemNotificationType,
@@ -26,7 +26,7 @@ const StyledContainerBox = styled(Box, {
left: 7,
}));
-const StyledListItem = styled(ListItem)(({ theme }) => ({
+const StyledListItemButton = styled(ListItemButton)(({ theme }) => ({
position: 'relative',
cursor: 'pointer',
margin: theme.spacing(2, 0),
@@ -109,7 +109,7 @@ export const Notification = ({
};
return (
- onNotificationClick(notification)}>
+ onNotificationClick(notification)}>
{resolveIcon(notification.notificationType)}{' '}
@@ -121,6 +121,6 @@ export const Notification = ({
-
+
);
};
diff --git a/frontend/src/component/common/Notifications/Notifications.tsx b/frontend/src/component/common/Notifications/Notifications.tsx
index d78bdbb3fd..9e9e9c4b53 100644
--- a/frontend/src/component/common/Notifications/Notifications.tsx
+++ b/frontend/src/component/common/Notifications/Notifications.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { KeyboardEvent, useState } from 'react';
import {
Paper,
Typography,
@@ -7,6 +7,7 @@ import {
styled,
ClickAwayListener,
Button,
+ Switch,
} from '@mui/material';
import { useNotifications } from 'hooks/api/getters/useNotifications/useNotifications';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
@@ -20,6 +21,7 @@ import { useNavigate } from 'react-router-dom';
import { useNotificationsApi } from 'hooks/api/actions/useNotificationsApi/useNotificationsApi';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
+import { flexRow } from 'themes/themeStyles';
import { Feedback } from 'component/common/Feedback/Feedback';
const StyledPrimaryContainerBox = styled(Box)(() => ({
@@ -45,8 +47,10 @@ const StyledPaper = styled(Paper)(({ theme }) => ({
boxShadow: theme.boxShadows.popup,
borderRadius: `${theme.shape.borderRadiusLarge}px`,
position: 'absolute',
- right: -20,
+ right: -100,
top: 60,
+ maxHeight: '80vh',
+ overflowY: 'auto',
}));
const StyledDotBox = styled(Box)(({ theme }) => ({
@@ -59,15 +63,24 @@ const StyledDotBox = styled(Box)(({ theme }) => ({
right: 4,
}));
+const StyledHeaderBox = styled(Box)(() => ({
+ ...flexRow,
+}));
+
+const StyledHeaderTypography = styled(Typography)(({ theme }) => ({
+ fontSize: theme.fontSizes.smallerBody,
+}));
+
export const Notifications = () => {
const [showNotifications, setShowNotifications] = useState(false);
const { notifications, refetchNotifications } = useNotifications({
- refreshInterval: 15,
+ refreshInterval: 15000,
});
const navigate = useNavigate();
const { markAsRead } = useNotificationsApi();
const { uiConfig } = useUiConfig();
const { trackEvent } = usePlausibleTracker();
+ const [showUnread, setShowUnread] = useState(false);
const onNotificationClick = (notification: NotificationsSchemaItem) => {
if (notification.link) {
@@ -110,6 +123,12 @@ export const Notifications = () => {
}
};
+ const onKeyDown = (event: KeyboardEvent) => {
+ if (event.key === 'Escape') {
+ setShowNotifications(false);
+ }
+ };
+
const unreadNotifications = notifications?.filter(
notification => notification.readAt === null
);
@@ -118,6 +137,24 @@ export const Notifications = () => {
unreadNotifications && unreadNotifications.length > 0
);
+ const filterUnread = (notification: NotificationsSchemaItem) => {
+ if (showUnread) {
+ return !Boolean(notification.readAt);
+ }
+
+ return true;
+ };
+
+ const notificationComponents = notifications
+ ?.filter(filterUnread)
+ .map(notification => (
+
+ ));
+
return (
{
setShowNotifications(false)}
>
-
-
+
+
+
+
+ Show only unread
+
+
+ setShowUnread(!showUnread)
+ }
+ />
+
+
{
}
/>{' '}
}
- />
-
- {notifications?.map(notification => (
-
- ))}
-
-
+
+ {notificationComponents}
+
+ 0 &&
+ !showUnread
+ )}
+ show={
+ <>
+
+
+ >
+ }
/>
-
}
diff --git a/frontend/src/component/common/Notifications/NotificationsHeader.tsx b/frontend/src/component/common/Notifications/NotificationsHeader.tsx
index 298eea2e03..3ddff8a6de 100644
--- a/frontend/src/component/common/Notifications/NotificationsHeader.tsx
+++ b/frontend/src/component/common/Notifications/NotificationsHeader.tsx
@@ -1,30 +1,29 @@
import Settings from '@mui/icons-material/Settings';
-import { Typography, Box, IconButton, styled } from '@mui/material';
+import { Typography, IconButton, styled, Box } from '@mui/material';
import { flexRow } from 'themes/themeStyles';
const StyledOuterContainerBox = styled(Box)(({ theme }) => ({
- padding: theme.spacing(1, 3),
+ padding: theme.spacing(1.5, 3, 0.5, 3),
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}));
-const StyledSettingsContainer = styled(Box)(() => ({
- ...flexRow,
+const StyledInnerBox = styled(Box)(({ theme }) => ({
+ boxShadow: theme.boxShadows.separator,
+ width: '100%',
+ height: '4px',
}));
-export const NotificationsHeader = () => {
+export const NotificationsHeader: React.FC = ({ children }) => {
return (
<>
Notifications
-
-
-
-
-
-
+ {children}
+
+
>
);
};
diff --git a/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx b/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx
index a1002cc70c..fd001ee445 100644
--- a/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx
+++ b/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx
@@ -3,10 +3,9 @@ import { Dialogue } from 'component/common/Dialogue/Dialogue';
import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect';
import { useExportApi } from 'hooks/api/actions/useExportApi/useExportApi';
import useToast from 'hooks/useToast';
-import { IEnvironment } from 'interfaces/environments';
import { FeatureSchema } from 'openapi';
-import { createRef, useState } from 'react';
+import { createRef, useEffect, useState } from 'react';
import { formatUnknownError } from 'utils/formatUnknownError';
interface IExportDialogProps {
diff --git a/frontend/src/hooks/api/actions/useNotificationsApi/useNotificationsApi.ts b/frontend/src/hooks/api/actions/useNotificationsApi/useNotificationsApi.ts
index 541f6dbc6a..296a75ed5a 100644
--- a/frontend/src/hooks/api/actions/useNotificationsApi/useNotificationsApi.ts
+++ b/frontend/src/hooks/api/actions/useNotificationsApi/useNotificationsApi.ts
@@ -14,9 +14,7 @@ export const useNotificationsApi = () => {
});
try {
- const res = await makeRequest(req.caller, req.id);
-
- return res.json();
+ await makeRequest(req.caller, req.id);
} catch (e) {
throw e;
}
diff --git a/frontend/src/themes/dark-theme.ts b/frontend/src/themes/dark-theme.ts
index 51dd591554..07ac3042f5 100644
--- a/frontend/src/themes/dark-theme.ts
+++ b/frontend/src/themes/dark-theme.ts
@@ -24,6 +24,7 @@ export default createTheme({
elevated: '0px 1px 20px rgba(45, 42, 89, 0.1)',
popup: '0px 2px 6px rgba(0, 0, 0, 0.25)',
primaryHeader: '0px 8px 24px rgba(97, 91, 194, 0.2)',
+ separator: '0px 2px 3px hsl(0deg 0% 78% / 50%)',
},
typography: {
fontFamily: 'Sen, Roboto, sans-serif',
diff --git a/frontend/src/themes/theme.ts b/frontend/src/themes/theme.ts
index a9296f3571..c78e879de6 100644
--- a/frontend/src/themes/theme.ts
+++ b/frontend/src/themes/theme.ts
@@ -17,6 +17,7 @@ export default createTheme({
elevated: '0px 1px 20px rgba(45, 42, 89, 0.1)',
popup: '0px 2px 6px rgba(0, 0, 0, 0.25)',
primaryHeader: '0px 8px 24px rgba(97, 91, 194, 0.2)',
+ separator: '0px 2px 3px hsl(0deg 0% 78% / 50%)',
},
typography: {
fontFamily: 'Sen, Roboto, sans-serif',
diff --git a/frontend/src/themes/themeTypes.ts b/frontend/src/themes/themeTypes.ts
index 70bccb2909..c63b5346df 100644
--- a/frontend/src/themes/themeTypes.ts
+++ b/frontend/src/themes/themeTypes.ts
@@ -28,6 +28,7 @@ declare module '@mui/material/styles' {
elevated: string;
popup: string;
primaryHeader: string;
+ separator: string;
};
}