Добавлена основа для представления дашбордов на фронтенде

This commit is contained in:
Pavel Gnedov 2023-10-06 08:19:39 +07:00
parent 2687062906
commit 6e2fc1de6c
6 changed files with 133 additions and 3 deletions

View file

@ -1,8 +1,17 @@
import React from 'react';
import { useParams } from 'react-router-dom';
import * as Store from './dashboard-store';
import { Dashboard } from './dashboard';
export const DashboardPage = (): JSX.Element => {
const params = useParams();
const id = params.id as string;
return <p>Dashboard</p>;
const store = Store.Dashboard.create({
id: id,
loaded: false,
});
Store.DashboardLoadData(store);
return <Dashboard store={store} />;
};

View file

@ -0,0 +1,49 @@
import axios from 'axios';
import { Instance, types } from 'mobx-state-tree';
type _WidgetParams = {
collapsed?: boolean;
} & Record<string, any>;
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,
widgetParams: types.maybe(WidgetParams),
dataLoaderParams: types.maybe(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) => {
self.data = data;
self.loaded = true;
},
};
});
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);
}

View file

@ -0,0 +1,13 @@
import { observer } from 'mobx-react-lite';
import React from 'react';
import * as Store from './dashboard-store';
export type Props = { store: Store.IDashboard };
export const Dashboard = observer((props: Props): JSX.Element => {
if (!props.store.loaded) {
return <pre>Loading... {JSON.stringify(props.store)}</pre>;
}
return <pre>{JSON.stringify(props.store, null, ' ')}</pre>;
});

View file

@ -0,0 +1,23 @@
import React from 'react';
import * as Store from './dashboards-store';
import { observer } from 'mobx-react-lite';
export type Props = { store: Store.IList };
export const DashboardsList = observer((props: Props): JSX.Element => {
if (!props.store.loaded) {
return <div>Loading...</div>;
}
return (
<ul>
{props.store.list.map((item) => {
return (
<li key={item.id}>
<a href={`/dashboard/${item.id}`}>{item.title}</a>
</li>
);
})}
</ul>
);
});

View file

@ -1,6 +1,10 @@
import React from 'react';
import { DashboardsList } from './dashboards-list';
import * as Store from './dashboards-store';
export const DashboardsPage = (): JSX.Element => {
// TODO: code for DashboardsPage
return <p>Dashboards</p>;
const store = Store.List.create({ loaded: false, list: [] });
Store.ListStoreLoadData(store);
return <DashboardsList store={store} />;
};

View file

@ -0,0 +1,32 @@
import axios from 'axios';
import { Instance, types } from 'mobx-state-tree';
export const Item = types.model({
id: types.string,
title: types.string,
});
export type IItem = Instance<typeof Item>;
export const List = types
.model({
list: types.array(Item),
loaded: types.boolean,
})
.actions((self) => {
return {
setList: (data: any) => {
self.list = data;
self.loaded = true;
},
};
});
export type IList = Instance<typeof List>;
export async function ListStoreLoadData(store: IList): Promise<void> {
const url = `${process.env.REACT_APP_BACKEND}api/dashboards`;
const resp = await axios.get(url);
if (!resp?.data) return;
store.setList(resp.data);
}