Добавлены все виджеты на дашборд
This commit is contained in:
parent
ae14189cd3
commit
a756677c89
11 changed files with 70 additions and 29 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import { Instance, types } from 'mobx-state-tree';
|
||||
import { IAnyModelType, Instance, types } from 'mobx-state-tree';
|
||||
|
||||
type _WidgetParams = Record<string, any> | null;
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ export const Widget = types
|
|||
dataLoaderParams: types.maybe(DataLoaderParams),
|
||||
loaded: false,
|
||||
data: types.maybe(types.frozen<any>()),
|
||||
dashboardId: types.maybe(types.string),
|
||||
})
|
||||
.actions((self) => {
|
||||
return {
|
||||
|
|
@ -36,6 +37,9 @@ export const Widget = types
|
|||
self.loaded = true;
|
||||
self.data = data;
|
||||
},
|
||||
setDashboardId: (dashboardId: string) => {
|
||||
self.dashboardId = dashboardId;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -49,8 +53,6 @@ export function createWidgetStore(
|
|||
widgetParams?: _WidgetParams,
|
||||
dataLoaderParams?: _DataLoaderParams,
|
||||
): IWidget {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
console.debug('init new Widget store, params:', arguments);
|
||||
return Widget.create({
|
||||
id: id,
|
||||
type: type,
|
||||
|
|
@ -76,7 +78,6 @@ export const Dashboard = types
|
|||
.actions((self) => {
|
||||
return {
|
||||
setData: (data: any) => {
|
||||
console.debug('Dashboard store new data:', data); // DEBUG
|
||||
if (data.widgets) {
|
||||
for (let i = 0; i < data.widgets.length; i++) {
|
||||
const widget = data.widgets[i];
|
||||
|
|
@ -112,10 +113,8 @@ export const Dashboard = types
|
|||
export type IDashboard = Instance<typeof Dashboard>;
|
||||
|
||||
export async function DashboardLoadData(store: IDashboard): Promise<void> {
|
||||
console.debug('DashboardLoadData store:', store); // DEBUG
|
||||
const url = `${process.env.REACT_APP_BACKEND}api/dashboard/${store.id}`;
|
||||
const resp = await axios.get(url);
|
||||
console.debug('DashboardLoadData resp:', resp); // DEBUG
|
||||
if (!resp.data) return;
|
||||
store.setData(resp.data);
|
||||
}
|
||||
|
|
@ -141,3 +140,15 @@ export async function LoadDataForWidget(
|
|||
}
|
||||
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?.data) {
|
||||
widget.setData(data?.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import React from 'react';
|
|||
import * as DashboardStoreNs from './dashboard-store';
|
||||
import * as TopRightMenuNs from '../misc-components/top-right-menu';
|
||||
import * as WidgetNs from './widget';
|
||||
import { DebugInfo } from '../misc-components/debug-info';
|
||||
|
||||
export type Props = { store: DashboardStoreNs.IDashboard };
|
||||
|
||||
|
|
@ -13,11 +12,10 @@ export const Dashboard = observer((props: Props): JSX.Element => {
|
|||
return <pre>Loading... {JSON.stringify(props.store)}</pre>;
|
||||
}
|
||||
|
||||
const debugInfo = JSON.stringify(props.store, null, ' ');
|
||||
|
||||
const topRightMenuStore = TopRightMenuNs.Store.create({ visible: false });
|
||||
|
||||
const widgets = props.store.data?.widgets.map((widget) => {
|
||||
widget.setDashboardId(props.store.id);
|
||||
return <WidgetNs.Widget key={widget.id} store={widget}></WidgetNs.Widget>;
|
||||
});
|
||||
|
||||
|
|
@ -28,7 +26,6 @@ export const Dashboard = observer((props: Props): JSX.Element => {
|
|||
<span>Дашборд - {props.store.data?.title || props.store.id}</span>
|
||||
</TopRightMenuNs.TopRightMenu>
|
||||
{widgets}
|
||||
<DebugInfo value={debugInfo} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -79,13 +79,22 @@ export type Props = {
|
|||
* }
|
||||
*/
|
||||
|
||||
function onWidgetVisibleToggleClick(store: DashboardStoreNs.IWidget): void {
|
||||
if (!store.loaded && store.dashboardId) {
|
||||
DashboardStoreNs.WidgetLoadData(store);
|
||||
}
|
||||
store.toggle();
|
||||
}
|
||||
|
||||
export const Widget = observer((props: Props): JSX.Element => {
|
||||
const display = props.store.visible ? 'block' : 'none';
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<button onClick={() => props.store.toggle()}>Show/hide</button>
|
||||
<button onClick={() => onWidgetVisibleToggleClick(props.store)}>
|
||||
Show/hide
|
||||
</button>
|
||||
<span>Title - {props.store.title}</span>
|
||||
</div>
|
||||
<div style={{ display: display }}>
|
||||
|
|
|
|||
18
frontend/src/dashboard/widgets/issues-list.tsx
Normal file
18
frontend/src/dashboard/widgets/issues-list.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { observer } from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
import * as DashboardStoreNs from '../dashboard-store';
|
||||
import * as IssuesListBoardsNs from '../../issues-list-board/issues-list-boards';
|
||||
import * as IssuesListBoardsStoreNs from '../../issues-list-board/store';
|
||||
import { onSnapshot } from 'mobx-state-tree';
|
||||
|
||||
export type Props = {
|
||||
store: DashboardStoreNs.IWidget;
|
||||
};
|
||||
|
||||
export const IssuesList = observer((props: Props): JSX.Element => {
|
||||
const store = IssuesListBoardsStoreNs.PageStore.create({ loaded: false });
|
||||
onSnapshot(props.store, (state) => {
|
||||
if (state?.data?.data) store.setData(state?.data?.data);
|
||||
});
|
||||
return <IssuesListBoardsNs.IssuesListBoards store={store} />;
|
||||
});
|
||||
|
|
@ -8,10 +8,10 @@ export type Props = {
|
|||
store: Instance<typeof DashboardStoreNs.Widget>;
|
||||
};
|
||||
|
||||
export const KanbanByTree = observer((props: Props): JSX.Element => {
|
||||
export const Kanban = observer((props: Props): JSX.Element => {
|
||||
const store = KanbanBoardsStoreNs.PageStore.create({ loaded: false });
|
||||
onSnapshot(props.store, (state) => {
|
||||
store.setData(state.data.data);
|
||||
if (state?.data?.data) store.setData(state?.data?.data);
|
||||
});
|
||||
return <KanbanBoardsNs.KanbanBoards store={store} />;
|
||||
});
|
||||
|
|
@ -2,8 +2,9 @@ import React from 'react';
|
|||
import * as DashboardStoreNs from '../dashboard-store';
|
||||
import { Instance } from 'mobx-state-tree';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import * as KanbanByTreeWidgetNs from './kanban-by-tree';
|
||||
import * as KanbanWidgetNs from './kanban';
|
||||
import { DebugInfo } from '../../misc-components/debug-info';
|
||||
import * as IssuesListNs from './issues-list';
|
||||
|
||||
export type Props = {
|
||||
store: Instance<typeof DashboardStoreNs.Widget>;
|
||||
|
|
@ -12,15 +13,18 @@ export type Props = {
|
|||
export const WidgetFactory = observer((props: Props): JSX.Element => {
|
||||
const type = props.store.type;
|
||||
|
||||
switch (type) {
|
||||
case 'kanban_by_tree':
|
||||
return <KanbanByTreeWidgetNs.KanbanByTree store={props.store} />;
|
||||
default:
|
||||
return (
|
||||
<div>
|
||||
<div>Unknown widget</div>
|
||||
<DebugInfo value={JSON.stringify(props.store, null, ' ')} />
|
||||
</div>
|
||||
);
|
||||
if (type.startsWith('kanban_by_')) {
|
||||
return <KanbanWidgetNs.Kanban store={props.store} />;
|
||||
}
|
||||
|
||||
if (type.startsWith('issues_list_')) {
|
||||
return <IssuesListNs.IssuesList store={props.store} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>Unknown widget</div>
|
||||
<DebugInfo value={JSON.stringify(props.store, null, ' ')} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ export const IssuesListCard = observer((props: Props): JSX.Element => {
|
|||
<span className={Css.timeBox}>{props.store.status.name}</span>
|
||||
<span> </span>
|
||||
<span className={Css.priorityBox} style={priorityStyle}>
|
||||
{props.store.priority.name}
|
||||
{props.store?.priority?.name}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ export type IBoardStore = Instance<typeof BoardStore>;
|
|||
|
||||
export const PageStore = types
|
||||
.model({
|
||||
loaded: types.boolean,
|
||||
type: types.string,
|
||||
name: types.string,
|
||||
loaded: false,
|
||||
type: '',
|
||||
name: '',
|
||||
data: types.maybeNull(types.array(BoardStore)),
|
||||
})
|
||||
.actions((self) => {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ export const PageStore = types
|
|||
.actions((self) => {
|
||||
return {
|
||||
setData: (data: any) => {
|
||||
console.debug('Kanban page store new data -', data); // DEBUG
|
||||
self.data = data;
|
||||
self.loaded = true;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const formatStringToCamelCase = (str: string): string => {
|
|||
export const getStyleObjectFromString = (
|
||||
str: string,
|
||||
): Record<string, string> => {
|
||||
if (!str) return {};
|
||||
const style = {} as Record<string, string>;
|
||||
str.split(';').forEach((el) => {
|
||||
const [property, value] = el.split(':');
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export class DashboardsDataService {
|
|||
widget.dataLoaderParams,
|
||||
cfg,
|
||||
);
|
||||
if (loadRes.result) return { widget: widget, data: loadRes.error };
|
||||
if (loadRes.result) return { widget: widget, data: loadRes.result };
|
||||
throw createAppError('CANNOT_LOAD_DATA');
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue