Skip to content
Snippets Groups Projects
Commit b7b2806a authored by Leonardo Christino's avatar Leonardo Christino
Browse files

feat(alerts): add alert banners with a few default alerts

parent ad02db83
No related branches found
No related tags found
1 merge request!42feat(alerts): add alert banners with a few default alerts
......@@ -28,6 +28,7 @@ import { logout } from '@graphpolaris/shared/lib/data-access/store/authSlice';
import { SchemaFromBackend } from '@graphpolaris/shared/lib/schema';
import { LinkPredictionInstance, setMLResult, allMLTypes } from '@graphpolaris/shared/lib/data-access/store/mlSlice';
import { Resizable } from '@graphpolaris/shared/lib/components/Resizable';
import { BrokerAlerts } from '@graphpolaris/shared/lib/data-access/socket/broker/brokerAlerts';
export interface App {}
......@@ -105,6 +106,7 @@ export function App(props: App) {
return (
<div className="h-screen w-screen">
<BrokerAlerts />
<div className={'h-screen w-screen ' + (!auth.authorized ? 'blur-sm pointer-events-none ' : '')}>
<div className="flex flex-col h-screen max-h-screen relative">
<aside className="h-[4rem]">
......
......@@ -41,7 +41,7 @@ export default {
'base-100': '#F7F9FA',
// 'base-200': '#F9FBFC',
info: '#99622E',
success: '#2DC177',
success: '#35a06a',
warning: '#eab308',
error: '#dc2626',
......
......@@ -67,8 +67,6 @@ export class WebSocketHandler implements BackendMessageReceiver {
*/
public onWebSocketMessage = (event: MessageEvent<any>) => {
let data = JSON.parse(event.data);
console.debug('WS message: ', data);
Broker.instance().publish(data.value, data.type);
};
......
import React, { ReactNode, useEffect, useState } from 'react';
import Broker from '@graphpolaris/shared/lib/data-access/socket/broker';
import { useImmer } from 'use-immer';
import styles from './brokerAlerts.module.scss';
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
type Message = {
message: ReactNode;
className: string;
};
export const BrokerAlerts = (props: { timer?: number }) => {
const [messages, setMessages] = useImmer<{ data: any; routingKey: string; message: Message; showing: boolean }[]>([]);
const timer = props.timer || 1200;
useEffect(() => {
Broker.instance().subscribeDefault((data: any, routingKey: string) => {
let message: Message | undefined = undefined;
// Use the logic below to define which broker messages should be shown as alerts.
if (routingKey === 'schema_result') {
message = {
message: (
<>
<CheckCircleOutlineIcon /> Schema graph updated
</>
),
className: 'alert-success',
};
} else if (routingKey === 'query_result') {
message = {
message: (
<>
<CheckCircleOutlineIcon /> Query Executed!
</>
),
className: 'alert-success',
};
}
// Queue the message to be shown for props.time time, then fade it out matching the animation of animate-closemenu fade out time
if (message) {
setMessages((draft) => {
draft.unshift({ data, routingKey, message: message as Message, showing: true });
return draft;
});
setTimeout(() => {
setMessages((draft) => {
draft[draft.length - 1].showing = false;
// draft.pop();
return draft;
});
setTimeout(() => {
setMessages((draft) => {
draft.pop();
return draft;
});
}, 300); // matches the animation of animate-closemenu
}, timer);
}
});
return () => {
Broker.instance().unSubscribeDefault();
};
}, []);
return (
<>
{messages &&
messages.map((m, i) => {
return (
<div
key={i}
className={
`absolute bottom-5 right-5 w-fit min-w-[20rem] alert z-50 ` +
(m.showing ? 'animate-openmenu ' : 'animate-closemenu ') +
(m.message?.className || '')
}
style={{
transform: `translateY(-${i * 5}rem)`,
}}
>
<span className="flex flex-row content-center gap-3 text-white">{m.message.message}</span>
{/* {!message && (m.data?.status ? m.data.status : m.routingKey)} */}
</div>
);
})}
</>
);
};
......@@ -20,6 +20,7 @@
export default class Broker {
private static singletonInstance: Broker;
private listeners: Record<string, Record<string, Function>> = {};
private catchAllListener: Function | undefined;
/** mostRecentMessages is a dictionary with <routingkey, messageObject>. It stores the most recent message for that routingkey. */
private mostRecentMessages: Record<string, unknown> = {};
......@@ -38,15 +39,34 @@ export default class Broker {
public publish(jsonObject: unknown, routingKey: string): void {
this.mostRecentMessages[routingKey] = jsonObject;
if (this.listeners[routingKey] && Object.keys(this.listeners[routingKey]).length != 0)
if (this.listeners[routingKey] && Object.keys(this.listeners[routingKey]).length != 0) {
if (this.catchAllListener) {
this.catchAllListener(jsonObject, routingKey);
}
Object.values(this.listeners[routingKey]).forEach((listener) => listener(jsonObject, routingKey));
// If there are no listeners, log the message
else
console.debug(
`no listeners for message with routing key %c${routingKey}`,
`message processed with routing key %c${routingKey}`,
'font-weight:bold; color: blue; background-color: white;',
jsonObject
);
}
// If there are no listeners, log the message
else {
if (this.catchAllListener) {
this.catchAllListener(jsonObject, routingKey);
console.debug(
`catch all used for message with routing key %c${routingKey}`,
'font-weight:bold; color: blue; background-color: white;',
jsonObject
);
} else {
console.debug(
`no listeners for message with routing key %c${routingKey}`,
'font-weight:bold; color: blue; background-color: white;',
jsonObject
);
}
}
}
/**
......@@ -74,6 +94,16 @@ export default class Broker {
return key;
}
/**
* Subscribe a listener to messages with the specified routingKey.
* @param {Function} newListener The listener to subscribe.
* @param {string} routingKey The routingkey to subscribe to.
* @param {boolean} consumeMostRecentMessage If true and there is a message for this routingkey available, notify the new listener. Default true.
*/
public subscribeDefault(newListener: Function): void {
this.catchAllListener = newListener;
}
/**
* Unsubscribes a listener from messages with specified routingkey.
* @param {string} routingKey The routing key to unsubscribe from
......@@ -85,6 +115,13 @@ export default class Broker {
}
}
/**
* Unsubscribes the catch all listener from messages
*/
public unSubscribeDefault(): void {
this.catchAllListener = undefined;
}
/**
* Unsubscribes all listeners from messages with specified routingkey.
* @param {string} routingKey The routing key to unsubscribe from
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment