ydb-embedded-ui 4.16.2 → 4.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/components/CircularProgressBar/CircularProgressBar.scss +42 -0
- package/dist/components/CircularProgressBar/CircularProgressBar.tsx +59 -0
- package/dist/components/DiagnosticCard/DiagnosticCard.scss +20 -3
- package/dist/components/DiagnosticCard/DiagnosticCard.tsx +5 -6
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +1 -5
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +40 -17
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → OldHealthcheck}/Details/Details.tsx +3 -3
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → OldHealthcheck}/Healthcheck.scss +27 -14
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → OldHealthcheck}/Healthcheck.tsx +6 -6
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → OldHealthcheck}/Preview/Preview.tsx +15 -16
- package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/Healthcheck.scss +108 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckDetails.tsx +45 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckPreview.tsx +83 -0
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/IssuesViewer/IssueTree.scss +1 -3
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/IssuesViewer/IssueTree.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/IssuesViewer/IssueTreeItem/IssueTreeItem.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/i18n/en.json +2 -1
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/i18n/index.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/i18n/ru.json +2 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.scss +52 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.tsx +48 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.scss +12 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx +134 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/OldTenantOverview.tsx +155 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +3 -5
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +76 -86
- package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json +3 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/ru.json +3 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/useHealthcheck.ts +53 -0
- package/dist/containers/Tenant/TenantPages.tsx +1 -0
- package/dist/containers/UserSettings/i18n/en.json +4 -1
- package/dist/containers/UserSettings/i18n/ru.json +4 -1
- package/dist/containers/UserSettings/settings.ts +7 -0
- package/dist/services/api.ts +6 -4
- package/dist/store/reducers/healthcheckInfo.ts +20 -12
- package/dist/store/reducers/settings/settings.ts +5 -0
- package/dist/store/reducers/tenant/constants.ts +7 -0
- package/dist/store/reducers/tenant/tenant.ts +15 -0
- package/dist/store/reducers/tenant/types.ts +5 -0
- package/dist/store/reducers/tenants/contants.ts +6 -0
- package/dist/store/reducers/tenants/types.ts +4 -0
- package/dist/store/reducers/tenants/utils.ts +114 -7
- package/dist/store/state-url-mapping.js +3 -0
- package/dist/styles/constants.scss +2 -0
- package/dist/types/api/tenant.ts +3 -0
- package/dist/utils/constants.ts +1 -0
- package/dist/utils/formatCPU/formatCPU.ts +20 -0
- package/dist/utils/formatCPU/i18n/en.json +3 -0
- package/dist/utils/formatCPU/i18n/index.ts +11 -0
- package/dist/utils/formatCPU/i18n/ru.json +3 -0
- package/package.json +1 -1
- /package/dist/containers/Tenant/Diagnostics/{Healthcheck → OldHealthcheck}/Details/index.ts +0 -0
- /package/dist/containers/Tenant/Diagnostics/{Healthcheck → OldHealthcheck}/Preview/index.ts +0 -0
- /package/dist/containers/Tenant/Diagnostics/{Healthcheck → OldHealthcheck}/index.ts +0 -0
- /package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/IssuesViewer/IssueTreeItem/IssueTreeItem.scss +0 -0
- /package/dist/containers/Tenant/Diagnostics/{Healthcheck → TenantOverview/Healthcheck}/IssuesViewer/IssueTreeItem/index.ts +0 -0
@@ -4,18 +4,17 @@ import {useDispatch} from 'react-redux';
|
|
4
4
|
|
5
5
|
import {Loader} from '@gravity-ui/uikit';
|
6
6
|
|
7
|
-
import {InfoViewer} from '../../../../components/InfoViewer';
|
8
|
-
import {PoolUsage} from '../../../../components/PoolUsage/PoolUsage';
|
9
|
-
import {Tablet} from '../../../../components/Tablet';
|
10
7
|
import EntityStatus from '../../../../components/EntityStatus/EntityStatus';
|
11
|
-
import {
|
12
|
-
import {
|
13
|
-
import {bytesToGB} from '../../../../utils/utils';
|
8
|
+
import {TENANT_DEFAULT_TITLE} from '../../../../utils/constants';
|
9
|
+
import {TENANT_METRICS_TABS_IDS} from '../../../../store/reducers/tenant/constants';
|
14
10
|
import {mapDatabaseTypeToDBName} from '../../utils/schema';
|
15
11
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
16
|
-
import type {ETabletVolatileState} from '../../../../types/api/tenant';
|
17
12
|
import type {AdditionalTenantsProps} from '../../../../types/additionalProps';
|
18
13
|
import {getTenantInfo, setDataWasNotLoaded} from '../../../../store/reducers/tenant/tenant';
|
14
|
+
import {calculateTenantMetrics} from '../../../../store/reducers/tenants/utils';
|
15
|
+
import {HealthcheckDetails} from './Healthcheck/HealthcheckDetails';
|
16
|
+
import {MetricsCards, type TenantMetrics} from './MetricsCards/MetricsCards';
|
17
|
+
import {useHealthcheck} from './useHealthcheck';
|
19
18
|
|
20
19
|
import i18n from './i18n';
|
21
20
|
import './TenantOverview.scss';
|
@@ -28,9 +27,26 @@ interface TenantOverviewProps {
|
|
28
27
|
}
|
29
28
|
|
30
29
|
export function TenantOverview({tenantName, additionalTenantProps}: TenantOverviewProps) {
|
31
|
-
const {tenant, loading, wasLoaded} = useTypedSelector((state) => state.tenant);
|
32
|
-
const {autorefresh} = useTypedSelector((state) => state.schema);
|
33
30
|
const dispatch = useDispatch();
|
31
|
+
|
32
|
+
const {
|
33
|
+
tenant,
|
34
|
+
loading: tenantLoading,
|
35
|
+
wasLoaded: tenantWasLoaded,
|
36
|
+
metricsTab,
|
37
|
+
} = useTypedSelector((state) => state.tenant);
|
38
|
+
const {autorefresh} = useTypedSelector((state) => state.schema);
|
39
|
+
|
40
|
+
const {
|
41
|
+
issueTrees,
|
42
|
+
issuesStatistics,
|
43
|
+
selfCheckResult,
|
44
|
+
fetchHealthcheck,
|
45
|
+
loading: healthcheckLoading,
|
46
|
+
wasLoaded: healthCheckWasLoaded,
|
47
|
+
error: healthcheckError,
|
48
|
+
} = useHealthcheck(tenantName);
|
49
|
+
|
34
50
|
const fetchTenant = useCallback(
|
35
51
|
(isBackground = true) => {
|
36
52
|
if (!isBackground) {
|
@@ -41,56 +57,30 @@ export function TenantOverview({tenantName, additionalTenantProps}: TenantOvervi
|
|
41
57
|
[dispatch, tenantName],
|
42
58
|
);
|
43
59
|
|
44
|
-
useAutofetcher(
|
60
|
+
useAutofetcher(
|
61
|
+
(isBackground) => {
|
62
|
+
fetchTenant(isBackground);
|
63
|
+
fetchHealthcheck(isBackground);
|
64
|
+
},
|
65
|
+
[fetchTenant, fetchHealthcheck],
|
66
|
+
autorefresh,
|
67
|
+
);
|
45
68
|
|
46
|
-
const {
|
47
|
-
Metrics = {},
|
48
|
-
PoolStats,
|
49
|
-
StateStats = [],
|
50
|
-
MemoryUsed,
|
51
|
-
Name,
|
52
|
-
State,
|
53
|
-
CoresUsed,
|
54
|
-
StorageGroups,
|
55
|
-
StorageAllocatedSize,
|
56
|
-
Type,
|
57
|
-
SystemTablets,
|
58
|
-
} = tenant || {};
|
69
|
+
const {Name, State, Type} = tenant || {};
|
59
70
|
|
60
71
|
const tenantType = mapDatabaseTypeToDBName(Type);
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
const
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
const cpuRaw = CoresUsed !== undefined ? Number(CoresUsed) * 1_000_000 : Metrics.CPU;
|
74
|
-
|
75
|
-
const cpu = formatCPU(cpuRaw);
|
76
|
-
|
77
|
-
const metricsInfo = [
|
78
|
-
{label: 'Type', value: Type},
|
79
|
-
{label: 'Memory', value: memory},
|
80
|
-
{label: 'CPU', value: cpu},
|
81
|
-
{label: 'Tablet storage', value: storage},
|
82
|
-
{label: 'Storage groups', value: storageGroups},
|
83
|
-
{label: 'Blob storage', value: blobStorage},
|
84
|
-
{label: 'Storage efficiency', value: storageEfficiency},
|
85
|
-
];
|
86
|
-
|
87
|
-
const tabletsInfo = StateStats.filter(
|
88
|
-
(item): item is {VolatileState: ETabletVolatileState; Count: number} => {
|
89
|
-
return item.VolatileState !== undefined && item.Count !== undefined;
|
90
|
-
},
|
91
|
-
).map((info) => {
|
92
|
-
return {label: TABLET_STATES[info.VolatileState], value: info.Count};
|
93
|
-
});
|
72
|
+
|
73
|
+
const {cpu, storage, memory, cpuLimit, storageLimit, memoryLimit} =
|
74
|
+
calculateTenantMetrics(tenant);
|
75
|
+
|
76
|
+
const calculatedMetrics: TenantMetrics = {
|
77
|
+
memoryUsed: memory,
|
78
|
+
memoryLimit,
|
79
|
+
cpuUsed: cpu,
|
80
|
+
cpuLimit,
|
81
|
+
storageUsed: storage,
|
82
|
+
storageLimit,
|
83
|
+
};
|
94
84
|
|
95
85
|
const renderName = () => {
|
96
86
|
return (
|
@@ -106,7 +96,27 @@ export function TenantOverview({tenantName, additionalTenantProps}: TenantOvervi
|
|
106
96
|
);
|
107
97
|
};
|
108
98
|
|
109
|
-
|
99
|
+
const renderTabContent = () => {
|
100
|
+
switch (metricsTab) {
|
101
|
+
case TENANT_METRICS_TABS_IDS.cpu: {
|
102
|
+
return i18n('label.under-development');
|
103
|
+
}
|
104
|
+
case TENANT_METRICS_TABS_IDS.storage: {
|
105
|
+
return i18n('label.under-development');
|
106
|
+
}
|
107
|
+
case TENANT_METRICS_TABS_IDS.memory: {
|
108
|
+
return i18n('label.under-development');
|
109
|
+
}
|
110
|
+
case TENANT_METRICS_TABS_IDS.healthcheck: {
|
111
|
+
return <HealthcheckDetails issueTrees={issueTrees} error={healthcheckError} />;
|
112
|
+
}
|
113
|
+
default: {
|
114
|
+
return undefined;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
};
|
118
|
+
|
119
|
+
if ((tenantLoading && !tenantWasLoaded) || (healthcheckLoading && !healthCheckWasLoaded)) {
|
110
120
|
return (
|
111
121
|
<div className={b('loader')}>
|
112
122
|
<Loader size="m" />
|
@@ -121,35 +131,15 @@ export function TenantOverview({tenantName, additionalTenantProps}: TenantOvervi
|
|
121
131
|
{renderName()}
|
122
132
|
{additionalTenantProps?.getMonitoringLink?.(Name, Type)}
|
123
133
|
</div>
|
124
|
-
<
|
125
|
-
{
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
{PoolStats ? (
|
134
|
-
<div className={b('section', {pools: true})}>
|
135
|
-
{PoolStats.map((pool, poolIndex) => (
|
136
|
-
<PoolUsage key={poolIndex} data={pool} />
|
137
|
-
))}
|
138
|
-
</div>
|
139
|
-
) : (
|
140
|
-
<div className="error">{i18n('no-pools-data')}</div>
|
141
|
-
)}
|
142
|
-
</div>
|
143
|
-
<InfoViewer
|
144
|
-
title={i18n('title.metrics')}
|
145
|
-
className={b('section', {metrics: true})}
|
146
|
-
info={metricsInfo}
|
147
|
-
/>
|
148
|
-
|
149
|
-
<div className={b('section')}>
|
150
|
-
<InfoViewer info={tabletsInfo} title="Tablets" />
|
151
|
-
</div>
|
152
|
-
</div>
|
134
|
+
<MetricsCards
|
135
|
+
metrics={calculatedMetrics}
|
136
|
+
issuesStatistics={issuesStatistics}
|
137
|
+
selfCheckResult={selfCheckResult}
|
138
|
+
fetchHealthcheck={fetchHealthcheck}
|
139
|
+
healthcheckLoading={healthcheckLoading}
|
140
|
+
healthcheckError={healthcheckError}
|
141
|
+
/>
|
142
|
+
{renderTabContent()}
|
153
143
|
</div>
|
154
144
|
);
|
155
145
|
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import {useCallback} from 'react';
|
2
|
+
import {useDispatch} from 'react-redux';
|
3
|
+
|
4
|
+
import {
|
5
|
+
getHealthcheckInfo,
|
6
|
+
selectIssuesStatistics,
|
7
|
+
selectIssuesTrees,
|
8
|
+
setDataWasNotLoaded,
|
9
|
+
} from '../../../../store/reducers/healthcheckInfo';
|
10
|
+
import type {IIssuesTree} from '../../../../types/store/healthcheck';
|
11
|
+
import {type StatusFlag, SelfCheckResult} from '../../../../types/api/healthcheck';
|
12
|
+
import type {IResponseError} from '../../../../types/api/error';
|
13
|
+
import {useTypedSelector} from '../../../../utils/hooks/useTypedSelector';
|
14
|
+
|
15
|
+
interface HealthcheckParams {
|
16
|
+
issueTrees: IIssuesTree[];
|
17
|
+
issuesStatistics: [StatusFlag, number][];
|
18
|
+
fetchHealthcheck: (isBackground?: boolean) => void;
|
19
|
+
loading: boolean;
|
20
|
+
wasLoaded: boolean;
|
21
|
+
error?: IResponseError;
|
22
|
+
selfCheckResult: SelfCheckResult;
|
23
|
+
}
|
24
|
+
|
25
|
+
export const useHealthcheck = (tenantName: string): HealthcheckParams => {
|
26
|
+
const dispatch = useDispatch();
|
27
|
+
|
28
|
+
const {data, loading, wasLoaded, error} = useTypedSelector((state) => state.healthcheckInfo);
|
29
|
+
const selfCheckResult = data?.self_check_result || SelfCheckResult.UNSPECIFIED;
|
30
|
+
const issuesStatistics = useTypedSelector(selectIssuesStatistics);
|
31
|
+
const issueTrees = useTypedSelector(selectIssuesTrees);
|
32
|
+
|
33
|
+
const fetchHealthcheck = useCallback(
|
34
|
+
(isBackground = true) => {
|
35
|
+
if (!isBackground) {
|
36
|
+
dispatch(setDataWasNotLoaded());
|
37
|
+
}
|
38
|
+
|
39
|
+
dispatch(getHealthcheckInfo(tenantName));
|
40
|
+
},
|
41
|
+
[dispatch, tenantName],
|
42
|
+
);
|
43
|
+
|
44
|
+
return {
|
45
|
+
issueTrees,
|
46
|
+
issuesStatistics,
|
47
|
+
fetchHealthcheck,
|
48
|
+
loading,
|
49
|
+
wasLoaded,
|
50
|
+
error,
|
51
|
+
selfCheckResult,
|
52
|
+
};
|
53
|
+
};
|
@@ -23,5 +23,8 @@
|
|
23
23
|
"settings.useBackendParamsForTables.popover": "Filter and sort Nodes and Storage tables with request params. May increase performance, but could causes additional fetches and longer loading time on older versions",
|
24
24
|
|
25
25
|
"settings.enableAdditionalQueryModes.title": "Enable additional query modes",
|
26
|
-
"settings.enableAdditionalQueryModes.popover": "Adds 'Data', 'YQL - QueryService' and 'PostgreSQL' modes. May not work on some versions"
|
26
|
+
"settings.enableAdditionalQueryModes.popover": "Adds 'Data', 'YQL - QueryService' and 'PostgreSQL' modes. May not work on some versions",
|
27
|
+
|
28
|
+
"settings.tenantDiagnostics.title": "Enable new database diagnostics design",
|
29
|
+
"settings.tenantDiagnostics.popover": "Adds indicators of database resources usage. Incomplete data may be displayed for some databases"
|
27
30
|
}
|
@@ -23,5 +23,8 @@
|
|
23
23
|
"settings.useBackendParamsForTables.popover": "Добавляет фильтрацию и сортировку таблиц Nodes и Storage с использованием параметров запроса. Может улушить производительность, но на старых версиях может привести к дополнительным запросам и большему времени ожидания загрузки",
|
24
24
|
|
25
25
|
"settings.enableAdditionalQueryModes.title": "Включить дополнительные режимы выполнения запросов",
|
26
|
-
"settings.enableAdditionalQueryModes.popover": "Добавляет режимы 'Data', 'YQL - QueryService' и 'PostgreSQL'. Может работать некорректно на некоторых версиях"
|
26
|
+
"settings.enableAdditionalQueryModes.popover": "Добавляет режимы 'Data', 'YQL - QueryService' и 'PostgreSQL'. Может работать некорректно на некоторых версиях",
|
27
|
+
|
28
|
+
"settings.tenantDiagnostics.title": "Включить новый дизайн для диагностики баз данных",
|
29
|
+
"settings.tenantDiagnostics.popover": "Добавляет индикаторы использования ресурсов базы данных. Для некоторых баз могут отображаться неполные данные"
|
27
30
|
}
|
@@ -5,6 +5,7 @@ import flaskIcon from '../../assets/icons/flask.svg';
|
|
5
5
|
|
6
6
|
import {
|
7
7
|
ENABLE_ADDITIONAL_QUERY_MODES,
|
8
|
+
ENABLE_NEW_TENANT_DIAGNOSTICS_DESIGN,
|
8
9
|
INVERTED_DISKS_KEY,
|
9
10
|
LANGUAGE_KEY,
|
10
11
|
THEME_KEY,
|
@@ -94,6 +95,11 @@ export const enableQueryModesForExplainSetting: SettingProps = {
|
|
94
95
|
title: i18n('settings.enableAdditionalQueryModes.title'),
|
95
96
|
helpPopoverContent: i18n('settings.enableAdditionalQueryModes.popover'),
|
96
97
|
};
|
98
|
+
export const enableNewTenantDiagnosticsDesign: SettingProps = {
|
99
|
+
settingKey: ENABLE_NEW_TENANT_DIAGNOSTICS_DESIGN,
|
100
|
+
title: i18n('settings.tenantDiagnostics.title'),
|
101
|
+
helpPopoverContent: i18n('settings.tenantDiagnostics.popover'),
|
102
|
+
};
|
97
103
|
|
98
104
|
export const generalSection: SettingsSection = {
|
99
105
|
id: 'generalSection',
|
@@ -108,6 +114,7 @@ export const experimentsSection: SettingsSection = {
|
|
108
114
|
useNodesEndpointSetting,
|
109
115
|
useBackendParamsForTables,
|
110
116
|
enableQueryModesForExplainSetting,
|
117
|
+
enableNewTenantDiagnosticsDesign,
|
111
118
|
],
|
112
119
|
};
|
113
120
|
|
package/dist/services/api.ts
CHANGED
@@ -350,10 +350,12 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
|
|
350
350
|
enable_sampling: enableSampling,
|
351
351
|
});
|
352
352
|
}
|
353
|
-
getHealthcheckInfo(database: string) {
|
354
|
-
return this.get<HealthCheckAPIResponse>(
|
355
|
-
|
356
|
-
|
353
|
+
getHealthcheckInfo(database: string, {concurrentId}: AxiosOptions = {}) {
|
354
|
+
return this.get<HealthCheckAPIResponse>(
|
355
|
+
this.getPath('/viewer/json/healthcheck'),
|
356
|
+
{tenant: database},
|
357
|
+
{concurrentId},
|
358
|
+
);
|
357
359
|
}
|
358
360
|
killTablet(id?: string) {
|
359
361
|
return this.get<string>(this.getPath(`/tablets?KillTabletID=${id}`), {});
|
@@ -44,6 +44,10 @@ const healthcheckInfo: Reducer<IHealthcheckInfoState, IHealthCheckInfoAction> =
|
|
44
44
|
};
|
45
45
|
}
|
46
46
|
case FETCH_HEALTHCHECK.FAILURE: {
|
47
|
+
if (action.error?.isCancelled) {
|
48
|
+
return state;
|
49
|
+
}
|
50
|
+
|
47
51
|
return {
|
48
52
|
...state,
|
49
53
|
error: action.error,
|
@@ -72,21 +76,25 @@ const mapStatusToPriority: Partial<Record<StatusFlag, number>> = {
|
|
72
76
|
GREEN: 4,
|
73
77
|
};
|
74
78
|
|
75
|
-
const
|
76
|
-
return data.
|
77
|
-
|
79
|
+
const sortIssues = (data: IssueLog[]): IssueLog[] => {
|
80
|
+
return data.sort((a, b) => {
|
81
|
+
const aPriority = mapStatusToPriority[a.status] || 0;
|
82
|
+
const bPriority = mapStatusToPriority[b.status] || 0;
|
78
83
|
|
79
|
-
|
80
|
-
let roots = data.filter((item) => {
|
81
|
-
return !data.find((issue) => issue.reason && issue.reason.indexOf(item.id) !== -1);
|
84
|
+
return aPriority - bPriority;
|
82
85
|
});
|
86
|
+
};
|
83
87
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
])(roots);
|
88
|
+
const getReasonsForIssue = ({issue, data}: {issue: IssueLog; data: IssueLog[]}) => {
|
89
|
+
return sortIssues(data.filter((item) => issue.reason && issue.reason.indexOf(item.id) !== -1));
|
90
|
+
};
|
88
91
|
|
89
|
-
|
92
|
+
const getRoots = (data: IssueLog[]): IssueLog[] => {
|
93
|
+
return sortIssues(
|
94
|
+
data.filter((item) => {
|
95
|
+
return !data.find((issue) => issue.reason && issue.reason.indexOf(item.id) !== -1);
|
96
|
+
}),
|
97
|
+
);
|
90
98
|
};
|
91
99
|
|
92
100
|
const getInvertedConsequencesTree = ({
|
@@ -147,7 +155,7 @@ export const selectIssuesStatistics: Selector<
|
|
147
155
|
|
148
156
|
export function getHealthcheckInfo(database: string) {
|
149
157
|
return createApiRequest({
|
150
|
-
request: window.api.getHealthcheckInfo(database),
|
158
|
+
request: window.api.getHealthcheckInfo(database, {concurrentId: 'getHealthcheckInfo'}),
|
151
159
|
actions: FETCH_HEALTHCHECK,
|
152
160
|
});
|
153
161
|
}
|
@@ -15,6 +15,7 @@ import {
|
|
15
15
|
LAST_USED_QUERY_ACTION_KEY,
|
16
16
|
USE_BACKEND_PARAMS_FOR_TABLES_KEY,
|
17
17
|
LANGUAGE_KEY,
|
18
|
+
ENABLE_NEW_TENANT_DIAGNOSTICS_DESIGN,
|
18
19
|
} from '../../../utils/constants';
|
19
20
|
import '../../../services/api';
|
20
21
|
import {parseJson} from '../../../utils/utils';
|
@@ -55,6 +56,10 @@ export const initialState = {
|
|
55
56
|
ENABLE_ADDITIONAL_QUERY_MODES,
|
56
57
|
'false',
|
57
58
|
),
|
59
|
+
[ENABLE_NEW_TENANT_DIAGNOSTICS_DESIGN]: readSavedSettingsValue(
|
60
|
+
ENABLE_NEW_TENANT_DIAGNOSTICS_DESIGN,
|
61
|
+
'false',
|
62
|
+
),
|
58
63
|
[SAVED_QUERIES_KEY]: readSavedSettingsValue(SAVED_QUERIES_KEY, '[]'),
|
59
64
|
[TENANT_INITIAL_PAGE_KEY]: readSavedSettingsValue(
|
60
65
|
TENANT_INITIAL_PAGE_KEY,
|
@@ -4,6 +4,7 @@ import type {TTenant} from '../../../types/api/tenant';
|
|
4
4
|
import type {
|
5
5
|
TenantAction,
|
6
6
|
TenantDiagnosticsTab,
|
7
|
+
TenantMetricsTab,
|
7
8
|
TenantPage,
|
8
9
|
TenantQueryTab,
|
9
10
|
TenantState,
|
@@ -19,6 +20,7 @@ const SET_TOP_LEVEL_TAB = 'tenant/SET_TOP_LEVEL_TAB';
|
|
19
20
|
const SET_QUERY_TAB = 'tenant/SET_QUERY_TAB';
|
20
21
|
const SET_DIAGNOSTICS_TAB = 'tenant/SET_DIAGNOSTICS_TAB';
|
21
22
|
const SET_SUMMARY_TAB = 'tenant/SET_SUMMARY_TAB';
|
23
|
+
const SET_METRICS_TAB = 'tenant/SET_METRICS_TAB';
|
22
24
|
const CLEAR_TENANT = 'tenant/CLEAR_TENANT';
|
23
25
|
const SET_DATA_WAS_NOT_LOADED = 'tenant/SET_DATA_WAS_NOT_LOADED';
|
24
26
|
|
@@ -88,6 +90,12 @@ const tenantReducer: Reducer<TenantState, TenantAction> = (state = initialState,
|
|
88
90
|
summaryTab: action.data,
|
89
91
|
};
|
90
92
|
}
|
93
|
+
case SET_METRICS_TAB: {
|
94
|
+
return {
|
95
|
+
...state,
|
96
|
+
metricsTab: action.data,
|
97
|
+
};
|
98
|
+
}
|
91
99
|
|
92
100
|
case SET_DATA_WAS_NOT_LOADED: {
|
93
101
|
return {
|
@@ -143,6 +151,13 @@ export function setSummaryTab(tab: TenantSummaryTab) {
|
|
143
151
|
} as const;
|
144
152
|
}
|
145
153
|
|
154
|
+
export function setMetricsTab(tab: TenantMetricsTab) {
|
155
|
+
return {
|
156
|
+
type: SET_METRICS_TAB,
|
157
|
+
data: tab,
|
158
|
+
} as const;
|
159
|
+
}
|
160
|
+
|
146
161
|
export const setDataWasNotLoaded = () => {
|
147
162
|
return {
|
148
163
|
type: SET_DATA_WAS_NOT_LOADED,
|
@@ -8,6 +8,7 @@ import {
|
|
8
8
|
TENANT_DIAGNOSTICS_TABS_IDS,
|
9
9
|
TENANT_PAGES_IDS,
|
10
10
|
TENANT_SUMMARY_TABS_IDS,
|
11
|
+
TENANT_METRICS_TABS_IDS,
|
11
12
|
} from './constants';
|
12
13
|
import {
|
13
14
|
FETCH_TENANT,
|
@@ -15,6 +16,7 @@ import {
|
|
15
16
|
setDiagnosticsTab,
|
16
17
|
setQueryTab,
|
17
18
|
setSummaryTab,
|
19
|
+
setMetricsTab,
|
18
20
|
setTenantPage,
|
19
21
|
setDataWasNotLoaded,
|
20
22
|
} from './tenant';
|
@@ -24,6 +26,7 @@ export type TenantPage = ValueOf<typeof TENANT_PAGES_IDS>;
|
|
24
26
|
export type TenantQueryTab = ValueOf<typeof TENANT_QUERY_TABS_ID>;
|
25
27
|
export type TenantDiagnosticsTab = ValueOf<typeof TENANT_DIAGNOSTICS_TABS_IDS>;
|
26
28
|
export type TenantSummaryTab = ValueOf<typeof TENANT_SUMMARY_TABS_IDS>;
|
29
|
+
export type TenantMetricsTab = ValueOf<typeof TENANT_METRICS_TABS_IDS>;
|
27
30
|
|
28
31
|
export interface TenantState {
|
29
32
|
loading: boolean;
|
@@ -32,6 +35,7 @@ export interface TenantState {
|
|
32
35
|
queryTab?: TenantQueryTab;
|
33
36
|
diagnosticsTab?: TenantDiagnosticsTab;
|
34
37
|
summaryTab?: TenantSummaryTab;
|
38
|
+
metricsTab?: TenantMetricsTab;
|
35
39
|
tenant?: TTenant;
|
36
40
|
error?: IResponseError;
|
37
41
|
}
|
@@ -43,4 +47,5 @@ export type TenantAction =
|
|
43
47
|
| ReturnType<typeof setQueryTab>
|
44
48
|
| ReturnType<typeof setDiagnosticsTab>
|
45
49
|
| ReturnType<typeof setSummaryTab>
|
50
|
+
| ReturnType<typeof setMetricsTab>
|
46
51
|
| ReturnType<typeof setDataWasNotLoaded>;
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import {FETCH_TENANTS, setSearchValue} from './tenants';
|
2
2
|
|
3
|
+
import {ValueOf} from '../../../types/common';
|
3
4
|
import type {TTenant} from '../../../types/api/tenant';
|
4
5
|
import type {IResponseError} from '../../../types/api/error';
|
5
6
|
import type {ApiRequestAction} from '../../utils';
|
7
|
+
import {METRIC_STATUS} from './contants';
|
6
8
|
|
7
9
|
export interface PreparedTenant extends TTenant {
|
8
10
|
backend: string | undefined;
|
@@ -30,3 +32,5 @@ export type TenantsAction =
|
|
30
32
|
export interface TenantsStateSlice {
|
31
33
|
tenants: TenantsState;
|
32
34
|
}
|
35
|
+
|
36
|
+
export type MetricStatus = ValueOf<typeof METRIC_STATUS>;
|