This is an automated email from the ASF dual-hosted git repository.
dockerzhang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git
The following commit(s) were added to refs/heads/master by this push:
new 72671f5541 [INLONG-10468][Dashboard] Audit data showing totals and
variances (#10469)
72671f5541 is described below
commit 72671f5541c8a308f38d706c04961819017a4757
Author: haifxu <[email protected]>
AuthorDate: Mon Jun 24 11:53:04 2024 +0800
[INLONG-10468][Dashboard] Audit data showing totals and variances (#10469)
---
inlong-dashboard/src/ui/locales/cn.json | 2 +
inlong-dashboard/src/ui/locales/en.json | 2 +
.../src/ui/pages/GroupDetail/Audit/config.tsx | 110 +++++++++++++++++++--
.../src/ui/pages/GroupDetail/Audit/index.tsx | 23 ++++-
4 files changed, 125 insertions(+), 12 deletions(-)
diff --git a/inlong-dashboard/src/ui/locales/cn.json
b/inlong-dashboard/src/ui/locales/cn.json
index 14e6b4b353..39e0b01db5 100644
--- a/inlong-dashboard/src/ui/locales/cn.json
+++ b/inlong-dashboard/src/ui/locales/cn.json
@@ -659,6 +659,8 @@
"pages.GroupDetail.Audit.Hour": "小时",
"pages.GroupDetail.Audit.Day": "天",
"pages.GroupDetail.Audit.Sink": "数据目标",
+ "pages.GroupDetail.Audit.Total": "总计",
+ "pages.GroupDetail.Audit.DatepickerRule": "超出可选范围",
"pages.GroupDetail.Delay.QueryDate": "查询日期",
"pages.GroupDetail.Delay.AverageTitle": "平均传输时延 (ms)",
"pages.GroupDetail.Delay.RealTimeTitle": "传输时延 (ms)",
diff --git a/inlong-dashboard/src/ui/locales/en.json
b/inlong-dashboard/src/ui/locales/en.json
index d048475993..1403297c64 100644
--- a/inlong-dashboard/src/ui/locales/en.json
+++ b/inlong-dashboard/src/ui/locales/en.json
@@ -659,6 +659,8 @@
"pages.GroupDetail.Audit.Day": "Day",
"pages.GroupDetail.Audit.Sink": "Sink",
"pages.GroupDetail.Audit.Item": "Audit item",
+ "pages.GroupDetail.Audit.Total": "Total",
+ "pages.GroupDetail.Audit.DatepickerRule": "Out of selectable time range",
"pages.GroupDetail.Delay.QueryDate": "Query date",
"pages.GroupDetail.Delay.AverageTitle": "Average transmission delay (ms)",
"pages.GroupDetail.Delay.RealTimeTitle": "Transmission delay (ms)",
diff --git a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/config.tsx
b/inlong-dashboard/src/ui/pages/GroupDetail/Audit/config.tsx
index c1f6d6a651..d98162c712 100644
--- a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/config.tsx
+++ b/inlong-dashboard/src/ui/pages/GroupDetail/Audit/config.tsx
@@ -93,14 +93,70 @@ export const toChartData = (source, sourceDataMap) => {
};
export const toTableData = (source, sourceDataMap) => {
- return Object.keys(sourceDataMap)
+ const map = Object.keys(sourceDataMap)
.reverse()
.map(logTs => ({
...sourceDataMap[logTs],
logTs,
}));
+ let sourceData = getSourceDataWithPercent(source, map);
+ return getSourceDataWithCommas(sourceData);
};
+export const getSourceDataWithPercent = (sourceKeys, sourceMap) => {
+ const auditIds = Array.from(
+ new Set(Object.values(sourceKeys).map(({ auditId }) => parseInt(auditId))),
+ );
+ return sourceMap.map(source => {
+ for (const auditId of auditIds) {
+ if (!(auditId in source)) {
+ source[auditId] = 0;
+ }
+ }
+ let newSource = {};
+ const keys = Object.keys(source).filter(key => key !== 'logTs');
+ const firstKey = keys[0];
+ const firstValue = source[firstKey];
+ newSource[firstKey] = firstValue.toString();
+ for (let key of keys.slice(1)) {
+ if (key !== 'logTs') {
+ let diff = getDiff(firstValue, source[key]);
+ newSource[key] = `${source[key]} (${diff})`;
+ }
+ }
+ newSource['logTs'] = source['logTs'];
+ return newSource;
+ });
+};
+
+export const getDiff = (first, current) => {
+ if (first === 0) {
+ return '0%';
+ }
+ let result;
+ const diff = Math.ceil((current / first - 1) * 100);
+ result = diff > 0 ? '+' + diff + '%' : diff + '%';
+ return result;
+};
+
+export const getSourceDataWithCommas = sourceData => {
+ sourceData.map(source => {
+ for (const key in source) {
+ if (key !== 'logTs') {
+ let parts = source[key].split(' ');
+ let numberPart = parts[0];
+ let percentPart = parts[1] || '';
+ let number = parseInt(numberPart, 10);
+ let formattedNumber = number.toLocaleString();
+ source[key] = formattedNumber + ' ' + percentPart;
+ }
+ }
+ });
+ return sourceData;
+};
+
+let endTimeVisible = true;
+
export const getFormContent = (inlongGroupId, initialValues, onSearch,
onDataStreamSuccess) => [
{
type: 'select',
@@ -179,20 +235,43 @@ export const getFormContent = (inlongGroupId,
initialValues, onSearch, onDataStr
label: i18n.t('pages.GroupDetail.Audit.EndDate'),
name: 'endDate',
initialValue: dayjs(initialValues.endDate),
+ rules: [
+ { required: true },
+ ({ getFieldValue }) => ({
+ validator(_, value) {
+ const dim = initialValues.timeStaticsDim;
+ if (dim === 'MINUTE') {
+ return Promise.resolve();
+ }
+ const timeDiff = value - getFieldValue('startDate');
+ console.log('timeDiff', value, getFieldValue('startDate'), timeDiff);
+ if (timeDiff >= 0) {
+ const isHourDiff = dim === 'HOUR' && timeDiff < 1000 * 60 * 60 *
24 * 3;
+ const isDayDiff = dim === 'DAY' && timeDiff < 1000 * 60 * 60 * 24
* 7;
+ if (isHourDiff || isDayDiff) {
+ return Promise.resolve();
+ }
+ }
+ return Promise.reject(new
Error(i18n.t('pages.GroupDetail.Audit.DatepickerRule')));
+ },
+ }),
+ ],
props: {
allowClear: false,
format: 'YYYY-MM-DD',
+ disabled: initialValues.timeStaticsDim === 'MINUTE',
disabledDate: current => {
const start = dayjs(initialValues.startDate);
const dim = initialValues.timeStaticsDim;
- if (dim === 'HOUR' || dim === 'DAY') {
- const tooLate = current && current <= start.endOf('day');
- const tooEarly = start && current > start.add(7, 'd').endOf('day');
- return tooLate || tooEarly;
+ const tooEarly = current < start.add(-1, 'd').endOf('day');
+ let tooLate;
+ if (dim === 'HOUR') {
+ tooLate = current >= start.add(2, 'd').endOf('day');
+ }
+ if (dim === 'DAY') {
+ tooLate = current >= start.add(6, 'd').endOf('day');
}
- const tooLate = current && current >= start.endOf('day');
- const tooEarly = start && current < start.add(-1, 'd').endOf('day');
- return tooLate || tooEarly;
+ return current && (tooLate || tooEarly);
},
},
},
@@ -244,16 +323,27 @@ export const getFormContent = (inlongGroupId,
initialValues, onSearch, onDataStr
},
];
-export const getTableColumns = source => {
+export const getTableColumns = (source, dim) => {
const data = source.map(item => ({
title: item.auditName,
dataIndex: item.auditId,
- render: text => text || 0,
+ render: text => {
+ let color = 'black';
+ if (text?.includes('+')) {
+ color = 'red';
+ } else if (text?.includes('-')) {
+ color = 'green';
+ }
+ return <span style={{ color: color }}>{text}</span>;
+ },
}));
return [
{
title: i18n.t('pages.GroupDetail.Audit.Time'),
dataIndex: 'logTs',
+ render: text => {
+ return dim === 'MINUTE' ? dayjs(text).format('HH:mm') : text;
+ },
},
].concat(data);
};
diff --git a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
b/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
index e0a91afa46..f4ba9fbbc4 100644
--- a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
+++ b/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
@@ -31,6 +31,8 @@ import {
getTableColumns,
timeStaticsDimList,
} from './config';
+import { Table } from 'antd';
+import i18n from '@/i18n';
type Props = CommonInterface;
@@ -92,7 +94,10 @@ const Comp: React.FC<Props> = ({ inlongGroupId }) => {
}, [sourceData, query.timeStaticsDim]);
const onSearch = async () => {
- await form.validateFields();
+ let values = await form.validateFields();
+ if (values.timeStaticsDim == 'MINUTE') {
+ setQuery(prev => ({ ...prev, endDate: prev.startDate }));
+ }
run();
};
@@ -126,9 +131,23 @@ const Comp: React.FC<Props> = ({ inlongGroupId }) => {
<HighTable
table={{
- columns: getTableColumns(sourceData),
+ columns: getTableColumns(sourceData, query.timeStaticsDim),
dataSource: toTableData(sourceData, sourceDataMap),
rowKey: 'logTs',
+ summary: () => (
+ <Table.Summary fixed>
+ <Table.Summary.Row>
+ <Table.Summary.Cell index={0}>
+ {i18n.t('pages.GroupDetail.Audit.Total')}
+ </Table.Summary.Cell>
+ {sourceData.map((row, index) => (
+ <Table.Summary.Cell index={index + 1}>
+ {row.auditSet.reduce((total, item) => total + item.count,
0).toLocaleString()}
+ </Table.Summary.Cell>
+ ))}
+ </Table.Summary.Row>
+ </Table.Summary>
+ ),
}}
/>
</>