ydb-embedded-ui 4.23.0 → 4.25.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 (31) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +11 -79
  3. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +0 -51
  4. package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx +5 -12
  5. package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +1 -10
  6. package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.scss +3 -16
  7. package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx +4 -27
  8. package/dist/containers/Tenant/Query/i18n/en.json +0 -2
  9. package/dist/containers/Tenant/Query/i18n/ru.json +0 -2
  10. package/dist/containers/Tenant/utils/schemaActions.ts +11 -18
  11. package/dist/containers/UserSettings/i18n/en.json +1 -7
  12. package/dist/containers/UserSettings/i18n/ru.json +1 -7
  13. package/dist/containers/UserSettings/settings.ts +1 -19
  14. package/dist/services/api.ts +2 -2
  15. package/dist/store/reducers/settings/settings.ts +14 -16
  16. package/dist/utils/constants.ts +0 -11
  17. package/dist/utils/hooks/useQueryModes.ts +3 -32
  18. package/dist/utils/query.ts +0 -4
  19. package/dist/utils/settings.ts +4 -1
  20. package/package.json +1 -1
  21. package/dist/containers/Tenant/Diagnostics/OldHealthcheck/Details/Details.tsx +0 -64
  22. package/dist/containers/Tenant/Diagnostics/OldHealthcheck/Details/index.ts +0 -1
  23. package/dist/containers/Tenant/Diagnostics/OldHealthcheck/Healthcheck.scss +0 -137
  24. package/dist/containers/Tenant/Diagnostics/OldHealthcheck/Healthcheck.tsx +0 -92
  25. package/dist/containers/Tenant/Diagnostics/OldHealthcheck/Preview/Preview.tsx +0 -82
  26. package/dist/containers/Tenant/Diagnostics/OldHealthcheck/Preview/index.ts +0 -1
  27. package/dist/containers/Tenant/Diagnostics/OldHealthcheck/index.ts +0 -1
  28. package/dist/containers/Tenant/Diagnostics/TenantOverview/OldTenantOverview.tsx +0 -155
  29. package/dist/utils/hooks/i18n/en.json +0 -3
  30. package/dist/utils/hooks/i18n/index.ts +0 -11
  31. package/dist/utils/hooks/i18n/ru.json +0 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.25.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.24.0...v4.25.0) (2023-12-07)
4
+
5
+
6
+ ### Features
7
+
8
+ * **Diagnostics:** remove tenant diagnostics cards setting ([#602](https://github.com/ydb-platform/ydb-embedded-ui/issues/602)) ([fe61df8](https://github.com/ydb-platform/ydb-embedded-ui/commit/fe61df86048013432c4e4788d1e621298ecb1fb2))
9
+ * **Query:** remove query modes setting ([#600](https://github.com/ydb-platform/ydb-embedded-ui/issues/600)) ([78c63e4](https://github.com/ydb-platform/ydb-embedded-ui/commit/78c63e4a2e60950970914eaba49304b68aad0f80))
10
+
11
+ ## [4.24.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.23.0...v4.24.0) (2023-12-07)
12
+
13
+
14
+ ### Features
15
+
16
+ * always use localStorage if no settingsApi ([#603](https://github.com/ydb-platform/ydb-embedded-ui/issues/603)) ([ff692df](https://github.com/ydb-platform/ydb-embedded-ui/commit/ff692dffa99d278f6b261bbf1aac0ee24c661a6d))
17
+
3
18
  ## [4.23.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.22.0...v4.23.0) (2023-12-06)
4
19
 
5
20
 
@@ -1,18 +1,10 @@
1
- import React, {useState} from 'react';
2
1
  import {useSelector} from 'react-redux';
3
2
  import cn from 'bem-cn-lite';
4
3
 
5
- import {Button, Modal} from '@gravity-ui/uikit';
6
-
7
4
  import type {EPathType} from '../../../../types/api/schema';
8
5
  import type {AdditionalNodesProps, AdditionalTenantsProps} from '../../../../types/additionalProps';
9
- import {Icon} from '../../../../components/Icon';
10
- import {useSetting} from '../../../../utils/hooks';
11
- import {DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS} from '../../../../utils/constants';
12
6
  import Overview from '../Overview/Overview';
13
- import {Healthcheck} from '../OldHealthcheck';
14
7
  import {TenantOverview} from '../TenantOverview/TenantOverview';
15
- import {OldTenantOverview} from '../TenantOverview/OldTenantOverview';
16
8
 
17
9
  import './DetailedOverview.scss';
18
10
 
@@ -29,86 +21,26 @@ const b = cn('kv-detailed-overview');
29
21
  function DetailedOverview(props: DetailedOverviewProps) {
30
22
  const {type, tenantName, additionalTenantProps, additionalNodesProps} = props;
31
23
 
32
- const [isModalVisible, setIsModalVisible] = useState(false);
33
-
34
24
  const {currentSchemaPath} = useSelector((state: any) => state.schema);
35
25
 
36
- const [displayMetricsCards] = useSetting(DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS);
37
-
38
- const openModalHandler = () => {
39
- setIsModalVisible(true);
40
- };
41
-
42
- const closeModalHandler = () => {
43
- setIsModalVisible(false);
44
- };
45
-
46
- const renderModal = () => {
47
- return (
48
- <Modal open={isModalVisible} onClose={closeModalHandler} className={b('modal')}>
49
- <Healthcheck tenant={props.tenantName} fetchData={false} />
50
- <Button
51
- className={b('close-modal-button')}
52
- onClick={closeModalHandler}
53
- view="flat-secondary"
54
- title="Close"
55
- >
56
- <Icon name="close" viewBox={'0 0 16 16 '} height={20} width={20} />
57
- </Button>
58
- </Modal>
59
- );
60
- };
61
-
62
26
  const renderTenantOverview = () => {
63
- if (displayMetricsCards) {
64
- return (
65
- <div className={b('section')}>
66
- <TenantOverview
67
- tenantName={tenantName}
68
- additionalTenantProps={additionalTenantProps}
69
- additionalNodesProps={additionalNodesProps}
70
- />
71
- </div>
72
- );
73
- }
74
-
75
- return (
76
- <>
77
- <div className={b('section')}>
78
- <OldTenantOverview
79
- tenantName={tenantName}
80
- additionalTenantProps={additionalTenantProps}
81
- />
82
- </div>
83
- <div className={b('section')}>
84
- <Healthcheck
85
- tenant={tenantName}
86
- preview={true}
87
- showMoreHandler={openModalHandler}
88
- />
89
- </div>
90
- </>
91
- );
92
- };
93
-
94
- const renderContent = () => {
95
- const isTenant = tenantName === currentSchemaPath;
96
27
  return (
97
- <div className={b()}>
98
- {isTenant ? (
99
- renderTenantOverview()
100
- ) : (
101
- <Overview type={type} tenantName={tenantName} />
102
- )}
28
+ <div className={b('section')}>
29
+ <TenantOverview
30
+ tenantName={tenantName}
31
+ additionalTenantProps={additionalTenantProps}
32
+ additionalNodesProps={additionalNodesProps}
33
+ />
103
34
  </div>
104
35
  );
105
36
  };
106
37
 
38
+ const isTenant = tenantName === currentSchemaPath;
39
+
107
40
  return (
108
- <React.Fragment>
109
- {renderContent()}
110
- {renderModal()}
111
- </React.Fragment>
41
+ <div className={b()}>
42
+ {isTenant ? renderTenantOverview() : <Overview type={type} tenantName={tenantName} />}
43
+ </div>
112
44
  );
113
45
  }
114
46
 
@@ -33,57 +33,6 @@
33
33
  gap: 10px;
34
34
  }
35
35
 
36
- &__common-info {
37
- display: flex;
38
- gap: 20px;
39
-
40
- flex-direction: column;
41
- justify-content: flex-start;
42
- align-items: stretch;
43
- }
44
-
45
- &__system-tablets {
46
- display: flex;
47
- flex-wrap: wrap;
48
- align-items: center;
49
-
50
- margin-bottom: 35px;
51
- }
52
-
53
- &__collapse-title {
54
- font-size: var(--yc-text-body-2-font-size);
55
- font-weight: 500;
56
- line-height: var(--yc-text-body-2-line-height);
57
- }
58
-
59
- &__section {
60
- border-radius: 10px;
61
-
62
- &_metrics {
63
- .info-viewer__label {
64
- min-width: 150px;
65
- }
66
- .info-viewer__value {
67
- min-width: 100px;
68
- }
69
- }
70
-
71
- &_pools {
72
- display: grid;
73
- grid-gap: 7px 20px;
74
-
75
- grid-template-columns: 110px 110px;
76
- }
77
- }
78
-
79
- &__section-title {
80
- margin-bottom: 20px;
81
-
82
- font-size: var(--yc-text-body-2-font-size);
83
- font-weight: 600;
84
- line-height: var(--yc-text-body-2-line-height);
85
- }
86
-
87
36
  &__info {
88
37
  position: sticky;
89
38
  left: 0;
@@ -9,7 +9,7 @@ import {setQueryTab} from '../../../../store/reducers/tenant/tenant';
9
9
  import {selectQueriesHistory} from '../../../../store/reducers/executeQuery';
10
10
  import {TENANT_QUERY_TABS_ID} from '../../../../store/reducers/tenant/constants';
11
11
  import {useQueryModes, useTypedSelector} from '../../../../utils/hooks';
12
- import {QUERY_MODES, QUERY_MODES_TITLES, QUERY_SYNTAX} from '../../../../utils/query';
12
+ import {QUERY_MODES, QUERY_SYNTAX} from '../../../../utils/query';
13
13
  import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants';
14
14
 
15
15
  import i18n from '../i18n';
@@ -31,22 +31,15 @@ function QueriesHistory({changeUserInput}: QueriesHistoryProps) {
31
31
  const reversedHistory = [...queriesHistory].reverse();
32
32
 
33
33
  const onQueryClick = (query: QueryInHistory) => {
34
- let isQueryModeSet = true;
35
-
36
34
  if (query.syntax === QUERY_SYNTAX.pg && queryMode !== QUERY_MODES.pg) {
37
- isQueryModeSet = setQueryMode(
38
- QUERY_MODES.pg,
39
- i18n('history.cannot-set-mode', {mode: QUERY_MODES_TITLES[QUERY_MODES.pg]}),
40
- );
35
+ setQueryMode(QUERY_MODES.pg);
41
36
  } else if (query.syntax !== QUERY_SYNTAX.pg && queryMode === QUERY_MODES.pg) {
42
37
  // Set query mode for queries with yql syntax
43
- isQueryModeSet = setQueryMode(QUERY_MODES.script);
38
+ setQueryMode(QUERY_MODES.script);
44
39
  }
45
40
 
46
- if (isQueryModeSet) {
47
- changeUserInput({input: query.queryText});
48
- dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
49
- }
41
+ changeUserInput({input: query.queryText});
42
+ dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
50
43
  };
51
44
 
52
45
  const columns: Column<QueryInHistory>[] = [
@@ -23,12 +23,11 @@ import {
23
23
  DEFAULT_IS_QUERY_RESULT_COLLAPSED,
24
24
  DEFAULT_SIZE_RESULT_PANE_KEY,
25
25
  SAVED_QUERIES_KEY,
26
- ENABLE_ADDITIONAL_QUERY_MODES,
27
26
  LAST_USED_QUERY_ACTION_KEY,
28
27
  QUERY_USE_MULTI_SCHEMA_KEY,
29
28
  } from '../../../../utils/constants';
30
29
  import {useSetting, useQueryModes} from '../../../../utils/hooks';
31
- import {QUERY_ACTIONS, QUERY_MODES, isNewQueryMode} from '../../../../utils/query';
30
+ import {QUERY_ACTIONS} from '../../../../utils/query';
32
31
 
33
32
  import {
34
33
  PaneVisibilityActionTypes,
@@ -85,16 +84,9 @@ function QueryEditor(props) {
85
84
 
86
85
  const [isResultLoaded, setIsResultLoaded] = useState(false);
87
86
  const [queryMode, setQueryMode] = useQueryModes();
88
- const [enableAdditionalQueryModes] = useSetting(ENABLE_ADDITIONAL_QUERY_MODES);
89
87
  const [useMultiSchema] = useSetting(QUERY_USE_MULTI_SCHEMA_KEY);
90
88
  const [lastUsedQueryAction, setLastUsedQueryAction] = useSetting(LAST_USED_QUERY_ACTION_KEY);
91
89
 
92
- useEffect(() => {
93
- if (isNewQueryMode(queryMode) && !enableAdditionalQueryModes) {
94
- setQueryMode(QUERY_MODES.script);
95
- }
96
- }, [enableAdditionalQueryModes, queryMode, setQueryMode]);
97
-
98
90
  useEffect(() => {
99
91
  if (savedPath !== path) {
100
92
  if (savedPath) {
@@ -470,7 +462,6 @@ function QueryEditor(props) {
470
462
  disabled={!executeQuery.input}
471
463
  onUpdateQueryMode={setQueryMode}
472
464
  queryMode={queryMode}
473
- enableAdditionalQueryModes={enableAdditionalQueryModes}
474
465
  highlitedAction={lastUsedQueryAction}
475
466
  />
476
467
  );
@@ -27,7 +27,7 @@
27
27
  $b: &;
28
28
 
29
29
  &__button {
30
- width: 189px;
30
+ width: 241px;
31
31
  margin-left: 2px;
32
32
  }
33
33
 
@@ -36,24 +36,11 @@
36
36
  justify-content: space-between;
37
37
  align-items: center;
38
38
 
39
- width: 163px;
39
+ width: 215px;
40
40
  }
41
41
 
42
42
  &__popup {
43
- width: 189px;
44
-
45
- &_extended {
46
- width: 241px;
47
- }
48
- }
49
-
50
- &_extended {
51
- #{$b}__button {
52
- width: 241px;
53
- }
54
- #{$b}__button-content {
55
- width: 215px;
56
- }
43
+ width: 241px;
57
44
  }
58
45
  }
59
46
 
@@ -19,17 +19,6 @@ const queryModeSelectorPopupQa = 'query-mode-selector-popup';
19
19
 
20
20
  const b = block('ydb-query-editor-controls');
21
21
 
22
- const OldQueryModeSelectorOptions = {
23
- [QUERY_MODES.script]: {
24
- title: QUERY_MODES_TITLES[QUERY_MODES.script],
25
- description: i18n('method-description.script'),
26
- },
27
- [QUERY_MODES.scan]: {
28
- title: QUERY_MODES_TITLES[QUERY_MODES.scan],
29
- description: i18n('method-description.scan'),
30
- },
31
- } as const;
32
-
33
22
  const QueryModeSelectorOptions = {
34
23
  [QUERY_MODES.script]: {
35
24
  title: QUERY_MODES_TITLES[QUERY_MODES.script],
@@ -63,7 +52,6 @@ interface QueryEditorControlsProps {
63
52
  disabled: boolean;
64
53
  onUpdateQueryMode: (mode: QueryMode) => void;
65
54
  queryMode: QueryMode;
66
- enableAdditionalQueryModes: boolean;
67
55
  highlitedAction: QueryAction;
68
56
  }
69
57
 
@@ -78,14 +66,9 @@ export const QueryEditorControls = ({
78
66
  onUpdateQueryMode,
79
67
  queryMode,
80
68
  highlitedAction,
81
- enableAdditionalQueryModes,
82
69
  }: QueryEditorControlsProps) => {
83
70
  const querySelectorMenuItems = useMemo(() => {
84
- const options = enableAdditionalQueryModes
85
- ? QueryModeSelectorOptions
86
- : OldQueryModeSelectorOptions;
87
-
88
- return Object.entries(options).map(([mode, {title, description}]) => {
71
+ return Object.entries(QueryModeSelectorOptions).map(([mode, {title, description}]) => {
89
72
  return {
90
73
  text: (
91
74
  <LabelWithPopover
@@ -100,7 +83,7 @@ export const QueryEditorControls = ({
100
83
  },
101
84
  };
102
85
  });
103
- }, [onUpdateQueryMode, enableAdditionalQueryModes]);
86
+ }, [onUpdateQueryMode]);
104
87
 
105
88
  const runView: ButtonView | undefined = highlitedAction === 'execute' ? 'action' : undefined;
106
89
  const explainView: ButtonView | undefined =
@@ -132,17 +115,11 @@ export const QueryEditorControls = ({
132
115
  >
133
116
  Explain
134
117
  </Button>
135
- <div
136
- className={b('mode-selector', {
137
- extended: enableAdditionalQueryModes,
138
- })}
139
- >
118
+ <div className={b('mode-selector')}>
140
119
  <DropdownMenu
141
120
  items={querySelectorMenuItems}
142
121
  popupProps={{
143
- className: b('mode-selector__popup', {
144
- extended: enableAdditionalQueryModes,
145
- }),
122
+ className: b('mode-selector__popup'),
146
123
  qa: queryModeSelectorPopupQa,
147
124
  }}
148
125
  switcher={
@@ -8,8 +8,6 @@
8
8
  "history.empty": "History is empty",
9
9
  "saved.empty": "There are no saved queries",
10
10
 
11
- "history.cannot-set-mode": "This query is available only with '{{mode}}' query mode. You need to turn in additional query modes in settings to enable it",
12
-
13
11
  "delete-dialog.header": "Delete query",
14
12
  "delete-dialog.question": "Are you sure you want to delete query",
15
13
  "delete-dialog.delete": "Delete",
@@ -8,8 +8,6 @@
8
8
  "history.empty": "История пуста",
9
9
  "saved.empty": "Нет сохраненных запросов",
10
10
 
11
- "history.cannot-set-mode": "Этот запрос доступен только в режиме '{{mode}}'. Вам необходимо включить дополнительные режимы выполнения запросов в настройках",
12
-
13
11
  "delete-dialog.header": "Удалить запрос",
14
12
  "delete-dialog.question": "Вы уверены что хотите удалить запрос",
15
13
  "delete-dialog.delete": "Удалить",
@@ -4,7 +4,6 @@ import copy from 'copy-to-clipboard';
4
4
  import type {NavigationTreeNodeType, NavigationTreeProps} from 'ydb-ui-components';
5
5
 
6
6
  import type {QueryMode} from '../../../types/store/query';
7
- import type {SetQueryModeIfAvailable} from '../../../utils/hooks';
8
7
  import {changeUserInput} from '../../../store/reducers/executeQuery';
9
8
  import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
10
9
  import {TENANT_QUERY_TABS_ID, TENANT_PAGES_IDS} from '../../../store/reducers/tenant/constants';
@@ -25,7 +24,7 @@ import {
25
24
  } from './queryTemplates';
26
25
 
27
26
  interface ActionsAdditionalEffects {
28
- setQueryMode: SetQueryModeIfAvailable;
27
+ setQueryMode: (mode: QueryMode) => void;
29
28
  setActivePath: (path: string) => void;
30
29
  }
31
30
 
@@ -36,18 +35,16 @@ const bindActions = (
36
35
  ) => {
37
36
  const {setActivePath, setQueryMode} = additionalEffects;
38
37
 
39
- const inputQuery =
40
- (tmpl: (path: string) => string, mode?: QueryMode, setQueryModeErrorMessage?: string) =>
41
- () => {
42
- const isNewQueryModeSet = mode && setQueryMode(mode, setQueryModeErrorMessage);
38
+ const inputQuery = (tmpl: (path: string) => string, mode?: QueryMode) => () => {
39
+ if (mode) {
40
+ setQueryMode(mode);
41
+ }
43
42
 
44
- if (!mode || isNewQueryModeSet) {
45
- dispatch(changeUserInput({input: tmpl(path)}));
46
- dispatch(setTenantPage(TENANT_PAGES_IDS.query));
47
- dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
48
- setActivePath(path);
49
- }
50
- };
43
+ dispatch(changeUserInput({input: tmpl(path)}));
44
+ dispatch(setTenantPage(TENANT_PAGES_IDS.query));
45
+ dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
46
+ setActivePath(path);
47
+ };
51
48
 
52
49
  return {
53
50
  createTable: inputQuery(createTableTemplate, 'script'),
@@ -56,11 +53,7 @@ const bindActions = (
56
53
  upsertQuery: inputQuery(upsertQueryTemplate),
57
54
  createExternalTable: inputQuery(createExternalTableTemplate, 'script'),
58
55
  dropExternalTable: inputQuery(dropExternalTableTemplate, 'script'),
59
- selectQueryFromExternalTable: inputQuery(
60
- selectQueryTemplate,
61
- 'query',
62
- i18n('actions.externalTableSelectUnavailable'),
63
- ),
56
+ selectQueryFromExternalTable: inputQuery(selectQueryTemplate, 'query'),
64
57
  createTopic: inputQuery(createTopicTemplate, 'script'),
65
58
  alterTopic: inputQuery(alterTopicTemplate, 'script'),
66
59
  dropTopic: inputQuery(dropTopicTemplate, 'script'),
@@ -22,12 +22,6 @@
22
22
  "settings.useBackendParamsForTables.title": "Use virtual table for cluster Nodes tab",
23
23
  "settings.useBackendParamsForTables.popover": "Use table with data load on scroll. It will increase performance, but could work unstable",
24
24
 
25
- "settings.enableAdditionalQueryModes.title": "Enable additional query modes",
26
- "settings.enableAdditionalQueryModes.popover": "Adds 'Data', 'YQL - QueryService' and 'PostgreSQL' modes. May not work on some versions",
27
-
28
25
  "settings.queryUseMultiSchema.title": "Allow queries with multiple result sets",
29
- "settings.queryUseMultiSchema.popover": "Use 'multi' schema for queries that enables queries with multiple result sets. Returns nothing on versions 23-3 and older",
30
-
31
- "settings.tenantDiagnostics.title": "Display metrics cards for database diagnostics",
32
- "settings.tenantDiagnostics.popover": "Adds indicators of database resources usage. Incomplete data may be displayed for some databases"
26
+ "settings.queryUseMultiSchema.popover": "Use 'multi' schema for queries that enables queries with multiple result sets. Returns nothing on versions 23-3 and older"
33
27
  }
@@ -22,12 +22,6 @@
22
22
  "settings.useBackendParamsForTables.title": "Использовать виртуализированную таблицу для вкладки Nodes кластера",
23
23
  "settings.useBackendParamsForTables.popover": "Использовать таблицу с загрузкой данных по скроллу. Это улучшит производительность, но может работать нестабильно",
24
24
 
25
- "settings.enableAdditionalQueryModes.title": "Включить дополнительные режимы выполнения запросов",
26
- "settings.enableAdditionalQueryModes.popover": "Добавляет режимы 'Data', 'YQL - QueryService' и 'PostgreSQL'. Может работать некорректно на некоторых версиях",
27
-
28
25
  "settings.queryUseMultiSchema.title": "Разрешить запросы с несколькими результатами",
29
- "settings.queryUseMultiSchema.popover": "Использовать для запросов схему 'multi', которая позволяет выполнять запросы с несколькими результатами. На версиях 23-3 и старше результат не возвращается вообще",
30
-
31
- "settings.tenantDiagnostics.title": "Показывать карточки с метриками в диагностике базы данных",
32
- "settings.tenantDiagnostics.popover": "Добавляет индикаторы использования ресурсов базы данных. Для некоторых баз могут отображаться неполные данные"
26
+ "settings.queryUseMultiSchema.popover": "Использовать для запросов схему 'multi', которая позволяет выполнять запросы с несколькими результатами. На версиях 23-3 и старше результат не возвращается вообще"
33
27
  }
@@ -4,8 +4,6 @@ import favoriteFilledIcon from '../../assets/icons/star.svg';
4
4
  import flaskIcon from '../../assets/icons/flask.svg';
5
5
 
6
6
  import {
7
- ENABLE_ADDITIONAL_QUERY_MODES,
8
- DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS,
9
7
  INVERTED_DISKS_KEY,
10
8
  LANGUAGE_KEY,
11
9
  THEME_KEY,
@@ -91,21 +89,11 @@ export const useBackendParamsForTables: SettingProps = {
91
89
  title: i18n('settings.useBackendParamsForTables.title'),
92
90
  helpPopoverContent: i18n('settings.useBackendParamsForTables.popover'),
93
91
  };
94
- export const enableQueryModesForExplainSetting: SettingProps = {
95
- settingKey: ENABLE_ADDITIONAL_QUERY_MODES,
96
- title: i18n('settings.enableAdditionalQueryModes.title'),
97
- helpPopoverContent: i18n('settings.enableAdditionalQueryModes.popover'),
98
- };
99
92
  export const queryUseMultiSchemaSetting: SettingProps = {
100
93
  settingKey: QUERY_USE_MULTI_SCHEMA_KEY,
101
94
  title: i18n('settings.queryUseMultiSchema.title'),
102
95
  helpPopoverContent: i18n('settings.queryUseMultiSchema.popover'),
103
96
  };
104
- export const enableNewTenantDiagnosticsDesign: SettingProps = {
105
- settingKey: DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS,
106
- title: i18n('settings.tenantDiagnostics.title'),
107
- helpPopoverContent: i18n('settings.tenantDiagnostics.popover'),
108
- };
109
97
 
110
98
  export const appearanceSection: SettingsSection = {
111
99
  id: 'appearanceSection',
@@ -115,13 +103,7 @@ export const appearanceSection: SettingsSection = {
115
103
  export const experimentsSection: SettingsSection = {
116
104
  id: 'experimentsSection',
117
105
  title: i18n('section.experiments'),
118
- settings: [
119
- useNodesEndpointSetting,
120
- useBackendParamsForTables,
121
- enableQueryModesForExplainSetting,
122
- queryUseMultiSchemaSetting,
123
- enableNewTenantDiagnosticsDesign,
124
- ],
106
+ settings: [useNodesEndpointSetting, useBackendParamsForTables, queryUseMultiSchemaSetting],
125
107
  };
126
108
 
127
109
  export const generalPage: SettingsPage = {
@@ -34,11 +34,10 @@ import type {StorageApiRequestParams} from '../store/reducers/storage/types';
34
34
 
35
35
  import {backend as BACKEND} from '../store';
36
36
  import {prepareSortValue} from '../utils/filters';
37
+ import {settingsApi} from '../utils/settings';
37
38
 
38
39
  const config = {withCredentials: !window.custom_backend};
39
40
 
40
- const settingsApi = window.web_version ? window.systemSettings?.settingsApi : undefined;
41
-
42
41
  type AxiosOptions = {
43
42
  concurrentId?: string;
44
43
  };
@@ -106,6 +105,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
106
105
  {concurrentId},
107
106
  );
108
107
  }
108
+ /** @deprecated use getNodes instead */
109
109
  getCompute(
110
110
  {sortOrder, sortValue, ...params}: ComputeApiRequestParams,
111
111
  {concurrentId}: AxiosOptions = {},
@@ -10,18 +10,21 @@ import {
10
10
  USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
11
11
  PARTITIONS_HIDDEN_COLUMNS_KEY,
12
12
  QUERY_INITIAL_MODE_KEY,
13
- ENABLE_ADDITIONAL_QUERY_MODES,
14
13
  CLUSTER_INFO_HIDDEN_KEY,
15
14
  LAST_USED_QUERY_ACTION_KEY,
16
15
  USE_BACKEND_PARAMS_FOR_TABLES_KEY,
17
16
  LANGUAGE_KEY,
18
- DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS,
19
17
  QUERY_USE_MULTI_SCHEMA_KEY,
20
18
  } from '../../../utils/constants';
21
19
  import '../../../services/api';
22
20
  import {parseJson} from '../../../utils/utils';
23
21
  import {QUERY_ACTIONS, QUERY_MODES} from '../../../utils/query';
24
- import {readSavedSettingsValue, systemSettings, userSettings} from '../../../utils/settings';
22
+ import {
23
+ readSavedSettingsValue,
24
+ settingsApi,
25
+ systemSettings,
26
+ userSettings,
27
+ } from '../../../utils/settings';
25
28
 
26
29
  import {TENANT_PAGES_IDS} from '../tenant/constants';
27
30
 
@@ -53,15 +56,7 @@ export const initialState = {
53
56
  USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
54
57
  'false',
55
58
  ),
56
- [ENABLE_ADDITIONAL_QUERY_MODES]: readSavedSettingsValue(
57
- ENABLE_ADDITIONAL_QUERY_MODES,
58
- 'true',
59
- ),
60
59
  [QUERY_USE_MULTI_SCHEMA_KEY]: readSavedSettingsValue(QUERY_USE_MULTI_SCHEMA_KEY, 'false'),
61
- [DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS]: readSavedSettingsValue(
62
- DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS,
63
- 'true',
64
- ),
65
60
  [SAVED_QUERIES_KEY]: readSavedSettingsValue(SAVED_QUERIES_KEY, '[]'),
66
61
  [TENANT_INITIAL_PAGE_KEY]: readSavedSettingsValue(
67
62
  TENANT_INITIAL_PAGE_KEY,
@@ -115,13 +110,16 @@ export const setSettingValue = (
115
110
  name: string,
116
111
  value: string,
117
112
  ): ThunkAction<void, RootState, unknown, SetSettingValueAction> => {
118
- return (dispatch, getState) => {
113
+ return (dispatch) => {
119
114
  dispatch({type: SET_SETTING_VALUE, data: {name, value}});
120
- const {singleClusterMode} = getState();
121
- if (singleClusterMode) {
122
- localStorage.setItem(name, value);
123
- } else {
115
+
116
+ // If there is no settingsApi, use localStorage
117
+ if (settingsApi) {
124
118
  window.api.postSetting(name, value);
119
+ } else {
120
+ try {
121
+ localStorage.setItem(name, value);
122
+ } catch {}
125
123
  }
126
124
  };
127
125
  };
@@ -19,14 +19,6 @@ export const DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS;
19
19
 
20
20
  export const MS_IN_NANOSECONDS = 1000000;
21
21
 
22
- export const TABLET_STATES = {
23
- TABLET_VOLATILE_STATE_UNKNOWN: 'unknown',
24
- TABLET_VOLATILE_STATE_STOPPED: 'stopped',
25
- TABLET_VOLATILE_STATE_BOOTING: 'booting',
26
- TABLET_VOLATILE_STATE_STARTING: 'starting',
27
- TABLET_VOLATILE_STATE_RUNNING: 'running',
28
- };
29
-
30
22
  export const TABLET_COLORS = {
31
23
  Created: 'gray',
32
24
  ResolveStateStorage: 'lightgray',
@@ -89,9 +81,6 @@ export const THEME_KEY = 'theme';
89
81
  export const LANGUAGE_KEY = 'language';
90
82
  export const INVERTED_DISKS_KEY = 'invertedDisks';
91
83
  export const USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY = 'useNodesEndpointInDiagnostics';
92
- export const ENABLE_ADDITIONAL_QUERY_MODES = 'enableAdditionalQueryModes';
93
- // Remain key name "enableNewTenantDiagnosticsDesign" for backward compatibility
94
- export const DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS = 'enableNewTenantDiagnosticsDesign';
95
84
  export const SAVED_QUERIES_KEY = 'saved_queries';
96
85
  export const ASIDE_HEADER_COMPACT_KEY = 'asideHeaderCompact';
97
86
  export const QUERIES_HISTORY_KEY = 'queries_history';
@@ -1,36 +1,7 @@
1
1
  import type {QueryMode} from '../../types/store/query';
2
- import {ENABLE_ADDITIONAL_QUERY_MODES, QUERY_INITIAL_MODE_KEY} from '../constants';
3
- import {QUERY_MODES_TITLES, isNewQueryMode} from '../query';
4
- import createToast from '../createToast';
2
+ import {QUERY_INITIAL_MODE_KEY} from '../constants';
5
3
  import {useSetting} from './useSetting';
6
- import i18n from './i18n';
7
4
 
8
- export type SetQueryModeIfAvailable = (
9
- value: QueryMode,
10
- errorMessage?: string | undefined,
11
- ) => boolean;
12
-
13
- export const useQueryModes = (): [QueryMode, SetQueryModeIfAvailable] => {
14
- const [queryMode, setQueryMode] = useSetting<QueryMode>(QUERY_INITIAL_MODE_KEY);
15
- const [enableAdditionalQueryModes] = useSetting<boolean>(ENABLE_ADDITIONAL_QUERY_MODES);
16
-
17
- const setQueryModeIfAvailable: SetQueryModeIfAvailable = (value, errorMessage) => {
18
- if (isNewQueryMode(value) && !enableAdditionalQueryModes) {
19
- createToast({
20
- name: 'QueryModeCannotBeSet',
21
- title:
22
- errorMessage ??
23
- i18n('useQueryModes.queryModeCannotBeSet', {mode: QUERY_MODES_TITLES[value]}),
24
- type: 'error',
25
- });
26
-
27
- return false;
28
- } else {
29
- setQueryMode(value);
30
-
31
- return true;
32
- }
33
- };
34
-
35
- return [queryMode, setQueryModeIfAvailable];
5
+ export const useQueryModes = () => {
6
+ return useSetting<QueryMode>(QUERY_INITIAL_MODE_KEY);
36
7
  };
@@ -38,10 +38,6 @@ export const QUERY_SYNTAX = {
38
38
  pg: 'pg',
39
39
  } as const;
40
40
 
41
- export const isNewQueryMode = (value: QueryMode) => {
42
- return value !== QUERY_MODES.script && value !== QUERY_MODES.scan;
43
- };
44
-
45
41
  // eslint-disable-next-line complexity
46
42
  export const getColumnType = (type: string) => {
47
43
  switch (type.replace(/\?$/, '')) {
@@ -3,8 +3,11 @@ import {getValueFromLS} from './utils';
3
3
  export const userSettings = window.userSettings || {};
4
4
  export const systemSettings = window.systemSettings || {};
5
5
 
6
+ export const settingsApi = window.web_version ? systemSettings.settingsApi : undefined;
7
+
6
8
  export function readSavedSettingsValue(key: string, defaultValue?: string) {
7
- const savedValue = window.web_version ? userSettings[key] : getValueFromLS(key);
9
+ // If there is no settingsApi, use localStorage
10
+ const savedValue = settingsApi ? userSettings[key] : getValueFromLS(key);
8
11
 
9
12
  return savedValue ?? defaultValue;
10
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "4.23.0",
3
+ "version": "4.25.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -1,64 +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 {IResponseError} from '../../../../../types/api/error';
8
- import type {IIssuesTree} from '../../../../../types/store/healthcheck';
9
- import {ResponseError} from '../../../../../components/Errors/ResponseError';
10
-
11
- import IssueTree from '../../TenantOverview/Healthcheck/IssuesViewer/IssueTree';
12
-
13
- import i18n from '../../TenantOverview/Healthcheck/i18n';
14
-
15
- const b = cn('old-healthcheck');
16
-
17
- interface DetailsProps {
18
- issueTrees?: IIssuesTree[];
19
- loading?: boolean;
20
- onUpdate: VoidFunction;
21
- error?: IResponseError;
22
- }
23
-
24
- export const Details = (props: DetailsProps) => {
25
- const {loading, onUpdate, issueTrees, error} = props;
26
-
27
- const renderHealthcheckHeader = () => {
28
- return (
29
- <div className={b('details-header')}>
30
- <h3 className={b('details-header-title')}>{i18n('title.healthcheck')}</h3>
31
- <div className={b('details-header-update')}>
32
- <Button size="s" onClick={onUpdate} loading={loading} view="flat-secondary">
33
- <Icon data={updateArrow} height={20} width={20} />
34
- </Button>
35
- </div>
36
- </div>
37
- );
38
- };
39
-
40
- const renderContent = () => {
41
- if (error) {
42
- return <ResponseError error={error} defaultMessage={i18n('no-data')} />;
43
- }
44
-
45
- if (!issueTrees || !issueTrees.length) {
46
- return i18n('status_message.ok');
47
- }
48
-
49
- return (
50
- <>
51
- {issueTrees.map((issueTree) => (
52
- <IssueTree key={issueTree.id} issueTree={issueTree} />
53
- ))}
54
- </>
55
- );
56
- };
57
-
58
- return (
59
- <div className={b('details')}>
60
- {renderHealthcheckHeader()}
61
- <div className={b('details-content-wrapper')}>{renderContent()}</div>
62
- </div>
63
- );
64
- };
@@ -1 +0,0 @@
1
- export * from './Details';
@@ -1,137 +0,0 @@
1
- @import '../../../../styles/mixins.scss';
2
- @import '@gravity-ui/uikit/styles/mixins.scss';
3
-
4
- .old-healthcheck {
5
- display: flex;
6
-
7
- &_expanded {
8
- // Since most of the inner containers have fixed width, we can set fixed width here as well
9
- // Thus we will get rid of unneeded layout shift when scrollbar appear
10
- min-width: 885px;
11
- }
12
-
13
- &__details {
14
- width: 860px;
15
- padding: 25px 20px 20px;
16
- }
17
-
18
- &__issue-preview {
19
- margin-bottom: 15px;
20
- }
21
-
22
- &__details-content-wrapper {
23
- overflow-x: hidden;
24
- overflow-y: auto;
25
-
26
- height: 70vh;
27
- max-height: 70vh;
28
- }
29
-
30
- &__message-container {
31
- padding: 15px 0;
32
- }
33
-
34
- &__details-header {
35
- display: flex;
36
- align-items: center;
37
-
38
- margin-bottom: 20px;
39
- }
40
-
41
- &__details-header-title {
42
- margin: 0 10px 0 0;
43
-
44
- @include text-header-1();
45
- }
46
-
47
- &__details-header-update {
48
- margin-left: 10px;
49
- }
50
-
51
- &__preview {
52
- width: 206px;
53
- padding: 16px;
54
- padding-bottom: 28px;
55
-
56
- border: 1px solid var(--yc-color-line-generic);
57
- border-radius: 8px;
58
- background-color: transparent;
59
- }
60
-
61
- &__preview-header {
62
- margin-bottom: var(--diagnostics-section-title-margin);
63
- gap: 8px;
64
- }
65
-
66
- &__preview-title {
67
- font-weight: 600;
68
- @include lead-typography();
69
- }
70
-
71
- &__preview-content {
72
- line-height: 24px;
73
- }
74
-
75
- &__preview-title-wrapper {
76
- display: flex;
77
- align-items: center;
78
-
79
- margin-bottom: 4px;
80
-
81
- gap: 8px;
82
- }
83
-
84
- &__issues-statistics {
85
- display: flex;
86
- flex-wrap: wrap;
87
- align-items: center;
88
-
89
- margin: 8px 0;
90
-
91
- gap: 10px;
92
- }
93
-
94
- &__self-check-status-indicator {
95
- display: inline-block;
96
-
97
- padding: 0 8px;
98
-
99
- font-size: 13px;
100
- line-height: 24px;
101
-
102
- border-radius: 4px;
103
-
104
- &_good,
105
- &_green {
106
- color: var(--yc-color-text-positive);
107
- background-color: var(--yc-color-base-positive);
108
- }
109
- &_degraded,
110
- &_yellow {
111
- color: var(--yc-color-text-warning);
112
- background-color: var(--yc-color-base-warning);
113
- }
114
-
115
- &_blue {
116
- color: var(--yc-color-text-info);
117
- background-color: var(--yc-color-base-info);
118
- }
119
-
120
- &_emergency,
121
- &_red {
122
- color: var(--yc-color-text-danger);
123
- background-color: var(--yc-color-base-danger);
124
- }
125
- &_unspecified,
126
- &_gray,
127
- &_grey {
128
- color: var(--yc-color-text-misc);
129
- background-color: var(--yc-color-base-misc);
130
- }
131
- &_maintenance_required,
132
- &_orange {
133
- color: var(--yc-color-text-warning-heavy);
134
- background-color: var(--yc-color-infographics-warning-light);
135
- }
136
- }
137
- }
@@ -1,92 +0,0 @@
1
- import {useCallback} from 'react';
2
- import {useDispatch} from 'react-redux';
3
- import cn from 'bem-cn-lite';
4
-
5
- import {Loader} from '@gravity-ui/uikit';
6
-
7
- import {SelfCheckResult} from '../../../../types/api/healthcheck';
8
- import {useTypedSelector, useAutofetcher} from '../../../../utils/hooks';
9
- import {
10
- getHealthcheckInfo,
11
- selectIssuesStatistics,
12
- selectIssuesTrees,
13
- setDataWasNotLoaded,
14
- } from '../../../../store/reducers/healthcheckInfo';
15
-
16
- import {Details} from './Details';
17
- import {Preview} from './Preview';
18
-
19
- import './Healthcheck.scss';
20
-
21
- interface HealthcheckProps {
22
- tenant: string;
23
- preview?: boolean;
24
- fetchData?: boolean;
25
- showMoreHandler?: VoidFunction;
26
- }
27
-
28
- const b = cn('old-healthcheck');
29
-
30
- export const Healthcheck = (props: HealthcheckProps) => {
31
- const {tenant, preview, fetchData = true, showMoreHandler} = props;
32
-
33
- const dispatch = useDispatch();
34
-
35
- const {data, loading, wasLoaded, error} = useTypedSelector((state) => state.healthcheckInfo);
36
- const issuesStatistics = useTypedSelector(selectIssuesStatistics);
37
- const issueTrees = useTypedSelector(selectIssuesTrees);
38
- const {autorefresh} = useTypedSelector((state) => state.schema);
39
-
40
- const selfCheckResult = data?.self_check_result || SelfCheckResult.UNSPECIFIED;
41
-
42
- const fetchHealthcheck = useCallback(
43
- (isBackground = true) => {
44
- if (!isBackground) {
45
- dispatch(setDataWasNotLoaded());
46
- }
47
-
48
- dispatch(getHealthcheckInfo(tenant));
49
- },
50
- [dispatch, tenant],
51
- );
52
-
53
- useAutofetcher(
54
- (isBackground) => {
55
- if (fetchData) {
56
- fetchHealthcheck(isBackground);
57
- }
58
- },
59
- [fetchData, fetchHealthcheck],
60
- autorefresh,
61
- );
62
-
63
- const renderContent = () => {
64
- if (loading && !wasLoaded) {
65
- return (
66
- <div className={b('old-preview', {loader: true})}>
67
- <Loader size="m" />
68
- </div>
69
- );
70
- }
71
-
72
- return preview ? (
73
- <Preview
74
- issuesStatistics={issuesStatistics}
75
- selfCheckResult={selfCheckResult}
76
- loading={loading}
77
- onShowMore={showMoreHandler}
78
- onUpdate={fetchHealthcheck}
79
- error={error}
80
- />
81
- ) : (
82
- <Details
83
- loading={loading}
84
- onUpdate={fetchHealthcheck}
85
- issueTrees={issueTrees}
86
- error={error}
87
- />
88
- );
89
- };
90
-
91
- return <div className={b({expanded: !preview})}>{renderContent()}</div>;
92
- };
@@ -1,82 +0,0 @@
1
- import cn from 'bem-cn-lite';
2
-
3
- import {Button, Icon, Link} from '@gravity-ui/uikit';
4
-
5
- import updateArrow from '../../../../../assets/icons/update-arrow.svg';
6
-
7
- import {SelfCheckResult, type StatusFlag} from '../../../../../types/api/healthcheck';
8
- import type {IResponseError} from '../../../../../types/api/error';
9
- import EntityStatus from '../../../../../components/EntityStatus/EntityStatus';
10
- import {ResponseError} from '../../../../../components/Errors/ResponseError';
11
-
12
- import i18n from '../../TenantOverview/Healthcheck/i18n';
13
-
14
- const b = cn('old-healthcheck');
15
-
16
- interface PreviewProps {
17
- selfCheckResult: SelfCheckResult;
18
- issuesStatistics?: [StatusFlag, number][];
19
- loading?: boolean;
20
- onShowMore?: VoidFunction;
21
- onUpdate: VoidFunction;
22
- error?: IResponseError;
23
- }
24
-
25
- export const Preview = (props: PreviewProps) => {
26
- const {selfCheckResult, issuesStatistics, loading, onShowMore, onUpdate, error} = props;
27
-
28
- const renderHeader = () => {
29
- const modifier = selfCheckResult.toLowerCase();
30
-
31
- return (
32
- <div className={b('preview-header')}>
33
- <div className={b('preview-title-wrapper')}>
34
- <div className={b('preview-title')}>{i18n('title.healthcheck')}</div>
35
- <Button size="s" onClick={onUpdate} loading={loading} view="flat-secondary">
36
- <Icon data={updateArrow} width={20} height={20} />
37
- </Button>
38
- </div>
39
- <div className={b('self-check-status-indicator', {[modifier]: true})}>
40
- {selfCheckResult}
41
- </div>
42
- </div>
43
- );
44
- };
45
-
46
- const renderContent = () => {
47
- if (error) {
48
- return <ResponseError error={error} defaultMessage={i18n('no-data')} />;
49
- }
50
-
51
- return (
52
- <div className={b('preview-content')}>
53
- {!issuesStatistics || !issuesStatistics.length ? (
54
- i18n('status_message.ok')
55
- ) : (
56
- <>
57
- <div>{i18n('label.issues')}</div>
58
- <div className={b('issues-statistics')}>
59
- {issuesStatistics.map(([status, count]) => (
60
- <EntityStatus
61
- key={status}
62
- mode="icons"
63
- status={status}
64
- label={count.toString()}
65
- size="l"
66
- />
67
- ))}
68
- </div>
69
- <Link onClick={() => onShowMore?.()}>{i18n('label.show-details')}</Link>
70
- </>
71
- )}
72
- </div>
73
- );
74
- };
75
-
76
- return (
77
- <div className={b('preview')}>
78
- {renderHeader()}
79
- {renderContent()}
80
- </div>
81
- );
82
- };
@@ -1 +0,0 @@
1
- export * from './Preview';
@@ -1 +0,0 @@
1
- export * from './Healthcheck';
@@ -1,155 +0,0 @@
1
- import cn from 'bem-cn-lite';
2
- import {useCallback} from 'react';
3
- import {useDispatch} from 'react-redux';
4
-
5
- import {Loader} from '@gravity-ui/uikit';
6
-
7
- import {InfoViewer} from '../../../../components/InfoViewer';
8
- import {PoolUsage} from '../../../../components/PoolUsage/PoolUsage';
9
- import {Tablet} from '../../../../components/Tablet';
10
- import EntityStatus from '../../../../components/EntityStatus/EntityStatus';
11
- import {formatCPU} from '../../../../utils/dataFormatters/dataFormatters';
12
- import {TABLET_STATES, TENANT_DEFAULT_TITLE} from '../../../../utils/constants';
13
- import {bytesToGB} from '../../../../utils/utils';
14
- import {mapDatabaseTypeToDBName} from '../../utils/schema';
15
- import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
16
- import type {ETabletVolatileState} from '../../../../types/api/tenant';
17
- import type {AdditionalTenantsProps} from '../../../../types/additionalProps';
18
- import {getTenantInfo, setDataWasNotLoaded} from '../../../../store/reducers/tenant/tenant';
19
-
20
- import i18n from './i18n';
21
- import './TenantOverview.scss';
22
-
23
- const b = cn('tenant-overview');
24
-
25
- interface OldTenantOverviewProps {
26
- tenantName: string;
27
- additionalTenantProps?: AdditionalTenantsProps;
28
- }
29
-
30
- export function OldTenantOverview({tenantName, additionalTenantProps}: OldTenantOverviewProps) {
31
- const {tenant, loading, wasLoaded} = useTypedSelector((state) => state.tenant);
32
- const {autorefresh} = useTypedSelector((state) => state.schema);
33
- const dispatch = useDispatch();
34
- const fetchTenant = useCallback(
35
- (isBackground = true) => {
36
- if (!isBackground) {
37
- dispatch(setDataWasNotLoaded());
38
- }
39
- dispatch(getTenantInfo({path: tenantName}));
40
- },
41
- [dispatch, tenantName],
42
- );
43
-
44
- useAutofetcher(fetchTenant, [fetchTenant], autorefresh);
45
-
46
- const {
47
- Metrics = {},
48
- PoolStats,
49
- StateStats = [],
50
- MemoryUsed,
51
- Name,
52
- State,
53
- CoresUsed,
54
- StorageGroups,
55
- StorageAllocatedSize,
56
- Type,
57
- SystemTablets,
58
- } = tenant || {};
59
-
60
- const tenantType = mapDatabaseTypeToDBName(Type);
61
- const memoryRaw = MemoryUsed ?? Metrics.Memory;
62
-
63
- const memory = (memoryRaw && bytesToGB(memoryRaw)) || i18n('no-data');
64
- const storage = (Metrics.Storage && bytesToGB(Metrics.Storage)) || i18n('no-data');
65
- const storageGroups = StorageGroups ?? i18n('no-data');
66
- const blobStorage =
67
- (StorageAllocatedSize && bytesToGB(StorageAllocatedSize)) || i18n('no-data');
68
- const storageEfficiency =
69
- Metrics.Storage && StorageAllocatedSize
70
- ? `${((parseInt(Metrics.Storage) * 100) / parseInt(StorageAllocatedSize)).toFixed(2)}%`
71
- : i18n('no-data');
72
-
73
- const cpuRaw = CoresUsed !== undefined ? Number(CoresUsed) * 1_000_000 : Metrics.CPU;
74
-
75
- const cpu = formatCPU(cpuRaw);
76
-
77
- const metricsInfo = [
78
- {label: 'Type', value: Type},
79
- {label: 'Memory', value: memory},
80
- {label: 'CPU', value: cpu},
81
- {label: 'Tablet storage', value: storage},
82
- {label: 'Storage groups', value: storageGroups},
83
- {label: 'Blob storage', value: blobStorage},
84
- {label: 'Storage efficiency', value: storageEfficiency},
85
- ];
86
-
87
- const tabletsInfo = StateStats.filter(
88
- (item): item is {VolatileState: ETabletVolatileState; Count: number} => {
89
- return item.VolatileState !== undefined && item.Count !== undefined;
90
- },
91
- ).map((info) => {
92
- return {label: TABLET_STATES[info.VolatileState], value: info.Count};
93
- });
94
-
95
- const renderName = () => {
96
- return (
97
- <div className={b('tenant-name-wrapper')}>
98
- <EntityStatus
99
- status={State}
100
- name={Name || TENANT_DEFAULT_TITLE}
101
- withLeftTrim
102
- hasClipboardButton={Boolean(tenant)}
103
- clipboardButtonAlwaysVisible
104
- />
105
- </div>
106
- );
107
- };
108
-
109
- if (loading && !wasLoaded) {
110
- return (
111
- <div className={b('loader')}>
112
- <Loader size="m" />
113
- </div>
114
- );
115
- }
116
-
117
- return (
118
- <div className={b()}>
119
- <div className={b('top-label')}>{tenantType}</div>
120
- <div className={b('top')}>
121
- {renderName()}
122
- {additionalTenantProps?.getMonitoringLink?.(Name, Type)}
123
- </div>
124
- <div className={b('system-tablets')}>
125
- {SystemTablets &&
126
- SystemTablets.map((tablet, tabletIndex) => (
127
- <Tablet key={tabletIndex} tablet={tablet} tenantName={Name} />
128
- ))}
129
- </div>
130
- <div className={b('common-info')}>
131
- <div>
132
- <div className={b('section-title')}>{i18n('title.pools')}</div>
133
- {PoolStats ? (
134
- <div className={b('section', {pools: true})}>
135
- {PoolStats.map((pool, poolIndex) => (
136
- <PoolUsage key={poolIndex} data={pool} />
137
- ))}
138
- </div>
139
- ) : (
140
- <div className="error">{i18n('no-pools-data')}</div>
141
- )}
142
- </div>
143
- <InfoViewer
144
- title={i18n('title.metrics')}
145
- className={b('section', {metrics: true})}
146
- info={metricsInfo}
147
- />
148
-
149
- <div className={b('section')}>
150
- <InfoViewer info={tabletsInfo} title="Tablets" />
151
- </div>
152
- </div>
153
- </div>
154
- );
155
- }
@@ -1,3 +0,0 @@
1
- {
2
- "useQueryModes.queryModeCannotBeSet": "Query mode '{{mode}}' cannot be set. You need to turn in additional query modes in settings to enable it"
3
- }
@@ -1,11 +0,0 @@
1
- import {i18n, Lang} from '../../../utils/i18n';
2
-
3
- import en from './en.json';
4
- import ru from './ru.json';
5
-
6
- const COMPONENT = 'ydb-hooks';
7
-
8
- i18n.registerKeyset(Lang.En, COMPONENT, en);
9
- i18n.registerKeyset(Lang.Ru, COMPONENT, ru);
10
-
11
- export default i18n.keyset(COMPONENT);
@@ -1,3 +0,0 @@
1
- {
2
- "useQueryModes.queryModeCannotBeSet": "Режим выполнения запроса '{{mode}}' недоступен. Вам необходимо включить дополнительные режимы выполнения запросов в настройках"
3
- }