pinkmine/frontend/src/dashboard/dashboard-store.tsx

154 lines
4 KiB
TypeScript

import axios from 'axios';
import { Instance, types } from 'mobx-state-tree';
type _WidgetParams = Record<string, any> | null;
export const WidgetParams = types.frozen<_WidgetParams>();
type _DataLoaderParams = Record<string, any> | 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<any>()),
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<typeof Widget>;
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<typeof Dashboard>;
export async function DashboardLoadData(store: IDashboard): Promise<void> {
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<void> {
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<void> {
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<void> {
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);
}
}
}