Skip to content

Commit cbc460e

Browse files
committed
refactor: migrate TenantOverview to ts
1 parent e315ca4 commit cbc460e

File tree

8 files changed

+177
-220
lines changed

8 files changed

+177
-220
lines changed

src/components/InfoViewer/InfoViewer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import cn from 'bem-cn-lite';
44
import './InfoViewer.scss';
55

66
export interface InfoViewerItem {
7-
label: ReactNode;
8-
value: ReactNode;
7+
label?: ReactNode;
8+
value?: ReactNode;
99
}
1010

1111
interface InfoViewerProps {

src/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import type {EPathType} from '../../../../types/api/schema';
88
import {Icon} from '../../../../components/Icon';
99
import Overview from '../Overview/Overview';
1010
import {Healthcheck} from '../Healthcheck';
11-
//@ts-ignore
12-
import TenantOverview from '../TenantOverview/TenantOverview';
11+
import {TenantOverview} from '../TenantOverview/TenantOverview';
1312

1413
import './DetailedOverview.scss';
1514

src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js

Lines changed: 0 additions & 213 deletions
This file was deleted.
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import cn from 'bem-cn-lite';
2+
import {useCallback} from 'react';
3+
import {useDispatch} from 'react-redux';
4+
5+
import {Loader} from '@gravity-ui/uikit';
6+
7+
import {InfoViewer} from '../../../../components/InfoViewer';
8+
import {PoolUsage} from '../../../../components/PoolUsage/PoolUsage';
9+
import {Tablet} from '../../../../components/Tablet';
10+
import EntityStatus from '../../../../components/EntityStatus/EntityStatus';
11+
import type {TTenant} from '../../../../types/api/tenant';
12+
import {formatCPU} from '../../../../utils';
13+
import {TABLET_STATES, TENANT_DEFAULT_TITLE} from '../../../../utils/constants';
14+
import {bytesToGB} from '../../../../utils/utils';
15+
import {mapDatabaseTypeToDBName} from '../../utils/schema';
16+
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
17+
import {getTenantInfo, setDataWasNotLoaded} from '../../../../store/reducers/tenant/tenant';
18+
19+
import './TenantOverview.scss';
20+
21+
const b = cn('tenant-overview');
22+
23+
interface TenantOverviewProps {
24+
tenantName: string;
25+
additionalTenantInfo?: any;
26+
}
27+
28+
export function TenantOverview({tenantName, additionalTenantInfo}: TenantOverviewProps) {
29+
const {tenant, loading, wasLoaded} = useTypedSelector((state) => state.tenant);
30+
const {autorefresh} = useTypedSelector((state) => state.schema);
31+
const dispatch = useDispatch();
32+
const fetchTenant = useCallback(
33+
(isBackground = true) => {
34+
if (!isBackground) {
35+
dispatch(setDataWasNotLoaded());
36+
}
37+
dispatch(getTenantInfo({path: tenantName}));
38+
},
39+
[dispatch, tenantName],
40+
);
41+
42+
useAutofetcher(
43+
(isBackground) => {
44+
fetchTenant(isBackground);
45+
},
46+
[fetchTenant],
47+
autorefresh,
48+
);
49+
50+
const {
51+
Metrics = {},
52+
PoolStats,
53+
StateStats = [],
54+
MemoryUsed,
55+
Name,
56+
CoresUsed,
57+
StorageGroups,
58+
StorageAllocatedSize,
59+
Type,
60+
SystemTablets,
61+
} = tenant || {};
62+
63+
const tenantType = mapDatabaseTypeToDBName(Type);
64+
const memoryRaw = MemoryUsed ?? Metrics.Memory;
65+
66+
const memory = (memoryRaw && bytesToGB(memoryRaw)) || 'no data';
67+
const storage = (Metrics.Storage && bytesToGB(Metrics.Storage)) || 'no data';
68+
const storageGroups = StorageGroups ?? 'no data';
69+
const blobStorage = (StorageAllocatedSize && bytesToGB(StorageAllocatedSize)) || 'no data';
70+
const storageEfficiency =
71+
Metrics.Storage && StorageAllocatedSize
72+
? `${((parseInt(Metrics.Storage) * 100) / parseInt(StorageAllocatedSize)).toFixed(2)}%`
73+
: 'no data';
74+
75+
const cpuRaw = CoresUsed !== undefined ? Number(CoresUsed) * 1_000_000 : Metrics.CPU;
76+
77+
const cpu = formatCPU(cpuRaw);
78+
79+
const metricsInfo = [
80+
{label: 'Type', value: Type},
81+
{label: 'Memory', value: memory},
82+
{label: 'CPU', value: cpu},
83+
{label: 'Tablet storage', value: storage},
84+
{label: 'Storage groups', value: storageGroups},
85+
{label: 'Blob storage', value: blobStorage},
86+
{label: 'Storage efficiency', value: storageEfficiency},
87+
];
88+
89+
const tabletsInfo = StateStats.map((info) => {
90+
if (info.VolatileState)
91+
return {label: TABLET_STATES[info.VolatileState], value: info.Count};
92+
return {};
93+
});
94+
95+
const renderName = (tenant?: TTenant) => {
96+
const {Name = TENANT_DEFAULT_TITLE, State} = tenant || {};
97+
return (
98+
<div className={b('tenant-name-wrapper')}>
99+
<EntityStatus
100+
status={State}
101+
name={Name}
102+
withLeftTrim
103+
hasClipboardButton={tenant}
104+
clipboardButtonAlwaysVisible
105+
/>
106+
</div>
107+
);
108+
};
109+
110+
if (loading && !wasLoaded) {
111+
return (
112+
<div className={b('loader')}>
113+
<Loader size="m" />
114+
</div>
115+
);
116+
}
117+
118+
return (
119+
<div className={b()}>
120+
<div className={b('top-label')}>{tenantType}</div>
121+
<div className={b('top')}>
122+
{renderName(tenant)}
123+
{tenant && additionalTenantInfo && additionalTenantInfo(tenant.Name, tenant.Type)}
124+
</div>
125+
<div className={b('system-tablets')}>
126+
{SystemTablets &&
127+
SystemTablets.map((tablet, tabletIndex) => (
128+
<Tablet key={tabletIndex} tablet={tablet} tenantName={Name} />
129+
))}
130+
</div>
131+
<div className={b('common-info')}>
132+
<div>
133+
<div className={b('section-title')}>Pools</div>
134+
{PoolStats ? (
135+
<div className={b('section', {pools: true})}>
136+
{PoolStats.map((pool, poolIndex) => (
137+
<PoolUsage key={poolIndex} data={pool} />
138+
))}
139+
</div>
140+
) : (
141+
<div className="error">no pools data</div>
142+
)}
143+
</div>
144+
<InfoViewer
145+
title="Metrics"
146+
className={b('section', {metrics: true})}
147+
info={metricsInfo}
148+
/>
149+
150+
<div className={b('section')}>
151+
<InfoViewer info={tabletsInfo} title="Tablets" />
152+
</div>
153+
</div>
154+
</div>
155+
);
156+
}

0 commit comments

Comments
 (0)