ydb-embedded-ui 2.0.0 → 2.2.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 +46 -0
- package/dist/assets/icons/update-arrow.svg +6 -0
- package/dist/components/EntityStatus/EntityStatus.js +37 -10
- package/dist/components/EntityStatus/EntityStatus.scss +36 -6
- package/dist/components/NodesViewer/NodesViewer.js +1 -0
- package/dist/components/ShortyString/ShortyString.tsx +21 -8
- package/dist/components/ShortyString/i18n/en.json +10 -0
- package/dist/components/ShortyString/i18n/index.ts +11 -0
- package/dist/components/ShortyString/i18n/ru.json +10 -0
- package/dist/containers/Cluster/Cluster.tsx +3 -3
- package/dist/containers/Nodes/Nodes.js +6 -6
- package/dist/containers/Storage/StorageFilter/StorageFilter.tsx +1 -0
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +2 -2
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +16 -9
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +18 -5
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +83 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuePreview/IssuePreview.tsx +35 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuePreview/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/IssuesList.tsx +62 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssueViewer.scss +21 -15
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssuesViewer.js +52 -86
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/Preview.tsx +74 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/en.json +7 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/index.ts +11 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/ru.json +7 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +4 -21
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +18 -19
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.scss +1 -0
- package/dist/containers/Tenant/Tenant.tsx +2 -2
- package/dist/containers/Tenants/Tenants.js +7 -7
- package/dist/services/api.d.ts +9 -0
- package/dist/types/api/healthcheck.ts +91 -0
- package/dist/types/store/healthcheck.ts +3 -0
- package/dist/utils/hooks/index.ts +1 -0
- package/dist/utils/hooks/useAutofetcher.ts +29 -0
- package/package.json +4 -1
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.js +0 -195
@@ -0,0 +1,91 @@
|
|
1
|
+
export enum SelfCheckResult {
|
2
|
+
UNSPECIFIED = 'UNSPECIFIED',
|
3
|
+
GOOD = 'GOOD',
|
4
|
+
DEGRADED = 'DEGRADED',
|
5
|
+
MAINTENANCE_REQUIRED = 'MAINTENANCE_REQUIRED',
|
6
|
+
EMERGENCY = 'EMERGENCY',
|
7
|
+
}
|
8
|
+
|
9
|
+
enum StatusFlag {
|
10
|
+
UNSPECIFIED = 'UNSPECIFIED',
|
11
|
+
GREY = 'GREY',
|
12
|
+
GREEN = 'GREEN',
|
13
|
+
BLUE = 'BLUE',
|
14
|
+
YELLOW = 'YELLOW',
|
15
|
+
ORANGE = 'ORANGE',
|
16
|
+
RED = 'RED',
|
17
|
+
}
|
18
|
+
|
19
|
+
interface LocationNode {
|
20
|
+
id: number;
|
21
|
+
host: string;
|
22
|
+
port: number;
|
23
|
+
}
|
24
|
+
|
25
|
+
interface LocationStoragePDisk {
|
26
|
+
id: string;
|
27
|
+
path: string;
|
28
|
+
}
|
29
|
+
|
30
|
+
interface LocationStorageVDisk {
|
31
|
+
id: string;
|
32
|
+
pdisk: LocationStoragePDisk;
|
33
|
+
}
|
34
|
+
|
35
|
+
interface LocationStorageGroup {
|
36
|
+
id: string;
|
37
|
+
vdisk: LocationStorageVDisk;
|
38
|
+
}
|
39
|
+
|
40
|
+
interface LocationStoragePool {
|
41
|
+
name: string;
|
42
|
+
group: LocationStorageGroup;
|
43
|
+
}
|
44
|
+
|
45
|
+
interface LocationStorage {
|
46
|
+
node: LocationNode;
|
47
|
+
pool: LocationStoragePool;
|
48
|
+
}
|
49
|
+
|
50
|
+
interface LocationComputePool {
|
51
|
+
name: string;
|
52
|
+
}
|
53
|
+
|
54
|
+
interface LocationComputeTablet {
|
55
|
+
type: string;
|
56
|
+
id?: string[];
|
57
|
+
count: number;
|
58
|
+
}
|
59
|
+
|
60
|
+
interface LocationCompute {
|
61
|
+
node: LocationNode;
|
62
|
+
pool: LocationComputePool;
|
63
|
+
tablet: LocationComputeTablet;
|
64
|
+
}
|
65
|
+
|
66
|
+
interface LocationDatabase {
|
67
|
+
name: string;
|
68
|
+
}
|
69
|
+
|
70
|
+
interface Location {
|
71
|
+
storage: LocationStorage;
|
72
|
+
compute: LocationCompute;
|
73
|
+
database: LocationDatabase;
|
74
|
+
}
|
75
|
+
|
76
|
+
export interface IssueLog {
|
77
|
+
id: string;
|
78
|
+
status: StatusFlag;
|
79
|
+
message: string;
|
80
|
+
location: Location;
|
81
|
+
reason?: string[];
|
82
|
+
type: string;
|
83
|
+
level: number;
|
84
|
+
}
|
85
|
+
|
86
|
+
export interface HealthCheckAPIResponse {
|
87
|
+
// eslint-disable-next-line camelcase
|
88
|
+
self_check_result: SelfCheckResult;
|
89
|
+
// eslint-disable-next-line camelcase
|
90
|
+
issue_log?: IssueLog[];
|
91
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './useAutofetcher';
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import {DependencyList, useEffect, useRef} from 'react';
|
2
|
+
|
3
|
+
import {AutoFetcher} from '../autofetcher';
|
4
|
+
|
5
|
+
export const useAutofetcher = (fetchData: VoidFunction, deps: DependencyList, enabled = true) => {
|
6
|
+
const ref = useRef<AutoFetcher | null>(null);
|
7
|
+
|
8
|
+
if (ref.current === null) {
|
9
|
+
ref.current = new AutoFetcher();
|
10
|
+
}
|
11
|
+
|
12
|
+
const autofetcher = ref.current;
|
13
|
+
|
14
|
+
// initial fetch
|
15
|
+
useEffect(fetchData, deps); // eslint-disable-line react-hooks/exhaustive-deps
|
16
|
+
|
17
|
+
useEffect(() => {
|
18
|
+
autofetcher.stop();
|
19
|
+
|
20
|
+
if (enabled) {
|
21
|
+
autofetcher.start();
|
22
|
+
autofetcher.fetch(fetchData);
|
23
|
+
}
|
24
|
+
|
25
|
+
return () => {
|
26
|
+
autofetcher.stop();
|
27
|
+
};
|
28
|
+
}, [enabled, ...deps]); // eslint-disable-line react-hooks/exhaustive-deps
|
29
|
+
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ydb-embedded-ui",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.2.0",
|
4
4
|
"files": [
|
5
5
|
"dist"
|
6
6
|
],
|
@@ -57,6 +57,9 @@
|
|
57
57
|
],
|
58
58
|
"*.{js,jsx,ts,tsx}": [
|
59
59
|
"eslint --fix --quiet"
|
60
|
+
],
|
61
|
+
"*.{json}": [
|
62
|
+
"prettier --write"
|
60
63
|
]
|
61
64
|
},
|
62
65
|
"jest": {
|
@@ -1,195 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
|
-
import {connect} from 'react-redux';
|
4
|
-
import cn from 'bem-cn-lite';
|
5
|
-
|
6
|
-
import {Loader, Button} from '@gravity-ui/uikit';
|
7
|
-
|
8
|
-
import IssuesViewer from './IssuesViewer/IssuesViewer';
|
9
|
-
|
10
|
-
import {getHealthcheckInfo} from '../../../../store/reducers/healthcheckInfo';
|
11
|
-
import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
|
12
|
-
import {AutoFetcher} from '../../../../utils/autofetcher';
|
13
|
-
|
14
|
-
import './Healthcheck.scss';
|
15
|
-
|
16
|
-
const b = cn('healthcheck');
|
17
|
-
|
18
|
-
class Healthcheck extends React.Component {
|
19
|
-
static propTypes = {
|
20
|
-
data: PropTypes.object,
|
21
|
-
loading: PropTypes.bool,
|
22
|
-
wasLoaded: PropTypes.bool,
|
23
|
-
error: PropTypes.object,
|
24
|
-
getHealthcheckInfo: PropTypes.func,
|
25
|
-
tenant: PropTypes.string,
|
26
|
-
preview: PropTypes.bool,
|
27
|
-
showMoreHandler: PropTypes.func,
|
28
|
-
};
|
29
|
-
|
30
|
-
autofetcher;
|
31
|
-
|
32
|
-
componentDidMount() {
|
33
|
-
this.autofetcher = new AutoFetcher();
|
34
|
-
this.fetchHealthcheck();
|
35
|
-
if (this.props.autorefresh) {
|
36
|
-
this.autofetcher.start();
|
37
|
-
this.autofetcher.fetch(() => this.fetchHealthcheck());
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
|
-
componentDidUpdate(prevProps) {
|
42
|
-
const {autorefresh} = this.props;
|
43
|
-
|
44
|
-
if (autorefresh && !prevProps.autorefresh) {
|
45
|
-
this.fetchHealthcheck();
|
46
|
-
this.autofetcher.stop();
|
47
|
-
this.autofetcher.start();
|
48
|
-
this.autofetcher.fetch(() => this.fetchHealthcheck());
|
49
|
-
}
|
50
|
-
if (!autorefresh && prevProps.autorefresh) {
|
51
|
-
this.autofetcher.stop();
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
componentWillUnmount() {
|
56
|
-
this.autofetcher.stop();
|
57
|
-
}
|
58
|
-
|
59
|
-
fetchHealthcheck = () => {
|
60
|
-
const {tenant, getHealthcheckInfo} = this.props;
|
61
|
-
getHealthcheckInfo(tenant);
|
62
|
-
};
|
63
|
-
|
64
|
-
renderLoader() {
|
65
|
-
return (
|
66
|
-
<div className={b('loader')}>
|
67
|
-
<Loader size="m" />
|
68
|
-
</div>
|
69
|
-
);
|
70
|
-
}
|
71
|
-
|
72
|
-
renderUpdateButton() {
|
73
|
-
const {loading} = this.props;
|
74
|
-
return (
|
75
|
-
<Button size="s" onClick={this.fetchHealthcheck} loading={loading}>
|
76
|
-
Update
|
77
|
-
</Button>
|
78
|
-
);
|
79
|
-
}
|
80
|
-
|
81
|
-
renderPreview = () => {
|
82
|
-
const {data, showMoreHandler} = this.props;
|
83
|
-
const {self_check_result: selfCheckResult} = data;
|
84
|
-
const modifier = selfCheckResult.toLowerCase();
|
85
|
-
|
86
|
-
const statusOk = selfCheckResult === 'GOOD';
|
87
|
-
const text = statusOk
|
88
|
-
? 'No issues have been found on this database.'
|
89
|
-
: 'Several issues have been found on this database.';
|
90
|
-
|
91
|
-
return (
|
92
|
-
<div>
|
93
|
-
<div className={b('status-wrapper')}>
|
94
|
-
<div className={b('preview-title')}>Healthcheck</div>
|
95
|
-
<div className={b('self-check-status-indicator', {[modifier]: true})}>
|
96
|
-
{statusOk ? 'Ok' : 'Error'}
|
97
|
-
</div>
|
98
|
-
{this.renderUpdateButton()}
|
99
|
-
</div>
|
100
|
-
<div className={b('preview-content')}>
|
101
|
-
{text}
|
102
|
-
{!statusOk && (
|
103
|
-
<Button
|
104
|
-
view="flat-info"
|
105
|
-
onClick={showMoreHandler}
|
106
|
-
size="s"
|
107
|
-
>
|
108
|
-
Show details
|
109
|
-
</Button>
|
110
|
-
)}
|
111
|
-
</div>
|
112
|
-
</div>
|
113
|
-
);
|
114
|
-
};
|
115
|
-
|
116
|
-
renderOverviewStatus = () => {
|
117
|
-
const {data} = this.props;
|
118
|
-
const {self_check_result: selfCheckResult} = data;
|
119
|
-
const modifier = selfCheckResult.toLowerCase();
|
120
|
-
|
121
|
-
return (
|
122
|
-
<div className={b('self-check-status')}>
|
123
|
-
<h3 className={b('self-check-status-label')}>Self check status</h3>
|
124
|
-
<div className={b('self-check-status-indicator', {[modifier]: true})} />
|
125
|
-
{selfCheckResult}
|
126
|
-
<div className={b('self-check-update')}>{this.renderUpdateButton()}</div>
|
127
|
-
</div>
|
128
|
-
);
|
129
|
-
};
|
130
|
-
|
131
|
-
renderHealthcheckIssues() {
|
132
|
-
const {data, showTooltip, hideTooltip} = this.props;
|
133
|
-
const {issue_log: issueLog} = data;
|
134
|
-
|
135
|
-
if (!issueLog) {
|
136
|
-
return null;
|
137
|
-
}
|
138
|
-
|
139
|
-
return (
|
140
|
-
<div className={b('issues')}>
|
141
|
-
<h3>Issues</h3>
|
142
|
-
<IssuesViewer
|
143
|
-
issues={issueLog}
|
144
|
-
showTooltip={showTooltip}
|
145
|
-
hideTooltip={hideTooltip}
|
146
|
-
/>
|
147
|
-
</div>
|
148
|
-
);
|
149
|
-
}
|
150
|
-
|
151
|
-
renderContent = () => {
|
152
|
-
const {preview} = this.props;
|
153
|
-
return preview ? (
|
154
|
-
this.renderPreview()
|
155
|
-
) : (
|
156
|
-
<div className={b()}>
|
157
|
-
{this.renderOverviewStatus()}
|
158
|
-
{this.renderHealthcheckIssues()}
|
159
|
-
</div>
|
160
|
-
);
|
161
|
-
};
|
162
|
-
|
163
|
-
render() {
|
164
|
-
const {error, data, loading, wasLoaded} = this.props;
|
165
|
-
|
166
|
-
if (error) {
|
167
|
-
return <div>{error.statusText}</div>;
|
168
|
-
} else if (data && data['self_check_result']) {
|
169
|
-
return this.renderContent();
|
170
|
-
} else if (loading && !wasLoaded) {
|
171
|
-
return this.renderLoader();
|
172
|
-
} else return <div className="error">no healthcheck data</div>;
|
173
|
-
}
|
174
|
-
}
|
175
|
-
|
176
|
-
function mapStateToProps(state) {
|
177
|
-
const {data, loading, wasLoaded, error} = state.healthcheckInfo;
|
178
|
-
const {autorefresh} = state.schema;
|
179
|
-
|
180
|
-
return {
|
181
|
-
data,
|
182
|
-
loading,
|
183
|
-
wasLoaded,
|
184
|
-
error,
|
185
|
-
autorefresh,
|
186
|
-
};
|
187
|
-
}
|
188
|
-
|
189
|
-
const mapDispatchToProps = {
|
190
|
-
getHealthcheckInfo,
|
191
|
-
hideTooltip,
|
192
|
-
showTooltip,
|
193
|
-
};
|
194
|
-
|
195
|
-
export default connect(mapStateToProps, mapDispatchToProps)(Healthcheck);
|