ydb-embedded-ui 3.4.0 → 3.4.2
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 +18 -0
- package/dist/components/BasicNodeViewer/BasicNodeViewer.tsx +2 -3
- package/dist/components/ClusterInfo/ClusterInfo.tsx +14 -36
- package/dist/components/CopyToClipboard/CopyToClipboard.tsx +1 -2
- package/dist/components/CriticalActionDialog/CriticalActionDialog.js +1 -1
- package/dist/components/EmptyState/{EmptyState.js → EmptyState.tsx} +12 -15
- package/dist/components/EmptyState/index.ts +1 -0
- package/dist/components/EnableFullscreenButton/EnableFullscreenButton.tsx +7 -2
- package/dist/components/Errors/403/AccessDenied.tsx +1 -1
- package/dist/components/Fullscreen/Fullscreen.tsx +1 -1
- package/dist/components/Icon/Icon.tsx +33 -0
- package/dist/components/Icon/index.ts +1 -0
- package/dist/components/Pagination/Pagination.js +1 -1
- package/dist/components/QueryExecutionStatus/QueryExecutionStatus.tsx +1 -1
- package/dist/components/Tablet/Tablet.tsx +59 -0
- package/dist/components/Tablet/index.ts +1 -0
- package/dist/components/Tag/Tag.tsx +16 -0
- package/dist/components/Tag/index.ts +1 -0
- package/dist/components/Tags/Tags.tsx +22 -0
- package/dist/components/Tags/index.ts +1 -0
- package/dist/containers/Header/Header.tsx +2 -3
- package/dist/containers/Header/Host/Host.js +1 -1
- package/dist/containers/Node/NodeStructure/Pdisk.tsx +1 -1
- package/dist/containers/Nodes/getNodesColumns.tsx +1 -1
- package/dist/containers/Storage/EmptyFilter/EmptyFilter.tsx +8 -9
- package/dist/containers/Storage/PDisk/PDisk.scss +15 -0
- package/dist/containers/Storage/PDisk/PDisk.tsx +38 -13
- package/dist/containers/Storage/StorageNodes/StorageNodes.scss +4 -2
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +1 -0
- package/dist/containers/Tablet/Tablet.js +6 -6
- package/dist/containers/Tablets/Tablets.scss +0 -4
- package/dist/containers/Tablets/Tablets.tsx +1 -2
- package/dist/containers/TabletsFilters/TabletsFilters.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Consumers/TopicStats/ConsumersTopicStats.scss +1 -1
- package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +27 -1
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +1 -2
- package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Partitions/Partitions.tsx +17 -13
- package/dist/containers/Tenant/Diagnostics/Partitions/PartitionsWrapper.tsx +2 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +1 -1
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +1 -1
- package/dist/containers/Tenant/Preview/Preview.js +1 -1
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +1 -1
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +1 -1
- package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.js +1 -1
- package/dist/containers/Tenant/TenantPages.tsx +1 -2
- package/dist/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx +2 -2
- package/dist/services/api.d.ts +11 -0
- package/dist/services/api.js +3 -3
- package/dist/store/reducers/consumer.ts +14 -0
- package/dist/store/reducers/{host.js → host.ts} +9 -5
- package/dist/store/reducers/shardsWorkload.ts +4 -0
- package/dist/store/reducers/tablet.ts +111 -0
- package/dist/store/reducers/topic.ts +13 -0
- package/dist/store/state-url-mapping.js +3 -0
- package/dist/types/api/cluster.ts +34 -0
- package/dist/types/api/systemState.ts +13 -0
- package/dist/types/api/tablet.ts +12 -4
- package/dist/types/store/consumer.ts +10 -2
- package/dist/types/store/host.ts +23 -0
- package/dist/types/store/tablet.ts +50 -0
- package/dist/types/store/tooltip.ts +3 -1
- package/dist/types/store/topic.ts +3 -2
- package/package.json +7 -5
- package/dist/components/Icon/Icon.js +0 -28
- package/dist/components/Tablet/Tablet.js +0 -61
- package/dist/components/Tag/Tag.js +0 -14
- package/dist/components/Tags/Tags.js +0 -36
- package/dist/store/reducers/tablet.js +0 -94
@@ -5,7 +5,7 @@ import ReactList from 'react-list';
|
|
5
5
|
|
6
6
|
import {Select} from '@gravity-ui/uikit';
|
7
7
|
|
8
|
-
import Tablet from '../../components/Tablet
|
8
|
+
import {Tablet} from '../../components/Tablet';
|
9
9
|
import TabletsOverall from '../../components/TabletsOverall/TabletsOverall';
|
10
10
|
import {Loader} from '../../components/Loader';
|
11
11
|
|
@@ -104,7 +104,6 @@ export const Tablets = ({path, nodeId, className}: TabletsProps) => {
|
|
104
104
|
onMouseEnter={onShowTooltip}
|
105
105
|
tablet={tabletsToRender[tabletIndex]}
|
106
106
|
key={tabletIndex}
|
107
|
-
className={b('tablet')}
|
108
107
|
/>
|
109
108
|
);
|
110
109
|
};
|
@@ -8,7 +8,7 @@ import _ from 'lodash';
|
|
8
8
|
import {Loader, Select} from '@gravity-ui/uikit';
|
9
9
|
import ReactList from 'react-list';
|
10
10
|
|
11
|
-
import Tablet from '../../components/Tablet
|
11
|
+
import {Tablet} from '../../components/Tablet';
|
12
12
|
import {AccessDenied} from '../../components/Errors/403';
|
13
13
|
|
14
14
|
import {tabletColorToTabletState, tabletStates} from '../../utils/tablet';
|
@@ -1,9 +1,15 @@
|
|
1
1
|
import DataTable, {Column} from '@gravity-ui/react-data-table';
|
2
2
|
import block from 'bem-cn-lite';
|
3
|
+
import qs from 'qs';
|
3
4
|
|
4
5
|
import type {IPreparedConsumerData} from '../../../../../types/store/topic';
|
5
6
|
import {SpeedMultiMeter} from '../../../../../components/SpeedMultiMeter';
|
7
|
+
import {InternalLink} from '../../../../../components/InternalLink';
|
6
8
|
import {formatMsToUptime} from '../../../../../utils';
|
9
|
+
import routes, {createHref} from '../../../../../routes';
|
10
|
+
|
11
|
+
import {TenantTabsGroups} from '../../../TenantPages';
|
12
|
+
import {GeneralPagesIds} from '../../DiagnosticsPages';
|
7
13
|
|
8
14
|
import {
|
9
15
|
CONSUMERS_COLUMNS_IDS,
|
@@ -23,7 +29,27 @@ export const columns: Column<IPreparedConsumerData>[] = [
|
|
23
29
|
name: CONSUMERS_COLUMNS_IDS.CONSUMER,
|
24
30
|
header: CONSUMERS_COLUMNS_TITILES[CONSUMERS_COLUMNS_IDS.CONSUMER],
|
25
31
|
align: DataTable.LEFT,
|
26
|
-
render: ({row}) =>
|
32
|
+
render: ({row}) => {
|
33
|
+
if (!row.name) {
|
34
|
+
return '–';
|
35
|
+
}
|
36
|
+
|
37
|
+
const queryParams = qs.parse(location.search, {
|
38
|
+
ignoreQueryPrefix: true,
|
39
|
+
});
|
40
|
+
|
41
|
+
return (
|
42
|
+
<InternalLink
|
43
|
+
to={createHref(routes.tenant, undefined, {
|
44
|
+
...queryParams,
|
45
|
+
[TenantTabsGroups.generalTab]: GeneralPagesIds.partitions,
|
46
|
+
selectedConsumer: row.name,
|
47
|
+
})}
|
48
|
+
>
|
49
|
+
{row.name}
|
50
|
+
</InternalLink>
|
51
|
+
);
|
52
|
+
},
|
27
53
|
},
|
28
54
|
{
|
29
55
|
name: CONSUMERS_COLUMNS_IDS.READ_SPEED,
|
@@ -5,8 +5,7 @@ import cn from 'bem-cn-lite';
|
|
5
5
|
import {Button, Modal} from '@gravity-ui/uikit';
|
6
6
|
|
7
7
|
import type {EPathType} from '../../../../types/api/schema';
|
8
|
-
|
9
|
-
import Icon from '../../../../components/Icon/Icon';
|
8
|
+
import {Icon} from '../../../../components/Icon';
|
10
9
|
import Overview from '../Overview/Overview';
|
11
10
|
import {Healthcheck} from '../Healthcheck';
|
12
11
|
//@ts-ignore
|
@@ -4,7 +4,7 @@ import {connect} from 'react-redux';
|
|
4
4
|
import {Loader} from '@gravity-ui/uikit';
|
5
5
|
import DataTable from '@gravity-ui/react-data-table';
|
6
6
|
|
7
|
-
import Icon from '../../../../components/Icon
|
7
|
+
import {Icon} from '../../../../components/Icon';
|
8
8
|
|
9
9
|
import {AutoFetcher} from '../../../../utils/autofetcher';
|
10
10
|
import {getHotKeys, setHotKeysOptions} from '../../../../store/reducers/hotKeys';
|
@@ -8,7 +8,7 @@ import {Link} from 'react-router-dom';
|
|
8
8
|
import {Loader, Checkbox} from '@gravity-ui/uikit';
|
9
9
|
|
10
10
|
import NodeNetwork from './NodeNetwork/NodeNetwork';
|
11
|
-
import Icon from '../../../../components/Icon
|
11
|
+
import {Icon} from '../../../../components/Icon';
|
12
12
|
import {ProblemFilter} from '../../../../components/ProblemFilter';
|
13
13
|
import {Illustration} from '../../../../components/Illustration';
|
14
14
|
|
@@ -17,6 +17,7 @@ import {
|
|
17
17
|
getConsumer,
|
18
18
|
selectPreparedPartitionsData,
|
19
19
|
setDataWasNotLoaded,
|
20
|
+
setSelectedConsumer,
|
20
21
|
} from '../../../../store/reducers/consumer';
|
21
22
|
|
22
23
|
import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton';
|
@@ -52,14 +53,15 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
|
|
52
53
|
|
53
54
|
const dispatch = useDispatch();
|
54
55
|
|
55
|
-
const [selectedConsumer, setSelectedConsumer] = useState<string[]>();
|
56
56
|
const [generalSearchValue, setGeneralSearchValue] = useState('');
|
57
57
|
const [partitionIdSearchValue, setPartitionIdSearchValue] = useState('');
|
58
58
|
|
59
59
|
const [componentCurrentPath, setComponentCurrentPath] = useState(path);
|
60
60
|
|
61
61
|
const {autorefresh} = useTypedSelector((state) => state.schema);
|
62
|
-
const {loading, wasLoaded, error} = useTypedSelector(
|
62
|
+
const {loading, wasLoaded, error, selectedConsumer} = useTypedSelector(
|
63
|
+
(state) => state.consumer,
|
64
|
+
);
|
63
65
|
|
64
66
|
const partitions = useTypedSelector((state) => selectPreparedPartitionsData(state));
|
65
67
|
|
@@ -70,7 +72,7 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
|
|
70
72
|
useEffect(() => {
|
71
73
|
// Manual path control to ensure it updates with other values so no request with wrong params will be sent
|
72
74
|
setComponentCurrentPath(path);
|
73
|
-
}, [path]);
|
75
|
+
}, [dispatch, path]);
|
74
76
|
|
75
77
|
const fetchConsumerData = useCallback(
|
76
78
|
(isBackground: boolean) => {
|
@@ -78,11 +80,11 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
|
|
78
80
|
dispatch(setDataWasNotLoaded());
|
79
81
|
}
|
80
82
|
|
81
|
-
if (selectedConsumer && selectedConsumer
|
82
|
-
dispatch(getConsumer(componentCurrentPath, selectedConsumer
|
83
|
+
if (selectedConsumer && consumers && consumers.includes(selectedConsumer)) {
|
84
|
+
dispatch(getConsumer(componentCurrentPath, selectedConsumer));
|
83
85
|
}
|
84
86
|
},
|
85
|
-
[dispatch, selectedConsumer, componentCurrentPath],
|
87
|
+
[dispatch, selectedConsumer, componentCurrentPath, consumers],
|
86
88
|
);
|
87
89
|
|
88
90
|
useAutofetcher(fetchConsumerData, [fetchConsumerData], autorefresh);
|
@@ -99,12 +101,13 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
|
|
99
101
|
);
|
100
102
|
|
101
103
|
useEffect(() => {
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
104
|
+
const shouldUpdateSelectedConsumer =
|
105
|
+
!selectedConsumer || (consumers && !consumers.includes(selectedConsumer));
|
106
|
+
|
107
|
+
if (consumersToSelect && consumersToSelect.length && shouldUpdateSelectedConsumer) {
|
108
|
+
dispatch(setSelectedConsumer(consumersToSelect[0].value));
|
106
109
|
}
|
107
|
-
}, [consumersToSelect]);
|
110
|
+
}, [dispatch, consumersToSelect, selectedConsumer, consumers]);
|
108
111
|
|
109
112
|
const selectedColumns: string[] = useMemo(
|
110
113
|
() =>
|
@@ -183,7 +186,7 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
|
|
183
186
|
};
|
184
187
|
|
185
188
|
const handleConsumerSelectChange = (value: string[]) => {
|
186
|
-
setSelectedConsumer(value);
|
189
|
+
dispatch(setSelectedConsumer(value[0]));
|
187
190
|
};
|
188
191
|
|
189
192
|
const handlePartitionIdSearchChange = (value: string) => {
|
@@ -210,8 +213,9 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
|
|
210
213
|
placeholder={i18n('controls.consumerSelector.placeholder')}
|
211
214
|
label={i18n('controls.consumerSelector')}
|
212
215
|
options={consumersToSelect}
|
213
|
-
value={selectedConsumer}
|
216
|
+
value={[selectedConsumer || '']}
|
214
217
|
onUpdate={handleConsumerSelectChange}
|
218
|
+
filterable={consumers && consumers.length > 5}
|
215
219
|
/>
|
216
220
|
<Search
|
217
221
|
onChange={handlePartitionIdSearchChange}
|
@@ -6,6 +6,7 @@ import type {EPathType} from '../../../../types/api/schema';
|
|
6
6
|
import {useTypedSelector} from '../../../../utils/hooks';
|
7
7
|
|
8
8
|
import {
|
9
|
+
cleanTopicData,
|
9
10
|
getTopic,
|
10
11
|
setDataWasNotLoaded as setTopicDataWasNotLoaded,
|
11
12
|
} from '../../../../store/reducers/topic';
|
@@ -61,6 +62,7 @@ export const PartitionsWrapper = ({path, type}: PartitionsWrapperProps) => {
|
|
61
62
|
|
62
63
|
useEffect(() => {
|
63
64
|
dispatch(setTopicDataWasNotLoaded());
|
65
|
+
dispatch(cleanTopicData());
|
64
66
|
dispatch(setNodesDataWasNotLoaded());
|
65
67
|
|
66
68
|
dispatch(getTopic(path));
|
@@ -7,7 +7,7 @@ import {Loader} from '@gravity-ui/uikit';
|
|
7
7
|
import EntityStatus from '../../../../components/EntityStatus/EntityStatus';
|
8
8
|
import InfoViewer from '../../../../components/InfoViewer/InfoViewer';
|
9
9
|
import PoolUsage from '../../../../components/PoolUsage/PoolUsage';
|
10
|
-
import Tablet from '../../../../components/Tablet
|
10
|
+
import {Tablet} from '../../../../components/Tablet';
|
11
11
|
|
12
12
|
import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
|
13
13
|
import {getTenantInfo} from '../../../../store/reducers/tenant';
|
@@ -5,7 +5,7 @@ import cn from 'bem-cn-lite';
|
|
5
5
|
|
6
6
|
import {Loader, Button} from '@gravity-ui/uikit';
|
7
7
|
|
8
|
-
import Icon from '../../../components/Icon
|
8
|
+
import {Icon} from '../../../components/Icon';
|
9
9
|
import Fullscreen from '../../../components/Fullscreen/Fullscreen';
|
10
10
|
import {QueryResultTable} from '../../../components/QueryResultTable';
|
11
11
|
|
@@ -11,7 +11,7 @@ import {QueryResultTable} from '../../../components/QueryResultTable';
|
|
11
11
|
|
12
12
|
import SaveQuery from './SaveQuery/SaveQuery';
|
13
13
|
import SavedQueries from './SavedQueries/SavedQueries';
|
14
|
-
import Icon from '../../../components/Icon
|
14
|
+
import {Icon} from '../../../components/Icon';
|
15
15
|
import QueryResult from './QueryResult/QueryResult';
|
16
16
|
import QueryExplain from './QueryExplain/QueryExplain';
|
17
17
|
|
@@ -4,7 +4,7 @@ import cn from 'bem-cn-lite';
|
|
4
4
|
import {Dialog, Popup, Button} from '@gravity-ui/uikit';
|
5
5
|
|
6
6
|
import TruncatedQuery from '../../../../components/TruncatedQuery/TruncatedQuery';
|
7
|
-
import Icon from '../../../../components/Icon
|
7
|
+
import {Icon} from '../../../../components/Icon';
|
8
8
|
import './SavedQueries.scss';
|
9
9
|
import {setQueryNameToEdit} from '../../../../store/reducers/saveQuery';
|
10
10
|
import {useDispatch} from 'react-redux';
|
@@ -4,7 +4,7 @@ import cn from 'bem-cn-lite';
|
|
4
4
|
|
5
5
|
import find from 'lodash/find';
|
6
6
|
|
7
|
-
import Icon from '../../../../components/Icon
|
7
|
+
import {Icon} from '../../../../components/Icon';
|
8
8
|
import DataTable from '@gravity-ui/react-data-table';
|
9
9
|
import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants';
|
10
10
|
import './SchemaViewer.scss';
|
package/dist/services/api.d.ts
CHANGED
@@ -52,10 +52,20 @@ interface Window {
|
|
52
52
|
getTenantInfo: (params: {
|
53
53
|
path: string;
|
54
54
|
}) => Promise<import('../types/api/tenant').TTenantInfo>;
|
55
|
+
getClusterInfo: () => Promise<import('../types/api/cluster').TClusterInfo>;
|
55
56
|
getTabletsInfo: (params: {
|
56
57
|
nodes?: string[];
|
57
58
|
path?: string;
|
58
59
|
}) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
|
60
|
+
getTabletDescribe: (
|
61
|
+
tenantId?: import('../types/api/tablet').TDomainKey,
|
62
|
+
) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
|
63
|
+
getTablet: (params: {
|
64
|
+
id?: string;
|
65
|
+
}) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
|
66
|
+
getTabletHistory: (params: {
|
67
|
+
id?: string;
|
68
|
+
}) => Promise<import('../types/api/tablet').UnmergedTEvTabletStateResponse>;
|
59
69
|
getHeatmapData: (params: {
|
60
70
|
path: string;
|
61
71
|
}) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
|
@@ -66,6 +76,7 @@ interface Window {
|
|
66
76
|
path?: string;
|
67
77
|
consumer?: string;
|
68
78
|
}) => Promise<import('../types/api/consumer').DescribeConsumerResult>;
|
79
|
+
getHostInfo: () => Promise<import('../types/api/systemState').TEvSystemStateResponse>;
|
69
80
|
[method: string]: Function;
|
70
81
|
};
|
71
82
|
}
|
package/dist/services/api.js
CHANGED
@@ -247,10 +247,10 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
|
|
247
247
|
this.getPath(`/tablets/app?TabletID=${hiveId}&page=ResumeTablet&tablet=${id}`),
|
248
248
|
);
|
249
249
|
}
|
250
|
-
getTabletDescribe(
|
250
|
+
getTabletDescribe(tenantId) {
|
251
251
|
return this.get(this.getPath('/viewer/json/describe'), {
|
252
|
-
schemeshard_id:
|
253
|
-
path_id:
|
252
|
+
schemeshard_id: tenantId?.SchemeShard,
|
253
|
+
path_id: tenantId?.PathId,
|
254
254
|
});
|
255
255
|
}
|
256
256
|
postSetting(name, value) {
|
@@ -20,6 +20,7 @@ import {createRequestActionTypes, createApiRequest} from '../utils';
|
|
20
20
|
export const FETCH_CONSUMER = createRequestActionTypes('consumer', 'FETCH_CONSUMER');
|
21
21
|
|
22
22
|
const SET_DATA_WAS_NOT_LOADED = 'consumer/SET_DATA_WAS_NOT_LOADED';
|
23
|
+
const SET_SELECTED_CONSUMER = 'consumer/SET_SELECTED_CONSUMER';
|
23
24
|
|
24
25
|
const initialState = {
|
25
26
|
loading: false,
|
@@ -66,6 +67,12 @@ const consumer: Reducer<IConsumerState, IConsumerAction> = (state = initialState
|
|
66
67
|
wasLoaded: false,
|
67
68
|
};
|
68
69
|
}
|
70
|
+
case SET_SELECTED_CONSUMER: {
|
71
|
+
return {
|
72
|
+
...state,
|
73
|
+
selectedConsumer: action.data,
|
74
|
+
};
|
75
|
+
}
|
69
76
|
default:
|
70
77
|
return state;
|
71
78
|
}
|
@@ -77,6 +84,13 @@ export const setDataWasNotLoaded = () => {
|
|
77
84
|
} as const;
|
78
85
|
};
|
79
86
|
|
87
|
+
export const setSelectedConsumer = (value?: string) => {
|
88
|
+
return {
|
89
|
+
type: SET_SELECTED_CONSUMER,
|
90
|
+
data: value,
|
91
|
+
} as const;
|
92
|
+
};
|
93
|
+
|
80
94
|
export function getConsumer(path?: string, consumerName?: string) {
|
81
95
|
return createApiRequest({
|
82
96
|
request: window.api.getConsumer({path, consumer: consumerName}),
|
@@ -1,11 +1,15 @@
|
|
1
|
-
import {
|
1
|
+
import type {Reducer} from 'redux';
|
2
|
+
|
3
|
+
import type {IHostAction, IHostState} from '../../types/store/host';
|
2
4
|
import '../../services/api';
|
3
5
|
|
4
|
-
|
6
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
7
|
+
|
8
|
+
export const FETCH_HOST = createRequestActionTypes('host', 'FETCH_HOST');
|
5
9
|
|
6
10
|
const initialState = {loading: true, wasLoaded: false, data: {}};
|
7
11
|
|
8
|
-
const
|
12
|
+
const host: Reducer<IHostState, IHostAction> = (state = initialState, action) => {
|
9
13
|
switch (action.type) {
|
10
14
|
case FETCH_HOST.REQUEST: {
|
11
15
|
return {
|
@@ -16,7 +20,7 @@ const cluster = function (state = initialState, action) {
|
|
16
20
|
case FETCH_HOST.SUCCESS: {
|
17
21
|
return {
|
18
22
|
...state,
|
19
|
-
data: action.data.SystemStateInfo[0],
|
23
|
+
data: action.data.SystemStateInfo?.[0],
|
20
24
|
loading: false,
|
21
25
|
wasLoaded: true,
|
22
26
|
error: undefined,
|
@@ -41,4 +45,4 @@ export function getHostInfo() {
|
|
41
45
|
});
|
42
46
|
}
|
43
47
|
|
44
|
-
export default
|
48
|
+
export default host;
|
@@ -133,6 +133,10 @@ const shardsWorkload: Reducer<IShardsWorkloadState, IShardsWorkloadAction> = (
|
|
133
133
|
}
|
134
134
|
// 401 Unauthorized error is handled by GenericAPI
|
135
135
|
case SEND_SHARD_QUERY.FAILURE: {
|
136
|
+
if (action.error?.isCancelled) {
|
137
|
+
return state;
|
138
|
+
}
|
139
|
+
|
136
140
|
return {
|
137
141
|
...state,
|
138
142
|
error: action.error || 'Unauthorized',
|
@@ -0,0 +1,111 @@
|
|
1
|
+
import type {Reducer} from 'redux';
|
2
|
+
|
3
|
+
import type {TDomainKey} from '../../types/api/tablet';
|
4
|
+
import type {
|
5
|
+
ITabletAction,
|
6
|
+
ITabletDescribeHandledResponse,
|
7
|
+
ITabletHandledResponse,
|
8
|
+
ITabletPreparedHistoryItem,
|
9
|
+
ITabletState,
|
10
|
+
} from '../../types/store/tablet';
|
11
|
+
import '../../services/api';
|
12
|
+
|
13
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
14
|
+
|
15
|
+
export const FETCH_TABLET = createRequestActionTypes('TABLET', 'FETCH_TABLET');
|
16
|
+
export const FETCH_TABLET_DESCRIBE = createRequestActionTypes('TABLET', 'FETCH_TABLET_DESCRIBE');
|
17
|
+
|
18
|
+
const initialState = {
|
19
|
+
loading: false,
|
20
|
+
tenantPath: '-',
|
21
|
+
};
|
22
|
+
|
23
|
+
const tablet: Reducer<ITabletState, ITabletAction> = (state = initialState, action) => {
|
24
|
+
switch (action.type) {
|
25
|
+
case FETCH_TABLET.REQUEST: {
|
26
|
+
return {
|
27
|
+
...state,
|
28
|
+
loading: true,
|
29
|
+
};
|
30
|
+
}
|
31
|
+
case FETCH_TABLET.SUCCESS: {
|
32
|
+
const {tabletData, historyData} = action.data;
|
33
|
+
const {TabletId: id} = tabletData;
|
34
|
+
return {
|
35
|
+
...state,
|
36
|
+
id,
|
37
|
+
data: tabletData,
|
38
|
+
history: historyData,
|
39
|
+
loading: false,
|
40
|
+
error: undefined,
|
41
|
+
};
|
42
|
+
}
|
43
|
+
case FETCH_TABLET.FAILURE: {
|
44
|
+
return {
|
45
|
+
...state,
|
46
|
+
error: action.error,
|
47
|
+
loading: false,
|
48
|
+
};
|
49
|
+
}
|
50
|
+
case FETCH_TABLET_DESCRIBE.SUCCESS: {
|
51
|
+
const {tenantPath} = action.data;
|
52
|
+
|
53
|
+
return {
|
54
|
+
...state,
|
55
|
+
tenantPath,
|
56
|
+
error: undefined,
|
57
|
+
};
|
58
|
+
}
|
59
|
+
default:
|
60
|
+
return state;
|
61
|
+
}
|
62
|
+
};
|
63
|
+
|
64
|
+
export const getTablet = (id: string) => {
|
65
|
+
return createApiRequest({
|
66
|
+
request: Promise.all([window.api.getTablet({id}), window.api.getTabletHistory({id})]),
|
67
|
+
actions: FETCH_TABLET,
|
68
|
+
dataHandler: ([tabletResponseData, historyResponseData]): ITabletHandledResponse => {
|
69
|
+
const historyData = Object.keys(historyResponseData).reduce<
|
70
|
+
ITabletPreparedHistoryItem[]
|
71
|
+
>((list, nodeId) => {
|
72
|
+
const tabletInfo = historyResponseData[nodeId]?.TabletStateInfo;
|
73
|
+
if (tabletInfo && tabletInfo.length) {
|
74
|
+
const leaderTablet = tabletInfo.find((t) => t.Leader) || tabletInfo[0];
|
75
|
+
|
76
|
+
const {ChangeTime, Generation, State, Leader, FollowerId} = leaderTablet;
|
77
|
+
|
78
|
+
list.push({
|
79
|
+
nodeId,
|
80
|
+
generation: Generation,
|
81
|
+
changeTime: ChangeTime,
|
82
|
+
state: State,
|
83
|
+
leader: Leader,
|
84
|
+
followerId: FollowerId,
|
85
|
+
});
|
86
|
+
}
|
87
|
+
return list;
|
88
|
+
}, []);
|
89
|
+
|
90
|
+
const {TabletStateInfo = []} = tabletResponseData;
|
91
|
+
const [tabletData = {}] = TabletStateInfo;
|
92
|
+
|
93
|
+
return {tabletData, historyData};
|
94
|
+
},
|
95
|
+
});
|
96
|
+
};
|
97
|
+
|
98
|
+
export const getTabletDescribe = (tenantId: TDomainKey = {}) => {
|
99
|
+
return createApiRequest({
|
100
|
+
request: window.api.getTabletDescribe(tenantId),
|
101
|
+
actions: FETCH_TABLET_DESCRIBE,
|
102
|
+
dataHandler: (tabletDescribe): ITabletDescribeHandledResponse => {
|
103
|
+
const {SchemeShard, PathId} = tenantId;
|
104
|
+
const tenantPath = tabletDescribe.Path || `${SchemeShard}:${PathId}`;
|
105
|
+
|
106
|
+
return {tenantPath};
|
107
|
+
},
|
108
|
+
});
|
109
|
+
};
|
110
|
+
|
111
|
+
export default tablet;
|
@@ -18,6 +18,7 @@ import {convertBytesObjectToSpeed} from '../../utils/bytesParsers';
|
|
18
18
|
export const FETCH_TOPIC = createRequestActionTypes('topic', 'FETCH_TOPIC');
|
19
19
|
|
20
20
|
const SET_DATA_WAS_NOT_LOADED = 'topic/SET_DATA_WAS_NOT_LOADED';
|
21
|
+
const CLEAN_TOPIC_DATA = 'topic/CLEAN_TOPIC_DATA';
|
21
22
|
|
22
23
|
const initialState = {
|
23
24
|
loading: true,
|
@@ -64,6 +65,12 @@ const topic: Reducer<ITopicState, ITopicAction> = (state = initialState, action)
|
|
64
65
|
wasLoaded: false,
|
65
66
|
};
|
66
67
|
}
|
68
|
+
case CLEAN_TOPIC_DATA: {
|
69
|
+
return {
|
70
|
+
...state,
|
71
|
+
data: undefined,
|
72
|
+
};
|
73
|
+
}
|
67
74
|
default:
|
68
75
|
return state;
|
69
76
|
}
|
@@ -75,6 +82,12 @@ export const setDataWasNotLoaded = () => {
|
|
75
82
|
} as const;
|
76
83
|
};
|
77
84
|
|
85
|
+
export const cleanTopicData = () => {
|
86
|
+
return {
|
87
|
+
type: CLEAN_TOPIC_DATA,
|
88
|
+
} as const;
|
89
|
+
};
|
90
|
+
|
78
91
|
export function getTopic(path?: string) {
|
79
92
|
return createApiRequest({
|
80
93
|
request: window.api.getTopic({path}),
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import type {EFlag} from './enums';
|
2
|
+
import type {TTabletStateInfo} from './tablet';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* endpoint: viewer/json/cluster
|
6
|
+
*
|
7
|
+
* source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
|
8
|
+
*/
|
9
|
+
export interface TClusterInfo {
|
10
|
+
Name?: string;
|
11
|
+
Overall?: EFlag;
|
12
|
+
NodesTotal?: number;
|
13
|
+
NodesAlive?: number;
|
14
|
+
NumberOfCpus?: number;
|
15
|
+
/** double */
|
16
|
+
LoadAverage?: number;
|
17
|
+
/** uint64 */
|
18
|
+
MemoryTotal?: string;
|
19
|
+
/** uint64 */
|
20
|
+
MemoryUsed?: string;
|
21
|
+
/** uint64 */
|
22
|
+
StorageTotal?: string;
|
23
|
+
/** uint64 */
|
24
|
+
StorageUsed?: string;
|
25
|
+
DataCenters?: string[];
|
26
|
+
Versions?: string[];
|
27
|
+
SystemTablets?: TTabletStateInfo[];
|
28
|
+
/** uint64 */
|
29
|
+
Hosts?: string;
|
30
|
+
/** uint64 */
|
31
|
+
Tenants?: string;
|
32
|
+
/** uint64 */
|
33
|
+
Tablets?: string;
|
34
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import {TSystemStateInfo} from './nodes';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* endpoint: /viewer/json/sysinfo
|
5
|
+
*
|
6
|
+
* source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
|
7
|
+
*/
|
8
|
+
export interface TEvSystemStateResponse {
|
9
|
+
SystemStateInfo?: TSystemStateInfo[];
|
10
|
+
/** uint64 */
|
11
|
+
ResponseTime?: string;
|
12
|
+
ResponseDuration?: number;
|
13
|
+
}
|