mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-06-11 07:47:12 +02:00
feat: adding frontend notifications for attribute updates
This commit is contained in:
@ -5,4 +5,14 @@ input.instantUpdate {
|
||||
.numberComponentButton {
|
||||
padding: 0.15em 6px !important;
|
||||
font-size: 0.70rem !important;
|
||||
}
|
||||
.navbarOffset {
|
||||
padding-top: 60px !important;
|
||||
right: 20;
|
||||
}
|
||||
/* .toastContainer {
|
||||
position: fixed;
|
||||
} */
|
||||
.notificationToast {
|
||||
background-color: rgba(114, 214, 253, 0.5) !important;
|
||||
}
|
@ -1,10 +1,18 @@
|
||||
import { useEffect, useReducer, useState } from 'react';
|
||||
import { Navbar, Form, Offcanvas, Container } from 'react-bootstrap';
|
||||
import {
|
||||
Navbar,
|
||||
Form,
|
||||
Offcanvas,
|
||||
Container,
|
||||
Toast,
|
||||
ToastContainer
|
||||
} from 'react-bootstrap';
|
||||
import { hostname, port, socket } from './socket';
|
||||
import {
|
||||
DataServiceComponent,
|
||||
DataServiceJSON
|
||||
} from './components/DataServiceComponent';
|
||||
import './App.css';
|
||||
|
||||
type ValueType = boolean | string | number | object;
|
||||
|
||||
@ -108,25 +116,38 @@ const App = () => {
|
||||
const [state, dispatch] = useReducer(reducer, null);
|
||||
const [isInstantUpdate, setIsInstantUpdate] = useState(true);
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
const [showNotification, setShowNotification] = useState(true);
|
||||
const [notifications, setNotifications] = useState([]);
|
||||
|
||||
const removeNotificationById = (id: number) => {
|
||||
setNotifications((prevNotifications) =>
|
||||
prevNotifications.filter((n) => n.id !== id)
|
||||
);
|
||||
};
|
||||
|
||||
const handleCloseSettings = () => setShowSettings(false);
|
||||
const handleShowSettings = () => setShowSettings(true);
|
||||
|
||||
function onNotify(value: NotificationElement) {
|
||||
dispatch({
|
||||
type: 'UPDATE_ATTRIBUTE',
|
||||
parent_path: value.data.parent_path,
|
||||
name: value.data.name,
|
||||
value: value.data.value
|
||||
});
|
||||
const newNotification = {
|
||||
id: Math.random(),
|
||||
text: `Attribute ${value.data.parent_path}.${value.data.name} updated to ${value.data.value}.`
|
||||
};
|
||||
setNotifications((prevNotifications) => [newNotification, ...prevNotifications]);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch data from the API when the component mounts
|
||||
fetch(`http://${hostname}:${port}/service-properties`)
|
||||
.then((response) => response.json())
|
||||
.then((data: DataServiceJSON) => dispatch({ type: 'SET_DATA', data }));
|
||||
|
||||
function onNotify(value: NotificationElement) {
|
||||
dispatch({
|
||||
type: 'UPDATE_ATTRIBUTE',
|
||||
parent_path: value.data.parent_path,
|
||||
name: value.data.name,
|
||||
value: value.data.value
|
||||
});
|
||||
}
|
||||
|
||||
socket.on('notify', onNotify);
|
||||
|
||||
return () => {
|
||||
@ -147,7 +168,41 @@ const App = () => {
|
||||
</Container>
|
||||
</Navbar>
|
||||
|
||||
<Offcanvas show={showSettings} onHide={handleCloseSettings} placement="end">
|
||||
{showNotification && (
|
||||
<ToastContainer
|
||||
className="navbarOffset toastContainer"
|
||||
position="top-end"
|
||||
style={{ position: 'fixed' }}>
|
||||
{notifications.map((notification) => (
|
||||
<Toast
|
||||
className="notificationToast"
|
||||
key={notification.id}
|
||||
onClose={() => {
|
||||
removeNotificationById(notification.id);
|
||||
}}
|
||||
onClick={() => {
|
||||
removeNotificationById(notification.id);
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
removeNotificationById(notification.id);
|
||||
}}
|
||||
show={true}
|
||||
autohide
|
||||
delay={2000}>
|
||||
<Toast.Header closeButton={false} className="notificationToast">
|
||||
<strong className="mr-auto">Notification</strong>
|
||||
</Toast.Header>
|
||||
<Toast.Body>{notification.text}</Toast.Body>
|
||||
</Toast>
|
||||
))}
|
||||
</ToastContainer>
|
||||
)}
|
||||
|
||||
<Offcanvas
|
||||
show={showSettings}
|
||||
onHide={handleCloseSettings}
|
||||
placement="end"
|
||||
style={{ zIndex: 9999 }}>
|
||||
<Offcanvas.Header closeButton>
|
||||
<Offcanvas.Title>Settings</Offcanvas.Title>
|
||||
</Offcanvas.Header>
|
||||
@ -158,11 +213,17 @@ const App = () => {
|
||||
type="switch"
|
||||
label="Enable Instant Update"
|
||||
/>
|
||||
<Form.Check
|
||||
checked={showNotification}
|
||||
onChange={(e) => setShowNotification(e.target.checked)}
|
||||
type="switch"
|
||||
label="Show Notifications"
|
||||
/>
|
||||
{/* Add any additional controls you want here */}
|
||||
</Offcanvas.Body>
|
||||
</Offcanvas>
|
||||
|
||||
<div className="App">
|
||||
<div className="App navbarOffset">
|
||||
<DataServiceComponent
|
||||
props={state as DataServiceJSON}
|
||||
isInstantUpdate={isInstantUpdate}
|
||||
|
Reference in New Issue
Block a user