Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new-log-viewer: Add NotificationContextProvider for managing pop-up messages; add pop-ups for errors and remove status bar dummy message. #84

Merged
merged 46 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
61f4b6e
Add NotificationContextProvider for publishing and subscribing notifi…
junhaoliao Sep 30, 2024
fc5fbc3
Abstract callback types for postPopup and postStatus into separate ty…
junhaoliao Sep 30, 2024
4e2ae14
Replace inline useHandleConfigFormSubmit call with handleConfigFormSu…
junhaoliao Sep 30, 2024
93e4a3d
Rename NotificationContextProvider -> NotificationContextProviderProps.
junhaoliao Sep 30, 2024
3a69b71
Add docs.
junhaoliao Sep 30, 2024
43b7378
Add docs; add const to standardize auto-dismiss timeout for notificat…
junhaoliao Sep 30, 2024
e8ce67a
Align closing bracket.
junhaoliao Sep 30, 2024
0df2470
Update dependency array in useCallback.
junhaoliao Sep 30, 2024
d0ab264
Add support for displaying multiple messages; add explicit option to …
junhaoliao Oct 8, 2024
68f9bfd
Change worker error prompt - Apply suggestions from code review
junhaoliao Oct 11, 2024
670cf09
Remove status message from the NotificationContextProvider and also t…
junhaoliao Oct 11, 2024
957f5a0
Merge branch 'main' into notification
junhaoliao Oct 11, 2024
306cc25
Fix an alignment issue of the pop-up messages.
junhaoliao Oct 11, 2024
0c30d20
Increase popup message title font size.
junhaoliao Oct 11, 2024
83f5007
Extend AUTO_DISMISS_TIMEOUT_MILLIS from 5000 -> 10000.
junhaoliao Oct 11, 2024
fc37786
Refactor notification context provider structure.
junhaoliao Oct 11, 2024
18c75e4
Avoid storing the timeout handle because no cancellation is required …
junhaoliao Oct 11, 2024
e346322
Move the timeout handling logic into `PopUpMessageBox`.
junhaoliao Oct 11, 2024
d44d073
Extract theme switch functionality into a new ThemeSwitchToggle compo…
junhaoliao Oct 11, 2024
3a63386
Move handleConfigFormSubmit generator inside SettingsDialog so that `…
junhaoliao Oct 11, 2024
db134b5
Move CssVarsProvider back into Layout.
junhaoliao Oct 11, 2024
729fac6
Separate concerns by moving `PopUpMessagesContainer` from `Notificati…
junhaoliao Oct 11, 2024
93ab288
Move PopUpMessagesContainer and related components to new structure f…
junhaoliao Oct 11, 2024
2c92af5
Change the semicolon to a comma in the children property within the N…
junhaoliao Oct 11, 2024
4c51ff2
Refactor postPopup API to accept a single object parameter.
junhaoliao Oct 11, 2024
f4d191a
take advantage of useContext, export the close method directly
davemarco Oct 11, 2024
fe57144
rename things
davemarco Oct 11, 2024
d8d997d
rename things
davemarco Oct 11, 2024
4704393
small cleanup
davemarco Oct 11, 2024
7881cb5
Add generic type `WithId`.
junhaoliao Oct 12, 2024
ddbb577
Add field `id` to the pop-up messages and use that as keys in renderi…
junhaoliao Oct 12, 2024
4635798
Add circular progress to PopupMessageBox for visualization of the tim…
junhaoliao Oct 12, 2024
d81e258
Update Popups to auto-scroll on new messages.
junhaoliao Oct 17, 2024
62409b0
Get new messages appear at the bottom and get rid of the auto-scrolli…
junhaoliao Oct 17, 2024
7b71ac4
Hide the scrollbar while keeping the container scrollable.
junhaoliao Oct 17, 2024
779d93b
Move PopupMessage type into separate file.
junhaoliao Oct 17, 2024
143a4bb
Use counter approach in calculating timer percentage - Apply suggesti…
junhaoliao Oct 17, 2024
2dec93b
Move PopupMessage-related constants into typings/notifications.ts; ch…
junhaoliao Oct 17, 2024
38cafbd
Add back the auto-dismiss behaviour.
junhaoliao Oct 17, 2024
189be81
Rename 'popup' references to 'popUp' across components.
junhaoliao Oct 17, 2024
c81d38c
more - Rename 'popup' references to 'popUp' across components.
junhaoliao Oct 18, 2024
ac0ee35
Refactor timeout logic in PopUpMessageBox.
junhaoliao Oct 18, 2024
e107a94
Fix typo - Apply suggestions from code review
junhaoliao Oct 18, 2024
de99ef3
Fix auto-dismiss calculation by rounding up intervals.
junhaoliao Oct 18, 2024
6980c7a
Increase progress ring thickness from 2 to 3 - Apply suggestions from…
junhaoliao Oct 18, 2024
df5be3b
Remove redundant template type specification - Apply suggestions from…
junhaoliao Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions new-log-viewer/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Layout from "./components/Layout";
import NotificationContextProvider from "./contexts/NotificationContextProvider";
import StateContextProvider from "./contexts/StateContextProvider";
import UrlContextProvider from "./contexts/UrlContextProvider";

Expand All @@ -10,11 +11,13 @@ import UrlContextProvider from "./contexts/UrlContextProvider";
*/
const App = () => {
return (
<UrlContextProvider>
<StateContextProvider>
<Layout/>
</StateContextProvider>
</UrlContextProvider>
<NotificationContextProvider>
<UrlContextProvider>
<StateContextProvider>
<Layout/>
</StateContextProvider>
</UrlContextProvider>
</NotificationContextProvider>
);
};

Expand Down
4 changes: 3 additions & 1 deletion new-log-viewer/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {CssVarsProvider} from "@mui/joy/styles";
import {CssVarsProvider} from "@mui/joy";

import {CONFIG_KEY} from "../typings/config";
import {CONFIG_DEFAULT} from "../utils/config";
import CentralContainer from "./CentralContainer";
import MenuBar from "./MenuBar";
import PopUps from "./PopUps";
import StatusBar from "./StatusBar";
import APP_THEME from "./theme";

Expand All @@ -23,6 +24,7 @@ const Layout = () => {
<MenuBar/>
<CentralContainer/>
<StatusBar/>
<PopUps/>
</CssVarsProvider>
);
};
Expand Down
121 changes: 121 additions & 0 deletions new-log-viewer/src/components/PopUps/PopUpMessageBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {
useContext,
useEffect,
useRef,
useState,
} from "react";

import {
Alert,
Box,
CircularProgress,
IconButton,
Typography,
} from "@mui/joy";

import CloseIcon from "@mui/icons-material/Close";

import {
NotificationContext,
PopUpMessage,
} from "../../contexts/NotificationContextProvider";
import {WithId} from "../../typings/common";
import {LOG_LEVEL} from "../../typings/logs";
import {DO_NOT_TIMEOUT_VALUE} from "../../typings/notifications";


const AUTO_DISMISS_PERCENT_UPDATE_INTERVAL_MILLIS = 50;

interface PopUpMessageProps {
message: WithId<PopUpMessage>,
}

/**
* Display a pop-up message in an alert box.
*
* @param props
* @param props.message
* @return
*/
const PopUpMessageBox = ({message}: PopUpMessageProps) => {
const {id, level, message: messageStr, title, timeoutMillis} = message;

const {handlePopUpMessageClose} = useContext(NotificationContext);
const [percentRemaining, setPercentRemaining] = useState<number>(100);
const intervalCountRef = useRef<number>(0);

const handleCloseButtonClick = () => {
handlePopUpMessageClose(id);
};

useEffect(() => {
if (DO_NOT_TIMEOUT_VALUE === timeoutMillis) {
return () => {};
}

const totalIntervals = Math.ceil(
timeoutMillis / AUTO_DISMISS_PERCENT_UPDATE_INTERVAL_MILLIS
);
const intervalId = setInterval(() => {
intervalCountRef.current++;
const newPercentRemaining = 100 - (100 * (intervalCountRef.current / totalIntervals));
if (0 >= newPercentRemaining) {
handlePopUpMessageClose(id);
}
setPercentRemaining(newPercentRemaining);
}, AUTO_DISMISS_PERCENT_UPDATE_INTERVAL_MILLIS);

return () => {
clearInterval(intervalId);
};
}, [
timeoutMillis,
handlePopUpMessageClose,
id,
]);

const color = level >= LOG_LEVEL.ERROR ?
"danger" :
"primary";

return (
<Alert
className={"pop-up-message-box-alert"}
color={color}
variant={"outlined"}
>
<div className={"pop-up-message-box-alert-layout"}>
<Box className={"pop-up-message-box-title-container"}>
<Typography
className={"pop-up-message-box-title-text"}
color={color}
level={"title-md"}
>
{title}
</Typography>
<CircularProgress
color={color}
determinate={true}
size={"sm"}
thickness={3}
value={percentRemaining}
>
<IconButton
className={"pop-up-message-box-close-button"}
color={color}
size={"sm"}
onClick={handleCloseButtonClick}
>
<CloseIcon/>
</IconButton>
</CircularProgress>
</Box>
<Typography level={"body-sm"}>
{messageStr}
</Typography>
</div>
</Alert>
);
};

export default PopUpMessageBox;
47 changes: 47 additions & 0 deletions new-log-viewer/src/components/PopUps/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.pop-up-messages-container-snackbar {
/* Disable pointer events on the transparent container to allow components underneath to be
accessed. */
pointer-events: none;

right: 14px !important;
bottom: var(--ylv-status-bar-height) !important;

padding: 0 !important;

background: transparent !important;
border: none !important;
box-shadow: none !important;
}

.pop-up-messages-container-stack {
scrollbar-width: none;
overflow-y: auto;
height: calc(100vh - var(--ylv-status-bar-height) - var(--ylv-menu-bar-height));
}

.pop-up-message-box-alert {
/* Restore pointer events on the pop-up messages. See above `pointer-events: none` in
`.pop-up-messages-container-snackbar`. */
pointer-events: initial;
padding-inline: 18px !important;
}

.pop-up-message-box-alert-layout {
width: 300px;
}
Comment on lines +29 to +31
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using relative units for width

The .pop-up-message-box-alert-layout class sets a fixed width for the alert box. While this ensures consistency, it might not be ideal for all screen sizes.

Consider using relative units (like percentages or rem) or a combination of min-width and max-width to make the layout more responsive. For example:

.pop-up-message-box-alert-layout {
    width: 90%;
    max-width: 300px;
    min-width: 200px;
}

This approach would maintain the desired size on larger screens while adapting to smaller screens.


.pop-up-message-box-title-container {
display: flex;
align-items: center;
}

.pop-up-message-box-title-text {
flex-grow: 1;
}

.pop-up-message-box-close-button {
/* stylelint-disable-next-line custom-property-pattern */
--IconButton-size: 18px !important;

border-radius: 18px !important;
}
42 changes: 42 additions & 0 deletions new-log-viewer/src/components/PopUps/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {useContext} from "react";

import {
Snackbar,
Stack,
} from "@mui/joy";

import {NotificationContext} from "../../contexts/NotificationContextProvider";
import PopUpMessageBox from "./PopUpMessageBox";

import "./index.css";


/**
* Displays pop-ups in a transparent container positioned on the right side of the viewport.
*
* @return
*/
const PopUps = () => {
const {popUpMessages} = useContext(NotificationContext);

return (
<Snackbar
className={"pop-up-messages-container-snackbar"}
open={0 < popUpMessages.length}
>
<Stack
className={"pop-up-messages-container-stack"}
direction={"column-reverse"}
gap={1}
>
{popUpMessages.map((message) => (
<PopUpMessageBox
key={message.id}
message={message}/>
))}
</Stack>
</Snackbar>
);
};

export default PopUps;
1 change: 0 additions & 1 deletion new-log-viewer/src/components/StatusBar/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@

.status-message {
flex-grow: 1;
padding-left: 8px;
}
7 changes: 2 additions & 5 deletions new-log-viewer/src/components/StatusBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ const StatusBar = () => {

return (
<Sheet className={"status-bar"}>
<Typography
className={"status-message"}
level={"body-sm"}
>
Status message
<Typography className={"status-message"}>
{/* This is left blank intentionally until status messages are implemented. */}
</Typography>
<Button
color={"primary"}
Expand Down
Loading
Loading