From 58f48695c84ccf0ff12afbda78d28c4496bb4b81 Mon Sep 17 00:00:00 2001 From: Aaron Chong Date: Thu, 7 Sep 2023 10:06:13 +0800 Subject: [PATCH] Feature/task table auto update (#763) * Sent refresh counter app event to be void, introduced interval event Signed-off-by: Aaron Chong * Fix prepend addition Signed-off-by: Aaron Chong * Using 5 second periodic query interval Signed-off-by: Aaron Chong * Refactor alert event to use void subject as well Signed-off-by: Aaron Chong --------- Signed-off-by: Aaron Chong --- .../dashboard/src/components/alert-store.tsx | 4 +- .../dashboard/src/components/app-events.ts | 4 +- packages/dashboard/src/components/appbar.tsx | 39 ++++++++++--------- .../src/components/tasks/tasks-app.tsx | 25 ++++++++++-- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/packages/dashboard/src/components/alert-store.tsx b/packages/dashboard/src/components/alert-store.tsx index 68ee27b41..95e0db09e 100644 --- a/packages/dashboard/src/components/alert-store.tsx +++ b/packages/dashboard/src/components/alert-store.tsx @@ -17,7 +17,6 @@ enum AlertCategory { export const AlertStore = React.memo(() => { const rmf = React.useContext(RmfAppContext); const [taskAlerts, setTaskAlerts] = React.useState>({}); - const refreshAlertCount = React.useRef(0); const categorizeAndPushAlerts = (alert: Alert) => { // We check if an existing alert has been acknowledged, remove it before @@ -51,8 +50,7 @@ export const AlertStore = React.memo(() => { } const sub = rmf.alertObsStore.subscribe(async (alert) => { categorizeAndPushAlerts(alert); - refreshAlertCount.current += 1; - AppEvents.refreshAlertCount.next(refreshAlertCount.current); + AppEvents.refreshAlert.next(); }); return () => sub.unsubscribe(); }, [rmf]); diff --git a/packages/dashboard/src/components/app-events.ts b/packages/dashboard/src/components/app-events.ts index 1edafe08c..21c1e7d02 100644 --- a/packages/dashboard/src/components/app-events.ts +++ b/packages/dashboard/src/components/app-events.ts @@ -15,8 +15,8 @@ export const AppEvents = { ingestorSelect: new Subject(), robotSelect: new Subject<[fleetName: string, robotName: string] | null>(), taskSelect: new Subject(), - refreshTaskAppCount: new Subject(), - refreshAlertCount: new Subject(), + refreshTaskApp: new Subject(), + refreshAlert: new Subject(), alertListOpenedAlert: new Subject(), disabledLayers: new ReplaySubject>(), zoom: new BehaviorSubject(null), diff --git a/packages/dashboard/src/components/appbar.tsx b/packages/dashboard/src/components/appbar.tsx index b3c6d85e3..0d3a86f58 100644 --- a/packages/dashboard/src/components/appbar.tsx +++ b/packages/dashboard/src/components/appbar.tsx @@ -203,8 +203,8 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea }, [rmf]); React.useEffect(() => { - const sub = AppEvents.refreshTaskAppCount.subscribe((currentValue) => { - setRefreshTaskAppCount(currentValue); + const sub = AppEvents.refreshTaskApp.subscribe({ + next: () => setRefreshTaskAppCount((oldValue) => ++oldValue), }); return () => sub.unsubscribe(); }, []); @@ -249,18 +249,21 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea }), ); subs.push( - AppEvents.refreshAlertCount.subscribe((_) => { - (async () => { - const resp = await rmf.alertsApi.getAlertsAlertsGet(); - const alerts = resp.data as Alert[]; - setUnacknowledgedAlertsNum( - alerts.filter( - (alert) => !(alert.acknowledged_by && alert.unix_millis_acknowledged_time), - ).length, - ); - })(); + AppEvents.refreshAlert.subscribe({ + next: () => { + (async () => { + const resp = await rmf.alertsApi.getAlertsAlertsGet(); + const alerts = resp.data as Alert[]; + setUnacknowledgedAlertsNum( + alerts.filter( + (alert) => !(alert.acknowledged_by && alert.unix_millis_acknowledged_time), + ).length, + ); + })(); + }, }), ); + // Get the initial number of unacknowledged alerts (async () => { const resp = await rmf.alertsApi.getAlertsAlertsGet(); @@ -293,9 +296,9 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea scheduleRequests.map((req) => rmf.tasksApi.postScheduledTaskScheduledTasksPost(req)), ); } - AppEvents.refreshTaskAppCount.next(refreshTaskAppCount + 1); + AppEvents.refreshTaskApp.next(); }, - [rmf, refreshTaskAppCount], + [rmf], ); const uploadFileInputRef = React.useRef(null); @@ -352,9 +355,9 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea throw new Error('tasks api not available'); } await rmf.tasksApi.postFavoriteTaskFavoriteTasksPost(taskFavoriteRequest); - AppEvents.refreshTaskAppCount.next(refreshTaskAppCount + 1); + AppEvents.refreshTaskApp.next(); }, - [rmf, refreshTaskAppCount], + [rmf], ); const deleteFavoriteTask = React.useCallback['deleteFavoriteTask']>( @@ -367,9 +370,9 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea } await rmf.tasksApi.deleteFavoriteTaskFavoriteTasksFavoriteTaskIdDelete(favoriteTask.id); - AppEvents.refreshTaskAppCount.next(refreshTaskAppCount + 1); + AppEvents.refreshTaskApp.next(); }, - [rmf, refreshTaskAppCount], + [rmf], ); //#endregion 'Favorite Task' diff --git a/packages/dashboard/src/components/tasks/tasks-app.tsx b/packages/dashboard/src/components/tasks/tasks-app.tsx index 292201bfe..1822058ee 100644 --- a/packages/dashboard/src/components/tasks/tasks-app.tsx +++ b/packages/dashboard/src/components/tasks/tasks-app.tsx @@ -58,6 +58,8 @@ import { RmfAppContext } from '../rmf-app'; import { TaskSummary } from './task-summary'; import { downloadCsvFull, downloadCsvMinimal } from './utils'; +const RefreshTaskQueueTableInterval = 5000; + interface TabPanelProps { children?: React.ReactNode; index: number; @@ -222,12 +224,27 @@ export const TasksApp = React.memo( const [sortFields, setSortFields] = React.useState({ model: undefined }); React.useEffect(() => { - const sub = AppEvents.refreshTaskAppCount.subscribe((currentValue) => { - setRefreshTaskAppCount(currentValue); + const sub = AppEvents.refreshTaskApp.subscribe({ + next: () => { + setRefreshTaskAppCount((oldValue) => ++oldValue); + }, }); return () => sub.unsubscribe(); }, []); + React.useEffect(() => { + const refreshTaskQueueTable = async () => { + AppEvents.refreshTaskApp.next(); + }; + const refreshInterval = window.setInterval( + refreshTaskQueueTable, + RefreshTaskQueueTableInterval, + ); + return () => { + clearInterval(refreshInterval); + }; + }, []); + // TODO: parameterize this variable const GET_LIMIT = 10; React.useEffect(() => { @@ -409,7 +426,7 @@ export const TasksApp = React.memo( } else { await rmf.tasksApi.delScheduledTasksScheduledTasksTaskIdDelete(task.id); } - AppEvents.refreshTaskAppCount.next(refreshTaskAppCount + 1); + AppEvents.refreshTaskApp.next(); // Set the default values setOpenDeleteScheduleDialog(false); @@ -472,7 +489,7 @@ export const TasksApp = React.memo( { - AppEvents.refreshTaskAppCount.next(refreshTaskAppCount + 1); + AppEvents.refreshTaskApp.next(); }} aria-label="Refresh" >