import axios from 'axios'; import { Instance, types } from 'mobx-state-tree'; type _WidgetParams = Record | null; export const WidgetParams = types.frozen<_WidgetParams>(); type _DataLoaderParams = Record | null; export const DataLoaderParams = types.frozen<_DataLoaderParams>(); export const Widget = types .model({ type: types.string, id: types.string, title: types.string, collapsed: types.maybe(types.boolean), visible: types.boolean, widgetParams: types.maybe(WidgetParams), dataLoaderParams: types.maybe(DataLoaderParams), loaded: false, data: types.maybe(types.frozen()), dashboardId: types.maybe(types.string), }) .actions((self) => { return { show: () => { self.visible = false; }, hide: () => { self.visible = true; }, toggle: () => { self.visible = !self.visible; }, setData: (data: any) => { self.loaded = true; self.data = data; }, setDashboardId: (dashboardId: string) => { self.dashboardId = dashboardId; }, }; }); export type IWidget = Instance; export function createWidgetStore( id: string, type: string, title: string, collapsed = false, widgetParams?: _WidgetParams, dataLoaderParams?: _DataLoaderParams, ): IWidget { return Widget.create({ id: id, type: type, title: title, collapsed: collapsed, visible: !collapsed, widgetParams: widgetParams, dataLoaderParams: dataLoaderParams, }); } export const Data = types.model({ widgets: types.array(Widget), title: types.maybe(types.string), }); export const Dashboard = types .model({ loaded: types.boolean, id: types.string, data: types.maybe(Data), }) .actions((self) => { return { setData: (data: any) => { if (data.widgets) { for (let i = 0; i < data.widgets.length; i++) { const widget = data.widgets[i]; widget.visible = !widget.collapsed; } } self.data = data; self.loaded = true; }, setWidgetsData: (data: any) => { for (let i = 0; i < data.length; i++) { const widgetData = data[i]?.data; const widgetId = data[i]?.widgetId; if (!widgetId || !widgetData) continue; const widgets = self.data?.widgets; if (!widgets || widgets.length <= 0) return; const widget = widgets.find((w) => w.id == widgetId); if (!widget) continue; widget.setData(widgetData); } }, setWidgetData: (widgetId: string, data: any) => { const widget = self.data?.widgets.find((w) => w.id == widgetId); if (!widget) return; widget.setData(data); }, }; }); export type IDashboard = Instance; export async function DashboardLoadData(store: IDashboard): Promise { const url = `${process.env.REACT_APP_BACKEND}api/dashboard/${store.id}`; const resp = await axios.get(url); if (!resp.data) return; store.setData(resp.data); } export async function LoadDataForWidgets(store: IDashboard): Promise { const url = `${process.env.REACT_APP_BACKEND}api/dashboard/${store.id}/load-data`; const resp = await fetch(url); if (resp && resp.ok) { const data = await resp.json(); store.setWidgetsData(data); } } export async function LoadDataForWidget( store: IDashboard, widgetId: string, ): Promise { const url = `${process.env.REACT_APP_BACKEND}api/dashboard/${store.id}/load-data/${widgetId}`; const resp = await fetch(url); if (resp && resp.ok) { const data = await resp.json(); store.setWidgetData(widgetId, data); } return; } export async function WidgetLoadData(widget: IWidget): Promise { if (!widget.dashboardId) return; const url = `${process.env.REACT_APP_BACKEND}api/dashboard/${widget.dashboardId}/load-data/${widget.id}`; const resp = await fetch(url); if (resp && resp.ok) { const data = await resp.json(); if (data) { widget.setData(data); } } }