ydb-embedded-ui 2.2.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/assets/icons/shield.svg +3 -0
  3. package/dist/components/Errors/403/AccessDenied.tsx +19 -0
  4. package/dist/components/Errors/403/index.ts +1 -0
  5. package/dist/components/Errors/i18n/en.json +4 -0
  6. package/dist/components/Errors/i18n/index.ts +11 -0
  7. package/dist/components/Errors/i18n/ru.json +4 -0
  8. package/dist/components/NodesViewer/NodesViewer.js +1 -1
  9. package/dist/components/QueryResultTable/QueryResultTable.tsx +16 -21
  10. package/dist/{containers/Storage/StorageFilter/StorageFilter.tsx → components/Search/Search.tsx} +22 -22
  11. package/dist/components/Search/index.ts +1 -0
  12. package/dist/containers/App/App.scss +5 -1
  13. package/dist/containers/Nodes/Nodes.js +6 -1
  14. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +7 -5
  15. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -11
  16. package/dist/containers/Storage/Pdisk/Pdisk.scss +15 -8
  17. package/dist/containers/Storage/Pdisk/Pdisk.tsx +22 -14
  18. package/dist/containers/Storage/Storage.js +39 -50
  19. package/dist/containers/Storage/StorageGroups/StorageGroups.scss +1 -4
  20. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +27 -2
  21. package/dist/containers/Storage/StorageGroups/i18n/en.json +2 -1
  22. package/dist/containers/Storage/StorageGroups/i18n/ru.json +2 -1
  23. package/dist/containers/Storage/StorageNodes/StorageNodes.scss +14 -12
  24. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +7 -5
  25. package/dist/containers/Storage/Vdisk/Vdisk.js +36 -23
  26. package/dist/containers/Storage/Vdisk/Vdisk.scss +6 -0
  27. package/dist/containers/TabletsFilters/TabletsFilters.js +5 -0
  28. package/dist/containers/Tenant/Diagnostics/Consumers/Consumers.scss +6 -0
  29. package/dist/containers/Tenant/Diagnostics/Consumers/Consumers.tsx +82 -0
  30. package/dist/containers/Tenant/Diagnostics/Consumers/i18n/en.json +6 -0
  31. package/dist/containers/Tenant/Diagnostics/Consumers/i18n/index.ts +11 -0
  32. package/dist/containers/Tenant/Diagnostics/Consumers/i18n/ru.json +6 -0
  33. package/dist/containers/Tenant/Diagnostics/Consumers/index.ts +1 -0
  34. package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +7 -0
  35. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +29 -11
  36. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +15 -8
  37. package/dist/containers/Tenant/Diagnostics/Healthcheck/Details/Details.tsx +55 -0
  38. package/dist/containers/Tenant/Diagnostics/Healthcheck/Details/index.ts +1 -0
  39. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +5 -5
  40. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +16 -6
  41. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/{IssueViewer.scss → IssueTree.scss} +3 -54
  42. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssueTree.tsx +87 -0
  43. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssueTreeItem/IssueTreeItem.scss +50 -0
  44. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssueTreeItem/IssueTreeItem.tsx +25 -0
  45. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssueTreeItem/index.ts +1 -0
  46. package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/Preview.tsx +13 -16
  47. package/dist/containers/Tenant/Diagnostics/Healthcheck/{IssuePreview/IssuePreview.tsx → Preview/PreviewItem/PreviewItem.tsx} +6 -8
  48. package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/PreviewItem/index.ts +1 -0
  49. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +34 -19
  50. package/dist/containers/Tenant/Preview/Preview.scss +6 -0
  51. package/dist/containers/Tenant/QueryEditor/QueryEditor.js +1 -9
  52. package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.scss +2 -2
  53. package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +1 -1
  54. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +27 -20
  55. package/dist/containers/Tenant/Tenant.tsx +14 -16
  56. package/dist/containers/Tenants/Tenants.js +1 -1
  57. package/dist/store/reducers/describe.ts +71 -0
  58. package/dist/store/reducers/healthcheckInfo.ts +123 -0
  59. package/dist/store/reducers/olapStats.js +13 -0
  60. package/dist/store/reducers/schema.js +43 -1
  61. package/dist/store/reducers/storage.js +27 -17
  62. package/dist/store/reducers/tenant.js +3 -1
  63. package/dist/store/utils.ts +21 -13
  64. package/dist/styles/mixins.scss +1 -1
  65. package/dist/types/api/consumers.ts +3 -0
  66. package/dist/types/api/healthcheck.ts +1 -1
  67. package/dist/types/api/storage.ts +35 -10
  68. package/dist/types/store/healthcheck.ts +5 -1
  69. package/dist/types/store/storage.ts +1 -0
  70. package/dist/utils/hooks/useAutofetcher.ts +9 -3
  71. package/package.json +1 -1
  72. package/dist/containers/Storage/StorageFilter/index.ts +0 -1
  73. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuePreview/index.ts +0 -1
  74. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/IssuesList.tsx +0 -62
  75. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/index.ts +0 -1
  76. package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesViewer/IssuesViewer.js +0 -151
  77. package/dist/store/reducers/describe.js +0 -45
  78. package/dist/store/reducers/healthcheckInfo.js +0 -45
@@ -1,3 +1,7 @@
1
- import type {HealthCheckAPIResponse} from "../api/healthcheck";
1
+ import type {HealthCheckAPIResponse, IssueLog} from '../api/healthcheck';
2
+
3
+ export interface IIssuesTree extends IssueLog {
4
+ reasonsItems?: IIssuesTree[];
5
+ }
2
6
 
3
7
  export type IHealthCheck = HealthCheckAPIResponse;
@@ -8,4 +8,5 @@ export interface IStoragePoolGroup extends TBSGroupStateInfo {
8
8
  Limit: number;
9
9
  Missing: number;
10
10
  UsedSpaceFlag: number;
11
+ Type: string | null;
11
12
  }
@@ -2,7 +2,11 @@ import {DependencyList, useEffect, useRef} from 'react';
2
2
 
3
3
  import {AutoFetcher} from '../autofetcher';
4
4
 
5
- export const useAutofetcher = (fetchData: VoidFunction, deps: DependencyList, enabled = true) => {
5
+ export const useAutofetcher = (
6
+ fetchData: (isBackground: boolean) => void,
7
+ deps: DependencyList,
8
+ enabled = true,
9
+ ) => {
6
10
  const ref = useRef<AutoFetcher | null>(null);
7
11
 
8
12
  if (ref.current === null) {
@@ -12,14 +16,16 @@ export const useAutofetcher = (fetchData: VoidFunction, deps: DependencyList, en
12
16
  const autofetcher = ref.current;
13
17
 
14
18
  // initial fetch
15
- useEffect(fetchData, deps); // eslint-disable-line react-hooks/exhaustive-deps
19
+ useEffect(() => {
20
+ fetchData(false);
21
+ }, deps); // eslint-disable-line react-hooks/exhaustive-deps
16
22
 
17
23
  useEffect(() => {
18
24
  autofetcher.stop();
19
25
 
20
26
  if (enabled) {
21
27
  autofetcher.start();
22
- autofetcher.fetch(fetchData);
28
+ autofetcher.fetch(() => fetchData(true));
23
29
  }
24
30
 
25
31
  return () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "2.2.1",
3
+ "version": "2.4.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -1 +0,0 @@
1
- export * from './StorageFilter';
@@ -1 +0,0 @@
1
- export * from './IssuePreview';
@@ -1,62 +0,0 @@
1
- import cn from 'bem-cn-lite';
2
-
3
- import {Button, Icon} from '@gravity-ui/uikit';
4
-
5
- import updateArrow from '../../../../../assets/icons/update-arrow.svg';
6
-
7
- import type {IHealthCheck} from '../../../../../types/store/healthcheck';
8
-
9
- import IssuesViewer from '../IssuesViewer/IssuesViewer';
10
-
11
- import i18n from '../i18n';
12
-
13
- const b = cn('healthcheck');
14
-
15
- interface IssuesListProps {
16
- data?: IHealthCheck;
17
- loading?: boolean;
18
- expandedIssueId?: string;
19
- onUpdate: VoidFunction;
20
- }
21
-
22
- export const IssuesList = (props: IssuesListProps) => {
23
- const {data, loading, onUpdate, expandedIssueId} = props;
24
-
25
- if (!data) {
26
- return null;
27
- }
28
-
29
- const renderHealthcheckHeader = () => {
30
- return (
31
- <div className={b('issues-list-header')}>
32
- <h3 className={b('issues-list-header-title')}>{i18n('title.healthcheck')}</h3>
33
- <div className={b('issues-list-header-update')}>
34
- <Button size="s" onClick={onUpdate} loading={loading} view="flat-secondary">
35
- <Icon data={updateArrow} height={20} width={20} />
36
- </Button>
37
- </div>
38
- </div>
39
- );
40
- };
41
-
42
- const renderHealthcheckIssues = () => {
43
- const {issue_log: issueLog} = data;
44
-
45
- if (!issueLog) {
46
- return null;
47
- }
48
-
49
- return (
50
- <div className={b('issues')}>
51
- <IssuesViewer issues={issueLog} expandedIssueId={expandedIssueId} />
52
- </div>
53
- );
54
- };
55
-
56
- return (
57
- <div className={b('issues-list')}>
58
- {renderHealthcheckHeader()}
59
- {renderHealthcheckIssues()}
60
- </div>
61
- );
62
- };
@@ -1 +0,0 @@
1
- export * from './IssuesList';
@@ -1,151 +0,0 @@
1
- import {useCallback, useEffect, useState} from 'react';
2
- import cn from 'bem-cn-lite';
3
- import JSONTree from 'react-json-inspector';
4
- import _ from 'lodash';
5
- import _flow from 'lodash/fp/flow';
6
- import _filter from 'lodash/fp/filter';
7
- import _sortBy from 'lodash/fp/sortBy';
8
- import _uniqBy from 'lodash/fp/uniqBy';
9
-
10
- import {TreeView} from 'ydb-ui-components';
11
-
12
- import EntityStatus from '../../../../../components/EntityStatus/EntityStatus';
13
-
14
- import './IssueViewer.scss';
15
-
16
- const issueBlock = cn('issue');
17
-
18
- const IssueRow = ({data, onClick}) => {
19
- const {status, message, type} = data;
20
-
21
- return (
22
- <div className={issueBlock()} onClick={onClick}>
23
- <div className={issueBlock('field', {status: true})}>
24
- <EntityStatus mode="icons" status={status} name={type} />
25
- </div>
26
- <div className={issueBlock('field', {message: true})}>{message}</div>
27
- </div>
28
- );
29
- };
30
-
31
- const issueViewerBlock = cn('issue-viewer');
32
-
33
- const IssuesViewer = ({issues, expandedIssueId}) => {
34
- const [data, setData] = useState([]);
35
- const [collapsedIssues, setCollapsedIssues] = useState({});
36
-
37
- useEffect(() => {
38
- const newData = getInvertedConsequencesTree({data: issues});
39
-
40
- setData(newData);
41
- }, [issues]);
42
-
43
- const renderTree = useCallback(
44
- (data, childrenKey) => {
45
- return _.map(data, (item) => {
46
- const {id} = item;
47
-
48
- // eslint-disable-next-line no-unused-vars
49
- const {status, message, type, reasonsItems, reason, level, ...rest} = item;
50
-
51
- if (level === 1 && expandedIssueId && id !== expandedIssueId) {
52
- return;
53
- }
54
-
55
- const isCollapsed =
56
- typeof collapsedIssues[id] === 'undefined' || collapsedIssues[id];
57
-
58
- const toggleCollapsed = () => {
59
- setCollapsedIssues((collapsedIssues) => ({
60
- ...collapsedIssues,
61
- [id]: !isCollapsed,
62
- }));
63
- };
64
-
65
- return (
66
- <TreeView
67
- key={id}
68
- name={<IssueRow data={item} />}
69
- collapsed={isCollapsed}
70
- hasArrow={true}
71
- onClick={toggleCollapsed}
72
- onArrowClick={toggleCollapsed}
73
- level={level - 1}
74
- >
75
- {renderInfoPanel(rest)}
76
- {renderTree(item[childrenKey], childrenKey)}
77
- </TreeView>
78
- );
79
- });
80
- },
81
- [data, collapsedIssues],
82
- );
83
-
84
- const renderInfoPanel = useCallback(
85
- (info) => {
86
- if (!info) {
87
- return null;
88
- }
89
-
90
- return (
91
- <div className={issueViewerBlock('info-panel')}>
92
- <JSONTree
93
- data={info}
94
- search={false}
95
- isExpanded={() => true}
96
- className={issueViewerBlock('inspector')}
97
- />
98
- </div>
99
- );
100
- },
101
- [data],
102
- );
103
-
104
- return (
105
- <div className={issueViewerBlock()}>
106
- <div className={issueViewerBlock('tree')}>{renderTree(data, 'reasonsItems')}</div>
107
- </div>
108
- );
109
- };
110
-
111
- function getReasonsForIssue({issue, data}) {
112
- return _.filter(data, (item) => issue.reason && issue.reason.indexOf(item.id) !== -1);
113
- }
114
-
115
- const mapStatusToPriority = {
116
- RED: 0,
117
- ORANGE: 1,
118
- YELLOW: 2,
119
- BLUE: 3,
120
- GREEN: 4,
121
- };
122
-
123
- function getInvertedConsequencesTree({data, roots: receivedRoots}) {
124
- let roots = receivedRoots;
125
- if (!roots && data) {
126
- roots = _flow([
127
- _filter((item) => {
128
- return !_.find(
129
- data,
130
- (issue) => issue.reason && issue.reason.indexOf(item.id) !== -1,
131
- );
132
- }),
133
- _uniqBy((item) => item.id),
134
- _sortBy(({status}) => mapStatusToPriority[status]),
135
- ])(data);
136
- }
137
-
138
- return _.map(roots, (issue) => {
139
- const reasonsItems = getInvertedConsequencesTree({
140
- roots: getReasonsForIssue({issue, data}),
141
- data,
142
- });
143
-
144
- return {
145
- ...issue,
146
- reasonsItems,
147
- };
148
- });
149
- }
150
-
151
- export default IssuesViewer;
@@ -1,45 +0,0 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
2
- import '../../services/api';
3
-
4
- const FETCH_DESCRIBE = createRequestActionTypes('describe', 'FETCH_DESCRIBE');
5
-
6
- const describe = function z(state = {loading: false, wasLoaded: false, data: {}}, action) {
7
- switch (action.type) {
8
- case FETCH_DESCRIBE.REQUEST: {
9
- return {
10
- ...state,
11
- loading: true,
12
- };
13
- }
14
- case FETCH_DESCRIBE.SUCCESS: {
15
- const newData = JSON.parse(JSON.stringify(state.data));
16
- newData[action.data.Path] = action.data;
17
- return {
18
- ...state,
19
- data: newData,
20
- currentDescribe: action.data,
21
- loading: false,
22
- wasLoaded: true,
23
- error: undefined,
24
- };
25
- }
26
- case FETCH_DESCRIBE.FAILURE: {
27
- return {
28
- ...state,
29
- error: action.error,
30
- loading: false,
31
- };
32
- }
33
- default:
34
- return state;
35
- }
36
- };
37
-
38
- export function getDescribe({path}) {
39
- return createApiRequest({
40
- request: window.api.getDescribe({path}),
41
- actions: FETCH_DESCRIBE,
42
- });
43
- }
44
-
45
- export default describe;
@@ -1,45 +0,0 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
2
- import '../../services/api';
3
-
4
- const FETCH_HEALTHCHECK = createRequestActionTypes('cluster', 'FETCH_HEALTHCHECK');
5
-
6
- const initialState = {loading: false, wasLoaded: false};
7
- const healthcheckInfo = function (state = initialState, action) {
8
- switch (action.type) {
9
- case FETCH_HEALTHCHECK.REQUEST: {
10
- return {
11
- ...state,
12
- loading: true,
13
- };
14
- }
15
- case FETCH_HEALTHCHECK.SUCCESS: {
16
- const {data} = action;
17
-
18
- return {
19
- ...state,
20
- data,
21
- wasLoaded: true,
22
- loading: false,
23
- error: undefined,
24
- };
25
- }
26
- case FETCH_HEALTHCHECK.FAILURE: {
27
- return {
28
- ...state,
29
- error: action.error,
30
- loading: false,
31
- };
32
- }
33
- default:
34
- return state;
35
- }
36
- };
37
-
38
- export function getHealthcheckInfo(database) {
39
- return createApiRequest({
40
- request: window.api.getHealthcheckInfo(database),
41
- actions: FETCH_HEALTHCHECK,
42
- });
43
- }
44
-
45
- export default healthcheckInfo;