Реализация виджета на 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"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "BROWSER=none react-scripts start --open=false",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject"
|
"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 { DebugInfo } from '../../misc-components/debug-info';
|
||||||
import * as IssuesListNs from './issues-list';
|
import * as IssuesListNs from './issues-list';
|
||||||
import * as CalendarNextEventsNs from './calendar-next-events';
|
import * as CalendarNextEventsNs from './calendar-next-events';
|
||||||
|
import * as DailyEccmV2 from './daily-eccm-v2';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
store: Instance<typeof DashboardStoreNs.Widget>;
|
store: Instance<typeof DashboardStoreNs.Widget>;
|
||||||
|
|
@ -26,6 +27,10 @@ export const WidgetFactory = observer((props: Props): JSX.Element => {
|
||||||
return <CalendarNextEventsNs.CalendarNextEvents store={props.store} />;
|
return <CalendarNextEventsNs.CalendarNextEvents store={props.store} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'daily_eccm_v2') {
|
||||||
|
return <DailyEccmV2.DailyEccmV2 store={props.store} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>Unknown widget</div>
|
<div>Unknown widget</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue