ydb-embedded-ui 4.29.0 → 4.31.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/README.md +2 -1
  2. package/dist/components/ClipboardButton/ClipboardButton.tsx +52 -0
  3. package/dist/components/ClipboardButton/index.ts +1 -0
  4. package/dist/components/EntityStatus/EntityStatus.js +9 -12
  5. package/dist/components/EntityStatus/EntityStatus.scss +2 -13
  6. package/dist/components/MetricChart/MetricChart.scss +34 -0
  7. package/dist/components/MetricChart/MetricChart.tsx +198 -0
  8. package/dist/components/MetricChart/convertReponse.ts +32 -0
  9. package/dist/components/MetricChart/getChartData.ts +20 -0
  10. package/dist/components/MetricChart/getDefaultDataFormatter.ts +36 -0
  11. package/dist/components/MetricChart/index.ts +2 -0
  12. package/dist/components/MetricChart/reducer.ts +86 -0
  13. package/dist/components/MetricChart/types.ts +32 -0
  14. package/dist/components/TimeFrameSelector/TimeFrameSelector.scss +5 -0
  15. package/dist/components/TimeFrameSelector/TimeFrameSelector.tsx +33 -0
  16. package/dist/containers/App/App.scss +9 -9
  17. package/dist/containers/App/Content.js +16 -12
  18. package/dist/containers/Tenant/Diagnostics/TenantOverview/DefaultDashboard.tsx +50 -0
  19. package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx +13 -4
  20. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/CpuDashboard.tsx +18 -0
  21. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TenantCpu.tsx +2 -0
  22. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantDashboard/TenantDashboard.scss +14 -0
  23. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantDashboard/TenantDashboard.tsx +71 -0
  24. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/MemoryDashboard.tsx +21 -0
  25. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TenantMemory.tsx +7 -1
  26. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +2 -1
  27. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/StorageDashboard.tsx +21 -0
  28. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.tsx +2 -0
  29. package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json +7 -1
  30. package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/ru.json +7 -1
  31. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +24 -30
  32. package/dist/containers/Tenant/Query/ExecuteResult/ExecuteResult.tsx +10 -16
  33. package/dist/containers/UserSettings/i18n/en.json +4 -1
  34. package/dist/containers/UserSettings/i18n/ru.json +4 -1
  35. package/dist/containers/UserSettings/settings.ts +12 -1
  36. package/dist/containers/Versions/NodesTreeTitle/NodesTreeTitle.scss +15 -0
  37. package/dist/containers/Versions/NodesTreeTitle/NodesTreeTitle.tsx +9 -6
  38. package/dist/services/api.ts +18 -0
  39. package/dist/services/settings.ts +2 -0
  40. package/dist/store/reducers/tenant/tenant.ts +6 -1
  41. package/dist/types/api/render.ts +34 -0
  42. package/dist/utils/cn.ts +3 -0
  43. package/dist/utils/constants.ts +2 -0
  44. package/dist/utils/timeParsers/formatDuration.ts +10 -0
  45. package/dist/utils/timeframes.ts +10 -0
  46. package/dist/utils/versions/getVersionsColors.ts +1 -0
  47. package/package.json +4 -2
  48. package/CHANGELOG.md +0 -1552
  49. package/dist/components/CopyToClipboard/CopyToClipboard.tsx +0 -38
@@ -1,5 +1,7 @@
1
1
  import React from 'react';
2
2
  import {Switch, Route, Redirect, Router, useLocation} from 'react-router-dom';
3
+ import {QueryParamProvider} from 'use-query-params';
4
+ import {ReactRouter5Adapter} from 'use-query-params/adapters/react-router-5';
3
5
  import cn from 'bem-cn-lite';
4
6
  import {connect} from 'react-redux';
5
7
 
@@ -80,18 +82,20 @@ function ContentWrapper(props) {
80
82
  <HistoryContext.Consumer>
81
83
  {(history) => (
82
84
  <Router history={history}>
83
- <Switch>
84
- <Route path={routes.auth}>
85
- <Authentication closable />
86
- </Route>
87
- <Route>
88
- <ThemeProvider theme={theme}>
89
- <div className={b({embedded: singleClusterMode})}>
90
- {isAuthenticated ? props.children : <Authentication />}
91
- </div>
92
- </ThemeProvider>
93
- </Route>
94
- </Switch>
85
+ <QueryParamProvider adapter={ReactRouter5Adapter}>
86
+ <Switch>
87
+ <Route path={routes.auth}>
88
+ <Authentication closable />
89
+ </Route>
90
+ <Route>
91
+ <ThemeProvider theme={theme}>
92
+ <div className={b({embedded: singleClusterMode})}>
93
+ {isAuthenticated ? props.children : <Authentication />}
94
+ </div>
95
+ </ThemeProvider>
96
+ </Route>
97
+ </Switch>
98
+ </QueryParamProvider>
95
99
  </Router>
96
100
  )}
97
101
  </HistoryContext.Consumer>
@@ -0,0 +1,50 @@
1
+ import {type ChartConfig, TenantDashboard} from './TenantDashboard/TenantDashboard';
2
+ import i18n from './i18n';
3
+
4
+ const defaultDashboardConfig: ChartConfig[] = [
5
+ {
6
+ title: i18n('charts.queries-per-second'),
7
+ metrics: [
8
+ {
9
+ target: 'queries.requests',
10
+ title: i18n('charts.queries-per-second'),
11
+ },
12
+ ],
13
+ },
14
+ {
15
+ title: i18n('charts.transaction-latency', {percentile: ''}),
16
+ metrics: [
17
+ {
18
+ target: 'queries.latencies.p50',
19
+ title: i18n('charts.transaction-latency', {
20
+ percentile: 'p50',
21
+ }),
22
+ },
23
+ {
24
+ target: 'queries.latencies.p75',
25
+ title: i18n('charts.transaction-latency', {
26
+ percentile: 'p75',
27
+ }),
28
+ },
29
+ {
30
+ target: 'queries.latencies.p90',
31
+ title: i18n('charts.transaction-latency', {
32
+ percentile: 'p90',
33
+ }),
34
+ },
35
+ {
36
+ target: 'queries.latencies.p99',
37
+ title: i18n('charts.transaction-latency', {
38
+ percentile: 'p99',
39
+ }),
40
+ },
41
+ ],
42
+ options: {
43
+ dataType: 'ms',
44
+ },
45
+ },
46
+ ];
47
+
48
+ export const DefaultDashboard = () => {
49
+ return <TenantDashboard charts={defaultDashboardConfig} />;
50
+ };
@@ -72,22 +72,31 @@ export function MetricsCards({
72
72
 
73
73
  const queryParams = parseQuery(location);
74
74
 
75
+ // Allow tabs untoggle behaviour
76
+ const getTabIfNotActive = (tab: TenantMetricsTab) => {
77
+ if (tab === metricsTab) {
78
+ return '';
79
+ }
80
+
81
+ return tab;
82
+ };
83
+
75
84
  const tabLinks: Record<TenantMetricsTab, string> = {
76
85
  [TENANT_METRICS_TABS_IDS.cpu]: getTenantPath({
77
86
  ...queryParams,
78
- [TenantTabsGroups.metricsTab]: TENANT_METRICS_TABS_IDS.cpu,
87
+ [TenantTabsGroups.metricsTab]: getTabIfNotActive(TENANT_METRICS_TABS_IDS.cpu),
79
88
  }),
80
89
  [TENANT_METRICS_TABS_IDS.storage]: getTenantPath({
81
90
  ...queryParams,
82
- [TenantTabsGroups.metricsTab]: TENANT_METRICS_TABS_IDS.storage,
91
+ [TenantTabsGroups.metricsTab]: getTabIfNotActive(TENANT_METRICS_TABS_IDS.storage),
83
92
  }),
84
93
  [TENANT_METRICS_TABS_IDS.memory]: getTenantPath({
85
94
  ...queryParams,
86
- [TenantTabsGroups.metricsTab]: TENANT_METRICS_TABS_IDS.memory,
95
+ [TenantTabsGroups.metricsTab]: getTabIfNotActive(TENANT_METRICS_TABS_IDS.memory),
87
96
  }),
88
97
  [TENANT_METRICS_TABS_IDS.healthcheck]: getTenantPath({
89
98
  ...queryParams,
90
- [TenantTabsGroups.metricsTab]: TENANT_METRICS_TABS_IDS.healthcheck,
99
+ [TenantTabsGroups.metricsTab]: getTabIfNotActive(TENANT_METRICS_TABS_IDS.healthcheck),
91
100
  }),
92
101
  };
93
102
 
@@ -0,0 +1,18 @@
1
+ import {type ChartConfig, TenantDashboard} from '../TenantDashboard/TenantDashboard';
2
+ import i18n from '../i18n';
3
+
4
+ const cpuDashboardConfig: ChartConfig[] = [
5
+ {
6
+ title: i18n('charts.cpu-usage'),
7
+ metrics: [
8
+ {
9
+ target: 'resources.cpu.usage',
10
+ title: i18n('charts.cpu-usage'),
11
+ },
12
+ ],
13
+ },
14
+ ];
15
+
16
+ export const CpuDashboard = () => {
17
+ return <TenantDashboard charts={cpuDashboardConfig} />;
18
+ };
@@ -1,4 +1,5 @@
1
1
  import type {AdditionalNodesProps} from '../../../../../types/additionalProps';
2
+ import {CpuDashboard} from './CpuDashboard';
2
3
  import {TopNodesByLoad} from './TopNodesByLoad';
3
4
  import {TopNodesByCpu} from './TopNodesByCpu';
4
5
  import {TopShards} from './TopShards';
@@ -12,6 +13,7 @@ interface TenantCpuProps {
12
13
  export function TenantCpu({path, additionalNodesProps}: TenantCpuProps) {
13
14
  return (
14
15
  <>
16
+ <CpuDashboard />
15
17
  <TopNodesByLoad path={path} additionalNodesProps={additionalNodesProps} />
16
18
  <TopNodesByCpu path={path} additionalNodesProps={additionalNodesProps} />
17
19
  <TopShards path={path} />
@@ -0,0 +1,14 @@
1
+ .ydb-tenant-dashboard {
2
+ width: var(--diagnostics-section-table-width);
3
+ margin-bottom: var(--diagnostics-section-margin);
4
+
5
+ &__controls {
6
+ margin-bottom: 10px;
7
+ }
8
+
9
+ &__charts {
10
+ display: flex;
11
+ flex-flow: row wrap;
12
+ gap: 16px;
13
+ }
14
+ }
@@ -0,0 +1,71 @@
1
+ import {StringParam, useQueryParam} from 'use-query-params';
2
+
3
+ import {cn} from '../../../../../utils/cn';
4
+ import type {TimeFrame} from '../../../../../utils/timeframes';
5
+ import {useSetting, useTypedSelector} from '../../../../../utils/hooks';
6
+ import {DISPLAY_CHARTS_IN_DB_DIAGNOSTICS_KEY} from '../../../../../utils/constants';
7
+ import {TimeFrameSelector} from '../../../../../components/TimeFrameSelector/TimeFrameSelector';
8
+ import {
9
+ type ChartOptions,
10
+ MetricChart,
11
+ type MetricDescription,
12
+ } from '../../../../../components/MetricChart';
13
+
14
+ import './TenantDashboard.scss';
15
+
16
+ const CHART_WIDTH = 428;
17
+ const CHART_WIDTH_FULL = 872;
18
+
19
+ const b = cn('ydb-tenant-dashboard');
20
+
21
+ export interface ChartConfig {
22
+ metrics: MetricDescription[];
23
+ title: string;
24
+ options?: ChartOptions;
25
+ }
26
+
27
+ interface TenantDashboardProps {
28
+ charts: ChartConfig[];
29
+ }
30
+
31
+ export const TenantDashboard = ({charts}: TenantDashboardProps) => {
32
+ const [timeFrame = '1h', setTimeframe] = useQueryParam('timeframe', StringParam);
33
+
34
+ const {autorefresh} = useTypedSelector((state) => state.schema);
35
+
36
+ const [chartsEnabled] = useSetting(DISPLAY_CHARTS_IN_DB_DIAGNOSTICS_KEY);
37
+
38
+ if (!chartsEnabled) {
39
+ return null;
40
+ }
41
+
42
+ // If there is only one chart, display it with full width
43
+ const chartWidth = charts.length === 1 ? CHART_WIDTH_FULL : CHART_WIDTH;
44
+ const chartHeight = CHART_WIDTH / 1.5;
45
+
46
+ const renderContent = () => {
47
+ return charts.map((chartConfig) => {
48
+ return (
49
+ <MetricChart
50
+ key={chartConfig.metrics.map(({target}) => target).join('&')}
51
+ title={chartConfig.title}
52
+ metrics={chartConfig.metrics}
53
+ timeFrame={timeFrame as TimeFrame}
54
+ chartOptions={chartConfig.options}
55
+ autorefresh={autorefresh}
56
+ width={chartWidth}
57
+ height={chartHeight}
58
+ />
59
+ );
60
+ });
61
+ };
62
+
63
+ return (
64
+ <div className={b(null)}>
65
+ <div className={b('controls')}>
66
+ <TimeFrameSelector value={timeFrame as TimeFrame} onChange={setTimeframe} />
67
+ </div>
68
+ <div className={b('charts')}>{renderContent()}</div>
69
+ </div>
70
+ );
71
+ };
@@ -0,0 +1,21 @@
1
+ import {type ChartConfig, TenantDashboard} from '../TenantDashboard/TenantDashboard';
2
+ import i18n from '../i18n';
3
+
4
+ const memoryDashboardConfig: ChartConfig[] = [
5
+ {
6
+ title: i18n('charts.memory-usage'),
7
+ metrics: [
8
+ {
9
+ target: 'resources.memory.used_bytes',
10
+ title: i18n('charts.memory-usage'),
11
+ },
12
+ ],
13
+ options: {
14
+ dataType: 'size',
15
+ },
16
+ },
17
+ ];
18
+
19
+ export const MemoryDashboard = () => {
20
+ return <TenantDashboard charts={memoryDashboardConfig} />;
21
+ };
@@ -1,3 +1,4 @@
1
+ import {MemoryDashboard} from './MemoryDashboard';
1
2
  import {TopNodesByMemory} from './TopNodesByMemory';
2
3
 
3
4
  interface TenantMemoryProps {
@@ -5,5 +6,10 @@ interface TenantMemoryProps {
5
6
  }
6
7
 
7
8
  export function TenantMemory({path}: TenantMemoryProps) {
8
- return <TopNodesByMemory path={path} />;
9
+ return (
10
+ <>
11
+ <MemoryDashboard />
12
+ <TopNodesByMemory path={path} />
13
+ </>
14
+ );
9
15
  }
@@ -17,6 +17,7 @@ import {HealthcheckDetails} from './Healthcheck/HealthcheckDetails';
17
17
  import {MetricsCards, type TenantMetrics} from './MetricsCards/MetricsCards';
18
18
  import {TenantStorage} from './TenantStorage/TenantStorage';
19
19
  import {TenantMemory} from './TenantMemory/TenantMemory';
20
+ import {DefaultDashboard} from './DefaultDashboard';
20
21
  import {useHealthcheck} from './useHealthcheck';
21
22
 
22
23
  import './TenantOverview.scss';
@@ -140,7 +141,7 @@ export function TenantOverview({
140
141
  );
141
142
  }
142
143
  default: {
143
- return undefined;
144
+ return <DefaultDashboard />;
144
145
  }
145
146
  }
146
147
  };
@@ -0,0 +1,21 @@
1
+ import {type ChartConfig, TenantDashboard} from '../TenantDashboard/TenantDashboard';
2
+ import i18n from '../i18n';
3
+
4
+ const storageDashboardConfig: ChartConfig[] = [
5
+ {
6
+ title: i18n('charts.storage-usage'),
7
+ metrics: [
8
+ {
9
+ target: 'resources.storage.used_bytes',
10
+ title: i18n('charts.storage-usage'),
11
+ },
12
+ ],
13
+ options: {
14
+ dataType: 'size',
15
+ },
16
+ },
17
+ ];
18
+
19
+ export const StorageDashboard = () => {
20
+ return <TenantDashboard charts={storageDashboardConfig} />;
21
+ };
@@ -7,6 +7,7 @@ import {getSizeWithSignificantDigits} from '../../../../../utils/bytesParsers';
7
7
 
8
8
  import '../TenantOverview.scss';
9
9
 
10
+ import {StorageDashboard} from './StorageDashboard';
10
11
  import {TopTables} from './TopTables';
11
12
  import {TopGroups} from './TopGroups';
12
13
 
@@ -62,6 +63,7 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
62
63
  ];
63
64
  return (
64
65
  <>
66
+ <StorageDashboard />
65
67
  <InfoViewer className={b('storage-info')} title="Storage details" info={info} />
66
68
  <TopTables path={tenantName} />
67
69
  <TopGroups tenant={tenantName} />
@@ -23,5 +23,11 @@
23
23
  "by-load": "by load",
24
24
  "by-memory": "by memory",
25
25
  "by-usage": "by usage",
26
- "by-size": "by size"
26
+ "by-size": "by size",
27
+
28
+ "charts.queries-per-second": "Queries per second",
29
+ "charts.transaction-latency": "Transactions latencies {{percentile}}",
30
+ "charts.cpu-usage": "CPU usage",
31
+ "charts.storage-usage": "Storage usage",
32
+ "charts.memory-usage": "Memory usage"
27
33
  }
@@ -23,5 +23,11 @@
23
23
  "by-load": "по нагрузке",
24
24
  "by-memory": "по памяти",
25
25
  "by-usage": "по потреблению",
26
- "by-size": "по размеру"
26
+ "by-size": "по размеру",
27
+
28
+ "charts.queries-per-second": "Количество запросов в секунду",
29
+ "charts.transaction-latency": "Задержка транзакций {{percentile}}",
30
+ "charts.cpu-usage": "Использование CPU",
31
+ "charts.storage-usage": "Использование хранилища",
32
+ "charts.memory-usage": "Использование памяти"
27
33
  }
@@ -1,60 +1,53 @@
1
+ import {HelpPopover} from '@gravity-ui/components';
2
+ import {Button, Tabs} from '@gravity-ui/uikit';
3
+ import cn from 'bem-cn-lite';
4
+ import qs from 'qs';
1
5
  import React, {ReactNode, useEffect, useReducer} from 'react';
2
6
  import {useDispatch} from 'react-redux';
3
7
  import {useLocation} from 'react-router';
4
8
  import {Link} from 'react-router-dom';
5
- import qs from 'qs';
6
- import cn from 'bem-cn-lite';
7
-
8
- import {Button, Tabs} from '@gravity-ui/uikit';
9
- import {HelpPopover} from '@gravity-ui/components';
10
-
11
- import SplitPane from '../../../components/SplitPane';
12
- import CopyToClipboard from '../../../components/CopyToClipboard/CopyToClipboard';
9
+ import {ClipboardButton} from '../../../components/ClipboardButton';
10
+ import {Icon} from '../../../components/Icon';
13
11
  import InfoViewer from '../../../components/InfoViewer/InfoViewer';
14
12
  import {
15
13
  CDCStreamOverview,
16
14
  PersQueueGroupOverview,
17
15
  } from '../../../components/InfoViewer/schemaOverview';
18
- import {Icon} from '../../../components/Icon';
19
16
  import {Loader} from '../../../components/Loader';
20
-
17
+ import SplitPane from '../../../components/SplitPane';
18
+ import routes, {createHref} from '../../../routes';
19
+ import {setShowPreview} from '../../../store/reducers/schema/schema';
20
+ import {
21
+ TENANT_PAGES_IDS,
22
+ TENANT_QUERY_TABS_ID,
23
+ TENANT_SUMMARY_TABS_IDS,
24
+ } from '../../../store/reducers/tenant/constants';
25
+ import {setQueryTab, setSummaryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
21
26
  import {
22
27
  EPathSubType,
23
28
  EPathType,
24
29
  TColumnDescription,
25
30
  TColumnTableDescription,
26
31
  } from '../../../types/api/schema';
27
- import routes, {createHref} from '../../../routes';
28
- import {formatDateTime} from '../../../utils/dataFormatters/dataFormatters';
29
- import {useTypedSelector} from '../../../utils/hooks';
30
32
  import {
31
33
  DEFAULT_IS_TENANT_COMMON_INFO_COLLAPSED,
32
34
  DEFAULT_SIZE_TENANT_SUMMARY_KEY,
33
35
  } from '../../../utils/constants';
34
- import {setShowPreview} from '../../../store/reducers/schema/schema';
35
- import {setQueryTab, setSummaryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
36
- import {
37
- TENANT_PAGES_IDS,
38
- TENANT_QUERY_TABS_ID,
39
- TENANT_SUMMARY_TABS_IDS,
40
- } from '../../../store/reducers/tenant/constants';
41
-
42
- import {SchemaTree} from '../Schema/SchemaTree/SchemaTree';
43
- import {SchemaViewer} from '../Schema/SchemaViewer/SchemaViewer';
36
+ import {formatDateTime} from '../../../utils/dataFormatters/dataFormatters';
37
+ import {useTypedSelector} from '../../../utils/hooks';
44
38
  import {Acl} from '../Acl/Acl';
45
- import {ExternalTableSummary} from '../Info/ExternalTable/ExternalTable';
39
+ import i18n from '../i18n';
46
40
  import {ExternalDataSourceSummary} from '../Info/ExternalDataSource/ExternalDataSource';
47
-
41
+ import {ExternalTableSummary} from '../Info/ExternalTable/ExternalTable';
42
+ import {SchemaTree} from '../Schema/SchemaTree/SchemaTree';
43
+ import {SchemaViewer} from '../Schema/SchemaViewer/SchemaViewer';
48
44
  import {TenantTabsGroups, TENANT_INFO_TABS, TENANT_SCHEMA_TAB} from '../TenantPages';
49
45
  import {
50
46
  PaneVisibilityActionTypes,
51
- paneVisibilityToggleReducerCreator,
52
47
  PaneVisibilityToggleButtons,
48
+ paneVisibilityToggleReducerCreator,
53
49
  } from '../utils/paneVisibilityToggleHelpers';
54
50
  import {isColumnEntityType, isExternalTable, isIndexTable, isTableType} from '../utils/schema';
55
-
56
- import i18n from '../i18n';
57
-
58
51
  import './ObjectSummary.scss';
59
52
 
60
53
  const b = cn('object-summary');
@@ -306,8 +299,9 @@ export function ObjectSummary({
306
299
  </Button>
307
300
  )}
308
301
  {currentSchemaPath && (
309
- <CopyToClipboard
302
+ <ClipboardButton
310
303
  text={currentSchemaPath}
304
+ view="flat-secondary"
311
305
  title={i18n('summary.copySchemaPath')}
312
306
  />
313
307
  )}
@@ -1,31 +1,25 @@
1
- import React, {useEffect, useState} from 'react';
2
- import {useDispatch} from 'react-redux';
1
+ import {RadioButton, Tabs} from '@gravity-ui/uikit';
3
2
  import cn from 'bem-cn-lite';
3
+ import React, {useEffect, useState} from 'react';
4
4
  import JSONTree from 'react-json-inspector';
5
-
6
- import {RadioButton, Tabs} from '@gravity-ui/uikit';
7
-
8
- import CopyToClipboard from '../../../../components/CopyToClipboard/CopyToClipboard';
5
+ import {useDispatch} from 'react-redux';
6
+ import {ClipboardButton} from '../../../../components/ClipboardButton';
9
7
  import Divider from '../../../../components/Divider/Divider';
10
8
  import EnableFullscreenButton from '../../../../components/EnableFullscreenButton/EnableFullscreenButton';
11
9
  import Fullscreen from '../../../../components/Fullscreen/Fullscreen';
12
10
  import {QueryExecutionStatus} from '../../../../components/QueryExecutionStatus';
13
11
  import {QueryResultTable} from '../../../../components/QueryResultTable/QueryResultTable';
14
-
12
+ import {disableFullscreen} from '../../../../store/reducers/fullscreen';
13
+ import type {ColumnType, KeyValueRow} from '../../../../types/api/query';
15
14
  import type {ValueOf} from '../../../../types/common';
16
15
  import type {IQueryResult, QueryErrorResponse} from '../../../../types/store/query';
17
- import type {ColumnType, KeyValueRow} from '../../../../types/api/query';
18
- import {disableFullscreen} from '../../../../store/reducers/fullscreen';
19
- import {prepareQueryError} from '../../../../utils/query';
20
- import {useTypedSelector} from '../../../../utils/hooks';
21
16
  import {getArray} from '../../../../utils';
22
-
17
+ import {useTypedSelector} from '../../../../utils/hooks';
18
+ import {prepareQueryError} from '../../../../utils/query';
23
19
  import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpers';
24
-
25
20
  import {ResultIssues} from '../Issues/Issues';
26
21
  import {QueryDuration} from '../QueryDuration/QueryDuration';
27
22
  import {getPreparedResult} from '../utils/getPreparedResult';
28
-
29
23
  import './ExecuteResult.scss';
30
24
 
31
25
  const b = cn('ydb-query-execute-result');
@@ -115,10 +109,10 @@ export function ExecuteResult({
115
109
 
116
110
  const renderClipboardButton = () => {
117
111
  return (
118
- <CopyToClipboard
112
+ <ClipboardButton
119
113
  text={textResults}
114
+ view="flat-secondary"
120
115
  title="Copy results"
121
- toastText="Results were copied to clipboard successfully"
122
116
  disabled={copyDisabled}
123
117
  />
124
118
  );
@@ -23,5 +23,8 @@
23
23
  "settings.useVirtualTables.popover": "It will increase performance, but could work unstable",
24
24
 
25
25
  "settings.queryUseMultiSchema.title": "Allow queries with multiple result sets",
26
- "settings.queryUseMultiSchema.popover": "Use 'multi' schema for queries that enables queries with multiple result sets. Returns nothing on versions 23-3 and older"
26
+ "settings.queryUseMultiSchema.popover": "Use 'multi' schema for queries that enables queries with multiple result sets. Returns nothing on versions 23-3 and older",
27
+
28
+ "settings.displayChartsInDbDiagnostics.title": "Display charts in database diagnostics",
29
+ "settings.displayChartsInDbDiagnostics.popover": "Incorrect data may be displayed (shows data only for the database related to the current node), does not work well on static nodes"
27
30
  }
@@ -23,5 +23,8 @@
23
23
  "settings.useVirtualTables.popover": "Это улучшит производительность, но может работать нестабильно",
24
24
 
25
25
  "settings.queryUseMultiSchema.title": "Разрешить запросы с несколькими результатами",
26
- "settings.queryUseMultiSchema.popover": "Использовать для запросов схему 'multi', которая позволяет выполнять запросы с несколькими результатами. На версиях 23-3 и старше результат не возвращается вообще"
26
+ "settings.queryUseMultiSchema.popover": "Использовать для запросов схему 'multi', которая позволяет выполнять запросы с несколькими результатами. На версиях 23-3 и старше результат не возвращается вообще",
27
+
28
+ "settings.displayChartsInDbDiagnostics.title": "Показывать графики в диагностике базы данных",
29
+ "settings.displayChartsInDbDiagnostics.popover": "Могут отображаться неправильные данные (показывает данные только для базы, относящейся к текущей ноде), плохо работает на статических нодах"
27
30
  }
@@ -10,6 +10,7 @@ import {
10
10
  USE_BACKEND_PARAMS_FOR_TABLES_KEY,
11
11
  USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
12
12
  QUERY_USE_MULTI_SCHEMA_KEY,
13
+ DISPLAY_CHARTS_IN_DB_DIAGNOSTICS_KEY,
13
14
  } from '../../utils/constants';
14
15
  import {Lang, defaultLang} from '../../utils/i18n';
15
16
 
@@ -94,6 +95,11 @@ export const queryUseMultiSchemaSetting: SettingProps = {
94
95
  title: i18n('settings.queryUseMultiSchema.title'),
95
96
  helpPopoverContent: i18n('settings.queryUseMultiSchema.popover'),
96
97
  };
98
+ export const displayChartsInDbDiagnosticsSetting: SettingProps = {
99
+ settingKey: DISPLAY_CHARTS_IN_DB_DIAGNOSTICS_KEY,
100
+ title: i18n('settings.displayChartsInDbDiagnostics.title'),
101
+ helpPopoverContent: i18n('settings.displayChartsInDbDiagnostics.popover'),
102
+ };
97
103
 
98
104
  export const appearanceSection: SettingsSection = {
99
105
  id: 'appearanceSection',
@@ -103,7 +109,12 @@ export const appearanceSection: SettingsSection = {
103
109
  export const experimentsSection: SettingsSection = {
104
110
  id: 'experimentsSection',
105
111
  title: i18n('section.experiments'),
106
- settings: [useNodesEndpointSetting, useVirtualTables, queryUseMultiSchemaSetting],
112
+ settings: [
113
+ useNodesEndpointSetting,
114
+ useVirtualTables,
115
+ queryUseMultiSchemaSetting,
116
+ displayChartsInDbDiagnosticsSetting,
117
+ ],
107
118
  };
108
119
 
109
120
  export const generalPage: SettingsPage = {
@@ -17,10 +17,12 @@
17
17
  margin-left: 30px;
18
18
  }
19
19
  }
20
+
20
21
  &__overview-container {
21
22
  display: flex;
22
23
  align-items: center;
23
24
  }
25
+
24
26
  &__info-label {
25
27
  font-weight: 200;
26
28
 
@@ -52,4 +54,17 @@
52
54
  width: 200px;
53
55
  }
54
56
  }
57
+
58
+ &__overview-title {
59
+ display: flex;
60
+ align-items: center;
61
+ }
62
+
63
+ &__clipboard-button {
64
+ visibility: hidden;
65
+
66
+ margin-left: 8px;
67
+
68
+ color: var(--yc-color-text-secondary);
69
+ }
55
70
  }
@@ -1,11 +1,9 @@
1
- import block from 'bem-cn-lite';
2
-
3
1
  import {Progress} from '@gravity-ui/uikit';
4
-
5
- import type {VersionValue} from '../../../types/versions';
2
+ import block from 'bem-cn-lite';
3
+ import {ClipboardButton} from '../../../components/ClipboardButton';
6
4
  import type {PreparedClusterNode} from '../../../store/reducers/clusterNodes/types';
5
+ import type {VersionValue} from '../../../types/versions';
7
6
  import type {GroupedNodesItem} from '../types';
8
-
9
7
  import './NodesTreeTitle.scss';
10
8
 
11
9
  const b = block('ydb-versions-nodes-tree-title');
@@ -43,7 +41,12 @@ export const NodesTreeTitle = ({
43
41
  {versionColor ? (
44
42
  <div className={b('version-color')} style={{background: versionColor}} />
45
43
  ) : null}
46
- <span className={b('overview-title')}>{title}</span>
44
+ {title ? (
45
+ <span className={b('overview-title')}>
46
+ {title}
47
+ <ClipboardButton text={title} size="s" className={b('clipboard-button')} />
48
+ </span>
49
+ ) : null}
47
50
  </div>
48
51
  <div className={b('overview-info')}>
49
52
  <div>