mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-09 06:55:03 +00:00
feat: redesign notification modal (#8140)
* fix: test expect Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: maintain state for read and cleared notification ids Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * feat: revamp Notifications Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: break things into components and use events Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: icon + more padding Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * chore: use classnames Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * chore: remove redundancy Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * chore: make it pixel accurate Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: remove redundant useMemo Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: colors of notification modal Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: use color paletter + fix badge color Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: ensure semantics for notification icon Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: handle keyboard navigation for drawer items Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: colors, no notification view, etc Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: don't crash on color of badge that is invalid Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: use hex color for type of notification Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix * Apply suggestions from code review Co-authored-by: Sid <siddharth@usebruno.com> * fix: use parseToRgb instead of custom isHexColor check + add unit tests Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> * fix: pointer events getting swallowed by iframe, causing resize issue Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> --------- Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com> Co-authored-by: naman-bruno <naman@usebruno.com> Co-authored-by: Sid <siddharth@usebruno.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { useRef } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { useDragResize } from 'hooks/useDragResize';
|
||||
import { usePersistedState } from 'hooks/usePersistedState';
|
||||
import Modal from 'components/Modal/index';
|
||||
import Portal from 'components/Portal';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import NotificationTabs from './NotificationTabs';
|
||||
import NotificationList from './NotificationList';
|
||||
import NotificationDetail from './NotificationDetail';
|
||||
|
||||
const DEFAULT_SIDEBAR_WIDTH = 260;
|
||||
const SIDEBAR_MIN = 200;
|
||||
// Reserved for the detail pane; caps the sidebar at ~420px in the 800px modal.
|
||||
const DETAIL_MIN = 380;
|
||||
|
||||
const NotificationsModal = ({ notifications, onClose }) => {
|
||||
const {
|
||||
visibleNotifications,
|
||||
listed,
|
||||
unreadCount,
|
||||
activeTab,
|
||||
selectedNotification,
|
||||
onTabChange,
|
||||
onSelect,
|
||||
onMarkAllRead,
|
||||
onClearAll
|
||||
} = notifications;
|
||||
|
||||
const containerRef = useRef(null);
|
||||
const [sidebarWidth, setSidebarWidth] = usePersistedState({
|
||||
key: 'notification-sidebar',
|
||||
default: DEFAULT_SIDEBAR_WIDTH
|
||||
});
|
||||
const { dragging, dragWidth, dragbarProps } = useDragResize({
|
||||
containerRef,
|
||||
width: sidebarWidth,
|
||||
onWidthChange: (w) => setSidebarWidth(w ?? DEFAULT_SIDEBAR_WIDTH),
|
||||
minLeft: SIDEBAR_MIN,
|
||||
minRight: DETAIL_MIN
|
||||
});
|
||||
const effectiveWidth = dragging ? dragWidth : sidebarWidth;
|
||||
const isEmpty = visibleNotifications.length === 0;
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<Modal
|
||||
size="md"
|
||||
title="Notifications"
|
||||
confirmText="Close"
|
||||
handleConfirm={onClose}
|
||||
handleCancel={onClose}
|
||||
hideFooter={true}
|
||||
disableCloseOnOutsideClick={true}
|
||||
disableEscapeKey={true}
|
||||
noPadding={true}
|
||||
>
|
||||
<StyledWrapper className={classnames('notifications-modal', { dragging })} ref={containerRef}>
|
||||
<div className="notif-sidebar" style={{ width: effectiveWidth, flexBasis: effectiveWidth }}>
|
||||
<NotificationTabs
|
||||
activeTab={activeTab}
|
||||
unreadCount={unreadCount}
|
||||
onTabChange={onTabChange}
|
||||
onMarkAllRead={onMarkAllRead}
|
||||
onClearAll={onClearAll}
|
||||
/>
|
||||
<NotificationList items={listed} selectedId={selectedNotification?.id} onSelect={onSelect} />
|
||||
</div>
|
||||
<div
|
||||
className={classnames('notif-resize-handle', { dragging })}
|
||||
{...dragbarProps}
|
||||
role="separator"
|
||||
aria-orientation="vertical"
|
||||
aria-label="Resize sidebar"
|
||||
/>
|
||||
{isEmpty ? (
|
||||
<div className="notif-empty">
|
||||
<div className="notif-empty-text">You are all caught up!</div>
|
||||
</div>
|
||||
) : (
|
||||
<NotificationDetail notification={selectedNotification} />
|
||||
)}
|
||||
</StyledWrapper>
|
||||
</Modal>
|
||||
</Portal>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationsModal;
|
||||
Reference in New Issue
Block a user