import { create } from "zustand"; import { Onvo, Dashboard, DataSource, Widget } from "@onvo-ai/js"; import { toast } from "sonner"; import { RequestQueue } from "./Queue"; interface DashboardState { id: string | undefined; setId: (id: string, backend: Onvo) => void; unauthorized: boolean; loading: boolean; refreshing: boolean; progress: number; dashboard: Dashboard | undefined; setDashboard: (dashboard: Dashboard | undefined) => void; widgetsLoaded: boolean; widgets: Widget[]; setWidgets: (widgets: Widget[]) => void; refreshWidgets: (backend: Onvo, widgetId?: string) => Promise; tab: number; setTab: (tab: number) => void; datasources: DataSource[]; queue: RequestQueue; } export const useDashboard = create((set, get) => ({ id: undefined, loading: false, refreshing: false, dashboard: undefined, widgets: [], datasources: [], unauthorized: false, tab: 0, progress: 0, setTab: (tab) => set({ tab }), queue: new RequestQueue(25), setId: (id, backend) => { let loading = get().loading; set({ id, loading: true }); backend.datasources.list({ dashboard: id }).then(ds => { set({ datasources: ds }); }); backend.dashboards.get(id).then((dash) => { let initialTab = 0; if (dash.tabs && dash.tabs.length > 0) { initialTab = dash.tabs[0].id || 0; } set({ dashboard: dash, loading: false, tab: initialTab }); if ( !loading ) { set({ refreshing: true, progress: 0 }); backend ?.dashboard(id) .updateCache(evt => { if (evt.progress) { set({ progress: evt.progress.completed / evt.progress.total }); } }) .then(async (data) => { let id = get().id; backend.dashboards.get(id || '').then((dash) => { set({ dashboard: dash }); }); // @ts-ignore if (!data || !data.id) { set({ loading: false, refreshing: false }); } else if (id === data.id) { backend.widgets.list({ dashboard: id }).then((wid) => { set({ widgets: wid }); toast.success("Dashboard successfully refreshed"); }); set({ loading: false, refreshing: false }); } else { set({ loading: false, refreshing: false, }); } }).catch(e => { set({ loading: false, refreshing: false, }); toast.error("Failed to update dashboard cache: " + e.message, { duration: Infinity, closeButton: true }); }); } }).catch((e) => { if (e.message === "Your subscription is not active") { set({ unauthorized: true }); } }) }, setDashboard: (dashboard) => set({ dashboard }), widgetsLoaded: false, setWidgets: (widgets) => set({ widgets, widgetsLoaded: true }), refreshWidgets: async (backend, widgetId?: string) => { let id = get().id; if (!id) return; if (widgetId) { let widgets = get().widgets; backend.widgets.get(widgetId).then((wid) => { set({ widgets: widgets.map((w) => { if (w.id === wid.id) { return wid; } return w; }) }); }); } else { backend.widgets.list({ dashboard: id }).then((wid) => { set({ widgets: wid, widgetsLoaded: true }); }); } } }));