Реализация виджета на frontend-е
This commit is contained in:
parent
77352a497b
commit
8479b6d68d
3 changed files with 152 additions and 1 deletions
|
|
@ -24,7 +24,7 @@
|
|||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"start": "BROWSER=none react-scripts start --open=false",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
|
|
|
|||
146
frontend/src/dashboard/widgets/daily-eccm-v2.tsx
Normal file
146
frontend/src/dashboard/widgets/daily-eccm-v2.tsx
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
import React from 'react';
|
||||
import * as DashboardStoreNs from '../dashboard-store';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { DebugInfo } from '../../misc-components/debug-info';
|
||||
import { Instance, onSnapshot, types } from 'mobx-state-tree';
|
||||
|
||||
export const DailyEccmV2Data = types.model({
|
||||
id: types.string,
|
||||
dashboardId: types.string,
|
||||
widgetId: types.string,
|
||||
datetime: types.number,
|
||||
datetimeFormatted: types.string,
|
||||
reportIssues: types.array(types.frozen()),
|
||||
issuesMetrics: types.frozen(),
|
||||
latest: types.boolean,
|
||||
});
|
||||
|
||||
export const DailyEccmV2Store = types
|
||||
.model({
|
||||
data: DailyEccmV2Data,
|
||||
})
|
||||
.actions((self) => ({
|
||||
setData(data: any) {
|
||||
self.data = data;
|
||||
},
|
||||
}));
|
||||
|
||||
export type IDailyEccmV2Store = Instance<typeof DailyEccmV2Store>;
|
||||
|
||||
export const DailyEccmV2 = observer(
|
||||
(props: { store: IDailyEccmV2Store }): JSX.Element => {
|
||||
const dashboardId = props.store?.data?.dashboardId;
|
||||
const widgetId = props.store?.data?.widgetId;
|
||||
const keyPrefix = `dashboard-${dashboardId}-widget-${widgetId}`;
|
||||
|
||||
const issuesByStatusCount: Record<string, any> =
|
||||
props.store?.data?.issuesMetrics?.issuesByStatusCount ?? {};
|
||||
const issuesByVersionsCount: Record<string, any> =
|
||||
props.store?.data?.issuesMetrics?.issuesByVersionsCount ?? {};
|
||||
const issuesByUsername: Record<string, any> =
|
||||
props.store?.data?.issuesMetrics?.issuesByUsername ?? {};
|
||||
|
||||
const byStatusLi: JSX.Element[] = [];
|
||||
|
||||
Object.keys(issuesByStatusCount).forEach((status) => {
|
||||
let byStatusHint: JSX.Element;
|
||||
const byVersion = issuesByStatusCount[status]?.byVersion;
|
||||
const keyPrefixForCurrentStatusBlock = `${keyPrefix}-issuesByStatusCount-${status}`;
|
||||
if (byVersion && Object.keys(byVersion).length > 0) {
|
||||
const byVersionSimple = Object.keys(byVersion).reduce(
|
||||
(acc: Record<string, number>, version) => {
|
||||
acc[version] = byVersion[version].count;
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, number>,
|
||||
);
|
||||
byStatusHint = (
|
||||
<span
|
||||
key={`${keyPrefixForCurrentStatusBlock}-byVersionHint`}
|
||||
style={{ marginLeft: '10px', color: 'lightgray' }}
|
||||
>
|
||||
(Версии: {JSON.stringify(byVersionSimple)})
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
byStatusHint = <></>;
|
||||
}
|
||||
byStatusLi.push(
|
||||
<li key={`${keyPrefixForCurrentStatusBlock}`}>
|
||||
{status}: {issuesByStatusCount[status].count} {byStatusHint}
|
||||
</li>,
|
||||
);
|
||||
});
|
||||
|
||||
const byVersionsLi: JSX.Element[] = [];
|
||||
|
||||
Object.keys(issuesByVersionsCount).forEach((version) => {
|
||||
const byStatus = issuesByVersionsCount[version].byStatus;
|
||||
const keyPrefixForCurrentVersionBlock = `${keyPrefix}-issuesByVersionsCount-${version}`;
|
||||
|
||||
let byStatusHint: JSX.Element = <></>;
|
||||
if (byStatus && Object.keys(byStatus).length > 0) {
|
||||
const byStatusSimple = Object.keys(byStatus).reduce((acc, status) => {
|
||||
acc[status] = byStatus[status].count;
|
||||
return acc;
|
||||
}, {} as Record<string, number>);
|
||||
byStatusHint = (
|
||||
<span
|
||||
style={{ marginLeft: '10px', color: 'lightgray' }}
|
||||
key={`${keyPrefixForCurrentVersionBlock}-byStatusHint`}
|
||||
>
|
||||
(Статусы: {JSON.stringify(byStatusSimple)})
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
byVersionsLi.push(
|
||||
<li key={keyPrefixForCurrentVersionBlock}>
|
||||
{version}: {issuesByVersionsCount[version].count} {byStatusHint}
|
||||
</li>,
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Daily ECCM V2</h1>
|
||||
<p>Дата выгрузки: {props.store?.data?.datetimeFormatted}</p>
|
||||
<p>Метрики:</p>
|
||||
<ul>
|
||||
<li>
|
||||
Простые счётчики:
|
||||
<ul>
|
||||
<li>
|
||||
По статусам:
|
||||
<ul>{byStatusLi}</ul>
|
||||
</li>
|
||||
<li>
|
||||
По версиям:
|
||||
<ul>{byVersionsLi}</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<DebugInfo value={JSON.stringify(props.store?.data, null, 2)} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export type Props = {
|
||||
store: DashboardStoreNs.IWidget;
|
||||
};
|
||||
|
||||
export const DailyEccmV2Widget = observer((props: Props): JSX.Element => {
|
||||
const dailyEccmV2Store = DailyEccmV2Store.create();
|
||||
onSnapshot(props.store, (storeState) => {
|
||||
if (storeState.data) {
|
||||
dailyEccmV2Store.setData(storeState.data);
|
||||
}
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<DailyEccmV2 store={dailyEccmV2Store} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
|
@ -6,6 +6,7 @@ import * as KanbanWidgetNs from './kanban';
|
|||
import { DebugInfo } from '../../misc-components/debug-info';
|
||||
import * as IssuesListNs from './issues-list';
|
||||
import * as CalendarNextEventsNs from './calendar-next-events';
|
||||
import * as DailyEccmV2 from './daily-eccm-v2';
|
||||
|
||||
export type Props = {
|
||||
store: Instance<typeof DashboardStoreNs.Widget>;
|
||||
|
|
@ -26,6 +27,10 @@ export const WidgetFactory = observer((props: Props): JSX.Element => {
|
|||
return <CalendarNextEventsNs.CalendarNextEvents store={props.store} />;
|
||||
}
|
||||
|
||||
if (type === 'daily_eccm_v2') {
|
||||
return <DailyEccmV2.DailyEccmV2 store={props.store} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>Unknown widget</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue