ydb-embedded-ui 1.3.0 → 1.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 +43 -0
- package/README.md +1 -1
- package/dist/components/EntityStatus/EntityStatus.scss +2 -3
- package/dist/containers/App/App.scss +1 -1
- package/dist/containers/App/NodesTable.scss +7 -6
- package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +10 -1
- package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +36 -54
- package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.scss +7 -5
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +1 -0
- package/dist/containers/Tenants/Tenants.js +11 -6
- package/dist/containers/Tenants/Tenants.scss +7 -1
- package/dist/store/reducers/settings.js +5 -1
- package/dist/utils/constants.js +2 -0
- package/dist/utils/getNodesColumns.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,48 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### [1.4.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.4.1...v1.4.2) (2022-05-23)
|
4
|
+
|
5
|
+
|
6
|
+
### UI Updates
|
7
|
+
|
8
|
+
* **QueryEditor:** replace warning for query losing with note about how query are saved ([89820ca](https://github.com/ydb-platform/ydb-embedded-ui/commit/89820ca7e2d02f880eb81d484b8947d599798d5f))
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* **QueryEditor:** confirm query deletion with enter ([d3dadbd](https://github.com/ydb-platform/ydb-embedded-ui/commit/d3dadbd0244fead5f41bd98445669c4f5ce23c43))
|
14
|
+
* **QueryEditor:** field autofocus in query save dialog ([9225238](https://github.com/ydb-platform/ydb-embedded-ui/commit/92252384dc68c40191f7898fff9a2c1106b0b2f1))
|
15
|
+
* **QueryEditor:** save query with enter ([5f9c450](https://github.com/ydb-platform/ydb-embedded-ui/commit/5f9c450aedc90f0e162515294a74000c006f9be7))
|
16
|
+
|
17
|
+
### [1.4.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.4.0...v1.4.1) (2022-05-17)
|
18
|
+
|
19
|
+
|
20
|
+
### UI Updates
|
21
|
+
|
22
|
+
* **Tenant:** add tenant name wrapper ([8176d28](https://github.com/ydb-platform/ydb-embedded-ui/commit/8176d28a5769b2b95d667ed960ad34d7a0d9bb4c))
|
23
|
+
|
24
|
+
|
25
|
+
### Bug Fixes
|
26
|
+
|
27
|
+
* **NodesTable:** align external link icon ([a379796](https://github.com/ydb-platform/ydb-embedded-ui/commit/a379796c6b8087f25f95ce3db4be33f18da71e04))
|
28
|
+
|
29
|
+
## [1.4.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.3.0...v1.4.0) (2022-05-16)
|
30
|
+
|
31
|
+
|
32
|
+
### Features
|
33
|
+
|
34
|
+
* **Tenant:** save initial tab preference ([7195d0f](https://github.com/ydb-platform/ydb-embedded-ui/commit/7195d0f7f5754c461555211515f80ea96464ca15))
|
35
|
+
|
36
|
+
|
37
|
+
### UI Updtaes
|
38
|
+
|
39
|
+
* **NodesTable:** don't reserve space for icons next to node fqdn ([8fcf1b3](https://github.com/ydb-platform/ydb-embedded-ui/commit/8fcf1b3269dee7ada83d7c5abcf44ad004191851))
|
40
|
+
|
41
|
+
|
42
|
+
### Bug Fixes
|
43
|
+
|
44
|
+
* **Tenant:** mapDispatchToProps types ([7dcaf56](https://github.com/ydb-platform/ydb-embedded-ui/commit/7dcaf561ec0c361d52d789b2ea3b1aba75339d83))
|
45
|
+
|
3
46
|
## [1.3.0](https://www.github.com/ydb-platform/ydb-embedded-ui/compare/v1.2.6...v1.3.0) (2022-05-12)
|
4
47
|
|
5
48
|
|
package/README.md
CHANGED
@@ -8,7 +8,7 @@ Local viewer for YDB clusters
|
|
8
8
|
|
9
9
|
1) Run on a machine with Docker installed:
|
10
10
|
```
|
11
|
-
docker pull cr.yandex/yc/yandex-docker-local-ydb
|
11
|
+
docker pull cr.yandex/yc/yandex-docker-local-ydb
|
12
12
|
docker run --hostname localhost -e YDB_ALLOW_ORIGIN="http://localhost:3000" -dp 2135:2135 -dp 8765:8765 cr.yandex/yc/yandex-docker-local-ydb
|
13
13
|
```
|
14
14
|
2) Run the frontend app in the development mode, via invoking `npm run dev`
|
@@ -9,8 +9,7 @@
|
|
9
9
|
line-height: var(--yc-text-body2-line-height);
|
10
10
|
|
11
11
|
&__clipboard-button {
|
12
|
-
display:
|
13
|
-
visibility: hidden;
|
12
|
+
display: none;
|
14
13
|
align-items: center;
|
15
14
|
|
16
15
|
margin-left: 8px;
|
@@ -22,7 +21,7 @@
|
|
22
21
|
}
|
23
22
|
|
24
23
|
&_visible {
|
25
|
-
|
24
|
+
display: flex;
|
26
25
|
}
|
27
26
|
}
|
28
27
|
|
@@ -1,25 +1,26 @@
|
|
1
1
|
.kv-nodes {
|
2
|
+
&__host-name-wrapper {
|
3
|
+
display: flex;
|
4
|
+
}
|
5
|
+
|
2
6
|
&__external-button {
|
3
|
-
display:
|
4
|
-
visibility: hidden;
|
7
|
+
display: none;
|
5
8
|
align-items: center;
|
6
9
|
|
7
10
|
margin-left: 4px;
|
8
11
|
|
9
|
-
transform: translateY(-1px);
|
10
|
-
|
11
12
|
.yc-button__text {
|
12
13
|
margin: 0 4px;
|
13
14
|
}
|
14
15
|
}
|
15
16
|
|
16
17
|
&__host-name {
|
17
|
-
|
18
|
+
overflow: hidden;
|
18
19
|
}
|
19
20
|
}
|
20
21
|
|
21
22
|
.data-table__row:hover {
|
22
23
|
.kv-nodes__external-button {
|
23
|
-
|
24
|
+
display: inline-flex;
|
24
25
|
}
|
25
26
|
}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import {connect} from 'react-redux';
|
1
2
|
import {Link} from 'react-router-dom';
|
2
3
|
import cn from 'bem-cn-lite';
|
3
4
|
import {useLocation} from 'react-router';
|
@@ -11,6 +12,8 @@ import Diagnostics from '../Diagnostics/Diagnostics';
|
|
11
12
|
|
12
13
|
import {TenantGeneralTabsIds, TenantTabsGroups, TENANT_GENERAL_TABS} from '../TenantPages';
|
13
14
|
import routes, {createHref} from '../../../routes';
|
15
|
+
import {setSettingValue} from '../../../store/reducers/settings';
|
16
|
+
import {TENANT_INITIAL_TAB_KEY} from '../../../utils/constants';
|
14
17
|
|
15
18
|
import './ObjectGeneral.scss';
|
16
19
|
|
@@ -20,6 +23,7 @@ interface ObjectGeneralProps {
|
|
20
23
|
type: string;
|
21
24
|
additionalTenantInfo?: any;
|
22
25
|
additionalNodesInfo?: any;
|
26
|
+
setSettingValue: (name: string, value: string) => void;
|
23
27
|
}
|
24
28
|
|
25
29
|
function ObjectGeneral(props: ObjectGeneralProps) {
|
@@ -63,6 +67,7 @@ function ObjectGeneral(props: ObjectGeneralProps) {
|
|
63
67
|
);
|
64
68
|
}}
|
65
69
|
allowNotSelected
|
70
|
+
onSelectTab={(id) => props.setSettingValue(TENANT_INITIAL_TAB_KEY, id)}
|
66
71
|
/>
|
67
72
|
</div>
|
68
73
|
);
|
@@ -101,4 +106,8 @@ function ObjectGeneral(props: ObjectGeneralProps) {
|
|
101
106
|
return renderContent();
|
102
107
|
}
|
103
108
|
|
104
|
-
|
109
|
+
const mapDispatchToProps = {
|
110
|
+
setSettingValue,
|
111
|
+
};
|
112
|
+
|
113
|
+
export default connect(null, mapDispatchToProps)(ObjectGeneral);
|
@@ -1,31 +1,24 @@
|
|
1
|
-
import React, {useState
|
1
|
+
import React, {useState} from 'react';
|
2
2
|
import _ from 'lodash';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
4
|
import {useDispatch, useSelector} from 'react-redux';
|
5
|
-
import {Dialog, DropdownMenu,
|
5
|
+
import {Dialog, DropdownMenu, TextInput, Button} from '@yandex-cloud/uikit';
|
6
6
|
|
7
|
-
import Icon from '../../../../components/Icon/Icon';
|
8
7
|
import {setQueryNameToEdit} from '../../../../store/reducers/saveQuery';
|
9
8
|
|
10
9
|
import './SaveQuery.scss';
|
11
10
|
|
12
11
|
const b = cn('kv-save-query');
|
13
12
|
|
14
|
-
const EMBEDDED_VERSION_WARNING =
|
15
|
-
'Please be aware: after cookies delete your saved queries will be lost.';
|
16
|
-
|
17
13
|
function SaveQuery({savedQueries, onSaveQuery, saveButtonDisabled}) {
|
18
14
|
const singleClusterMode = useSelector((state) => state.singleClusterMode);
|
19
15
|
const [isDialogVisible, setIsDialogVisible] = useState(false);
|
20
|
-
const [isEmbeddedWarningVisible, setIsEmbeddedWarningVisible] = useState(false);
|
21
16
|
const [queryName, setQueryName] = useState('');
|
22
17
|
const [validationError, setValidationError] = useState(null);
|
23
18
|
|
24
19
|
const queryNameToEdit = useSelector((state) => state.saveQuery);
|
25
20
|
const dispatch = useDispatch();
|
26
21
|
|
27
|
-
const warningRef = useRef();
|
28
|
-
|
29
22
|
const onSaveQueryClick = () => {
|
30
23
|
setIsDialogVisible(true);
|
31
24
|
dispatch(setQueryNameToEdit(null));
|
@@ -42,13 +35,6 @@ function SaveQuery({savedQueries, onSaveQuery, saveButtonDisabled}) {
|
|
42
35
|
setValidationError(validateQueryName(value));
|
43
36
|
};
|
44
37
|
|
45
|
-
const onEmbeddedWarningOpen = () => {
|
46
|
-
setIsEmbeddedWarningVisible(true);
|
47
|
-
};
|
48
|
-
const onEmbeddedWarningClose = () => {
|
49
|
-
setIsEmbeddedWarningVisible(false);
|
50
|
-
};
|
51
|
-
|
52
38
|
const validateQueryName = (value) => {
|
53
39
|
if (_.some(savedQueries, (q) => q.name.toLowerCase() === value.trim().toLowerCase())) {
|
54
40
|
return 'This name already exists';
|
@@ -57,9 +43,11 @@ function SaveQuery({savedQueries, onSaveQuery, saveButtonDisabled}) {
|
|
57
43
|
};
|
58
44
|
|
59
45
|
const onSaveClick = () => {
|
60
|
-
if (queryName
|
61
|
-
|
46
|
+
if (!queryName || validationError) {
|
47
|
+
return;
|
62
48
|
}
|
49
|
+
|
50
|
+
onSaveQuery(queryName);
|
63
51
|
onCloseDialog();
|
64
52
|
};
|
65
53
|
|
@@ -70,18 +58,38 @@ function SaveQuery({savedQueries, onSaveQuery, saveButtonDisabled}) {
|
|
70
58
|
|
71
59
|
const renderDialog = () => {
|
72
60
|
return (
|
73
|
-
<Dialog
|
61
|
+
<Dialog
|
62
|
+
open={isDialogVisible}
|
63
|
+
hasCloseButton={false}
|
64
|
+
size="s"
|
65
|
+
onClose={onCloseDialog}
|
66
|
+
onEnterKeyDown={onSaveClick}
|
67
|
+
>
|
74
68
|
<Dialog.Header caption="Save query" />
|
75
69
|
<Dialog.Body className={b('dialog-body')}>
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
70
|
+
{singleClusterMode && (
|
71
|
+
<div className={b('dialog-row')}>
|
72
|
+
The query will be saved in your browser
|
73
|
+
</div>
|
74
|
+
)}
|
75
|
+
<div className={b('dialog-row')}>
|
76
|
+
<label
|
77
|
+
htmlFor="queryName"
|
78
|
+
className={b('field-title', 'required')}
|
79
|
+
>
|
80
|
+
Query name
|
81
|
+
</label>
|
82
|
+
<div className={b('control-wrapper')}>
|
83
|
+
<TextInput
|
84
|
+
id="queryName"
|
85
|
+
placeholder="Enter query name"
|
86
|
+
text={queryName}
|
87
|
+
onUpdate={onQueryNameChange}
|
88
|
+
hasClear
|
89
|
+
autoFocus
|
90
|
+
/>
|
91
|
+
<span className={b('error')}>{validationError}</span>
|
92
|
+
</div>
|
85
93
|
</div>
|
86
94
|
</Dialog.Body>
|
87
95
|
<Dialog.Footer
|
@@ -121,36 +129,10 @@ function SaveQuery({savedQueries, onSaveQuery, saveButtonDisabled}) {
|
|
121
129
|
);
|
122
130
|
};
|
123
131
|
|
124
|
-
const renderEmbeddedVersionWarning = () => {
|
125
|
-
return (
|
126
|
-
<React.Fragment>
|
127
|
-
<Popup
|
128
|
-
className={b('embedded-popup')}
|
129
|
-
anchorRef={warningRef}
|
130
|
-
placement={['top']}
|
131
|
-
open={isEmbeddedWarningVisible}
|
132
|
-
hasArrow
|
133
|
-
>
|
134
|
-
{EMBEDDED_VERSION_WARNING}
|
135
|
-
</Popup>
|
136
|
-
<div
|
137
|
-
className={b('embedded-tooltip')}
|
138
|
-
ref={warningRef}
|
139
|
-
onMouseEnter={onEmbeddedWarningOpen}
|
140
|
-
onMouseLeave={onEmbeddedWarningClose}
|
141
|
-
>
|
142
|
-
<Icon name="question" height={18} width={18} viewBox="0 0 24 24" />
|
143
|
-
</div>
|
144
|
-
</React.Fragment>
|
145
|
-
);
|
146
|
-
};
|
147
|
-
|
148
132
|
return (
|
149
133
|
<React.Fragment>
|
150
134
|
{queryNameToEdit ? renderSaveDropdownMenu() : renderSaveButton(onSaveQueryClick)}
|
151
135
|
{isDialogVisible && renderDialog()}
|
152
|
-
|
153
|
-
{singleClusterMode && renderEmbeddedVersionWarning()}
|
154
136
|
</React.Fragment>
|
155
137
|
);
|
156
138
|
}
|
@@ -1,17 +1,19 @@
|
|
1
|
-
@import '../../../../styles/mixins.scss';
|
2
|
-
|
3
1
|
.kv-save-query {
|
4
|
-
&__dialog-
|
2
|
+
&__dialog-row {
|
5
3
|
display: flex;
|
6
4
|
align-items: flex-start;
|
5
|
+
|
6
|
+
& + & {
|
7
|
+
margin-top: var(--yc-text-body-line-height);
|
8
|
+
}
|
7
9
|
}
|
8
10
|
&__field-title {
|
9
11
|
margin-right: 12px;
|
10
12
|
|
11
13
|
font-weight: 500;
|
12
|
-
line-height:
|
14
|
+
line-height: 28px;
|
13
15
|
white-space: nowrap;
|
14
|
-
|
16
|
+
|
15
17
|
&.required {
|
16
18
|
&::after {
|
17
19
|
content: '*';
|
@@ -71,6 +71,7 @@ function SavedQueries({savedQueries, changeUserInput, onDeleteQuery}) {
|
|
71
71
|
hasCloseButton={false}
|
72
72
|
size="s"
|
73
73
|
onClose={onClickCancelDelete}
|
74
|
+
onEnterKeyDown={onConfirmDeleteClick}
|
74
75
|
>
|
75
76
|
<Dialog.Header caption="Delete query" />
|
76
77
|
<Dialog.Body className={b('dialog-body')}>
|
@@ -17,9 +17,9 @@ import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
|
17
17
|
import {formatCPU, formatBytesToGigabyte} from '../../utils';
|
18
18
|
import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
|
19
19
|
import {withSearch} from '../../HOCS';
|
20
|
-
import {ALL, DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
|
20
|
+
import {ALL, DEFAULT_TABLE_SETTINGS, TENANT_INITIAL_TAB_KEY} from '../../utils/constants';
|
21
21
|
import {getTenantsInfo} from '../../store/reducers/tenants';
|
22
|
-
import {changeFilter} from '../../store/reducers/settings';
|
22
|
+
import {changeFilter, getSettingValue} from '../../store/reducers/settings';
|
23
23
|
import {setHeader} from '../../store/reducers/header';
|
24
24
|
|
25
25
|
import {clusterName} from '../../store';
|
@@ -119,6 +119,7 @@ class Tenants extends React.Component {
|
|
119
119
|
filter,
|
120
120
|
handleSearchQuery,
|
121
121
|
additionalTenantsInfo = {},
|
122
|
+
savedTenantInitialTab,
|
122
123
|
} = this.props;
|
123
124
|
|
124
125
|
const filteredTenantsBySearch = tenants.filter(
|
@@ -129,6 +130,9 @@ class Tenants extends React.Component {
|
|
129
130
|
);
|
130
131
|
const filteredTenants = Tenants.filterTenants(filteredTenantsBySearch, filter);
|
131
132
|
|
133
|
+
const initialTenantGeneralTab = savedTenantInitialTab || TENANT_GENERAL_TABS[0].id;
|
134
|
+
const initialTenantInfoTab = TENANT_INFO_TABS[0].id;
|
135
|
+
|
132
136
|
const columns = [
|
133
137
|
{
|
134
138
|
name: 'Name',
|
@@ -140,7 +144,7 @@ class Tenants extends React.Component {
|
|
140
144
|
: undefined;
|
141
145
|
const isExternalLink = Boolean(backend);
|
142
146
|
return (
|
143
|
-
<
|
147
|
+
<div className={b('name-wrapper')}>
|
144
148
|
<EntityStatus
|
145
149
|
externalLink={isExternalLink}
|
146
150
|
className={b('name')}
|
@@ -150,12 +154,12 @@ class Tenants extends React.Component {
|
|
150
154
|
path={createHref(routes.tenant, undefined, {
|
151
155
|
name: value,
|
152
156
|
backend: tenantBackend,
|
153
|
-
[TenantTabsGroups.info]:
|
154
|
-
[TenantTabsGroups.general]:
|
157
|
+
[TenantTabsGroups.info]: initialTenantInfoTab,
|
158
|
+
[TenantTabsGroups.general]: initialTenantGeneralTab,
|
155
159
|
})}
|
156
160
|
/>
|
157
161
|
{additionalTenantsInfo.name && additionalTenantsInfo.name(value, row)}
|
158
|
-
</
|
162
|
+
</div>
|
159
163
|
);
|
160
164
|
},
|
161
165
|
width: 440,
|
@@ -347,6 +351,7 @@ const mapStateToProps = (state) => {
|
|
347
351
|
loading,
|
348
352
|
error,
|
349
353
|
filter: state.settings.problemFilter,
|
354
|
+
savedTenantInitialTab: getSettingValue(state, TENANT_INITIAL_TAB_KEY),
|
350
355
|
};
|
351
356
|
};
|
352
357
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {ALL, defaultUserSettings, SAVED_QUERIES_KEY, THEME_KEY} from '../../utils/constants';
|
1
|
+
import {ALL, defaultUserSettings, SAVED_QUERIES_KEY, THEME_KEY, TENANT_INITIAL_TAB_KEY} from '../../utils/constants';
|
2
2
|
import '../../services/api';
|
3
3
|
import {getValueFromLS} from '../../utils/utils';
|
4
4
|
|
@@ -13,6 +13,9 @@ const theme = window.web_version
|
|
13
13
|
const savedQueries = window.web_version
|
14
14
|
? userSettings[SAVED_QUERIES_KEY]
|
15
15
|
: getValueFromLS(SAVED_QUERIES_KEY, '[]');
|
16
|
+
const savedTenantGeneralTab = window.web_version
|
17
|
+
? userSettings[TENANT_INITIAL_TAB_KEY]
|
18
|
+
: getValueFromLS(TENANT_INITIAL_TAB_KEY);
|
16
19
|
|
17
20
|
export const initialState = {
|
18
21
|
problemFilter: ALL,
|
@@ -21,6 +24,7 @@ export const initialState = {
|
|
21
24
|
...userSettings,
|
22
25
|
theme,
|
23
26
|
[SAVED_QUERIES_KEY]: savedQueries,
|
27
|
+
[TENANT_INITIAL_TAB_KEY]: savedTenantGeneralTab,
|
24
28
|
},
|
25
29
|
systemSettings,
|
26
30
|
};
|
package/dist/utils/constants.js
CHANGED
@@ -31,7 +31,7 @@ export function getNodesColumns({showTooltip, hideTooltip, tabletsPath, getNodeR
|
|
31
31
|
return <span>—</span>;
|
32
32
|
}
|
33
33
|
return (
|
34
|
-
<
|
34
|
+
<div className={b('host-name-wrapper')}>
|
35
35
|
<EntityStatus
|
36
36
|
name={row.Host}
|
37
37
|
status={row.Overall}
|
@@ -44,7 +44,7 @@ export function getNodesColumns({showTooltip, hideTooltip, tabletsPath, getNodeR
|
|
44
44
|
<Icon name="external" />
|
45
45
|
</Button>
|
46
46
|
)}
|
47
|
-
</
|
47
|
+
</div>
|
48
48
|
);
|
49
49
|
},
|
50
50
|
width: '350px',
|