ydb-embedded-ui 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/assets/icons/update-arrow.svg +6 -0
  3. package/dist/components/EntityStatus/EntityStatus.js +37 -10
  4. package/dist/components/EntityStatus/EntityStatus.scss +36 -6
  5. package/dist/components/NodesViewer/NodesViewer.js +1 -0
  6. package/dist/components/ShortyString/ShortyString.tsx +21 -8
  7. package/dist/components/ShortyString/i18n/en.json +10 -0
  8. package/dist/components/ShortyString/i18n/index.ts +11 -0
  9. package/dist/components/ShortyString/i18n/ru.json +10 -0
  10. package/dist/containers/Cluster/Cluster.tsx +3 -3
  11. package/dist/containers/Nodes/Nodes.js +6 -6
  12. package/dist/containers/Storage/StorageFilter/StorageFilter.tsx +1 -0
  13. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +2 -2
  14. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +16 -9
  15. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +18 -5
  16. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +83 -0
  17. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuePreview/IssuePreview.tsx +35 -0
  18. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuePreview/index.ts +1 -0
  19. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/IssuesList.tsx +62 -0
  20. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/index.ts +1 -0
  21. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssueViewer.scss +21 -15
  22. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssuesViewer.js +52 -86
  23. package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/Preview.tsx +74 -0
  24. package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/index.ts +1 -0
  25. package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/en.json +7 -0
  26. package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/index.ts +11 -0
  27. package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/ru.json +7 -0
  28. package/dist/containers/Tenant/Diagnostics/Healthcheck/index.ts +1 -0
  29. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +4 -21
  30. package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +18 -19
  31. package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.scss +1 -0
  32. package/dist/containers/Tenant/Tenant.tsx +2 -2
  33. package/dist/containers/Tenants/Tenants.js +7 -7
  34. package/dist/services/api.d.ts +9 -0
  35. package/dist/types/api/healthcheck.ts +91 -0
  36. package/dist/types/store/healthcheck.ts +3 -0
  37. package/dist/utils/hooks/index.ts +1 -0
  38. package/dist/utils/hooks/useAutofetcher.ts +29 -0
  39. package/package.json +4 -1
  40. 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,3 @@
1
+ import type {HealthCheckAPIResponse} from "../api/healthcheck";
2
+
3
+ export type IHealthCheck = HealthCheckAPIResponse;
@@ -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.0.0",
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);