ydb-embedded-ui 4.3.0 → 4.4.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/containers/App/Content.js +2 -8
  3. package/dist/containers/AsideNavigation/AsideNavigation.tsx +1 -1
  4. package/dist/containers/Cluster/Cluster.scss +4 -0
  5. package/dist/containers/Cluster/Cluster.tsx +14 -8
  6. package/dist/{components → containers}/ClusterInfo/ClusterInfo.scss +39 -0
  7. package/dist/containers/ClusterInfo/ClusterInfo.tsx +207 -0
  8. package/dist/containers/ClusterInfo/utils.ts +13 -0
  9. package/dist/containers/Header/Header.tsx +9 -16
  10. package/dist/containers/Nodes/Nodes.tsx +4 -6
  11. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +2 -3
  12. package/dist/containers/Tenant/Diagnostics/Partitions/Headers/Headers.tsx +4 -4
  13. package/dist/containers/Tenant/Diagnostics/Partitions/Partitions.scss +4 -0
  14. package/dist/containers/Tenant/Diagnostics/Partitions/Partitions.tsx +2 -2
  15. package/dist/containers/Tenant/Diagnostics/Partitions/PartitionsControls/PartitionsControls.tsx +20 -26
  16. package/dist/containers/Tenant/Diagnostics/Partitions/i18n/en.json +1 -1
  17. package/dist/containers/Tenant/Diagnostics/Partitions/i18n/ru.json +1 -1
  18. package/dist/containers/UserSettings/Setting.tsx +82 -0
  19. package/dist/containers/UserSettings/UserSettings.tsx +61 -99
  20. package/dist/containers/Versions/GroupedNodesTree/GroupedNodesTree.scss +59 -0
  21. package/dist/containers/Versions/GroupedNodesTree/GroupedNodesTree.tsx +98 -0
  22. package/dist/containers/Versions/NodesTable/NodesTable.tsx +150 -0
  23. package/dist/containers/Versions/NodesTreeTitle/NodesTreeTitle.scss +55 -0
  24. package/dist/containers/Versions/NodesTreeTitle/NodesTreeTitle.tsx +62 -0
  25. package/dist/containers/Versions/Versions.scss +32 -0
  26. package/dist/containers/Versions/Versions.tsx +121 -0
  27. package/dist/containers/Versions/groupNodes.ts +124 -0
  28. package/dist/containers/Versions/types.ts +16 -0
  29. package/dist/routes.ts +0 -6
  30. package/dist/services/api.ts +3 -0
  31. package/dist/store/reducers/cluster/cluster.ts +4 -0
  32. package/dist/store/reducers/cluster/types.ts +3 -2
  33. package/dist/store/reducers/clusterNodes/clusterNodes.tsx +64 -0
  34. package/dist/store/reducers/clusterNodes/types.ts +22 -0
  35. package/dist/store/reducers/index.ts +2 -8
  36. package/dist/store/reducers/partitions/partitions.ts +2 -2
  37. package/dist/store/reducers/partitions/types.ts +1 -1
  38. package/dist/types/additionalProps.ts +5 -0
  39. package/dist/types/versions.ts +9 -0
  40. package/dist/utils/constants.ts +0 -11
  41. package/dist/utils/hooks/useSetting.ts +5 -3
  42. package/dist/utils/versions/getVersionsColors.ts +98 -0
  43. package/dist/utils/versions/index.ts +3 -0
  44. package/dist/utils/versions/parseNodesToVersionsValues.ts +28 -0
  45. package/dist/utils/versions/parseVersion.ts +23 -0
  46. package/package.json +1 -1
  47. package/dist/components/ClusterInfo/ClusterInfo.tsx +0 -239
  48. package/dist/components/FullGroupViewer/FullGroupViewer.js +0 -147
  49. package/dist/components/FullGroupViewer/FullGroupViewer.scss +0 -35
  50. package/dist/components/GroupTreeViewer/GroupTreeViewer.js +0 -87
  51. package/dist/components/GroupTreeViewer/GroupTreeViewer.scss +0 -16
  52. package/dist/components/GroupViewer/GroupViewer.js +0 -100
  53. package/dist/components/GroupViewer/GroupViewer.scss +0 -45
  54. package/dist/components/PDiskViewer/PDiskViewer.js +0 -79
  55. package/dist/components/PDiskViewer/PDiskViewer.scss +0 -46
  56. package/dist/components/TabletsViewer/TabletsViewer.js +0 -44
  57. package/dist/components/TabletsViewer/TabletsViewer.scss +0 -40
  58. package/dist/components/VerticalBars/VerticalBars.scss +0 -15
  59. package/dist/components/VerticalBars/VerticalBars.tsx +0 -38
  60. package/dist/components/VerticalBars/index.ts +0 -1
  61. package/dist/containers/Group/Group.js +0 -97
  62. package/dist/containers/Group/Group.scss +0 -6
  63. package/dist/containers/Header/Host/Host.js +0 -66
  64. package/dist/containers/Header/Host/Host.scss +0 -50
  65. package/dist/containers/Pdisk/Pdisk.js +0 -156
  66. package/dist/containers/Pdisk/Pdisk.scss +0 -42
  67. package/dist/containers/Pool/Pool.js +0 -170
  68. package/dist/containers/Pool/Pool.scss +0 -35
  69. package/dist/containers/Vdisk/Vdisk.js +0 -158
  70. package/dist/containers/Vdisk/Vdisk.scss +0 -42
  71. package/dist/containers/VdiskPdiskNode/VdiskPdiskNode.js +0 -526
  72. package/dist/containers/VdiskPdiskNode/VdiskPdiskNode.scss +0 -60
  73. package/dist/store/reducers/group.js +0 -49
  74. package/dist/store/reducers/pdisk.js +0 -51
  75. package/dist/store/reducers/pool.js +0 -42
  76. package/dist/store/reducers/vdisk.js +0 -49
@@ -1,100 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import cn from 'bem-cn-lite';
4
-
5
- import EntityStatus from '../EntityStatus/EntityStatus';
6
- import ProgressViewer from '../ProgressViewer/ProgressViewer';
7
-
8
- import routes, {createHref} from '../../routes';
9
- import {formatStorageValues, formatThroughput, formatIOPS} from '../../utils';
10
-
11
- import './GroupViewer.scss';
12
-
13
- const b = cn('group-viewer');
14
-
15
- class GroupViewer extends React.Component {
16
- static propTypes = {
17
- group: PropTypes.object.isRequired,
18
- className: PropTypes.string,
19
- };
20
-
21
- static defaultProps = {
22
- className: '',
23
- };
24
-
25
- render() {
26
- const {group, className} = this.props;
27
- const {
28
- GroupID = 'no id',
29
- Overall = 'gray',
30
- VDisks,
31
- ErasureSpecies,
32
- Latency = 'gray',
33
- AcquiredIOPS,
34
- AcquiredSize,
35
- AcquiredThroughput,
36
- MaximumIOPS,
37
- MaximumSize,
38
- MaximumThroughput,
39
- } = group;
40
- if (group && Object.keys(group).length) {
41
- return (
42
- <div className={`${b()} ${className}`}>
43
- <div className={b('group')}>
44
- <EntityStatus
45
- name={GroupID}
46
- status={Overall}
47
- path={createHref(routes.group, {id: GroupID})}
48
- className={b('name')}
49
- />
50
- </div>
51
-
52
- <div className={b('latency')}>
53
- <EntityStatus name="Latency" status={Latency} />
54
- </div>
55
-
56
- <div className={b('label')}>{(VDisks && VDisks.length) || 0} Vdisks</div>
57
- <div className={b('label')}>{ErasureSpecies || 'no ErasureSpecies info'}</div>
58
- <div className={b('vdisks')}>
59
- {VDisks?.map((disk) => (
60
- <div key={disk.Guid} className={b('disk-overall')}>
61
- <EntityStatus status={disk.Overall} />
62
- </div>
63
- ))}
64
- </div>
65
-
66
- <div className={b('progress')}>
67
- <ProgressViewer
68
- value={AcquiredSize}
69
- capacity={MaximumSize}
70
- colorizeProgress={true}
71
- formatValues={formatStorageValues}
72
- />
73
- </div>
74
-
75
- <div className={b('progress')}>
76
- <ProgressViewer
77
- value={AcquiredIOPS}
78
- capacity={MaximumIOPS}
79
- colorizeProgress={true}
80
- formatValues={formatIOPS}
81
- />
82
- </div>
83
-
84
- <div className={b('progress')}>
85
- <ProgressViewer
86
- value={AcquiredThroughput}
87
- capacity={MaximumThroughput}
88
- colorizeProgress={true}
89
- formatValues={formatThroughput}
90
- />
91
- </div>
92
- </div>
93
- );
94
- } else {
95
- return <div className={b()}>No data</div>;
96
- }
97
- }
98
- }
99
-
100
- export default GroupViewer;
@@ -1,45 +0,0 @@
1
- .group-viewer {
2
- display: flex;
3
- align-items: center;
4
- &__group {
5
- margin-right: 20px;
6
- }
7
-
8
- &__label {
9
- margin-right: 20px;
10
-
11
- font-size: var(--yc-text-body-1-font-size);
12
-
13
- color: var(--yc-color-text-complementary);
14
- }
15
-
16
- &__name {
17
- display: inline-block;
18
-
19
- text-decoration: none;
20
-
21
- color: var(--yc-color-base-special);
22
-
23
- &:before {
24
- transform: translateY(3px);
25
- }
26
- }
27
-
28
- &__latency {
29
- margin-right: 20px;
30
- }
31
-
32
- &__vdisks {
33
- display: flex;
34
- }
35
-
36
- &__disk-overall {
37
- .entity-status:before {
38
- margin-right: 5px;
39
- }
40
- }
41
-
42
- &__progress {
43
- margin-right: 10px;
44
- }
45
- }
@@ -1,79 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import cn from 'bem-cn-lite';
4
-
5
- import ProgressViewer from '../ProgressViewer/ProgressViewer';
6
- import EntityStatus from '../EntityStatus/EntityStatus';
7
-
8
- import {formatStorageValues} from '../../utils';
9
- import routes, {createHref} from '../../routes';
10
-
11
- import {getDefaultNodePath} from '../../containers/Node/NodePages';
12
-
13
- import './PDiskViewer.scss';
14
-
15
- const b = cn('pdisk-viewer');
16
-
17
- class PDiskViewer extends React.Component {
18
- static propTypes = {
19
- disk: PropTypes.object.isRequired,
20
- className: PropTypes.string,
21
- };
22
-
23
- static defaultProps = {
24
- className: '',
25
- };
26
-
27
- render() {
28
- const {disk, className} = this.props;
29
-
30
- if (disk) {
31
- return (
32
- <div className={`${b()} ${className}`}>
33
- {disk && (
34
- <div className={b('item')}>
35
- <EntityStatus
36
- status={disk.Realtime}
37
- path={createHref(
38
- routes.pdisk,
39
- {id: disk.PDiskId},
40
- {node_id: disk.NodeId},
41
- )}
42
- label="PDiskID"
43
- name={disk.PDiskId}
44
- />
45
- </div>
46
- )}
47
-
48
- {disk && (
49
- <div className={b('item')}>
50
- <EntityStatus
51
- status={'green'}
52
- label="NodeID"
53
- path={getDefaultNodePath(disk.NodeId)}
54
- name={disk.NodeId}
55
- />
56
- </div>
57
- )}
58
-
59
- {disk && (
60
- <ProgressViewer
61
- value={disk.TotalSize - disk.AvailableSize || 0}
62
- capacity={disk.TotalSize || 0}
63
- formatValues={formatStorageValues}
64
- colorizeProgress={true}
65
- className={b('size')}
66
- />
67
- )}
68
- <div className={b('item')}>
69
- {disk && <div className={b('label')}>{disk.Path || 'no path'}</div>}
70
- </div>
71
- </div>
72
- );
73
- } else {
74
- return <div className="error">no PDisk data</div>;
75
- }
76
- }
77
- }
78
-
79
- export default PDiskViewer;
@@ -1,46 +0,0 @@
1
- .pdisk-viewer {
2
- display: flex;
3
- align-items: center;
4
-
5
- &__item,
6
- &__size {
7
- margin-right: 24px;
8
-
9
- font-size: var(--yc-text-body-2-font-size);
10
- line-height: 0;
11
-
12
- color: var(--yc-color-text-complementary);
13
- }
14
-
15
- &__item .entity-status {
16
- min-width: 100px;
17
- }
18
-
19
- &__item .entity-status a {
20
- overflow: initial;
21
- }
22
-
23
- &__row {
24
- display: flex;
25
- align-items: center;
26
- }
27
-
28
- &__size {
29
- width: 120px;
30
-
31
- font-size: 10px;
32
-
33
- color: var(--yc-color-text-complementary);
34
- }
35
-
36
- &__label {
37
- margin: 0 5px;
38
- &_link {
39
- display: inline-block;
40
-
41
- text-decoration: none;
42
-
43
- color: var(--yc-color-base-special);
44
- }
45
- }
46
- }
@@ -1,44 +0,0 @@
1
- import React from 'react';
2
- import cn from 'bem-cn-lite';
3
- import PropTypes from 'prop-types';
4
- import {formatNumber} from '../../utils';
5
- import './TabletsViewer.scss';
6
-
7
- import {TABLET_STATES} from '../../utils/constants';
8
-
9
- const b = cn('tablets-viewer');
10
-
11
- const prepareStates = (states) => {
12
- return states.map((state) => {
13
- return {
14
- label: TABLET_STATES[state.VolatileState],
15
- count: formatNumber(state.Count),
16
- };
17
- });
18
- };
19
-
20
- class TabletsViewer extends React.Component {
21
- static propTypes = {
22
- tablets: PropTypes.array,
23
- };
24
- renderTabletInfo = (item, index) => {
25
- return (
26
- <div key={index} className={b('row')}>
27
- <div className={b('tablet-label')}>{item.label}</div>
28
- <span>{item.count}</span>
29
- </div>
30
- );
31
- };
32
- render() {
33
- const {tablets = []} = this.props;
34
- const preparedStates = prepareStates(tablets);
35
-
36
- return (
37
- <div className={b()}>
38
- <div className={b('grid')}>{preparedStates.map(this.renderTabletInfo)}</div>
39
- </div>
40
- );
41
- }
42
- }
43
-
44
- export default TabletsViewer;
@@ -1,40 +0,0 @@
1
- .tablets-viewer {
2
- &__grid {
3
- display: grid;
4
- grid-gap: 8px;
5
-
6
- grid-template-columns: repeat(auto-fill, 125px);
7
- }
8
-
9
- &__row {
10
- display: flex;
11
- align-items: center;
12
-
13
- margin: 0;
14
- }
15
-
16
- &__tablet-label {
17
- min-width: 60px;
18
- margin-right: 20px;
19
-
20
- font-size: var(--yc-text-body-1-font-size);
21
- line-height: 18px;
22
- white-space: nowrap;
23
- text-transform: capitalize;
24
-
25
- color: var(--yc-color-text-hint);
26
-
27
- .yc-root_theme_dark & {
28
- color: var(--yc-color-text-hint);
29
- }
30
- }
31
-
32
- &__title {
33
- margin: 0;
34
- margin-bottom: 16px;
35
-
36
- font-size: var(--yc-text-body-2-font-size);
37
- font-weight: bold;
38
- line-height: 20px;
39
- }
40
- }
@@ -1,15 +0,0 @@
1
- .ydb-bars {
2
- display: flex;
3
- flex-direction: row;
4
- align-items: flex-end;
5
-
6
- height: 20px;
7
-
8
- &__value {
9
- width: 6px;
10
- min-height: 3px;
11
- margin-right: 2px;
12
-
13
- background-color: var(--yc-color-infographics-info-heavy);
14
- }
15
- }
@@ -1,38 +0,0 @@
1
- import cn from 'bem-cn-lite';
2
- import {useMemo} from 'react';
3
-
4
- import './VerticalBars.scss';
5
-
6
- const b = cn('ydb-bars');
7
-
8
- const calculateValuesInPercents = (values: number[]) => {
9
- const max = Math.max(...values);
10
-
11
- if (!max) {
12
- return values;
13
- }
14
-
15
- const res = [];
16
-
17
- for (const value of values) {
18
- res.push((value / max) * 100);
19
- }
20
-
21
- return res;
22
- };
23
-
24
- interface VerticalBarsProps {
25
- values: number[];
26
- }
27
-
28
- export const VerticalBars = ({values}: VerticalBarsProps) => {
29
- const preparedValues = useMemo(() => calculateValuesInPercents(values), [values]);
30
-
31
- const getBars = () => {
32
- return preparedValues.map((value, index) => {
33
- return <div key={index} style={{height: `${value}%`}} className={b('value')} />;
34
- });
35
- };
36
-
37
- return <div className={b()}>{getBars()}</div>;
38
- };
@@ -1 +0,0 @@
1
- export * from './VerticalBars';
@@ -1,97 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import cn from 'bem-cn-lite';
4
- import {connect} from 'react-redux';
5
- import {getGroupInfo, clearStore} from '../../store/reducers/group';
6
- import FullGroupViewer from '../../components/FullGroupViewer/FullGroupViewer';
7
- import {Loader} from '@gravity-ui/uikit';
8
- import {GROUP_AUTO_RELOAD_INTERVAL} from '../../utils/constants';
9
- import './Group.scss';
10
-
11
- const b = cn('group');
12
-
13
- class Group extends React.Component {
14
- static renderLoader() {
15
- return (
16
- <div className={'loader'}>
17
- <Loader size="l" />
18
- </div>
19
- );
20
- }
21
-
22
- static propTypes = {
23
- className: PropTypes.string,
24
- loading: PropTypes.bool,
25
- wasLoaded: PropTypes.bool,
26
- error: PropTypes.bool,
27
- getGroupInfo: PropTypes.func,
28
- clearStore: PropTypes.func,
29
- group: PropTypes.object,
30
- location: PropTypes.object,
31
- match: PropTypes.object,
32
- };
33
-
34
- static defaultProps = {
35
- className: '',
36
- };
37
-
38
- componentDidMount() {
39
- const {id} = this.props.match.params;
40
- this.props.getGroupInfo(id);
41
- this.reloadDescriptor = setInterval(
42
- () => this.props.getGroupInfo(id),
43
- GROUP_AUTO_RELOAD_INTERVAL,
44
- );
45
- }
46
-
47
- componentWillUnmount() {
48
- this.props.clearStore();
49
- clearInterval(this.reloadDescriptor);
50
- }
51
-
52
- renderContent = () => {
53
- const {className, group} = this.props;
54
- return (
55
- <div className={`${b()} ${className}`}>
56
- <FullGroupViewer group={group} />
57
- </div>
58
- );
59
- };
60
-
61
- render() {
62
- const {loading, wasLoaded, error, group} = this.props;
63
-
64
- if (loading && !wasLoaded) {
65
- return Group.renderLoader();
66
- } else if (error) {
67
- return <div>{error.statusText}</div>;
68
- } else if (group) {
69
- return this.renderContent();
70
- } else {
71
- return <div className="error">no data</div>;
72
- }
73
- }
74
- }
75
-
76
- const mapStateToProps = (state) => {
77
- const {data, wasLoaded, loading, error} = state.group;
78
-
79
- let group;
80
- if (data) {
81
- group = data.StoragePools[0].Groups[0];
82
- }
83
-
84
- return {
85
- group,
86
- wasLoaded,
87
- loading,
88
- error,
89
- };
90
- };
91
-
92
- const mapDispatchToProps = {
93
- getGroupInfo,
94
- clearStore,
95
- };
96
-
97
- export default connect(mapStateToProps, mapDispatchToProps)(Group);
@@ -1,6 +0,0 @@
1
- @import '../../styles/mixins';
2
-
3
- .group {
4
- overflow: auto;
5
- @include flex-container();
6
- }
@@ -1,66 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import cn from 'bem-cn-lite';
4
-
5
- import {Link as ExternalLink} from '@gravity-ui/uikit';
6
-
7
- import EntityStatus from '../../../components/EntityStatus/EntityStatus';
8
- import {Tag} from '../../../components/Tag';
9
-
10
- import {calcUptime} from '../../../utils';
11
- import {customBackend} from '../../../store';
12
-
13
- import './Host.scss';
14
-
15
- const b = cn('host');
16
-
17
- export default class Host extends React.Component {
18
- static propTypes = {
19
- host: PropTypes.object,
20
- singleClusterMode: PropTypes.bool,
21
- };
22
-
23
- renderStatus = () => {
24
- const {host} = this.props;
25
-
26
- return (
27
- <div className={b('status')}>
28
- <EntityStatus size="m" status={host.SystemState} name={'Internal viewer'} />
29
- </div>
30
- );
31
- };
32
-
33
- render() {
34
- const {host, backend, singleClusterMode} = this.props;
35
- const uptime = calcUptime(host.StartTime);
36
-
37
- let link = backend + '/internal';
38
-
39
- if (singleClusterMode && !customBackend) {
40
- link = `/internal`;
41
- }
42
-
43
- return (
44
- <div className={b()}>
45
- <div className={b('common')}>
46
- {link ? (
47
- <ExternalLink href={link}>{this.renderStatus()}</ExternalLink>
48
- ) : (
49
- this.renderStatus()
50
- )}
51
- <Tag text={host.DataCenter} />
52
- </div>
53
- <div className={b('info')}>
54
- <div className={b('info-item')}>
55
- <div className={b('label')}>Uptime</div>
56
- <div className={b('value')}>{uptime}</div>
57
- </div>
58
- <div className={b('info-item')}>
59
- <div className={b('label')}>Version</div>
60
- <div className={b('value')}>{host.Version}</div>
61
- </div>
62
- </div>
63
- </div>
64
- );
65
- }
66
- }
@@ -1,50 +0,0 @@
1
- .host {
2
- display: flex;
3
- flex-direction: column;
4
-
5
- &__common {
6
- display: flex;
7
- align-items: center;
8
-
9
- margin-bottom: 4px;
10
- }
11
- &__status {
12
- display: flex;
13
-
14
- margin-right: 15px;
15
-
16
- font-size: var(--yc-text-body-2-font-size);
17
- line-height: var(--yc-text-body-2-line-height);
18
- }
19
- &__info {
20
- display: flex;
21
- align-items: center;
22
- }
23
- &__info-item {
24
- display: flex;
25
-
26
- margin-right: 20px;
27
-
28
- &:last-child {
29
- margin-right: 0;
30
- }
31
- }
32
- &__label {
33
- margin-right: 10px;
34
-
35
- font-size: var(--yc-text-body-1-font-size);
36
- line-height: var(--yc-text-body-1-line-height);
37
-
38
- color: var(--yc-color-text-hint);
39
-
40
- .yc-root_theme_dark & {
41
- color: var(--yc-color-text-hint);
42
- }
43
- }
44
- &__value {
45
- font-size: var(--yc-text-body-1-font-size);
46
- line-height: var(--yc-text-body-1-line-height);
47
-
48
- color: var(--yc-color-text-primary);
49
- }
50
- }