+
string)> = {
+ ['ms']: (v, settings) =>
+ format.TimeDuration(Math.round(v!), {format: 'milliseconds', ...settings}),
+ ['bytes']: (v, settings) => formatBytes(v, settings),
+ ['bytes * sec']: (v, settings) => formatBytes(v, settings, ' * sec'),
+ ['ms * bytes']: (v, settings) => formatBytes(v, settings, ' * ms'),
+ ['Mb*sec']: (v, settings) => formatBytes(v! * 1024 * 1024, settings, ' * sec'),
+};
+
+function formatBytes(v?: number, settings?: object, suffix = '') {
+ return isNaN(v!) ? format.NO_VALUE : format.Bytes(Math.round(v!), settings) + suffix;
+}
+
+export function formatByUnit(v?: number, unit?: string, settings?: object) {
+ const formatFn = UNIT_TO_FORMATTER[unit!] ?? format.Number;
+ return formatFn?.(v, settings);
+}
diff --git a/packages/ui/src/ui/pages/job/tabs/Statistics/Statistics.scss b/packages/ui/src/ui/pages/job/tabs/Statistics/Statistics.scss
new file mode 100644
index 000000000..913288d1d
--- /dev/null
+++ b/packages/ui/src/ui/pages/job/tabs/Statistics/Statistics.scss
@@ -0,0 +1,3 @@
+.yt-job-statistics {
+ margin-bottom: 50px;
+}
diff --git a/packages/ui/src/ui/pages/job/tabs/Statistics/Statistics.tsx b/packages/ui/src/ui/pages/job/tabs/Statistics/Statistics.tsx
index ec0a34df9..674ed0bfb 100644
--- a/packages/ui/src/ui/pages/job/tabs/Statistics/Statistics.tsx
+++ b/packages/ui/src/ui/pages/job/tabs/Statistics/Statistics.tsx
@@ -3,6 +3,7 @@ import {useSelector} from 'react-redux';
import cn from 'bem-cn-lite';
import {getRawStatistic} from '../../../../store/selectors/job/statistics';
+import {getOperationStatisticsDescription} from '../../../../store/selectors/global/supported-features';
import {StatisticTable, StatisticTree} from '../../../../components/StatisticTable';
import {isDocsAllowed} from '../../../../config';
import UIFactory from '../../../../UIFactory';
@@ -13,12 +14,14 @@ const block = cn('yt-job-statistics');
export default function Statistics() {
const statistic = useSelector(getRawStatistic);
+ const {getStatisticInfo} = useSelector(getOperationStatisticsDescription);
return (
);
}
diff --git a/packages/ui/src/ui/pages/operations/OperationDetail/tabs/statistics/OperationStatisticName.scss b/packages/ui/src/ui/pages/operations/OperationDetail/tabs/statistics/OperationStatisticName.scss
deleted file mode 100644
index 0e6fa1fe4..000000000
--- a/packages/ui/src/ui/pages/operations/OperationDetail/tabs/statistics/OperationStatisticName.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.operation-statistc-name {
- &__description {
- width: 100%;
- text-overflow: unset;
- white-space: unset;
- }
-}
diff --git a/packages/ui/src/ui/pages/operations/OperationDetail/tabs/statistics/OperationStatisticName.tsx b/packages/ui/src/ui/pages/operations/OperationDetail/tabs/statistics/OperationStatisticName.tsx
index 314ad9d77..6582c2a28 100644
--- a/packages/ui/src/ui/pages/operations/OperationDetail/tabs/statistics/OperationStatisticName.tsx
+++ b/packages/ui/src/ui/pages/operations/OperationDetail/tabs/statistics/OperationStatisticName.tsx
@@ -1,85 +1,20 @@
import React from 'react';
import {useSelector} from 'react-redux';
-import find_ from 'lodash/find';
-import cn from 'bem-cn-lite';
-
import {getOperationStatisticsDescription} from '../../../../../store/selectors/global/supported-features';
-import MetaTable from '../../../../../components/MetaTable/MetaTable';
import {Tooltip} from '../../../../../components/Tooltip/Tooltip';
-import Icon from '../../../../../components/Icon/Icon';
-import {Secondary} from '../../../../../components/Text/Text';
import format from '../../../../../common/hammer/format';
-
-import './OperationStatisticName.scss';
-
-const block = cn('operation-statistc-name');
+import {StatisticName, formatByUnit} from '../../../../../components/StatisticTable';
function useStatisticInfo(name: string) {
- const {byName, byRegexp} = useSelector(getOperationStatisticsDescription);
-
- const info = React.useMemo(() => {
- const key = name.startsWith('/') ? name.substring('/'.length) : name;
- const res = key.endsWith('/$$') ? byName[key.substring(0, key.length - 3)] : byName[key];
- if (res) {
- return res;
- }
-
- return find_(byRegexp, ({regexp}) => {
- return regexp.test(key);
- });
- }, [name, byName, byRegexp]);
-
- return info;
+ const {getStatisticInfo} = useSelector(getOperationStatisticsDescription);
+ return getStatisticInfo(name);
}
function OperationStatisticNameImpl({name, title}: {name: string; title: string}) {
const info = useStatisticInfo(name);
- const emptyInfo = !info?.description && !info?.unit;
- return (
-
- )
- }
- >
- {title}{' '}
- {!emptyInfo && (
-
-
-
- )}
-
- );
-}
-
-const UNIT_TO_FORMATTER: Record string> = {
- ['ms']: (v, settings) =>
- format.TimeDuration(Math.round(v!), {format: 'milliseconds', ...settings}),
- ['bytes']: (v, settings) => formatBytes(v, settings),
- ['bytes * sec']: (v, settings) => formatBytes(v, settings, ' * sec'),
- ['ms * bytes']: (v, settings) => formatBytes(v, settings, ' * ms'),
- ['Mb*sec']: (v, settings) => formatBytes(v! * 1024 * 1024, settings, ' * sec'),
-};
-
-function formatBytes(v?: number, settings?: object, suffix = '') {
- return isNaN(v!) ? format.NO_VALUE : format.Bytes(Math.round(v!), settings) + suffix;
+ return ;
}
function OperationStatisticValueImpl({
@@ -92,11 +27,10 @@ function OperationStatisticValueImpl({
settings?: {significantDigits: number};
}) {
const info = useStatisticInfo(name);
- const formatFn = UNIT_TO_FORMATTER[info?.unit || ''];
-
+ const asStr = formatByUnit(value, info?.unit, settings);
const asNumber = format.Number(value, settings);
- return formatFn ? {formatFn(value, settings)} : asNumber;
+ return asStr !== undefined ? {asStr} : asNumber;
}
export const OperationStatisticValue = React.memo(OperationStatisticValueImpl);
diff --git a/packages/ui/src/ui/store/reducers/global/supported-features.ts b/packages/ui/src/ui/store/reducers/global/supported-features.ts
index 24237203c..bce63e86c 100644
--- a/packages/ui/src/ui/store/reducers/global/supported-features.ts
+++ b/packages/ui/src/ui/store/reducers/global/supported-features.ts
@@ -6,6 +6,7 @@ import {
SUPPORTED_FEATURES_SUCCESS,
} from '../../../constants/global';
import {mergeStateOnClusterChange} from '../../../store/reducers/utils';
+import type {StatisticInfo} from '../../../components/StatisticTable';
export interface SupportedFeaturesState {
loaded: boolean;
@@ -22,10 +23,7 @@ export interface SupportedFeaturesState {
};
}
-export interface OperationStatisticInfo {
- description?: string;
- unit?: string;
-}
+export type OperationStatisticInfo = StatisticInfo;
const initialState: SupportedFeaturesState = {
loaded: false,
diff --git a/packages/ui/src/ui/store/selectors/global/supported-features.ts b/packages/ui/src/ui/store/selectors/global/supported-features.ts
index 0ab7786d0..55196d611 100644
--- a/packages/ui/src/ui/store/selectors/global/supported-features.ts
+++ b/packages/ui/src/ui/store/selectors/global/supported-features.ts
@@ -180,9 +180,33 @@ export const getOperationStatisticsDescription = createSelector(
}
});
+ const cache = new Map();
+ function putToCache(key: string, info?: OperationStatisticInfo) {
+ cache.set(key, info);
+ return info;
+ }
+
return {
- byName,
- byRegexp,
+ getStatisticInfo: (name: string) => {
+ if (cache.has(name)) {
+ return cache.get(name);
+ }
+
+ const key = name.startsWith('/') ? name.substring('/'.length) : name;
+ const res = key.endsWith('/$$')
+ ? byName[key.substring(0, key.length - 3)]
+ : byName[key];
+ if (res) {
+ return putToCache(name, res);
+ }
+
+ return putToCache(
+ name,
+ find_(byRegexp, ({regexp}) => {
+ return regexp.test(key);
+ }),
+ );
+ },
};
},
);
diff --git a/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts b/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts
index ecaac5b98..73a2b9089 100644
--- a/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts
+++ b/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts
@@ -68,7 +68,9 @@ test('Job - Details', async ({page}) => {
await test.step('Statistics', async () => {
await page.click('.tabs :text("Statistics")');
- await page.waitForSelector('.job-statistics__table-container .job-statistics__group');
+ await page.waitForSelector(
+ '.yt-statistics-table__table-container .yt-statistics-table__group',
+ );
await expect(page).toHaveScreenshot();
});
diff --git a/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts-snapshots/Job---Details-3-chromium-linux.png b/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts-snapshots/Job---Details-3-chromium-linux.png
index ec5200a5c..43b01d33e 100644
Binary files a/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts-snapshots/Job---Details-3-chromium-linux.png and b/packages/ui/tests/screenshots/pages/operations/jobs.base.screen.ts-snapshots/Job---Details-3-chromium-linux.png differ