From a756677c897529b15f2625da6029c71a019772a9 Mon Sep 17 00:00:00 2001 From: Pavel Gnedov Date: Fri, 3 Nov 2023 20:18:22 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=B2=D1=81=D0=B5=20=D0=B2=D0=B8=D0=B4=D0=B6?= =?UTF-8?q?=D0=B5=D1=82=D1=8B=20=D0=BD=D0=B0=20=D0=B4=D0=B0=D1=88=D0=B1?= =?UTF-8?q?=D0=BE=D1=80=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/dashboard/dashboard-store.tsx | 23 +++++++++++----- frontend/src/dashboard/dashboard.tsx | 5 +--- frontend/src/dashboard/widget.tsx | 11 +++++++- .../src/dashboard/widgets/issues-list.tsx | 18 +++++++++++++ .../{kanban-by-tree.tsx => kanban.tsx} | 4 +-- .../src/dashboard/widgets/widget-factory.tsx | 26 +++++++++++-------- .../issues-list-board/issues-list-card.tsx | 2 +- frontend/src/issues-list-board/store.ts | 6 ++--- frontend/src/kanban-board/store.ts | 1 + frontend/src/utils/style.ts | 1 + .../src/dashboards/dashboards-data.service.ts | 2 +- 11 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 frontend/src/dashboard/widgets/issues-list.tsx rename frontend/src/dashboard/widgets/{kanban-by-tree.tsx => kanban.tsx} (81%) diff --git a/frontend/src/dashboard/dashboard-store.tsx b/frontend/src/dashboard/dashboard-store.tsx index dffcc2d..594b55b 100644 --- a/frontend/src/dashboard/dashboard-store.tsx +++ b/frontend/src/dashboard/dashboard-store.tsx @@ -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 | null; @@ -20,6 +20,7 @@ export const Widget = types dataLoaderParams: types.maybe(DataLoaderParams), loaded: false, data: types.maybe(types.frozen()), + 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; export async function DashboardLoadData(store: IDashboard): Promise { - 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 { + 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); + } + } +} diff --git a/frontend/src/dashboard/dashboard.tsx b/frontend/src/dashboard/dashboard.tsx index 47ef169..654e996 100644 --- a/frontend/src/dashboard/dashboard.tsx +++ b/frontend/src/dashboard/dashboard.tsx @@ -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
Loading... {JSON.stringify(props.store)}
; } - 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 ; }); @@ -28,7 +26,6 @@ export const Dashboard = observer((props: Props): JSX.Element => { Дашборд - {props.store.data?.title || props.store.id} {widgets} - ); diff --git a/frontend/src/dashboard/widget.tsx b/frontend/src/dashboard/widget.tsx index 0008e55..214afdb 100644 --- a/frontend/src/dashboard/widget.tsx +++ b/frontend/src/dashboard/widget.tsx @@ -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 (
- + Title - {props.store.title}
diff --git a/frontend/src/dashboard/widgets/issues-list.tsx b/frontend/src/dashboard/widgets/issues-list.tsx new file mode 100644 index 0000000..3cbdcd4 --- /dev/null +++ b/frontend/src/dashboard/widgets/issues-list.tsx @@ -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 ; +}); diff --git a/frontend/src/dashboard/widgets/kanban-by-tree.tsx b/frontend/src/dashboard/widgets/kanban.tsx similarity index 81% rename from frontend/src/dashboard/widgets/kanban-by-tree.tsx rename to frontend/src/dashboard/widgets/kanban.tsx index 8641284..d86f8ec 100644 --- a/frontend/src/dashboard/widgets/kanban-by-tree.tsx +++ b/frontend/src/dashboard/widgets/kanban.tsx @@ -8,10 +8,10 @@ export type Props = { store: Instance; }; -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 ; }); diff --git a/frontend/src/dashboard/widgets/widget-factory.tsx b/frontend/src/dashboard/widgets/widget-factory.tsx index 1cb27fb..df2ece7 100644 --- a/frontend/src/dashboard/widgets/widget-factory.tsx +++ b/frontend/src/dashboard/widgets/widget-factory.tsx @@ -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; @@ -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 ; - default: - return ( -
-
Unknown widget
- -
- ); + if (type.startsWith('kanban_by_')) { + return ; } + + if (type.startsWith('issues_list_')) { + return ; + } + + return ( +
+
Unknown widget
+ +
+ ); }); diff --git a/frontend/src/issues-list-board/issues-list-card.tsx b/frontend/src/issues-list-board/issues-list-card.tsx index ea49df0..6e52c1b 100644 --- a/frontend/src/issues-list-board/issues-list-card.tsx +++ b/frontend/src/issues-list-board/issues-list-card.tsx @@ -64,7 +64,7 @@ export const IssuesListCard = observer((props: Props): JSX.Element => { {props.store.status.name} - {props.store.priority.name} + {props.store?.priority?.name}
diff --git a/frontend/src/issues-list-board/store.ts b/frontend/src/issues-list-board/store.ts index 6fbfe73..0d5de8f 100644 --- a/frontend/src/issues-list-board/store.ts +++ b/frontend/src/issues-list-board/store.ts @@ -30,9 +30,9 @@ export type IBoardStore = Instance; 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) => { diff --git a/frontend/src/kanban-board/store.ts b/frontend/src/kanban-board/store.ts index cfaeaf4..2fb1600 100644 --- a/frontend/src/kanban-board/store.ts +++ b/frontend/src/kanban-board/store.ts @@ -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; }, diff --git a/frontend/src/utils/style.ts b/frontend/src/utils/style.ts index 268f4fc..1908318 100644 --- a/frontend/src/utils/style.ts +++ b/frontend/src/utils/style.ts @@ -13,6 +13,7 @@ const formatStringToCamelCase = (str: string): string => { export const getStyleObjectFromString = ( str: string, ): Record => { + if (!str) return {}; const style = {} as Record; str.split(';').forEach((el) => { const [property, value] = el.split(':'); diff --git a/libs/event-emitter/src/dashboards/dashboards-data.service.ts b/libs/event-emitter/src/dashboards/dashboards-data.service.ts index 484be8b..9f68d94 100644 --- a/libs/event-emitter/src/dashboards/dashboards-data.service.ts +++ b/libs/event-emitter/src/dashboards/dashboards-data.service.ts @@ -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'); }