ydb-embedded-ui 6.7.0 → 6.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. package/dist/package.json +30 -30
  2. package/dist/src/components/InfoViewer/InfoViewer.d.ts +1 -1
  3. package/dist/src/components/InfoViewer/InfoViewer.js +2 -1
  4. package/dist/src/components/InfoViewer/i18n/en.json +2 -1
  5. package/dist/src/components/InfoViewer/i18n/index.d.ts +1 -1
  6. package/dist/src/components/InfoViewer/i18n/index.js +1 -2
  7. package/dist/src/containers/AppWithClusters/AppWithClusters.js +1 -1
  8. package/dist/src/containers/Storage/StorageGroups/getStorageGroupsColumns.js +4 -3
  9. package/dist/src/containers/Tenant/Acl/Acl.js +80 -54
  10. package/dist/src/containers/Tenant/Acl/Acl.scss +14 -9
  11. package/dist/src/containers/Tenant/Diagnostics/Overview/TableInfo/TableInfo.js +3 -3
  12. package/dist/src/containers/Tenant/Diagnostics/TenantOverview/i18n/index.d.ts +1 -1
  13. package/dist/src/containers/Tenant/EntityTitle/EntityTitle.d.ts +6 -0
  14. package/dist/src/containers/Tenant/EntityTitle/EntityTitle.js +11 -0
  15. package/dist/src/containers/Tenant/ObjectSummary/ObjectSummary.js +2 -2
  16. package/dist/src/containers/Tenant/TenantNavigation/TenantNavigation.js +1 -1
  17. package/dist/src/containers/Tenant/i18n/en.json +5 -1
  18. package/dist/src/containers/Tenant/i18n/index.d.ts +1 -1
  19. package/dist/src/containers/Tenant/utils/index.d.ts +1 -0
  20. package/dist/src/containers/Tenant/utils/index.js +6 -0
  21. package/dist/src/containers/Tenant/utils/queryTemplates.d.ts +3 -0
  22. package/dist/src/containers/Tenant/utils/queryTemplates.js +20 -0
  23. package/dist/src/containers/Tenant/utils/schemaActions.js +16 -2
  24. package/dist/src/containers/UserSettings/Setting.d.ts +7 -9
  25. package/dist/src/containers/UserSettings/Setting.js +13 -28
  26. package/dist/src/containers/UserSettings/UserSettings.d.ts +0 -2
  27. package/dist/src/containers/UserSettings/UserSettings.js +3 -6
  28. package/dist/src/containers/UserSettings/i18n/en.json +2 -2
  29. package/dist/src/containers/UserSettings/settings.js +3 -3
  30. package/dist/src/services/api.js +1 -0
  31. package/dist/src/styles/mixins.scss +5 -0
  32. package/dist/src/styles/themes.scss +1 -1
  33. package/dist/src/types/api/acl.d.ts +2 -1
  34. package/dist/src/types/api/schema/schema.d.ts +5 -0
  35. package/package.json +30 -30
  36. package/dist/src/components/InfoViewer/i18n/ru.json +0 -4
  37. package/dist/src/containers/UserSettings/UserSettings.scss +0 -9
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "6.7.0",
3
+ "version": "6.8.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -12,18 +12,18 @@
12
12
  "dependencies": {
13
13
  "@bem-react/classname": "^1.6.0",
14
14
  "@gravity-ui/axios-wrapper": "^1.4.1",
15
- "@gravity-ui/chartkit": "^5.5.0",
16
- "@gravity-ui/components": "^3.6.2",
17
- "@gravity-ui/date-utils": "^2.4.0",
18
- "@gravity-ui/i18n": "^1.5.0",
19
- "@gravity-ui/icons": "^2.9.1",
20
- "@gravity-ui/navigation": "^2.10.0",
15
+ "@gravity-ui/chartkit": "^5.9.0",
16
+ "@gravity-ui/components": "^3.7.0",
17
+ "@gravity-ui/date-utils": "^2.5.3",
18
+ "@gravity-ui/i18n": "^1.5.1",
19
+ "@gravity-ui/icons": "^2.10.0",
20
+ "@gravity-ui/navigation": "^2.16.0",
21
21
  "@gravity-ui/paranoid": "^2.0.1",
22
22
  "@gravity-ui/react-data-table": "^2.1.1",
23
- "@gravity-ui/uikit": "^6.15.0",
23
+ "@gravity-ui/uikit": "^6.20.1",
24
24
  "@gravity-ui/websql-autocomplete": "^9.1.0",
25
25
  "@reduxjs/toolkit": "^2.2.3",
26
- "axios": "^1.6.8",
26
+ "axios": "^1.7.2",
27
27
  "axios-retry": "^4.4.0",
28
28
  "colord": "^2.9.3",
29
29
  "copy-to-clipboard": "^3.3.3",
@@ -35,17 +35,17 @@
35
35
  "path-to-regexp": "^3.0.0",
36
36
  "qs": "^6.12.0",
37
37
  "react-error-boundary": "^4.0.13",
38
- "react-helmet-async": "2.0.4",
38
+ "react-helmet-async": "^2.0.5",
39
39
  "react-json-inspector": "^7.1.1",
40
40
  "react-list": "^0.8.17",
41
41
  "react-monaco-editor": "^0.55.0",
42
- "react-redux": "^9.1.0",
42
+ "react-redux": "^9.1.2",
43
43
  "react-router": "^5.3.4",
44
44
  "react-router-dom": "^5.3.4",
45
45
  "react-split": "^2.0.14",
46
46
  "redux": "^5.0.1",
47
47
  "redux-location-state": "^2.8.2",
48
- "tslib": "^2.6.2",
48
+ "tslib": "^2.6.3",
49
49
  "url": "^0.11.3",
50
50
  "use-query-params": "^2.2.1",
51
51
  "web-vitals": "^1.1.2",
@@ -122,54 +122,54 @@
122
122
  ]
123
123
  },
124
124
  "devDependencies": {
125
- "@commitlint/cli": "^19.2.1",
126
- "@commitlint/config-conventional": "^19.1.0",
125
+ "@commitlint/cli": "^19.3.0",
126
+ "@commitlint/config-conventional": "^19.2.2",
127
127
  "@gravity-ui/eslint-config": "^3.2.0",
128
128
  "@gravity-ui/prettier-config": "^1.1.0",
129
129
  "@gravity-ui/stylelint-config": "^4.0.1",
130
130
  "@gravity-ui/tsconfig": "^1.0.0",
131
131
  "@playwright/test": "^1.42.1",
132
- "@testing-library/jest-dom": "^6.4.2",
132
+ "@testing-library/jest-dom": "^6.4.6",
133
133
  "@testing-library/react": "^14.2.2",
134
134
  "@testing-library/user-event": "^14.5.2",
135
135
  "@types/jest": "^29.5.12",
136
136
  "@types/lodash": "^4.17.0",
137
137
  "@types/numeral": "^2.0.5",
138
- "@types/qs": "^6.9.14",
139
- "@types/react": "^18.2.73",
140
- "@types/react-dom": "^18.2.23",
138
+ "@types/qs": "^6.9.15",
139
+ "@types/react": "^18.3.3",
140
+ "@types/react-dom": "^18.3.0",
141
141
  "@types/react-router": "^5.1.20",
142
142
  "@types/react-router-dom": "^5.3.3",
143
143
  "copyfiles": "^2.4.1",
144
144
  "http-proxy-middleware": "^2.0.6",
145
145
  "husky": "^9.0.11",
146
146
  "jest-transform-css": "^6.0.1",
147
- "lint-staged": "^15.2.2",
147
+ "lint-staged": "^15.2.7",
148
148
  "npm-run-all": "^4.1.5",
149
149
  "postcss": "^8.4.38",
150
150
  "prettier": "^3.2.5",
151
151
  "prop-types": "^15.8.1",
152
- "react": "^18.2.0",
152
+ "react": "^18.3.1",
153
153
  "react-app-rewired": "^2.2.1",
154
- "react-dom": "^18.2.0",
154
+ "react-dom": "^18.3.1",
155
155
  "react-scripts": "^5.0.1",
156
156
  "sass": "^1.72.0",
157
157
  "source-map-explorer": "^2.5.3",
158
- "stylelint": "^15.0.0",
159
- "ts-jest": "^29.1.2",
158
+ "stylelint": "^15.11.0",
159
+ "ts-jest": "^29.1.5",
160
160
  "typescript": "^5.4.3"
161
161
  },
162
162
  "peerDependencies": {
163
163
  "prop-types": "^15.8.1",
164
- "react": "^18.2.0",
165
- "react-dom": "^18.2.0"
164
+ "react": "^18.3.1",
165
+ "react-dom": "^18.3.1"
166
166
  },
167
167
  "overrides": {
168
168
  "fork-ts-checker-webpack-plugin": "^9.0.2",
169
- "react": "^18.2.0",
170
- "react-dom": "^18.2.0",
171
- "redux": "^5.0.1",
172
- "typescript": "^5.4.3",
173
- "monaco-editor": "^0.48.0"
169
+ "react": "$react",
170
+ "react-dom": "$react-dom",
171
+ "redux": "$redux",
172
+ "typescript": "$typescript",
173
+ "monaco-editor": "$monaco-editor"
174
174
  }
175
175
  }
@@ -5,7 +5,7 @@ export interface InfoViewerItem {
5
5
  value: React.ReactNode;
6
6
  }
7
7
  export interface InfoViewerProps {
8
- title?: string;
8
+ title?: React.ReactNode;
9
9
  info?: InfoViewerItem[];
10
10
  dots?: boolean;
11
11
  size?: 's';
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { cn } from '../../utils/cn';
4
+ import i18n from './i18n';
4
5
  import './InfoViewer.scss';
5
6
  const b = cn('info-viewer');
6
7
  export const InfoViewer = ({ title, info, dots = true, size, className, multilineLabels, renderEmptyState, }) => {
7
8
  if ((!info || !info.length) && renderEmptyState) {
8
9
  return _jsx(React.Fragment, { children: renderEmptyState({ title, size }) });
9
10
  }
10
- return (_jsxs("div", { className: b({ size }, className), children: [title && _jsx("div", { className: b('title'), children: title }), info && info.length > 0 ? (_jsx("div", { className: b('items'), children: info.map((data, infoIndex) => (_jsxs("div", { className: b('row'), children: [_jsxs("div", { className: b('label'), children: [_jsx("div", { className: b('label-text', { multiline: multilineLabels }), children: data.label }), dots && _jsx("div", { className: b('dots') })] }), _jsx("div", { className: b('value'), children: data.value })] }, infoIndex))) })) : (_jsxs(React.Fragment, { children: ["No ", title, " data"] }))] }));
11
+ return (_jsxs("div", { className: b({ size }, className), children: [title && _jsx("div", { className: b('title'), children: title }), info && info.length > 0 ? (_jsx("div", { className: b('items'), children: info.map((data, infoIndex) => (_jsxs("div", { className: b('row'), children: [_jsxs("div", { className: b('label'), children: [_jsx("div", { className: b('label-text', { multiline: multilineLabels }), children: data.label }), dots && _jsx("div", { className: b('dots') })] }), _jsx("div", { className: b('value'), children: data.value })] }, infoIndex))) })) : (i18n('no-data'))] }));
11
12
  };
12
13
  export default InfoViewer;
@@ -1,4 +1,5 @@
1
1
  {
2
2
  "common.created": "Created",
3
- "common.type": "Type"
3
+ "common.type": "Type",
4
+ "no-data": "No data"
4
5
  }
@@ -1,2 +1,2 @@
1
- declare const _default: (key: "common.created" | "common.type", params?: import("@gravity-ui/i18n").Params | undefined) => string;
1
+ declare const _default: (key: "common.created" | "common.type" | "no-data", params?: import("@gravity-ui/i18n").Params | undefined) => string;
2
2
  export default _default;
@@ -1,5 +1,4 @@
1
1
  import { registerKeysets } from '../../../utils/i18n';
2
2
  import en from './en.json';
3
- import ru from './ru.json';
4
3
  const COMPONENT = 'ydb-components-info-viewer';
5
- export default registerKeysets(COMPONENT, { ru, en });
4
+ export default registerKeysets(COMPONENT, { en });
@@ -10,7 +10,7 @@ import i18n from './i18n';
10
10
  const defaultUserSettings = settings;
11
11
  defaultUserSettings[2].sections[0].settings.push({
12
12
  title: i18n('settings.useClusterBalancerAsBackend.title'),
13
- helpPopoverContent: i18n('settings.useClusterBalancerAsBackend.popover'),
13
+ description: i18n('settings.useClusterBalancerAsBackend.popover'),
14
14
  settingKey: USE_CLUSTER_BALANCER_AS_BACKEND_KEY,
15
15
  });
16
16
  export function AppWithClusters({ store, history, getMonitoringLink = getMonitoringLinkDefault, getMonitoringClusterLink = getMonitoringClusterLinkDefault, userSettings = defaultUserSettings, children, }) {
@@ -63,7 +63,8 @@ const erasureColumn = {
63
63
  const degradedColumn = {
64
64
  name: GROUPS_COLUMNS_IDS.Degraded,
65
65
  header: 'Degraded',
66
- width: 100,
66
+ width: 110,
67
+ resizeMinWidth: 110,
67
68
  render: ({ row }) => row.Degraded ? (_jsxs(Label, { theme: getDegradedSeverity(row), children: ["Degraded: ", row.Degraded] })) : ('-'),
68
69
  align: DataTable.LEFT,
69
70
  defaultOrder: DataTable.DESCENDING,
@@ -71,8 +72,8 @@ const degradedColumn = {
71
72
  const usageColumn = {
72
73
  name: GROUPS_COLUMNS_IDS.Usage,
73
74
  header: 'Usage',
74
- width: 100,
75
- resizeMinWidth: 70,
75
+ width: 75,
76
+ resizeMinWidth: 75,
76
77
  render: ({ row }) => {
77
78
  // without a limit the usage can be evaluated as 0,
78
79
  // but the absence of a value is more clear
@@ -1,16 +1,14 @@
1
+ import { __rest } from "tslib";
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import React from 'react';
4
+ import { DefinitionList } from '@gravity-ui/components';
3
5
  import { ResponseError } from '../../../components/Errors/ResponseError';
4
6
  import { Loader } from '../../../components/Loader';
5
- import { ResizeableDataTable } from '../../../components/ResizeableDataTable/ResizeableDataTable';
6
7
  import { schemaAclApi } from '../../../store/reducers/schemaAcl/schemaAcl';
7
8
  import { cn } from '../../../utils/cn';
8
- import { DEFAULT_TABLE_SETTINGS } from '../../../utils/constants';
9
9
  import i18n from '../i18n';
10
10
  import './Acl.scss';
11
11
  const b = cn('ydb-acl');
12
- const ACL_COLUMNS_WIDTH_LS_KEY = 'aclTableColumnsWidth';
13
- const TABLE_SETTINGS = Object.assign(Object.assign({}, DEFAULT_TABLE_SETTINGS), { dynamicRender: false, stickyTop: 36 });
14
12
  const prepareLogin = (value) => {
15
13
  if (value && value.endsWith('@staff') && !value.startsWith('svc_')) {
16
14
  const login = value.split('@')[0];
@@ -18,60 +16,88 @@ const prepareLogin = (value) => {
18
16
  }
19
17
  return value;
20
18
  };
21
- const columns = [
22
- {
23
- name: 'AccessType',
24
- header: 'Access Type',
25
- sortable: false,
26
- render: ({ row }) => row.AccessType,
27
- },
28
- {
29
- name: 'AccessRights',
30
- header: 'Access Rights',
31
- render: ({ row }) => {
32
- var _a;
33
- return (_a = row.AccessRights) === null || _a === void 0 ? void 0 : _a.map((item, index) => {
34
- return _jsx("div", { children: item }, index);
35
- });
36
- },
37
- sortable: false,
38
- },
39
- {
40
- name: 'Subject',
41
- sortable: false,
42
- render: ({ row }) => {
43
- return prepareLogin(row.Subject);
44
- },
45
- width: 140,
46
- },
47
- {
48
- name: 'InheritanceType',
49
- header: 'Inheritance Type',
50
- render: ({ row }) => {
51
- var _a;
52
- return (_a = row.InheritanceType) === null || _a === void 0 ? void 0 : _a.map((item, index) => {
53
- return _jsx("div", { children: item }, index);
54
- });
19
+ const aclParams = ['access', 'type', 'inheritance'];
20
+ const aclParamToName = {
21
+ access: 'Access',
22
+ type: 'Access type',
23
+ inheritance: 'Inheritance type',
24
+ };
25
+ const defaultInheritanceType = ['Object', 'Container'];
26
+ const defaultAccessType = 'Allow';
27
+ const defaultInheritanceTypeSet = new Set(defaultInheritanceType);
28
+ function normalizeAcl(acl) {
29
+ return acl.map((ace) => {
30
+ const { AccessRules = [], AccessRights = [], AccessType, InheritanceType, Subject } = ace;
31
+ const access = AccessRules.concat(AccessRights);
32
+ //"Allow" is default access type. We want to show it only if it isn't default
33
+ const type = AccessType === defaultAccessType ? undefined : AccessType;
34
+ let inheritance;
35
+ // ['Object', 'Container'] - is default inheritance type. We want to show it only if it isn't default
36
+ if ((InheritanceType === null || InheritanceType === void 0 ? void 0 : InheritanceType.length) !== defaultInheritanceTypeSet.size ||
37
+ InheritanceType.some((t) => !defaultInheritanceTypeSet.has(t))) {
38
+ inheritance = InheritanceType;
39
+ }
40
+ return {
41
+ access: access.length ? access : undefined,
42
+ type,
43
+ inheritance,
44
+ Subject,
45
+ };
46
+ });
47
+ }
48
+ function DefinitionValue({ value }) {
49
+ const normalizedValue = typeof value === 'string' ? [value] : value;
50
+ return (_jsx("div", { className: b('definition-content'), children: normalizedValue.map((el) => (_jsx("span", { children: el }, el))) }));
51
+ }
52
+ function getAclListItems(acl) {
53
+ if (!acl || !acl.length) {
54
+ return [];
55
+ }
56
+ const normalizedAcl = normalizeAcl(acl);
57
+ return normalizedAcl.map((_a) => {
58
+ var { Subject } = _a, data = __rest(_a, ["Subject"]);
59
+ const definedDataEntries = Object.entries(data).filter(([_key, value]) => Boolean(value));
60
+ if (definedDataEntries.length === 1 && definedDataEntries[0][0] === 'access') {
61
+ return {
62
+ name: Subject,
63
+ content: _jsx(DefinitionValue, { value: definedDataEntries[0][1] }),
64
+ };
65
+ }
66
+ return {
67
+ label: _jsx("span", { className: b('group-label'), children: Subject }),
68
+ items: aclParams
69
+ .map((key) => {
70
+ const value = data[key];
71
+ if (value) {
72
+ return {
73
+ name: aclParamToName[key],
74
+ content: _jsx(DefinitionValue, { value: value }),
75
+ };
76
+ }
77
+ return undefined;
78
+ })
79
+ .filter(Boolean),
80
+ };
81
+ });
82
+ }
83
+ function getOwnerItem(owner) {
84
+ const preparedOwner = prepareLogin(owner);
85
+ if (!preparedOwner) {
86
+ return [];
87
+ }
88
+ return [
89
+ {
90
+ name: _jsx("span", { className: b('owner'), children: preparedOwner }),
91
+ content: _jsx("span", { className: b('owner'), children: i18n('acl.owner') }),
55
92
  },
56
- sortable: false,
57
- },
58
- ];
93
+ ];
94
+ }
59
95
  export const Acl = ({ path }) => {
60
96
  const { currentData, isFetching, error } = schemaAclApi.useGetSchemaAclQuery({ path });
61
97
  const loading = isFetching && !currentData;
62
98
  const { acl, owner } = currentData || {};
63
- const renderTable = () => {
64
- if (!acl || !acl.length) {
65
- return null;
66
- }
67
- return (_jsx(ResizeableDataTable, { columnsWidthLSKey: ACL_COLUMNS_WIDTH_LS_KEY, columns: columns, data: acl, settings: TABLE_SETTINGS }));
68
- };
69
- const renderOwner = () => {
70
- if (!owner) {
71
- return null;
72
- }
73
- return (_jsxs("div", { className: b('owner-container'), children: [_jsx("span", { className: b('owner-label'), children: `${i18n('acl.owner')}: ` }), prepareLogin(owner)] }));
74
- };
99
+ const aclListItems = getAclListItems(acl);
100
+ const ownerItem = getOwnerItem(owner);
75
101
  if (loading) {
76
102
  return _jsx(Loader, {});
77
103
  }
@@ -81,5 +107,5 @@ export const Acl = ({ path }) => {
81
107
  if (!acl && !owner) {
82
108
  return _jsx(React.Fragment, { children: i18n('acl.empty') });
83
109
  }
84
- return (_jsx("div", { className: b(), children: _jsxs("div", { className: b('result'), children: [renderOwner(), renderTable()] }) }));
110
+ return (_jsxs("div", { className: b(), children: [ownerItem.length ? (_jsx(DefinitionList, { items: ownerItem, nameMaxWidth: 200, className: b('owner-container') })) : null, aclListItems.length ? (_jsx(DefinitionList, { items: aclListItems, nameMaxWidth: 200, className: b('result') })) : null] }));
85
111
  };
@@ -1,17 +1,22 @@
1
1
  @import '../../../styles/mixins.scss';
2
2
 
3
3
  .ydb-acl {
4
- &__result {
5
- align-self: flex-start;
6
- }
7
-
4
+ width: 100%;
8
5
  &__owner-container {
9
- position: sticky;
10
- z-index: 2;
11
- top: 0;
12
-
6
+ padding-bottom: 25px;
7
+ }
8
+ &__result {
13
9
  padding-bottom: 16px;
10
+ }
14
11
 
15
- background-color: var(--g-color-base-background);
12
+ &__owner {
13
+ font-weight: 600;
14
+ }
15
+ &__definition-content {
16
+ display: flex;
17
+ flex-direction: column;
18
+ }
19
+ &__group-label {
20
+ @include subheader-2-typography();
16
21
  }
17
22
  }
@@ -2,13 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { InfoViewer } from '../../../../../components/InfoViewer';
4
4
  import { cn } from '../../../../../utils/cn';
5
- import { getEntityName } from '../../../utils';
5
+ import { EntityTitle } from '../../../EntityTitle/EntityTitle';
6
6
  import i18n from './i18n';
7
7
  import { prepareTableInfo } from './prepareTableInfo';
8
8
  import './TableInfo.scss';
9
9
  const b = cn('ydb-diagnostics-table-info');
10
10
  export const TableInfo = ({ data, type, olapStats }) => {
11
- const entityName = getEntityName(data === null || data === void 0 ? void 0 : data.PathDescription);
11
+ const title = _jsx(EntityTitle, { data: data === null || data === void 0 ? void 0 : data.PathDescription });
12
12
  const { generalInfo = [], tableStatsInfo = [], tabletMetricsInfo = [], partitionConfigInfo = [], } = React.useMemo(() => prepareTableInfo(data, type, olapStats), [data, type, olapStats]);
13
- return (_jsxs("div", { className: b(), children: [_jsx(InfoViewer, { info: generalInfo, title: entityName, className: b('info-block'), renderEmptyState: () => _jsx("div", { className: b('title'), children: entityName }) }), _jsxs("div", { className: b('row'), children: [_jsx("div", { className: b('col'), children: tableStatsInfo.map((info, index) => (_jsx(InfoViewer, { info: info, title: index === 0 ? i18n('tableStats') : undefined, className: b('info-block'), renderEmptyState: () => null }, index))) }), tabletMetricsInfo.length > 0 || partitionConfigInfo.length > 0 ? (_jsxs("div", { className: b('col'), children: [_jsx(InfoViewer, { info: tabletMetricsInfo, title: i18n('tabletMetrics'), className: b('info-block'), renderEmptyState: () => null }), _jsx(InfoViewer, { info: partitionConfigInfo, title: i18n('partitionConfig'), className: b('info-block'), renderEmptyState: () => null })] })) : null] })] }));
13
+ return (_jsxs("div", { className: b(), children: [_jsx(InfoViewer, { info: generalInfo, title: title, className: b('info-block'), renderEmptyState: () => _jsx("div", { className: b('title'), children: title }) }), _jsxs("div", { className: b('row'), children: [_jsx("div", { className: b('col'), children: tableStatsInfo.map((info, index) => (_jsx(InfoViewer, { info: info, title: index === 0 ? i18n('tableStats') : undefined, className: b('info-block'), renderEmptyState: () => null }, index))) }), tabletMetricsInfo.length > 0 || partitionConfigInfo.length > 0 ? (_jsxs("div", { className: b('col'), children: [_jsx(InfoViewer, { info: tabletMetricsInfo, title: i18n('tabletMetrics'), className: b('info-block'), renderEmptyState: () => null }), _jsx(InfoViewer, { info: partitionConfigInfo, title: i18n('partitionConfig'), className: b('info-block'), renderEmptyState: () => null })] })) : null] })] }));
14
14
  };
@@ -1,2 +1,2 @@
1
- declare const _default: (key: "nodes" | "queries" | "groups" | "top" | "shards" | "tables" | "no-data" | "no-pools-data" | "top-nodes.empty-data" | "top-groups.empty-data" | "by-pools-usage" | "by-cpu-time" | "by-cpu-usage" | "by-load" | "by-memory" | "by-usage" | "by-size" | "cards.cpu-label" | "cards.storage-label" | "cards.memory-label" | "charts.queries-per-second" | "charts.transaction-latency" | "charts.cpu-usage" | "charts.storage-usage" | "charts.memory-usage" | "storage.tablet-storage-title" | "storage.tablet-storage-description" | "storage.db-storage-title" | "storage.db-storage-description", params?: import("@gravity-ui/i18n").Params | undefined) => string;
1
+ declare const _default: (key: "nodes" | "queries" | "groups" | "no-data" | "top" | "shards" | "tables" | "no-pools-data" | "top-nodes.empty-data" | "top-groups.empty-data" | "by-pools-usage" | "by-cpu-time" | "by-cpu-usage" | "by-load" | "by-memory" | "by-usage" | "by-size" | "cards.cpu-label" | "cards.storage-label" | "cards.memory-label" | "charts.queries-per-second" | "charts.transaction-latency" | "charts.cpu-usage" | "charts.storage-usage" | "charts.memory-usage" | "storage.tablet-storage-title" | "storage.tablet-storage-description" | "storage.db-storage-title" | "storage.db-storage-description", params?: import("@gravity-ui/i18n").Params | undefined) => string;
2
2
  export default _default;
@@ -0,0 +1,6 @@
1
+ import type { TPathDescription } from '../../../types/api/schema';
2
+ interface EntityTitleProps {
3
+ data?: TPathDescription;
4
+ }
5
+ export declare function EntityTitle({ data }: EntityTitleProps): string | import("react/jsx-runtime").JSX.Element | undefined;
6
+ export {};
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Flex, Label } from '@gravity-ui/uikit';
3
+ import i18n from '../i18n';
4
+ import { getEntityName, isReadOnlyTable } from '../utils';
5
+ export function EntityTitle({ data }) {
6
+ const entityName = getEntityName(data);
7
+ if (isReadOnlyTable(data)) {
8
+ return (_jsxs(Flex, { gap: 1, wrap: 'nowrap', children: [entityName, " ", _jsx(Label, { children: i18n('label.read-only') })] }));
9
+ }
10
+ return entityName;
11
+ }
@@ -13,7 +13,6 @@ import InfoViewer from '../../../components/InfoViewer/InfoViewer';
13
13
  import { LinkWithIcon } from '../../../components/LinkWithIcon/LinkWithIcon';
14
14
  import { Loader } from '../../../components/Loader';
15
15
  import SplitPane from '../../../components/SplitPane';
16
- import { getEntityName } from '../../../containers/Tenant/utils';
17
16
  import routes, { createExternalUILink, createHref } from '../../../routes';
18
17
  import { schemaApi, setShowPreview } from '../../../store/reducers/schema/schema';
19
18
  import { TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID, TENANT_SUMMARY_TABS_IDS, } from '../../../store/reducers/tenant/constants';
@@ -24,6 +23,7 @@ import { DEFAULT_IS_TENANT_COMMON_INFO_COLLAPSED, DEFAULT_SIZE_TENANT_SUMMARY_KE
24
23
  import { formatDateTime, formatSecondsToHours } from '../../../utils/dataFormatters/dataFormatters';
25
24
  import { useTypedDispatch, useTypedSelector } from '../../../utils/hooks';
26
25
  import { Acl } from '../Acl/Acl';
26
+ import { EntityTitle } from '../EntityTitle/EntityTitle';
27
27
  import { SchemaTree } from '../Schema/SchemaTree/SchemaTree';
28
28
  import { SchemaViewer } from '../Schema/SchemaViewer/SchemaViewer';
29
29
  import { TENANT_INFO_TABS, TENANT_SCHEMA_TAB, TenantTabsGroups } from '../TenantPages';
@@ -86,7 +86,7 @@ export function ObjectSummary({ type, subType, tenantName, path, onCollapseSumma
86
86
  value: formatDateTime(CreateStep, ''),
87
87
  });
88
88
  const { PathDescription } = currentObjectData;
89
- const title = getEntityName(PathDescription);
89
+ const title = _jsx(EntityTitle, { data: PathDescription });
90
90
  const getPathTypeOverview = {
91
91
  [EPathType.EPathTypeInvalid]: undefined,
92
92
  [EPathType.EPathTypeDir]: undefined,
@@ -15,5 +15,5 @@ export const TenantNavigation = () => {
15
15
  nextItem === null || nextItem === void 0 ? void 0 : nextItem.onForward();
16
16
  };
17
17
  const getCurrentItem = () => navigationItems.find((item) => item.current) || navigationItems[0];
18
- return (_jsx("div", { className: b(), children: _jsx(RadioButton, { width: "auto", onUpdate: handleUpdate, size: "l", className: b('body'), defaultValue: getCurrentItem().id, options: navigationItems.map(transformItemToOption) }) }));
18
+ return (_jsx("div", { className: b(), children: _jsx(RadioButton, { width: "auto", onUpdate: handleUpdate, size: "l", className: b('body'), value: getCurrentItem().id, options: navigationItems.map(transformItemToOption) }) }));
19
19
  };
@@ -21,6 +21,7 @@
21
21
  "summary.mode": "Mode",
22
22
  "summary.format": "Format",
23
23
  "summary.retention": "Retention",
24
+ "label.read-only": "ReadOnly",
24
25
  "actions.copied": "The path is copied to the clipboard",
25
26
  "actions.notCopied": "Couldn’t copy the path",
26
27
  "actions.copyPath": "Copy path",
@@ -29,6 +30,7 @@
29
30
  "actions.createExternalTable": "Create external table...",
30
31
  "actions.createTopic": "Create topic...",
31
32
  "actions.createColumnTable": "Create column table...",
33
+ "actions.createAsyncReplication": "Create async replication...",
32
34
  "actions.createView": "Create view...",
33
35
  "actions.dropTable": "Drop table...",
34
36
  "actions.dropTopic": "Drop topic...",
@@ -36,5 +38,7 @@
36
38
  "actions.alterTable": "Alter table...",
37
39
  "actions.alterTopic": "Alter topic...",
38
40
  "actions.selectQuery": "Select query...",
39
- "actions.upsertQuery": "Upsert query..."
41
+ "actions.upsertQuery": "Upsert query...",
42
+ "actions.alterReplication": "Alter async replicaton...",
43
+ "actions.dropReplication": "Drop async replicaton..."
40
44
  }
@@ -1,2 +1,2 @@
1
- declare const _default: (key: "page.title" | "pages.query" | "pages.diagnostics" | "acl.owner" | "acl.empty" | "summary.navigation" | "summary.showPreview" | "summary.source-type" | "summary.data-source" | "summary.copySchemaPath" | "summary.type" | "summary.subtype" | "summary.id" | "summary.version" | "summary.created" | "summary.partitions" | "summary.paths" | "summary.shards" | "summary.state" | "summary.mode" | "summary.format" | "summary.retention" | "actions.copied" | "actions.notCopied" | "actions.copyPath" | "actions.openPreview" | "actions.createTable" | "actions.createExternalTable" | "actions.createTopic" | "actions.createColumnTable" | "actions.createView" | "actions.dropTable" | "actions.dropTopic" | "actions.dropView" | "actions.alterTable" | "actions.alterTopic" | "actions.selectQuery" | "actions.upsertQuery", params?: import("@gravity-ui/i18n").Params | undefined) => string;
1
+ declare const _default: (key: "page.title" | "pages.query" | "pages.diagnostics" | "acl.owner" | "acl.empty" | "summary.navigation" | "summary.showPreview" | "summary.source-type" | "summary.data-source" | "summary.copySchemaPath" | "summary.type" | "summary.subtype" | "summary.id" | "summary.version" | "summary.created" | "summary.partitions" | "summary.paths" | "summary.shards" | "summary.state" | "summary.mode" | "summary.format" | "summary.retention" | "label.read-only" | "actions.copied" | "actions.notCopied" | "actions.copyPath" | "actions.openPreview" | "actions.createTable" | "actions.createExternalTable" | "actions.createTopic" | "actions.createColumnTable" | "actions.createAsyncReplication" | "actions.createView" | "actions.dropTable" | "actions.dropTopic" | "actions.dropView" | "actions.alterTable" | "actions.alterTopic" | "actions.selectQuery" | "actions.upsertQuery" | "actions.alterReplication" | "actions.dropReplication", params?: import("@gravity-ui/i18n").Params | undefined) => string;
2
2
  export default _default;
@@ -1,2 +1,3 @@
1
1
  import type { TPathDescription } from '../../../types/api/schema';
2
2
  export declare const getEntityName: (pathDescription?: TPathDescription) => string | undefined;
3
+ export declare const isReadOnlyTable: (pathDescription?: TPathDescription) => boolean | undefined;
@@ -3,3 +3,9 @@ export const getEntityName = (pathDescription) => {
3
3
  const { PathType, PathSubType } = (pathDescription === null || pathDescription === void 0 ? void 0 : pathDescription.Self) || {};
4
4
  return mapPathTypeToEntityName(PathType, PathSubType);
5
5
  };
6
+ export const isReadOnlyTable = (pathDescription) => {
7
+ var _a;
8
+ return (_a = pathDescription === null || pathDescription === void 0 ? void 0 : pathDescription.UserAttributes) === null || _a === void 0 ? void 0 : _a.some(({ Key, Value }) => {
9
+ return Key === '__async_replica' && Value === 'true';
10
+ });
11
+ };
@@ -1,5 +1,6 @@
1
1
  export declare const createTableTemplate: (path: string) => string;
2
2
  export declare const createColumnTableTemplate: (path: string) => string;
3
+ export declare const createAsyncReplicationTemplate: () => string;
3
4
  export declare const alterTableTemplate: (path: string) => string;
4
5
  export declare const selectQueryTemplate: (path: string) => string;
5
6
  export declare const upsertQueryTemplate: (path: string) => string;
@@ -10,3 +11,5 @@ export declare const alterTopicTemplate: (path: string) => string;
10
11
  export declare const dropTopicTemplate: (path: string) => string;
11
12
  export declare const createViewTemplate: (path: string) => string;
12
13
  export declare const dropViewTemplate: (path: string) => string;
14
+ export declare const dropAsyncReplicationTemplate: (path: string) => string;
15
+ export declare const alterAsyncReplicationTemplate: (path: string) => string;
@@ -42,6 +42,20 @@ CREATE TABLE \`${path}/ydb_column_table\` (
42
42
  PARTITION BY HASH(id)
43
43
  WITH (STORE = COLUMN)`;
44
44
  };
45
+ export const createAsyncReplicationTemplate = () => {
46
+ return `CREATE OBJECT secret_name (TYPE SECRET) WITH value="secret_value";
47
+
48
+ CREATE ASYNC REPLICATION my_replication
49
+ FOR \`/remote_database/table_name\` AS \`local_table_name\` --[, \`/remote_database/another_table_name\` AS \`another_local_table_name\` ...]
50
+ WITH (
51
+ CONNECTION_STRING="grpcs://mydb.ydb.tech:2135/?database=/remote_database",
52
+ TOKEN_SECRET_NAME = "secret_name"
53
+ -- ENDPOINT="mydb.ydb.tech:2135",
54
+ -- DATABASE=\`/remote_database\`,
55
+ -- USER="user",
56
+ -- PASSWORD_SECRET_NAME="your_password"
57
+ );`;
58
+ };
45
59
  export const alterTableTemplate = (path) => {
46
60
  return `ALTER TABLE \`${path}\`
47
61
  ADD COLUMN is_deleted Bool;`;
@@ -123,3 +137,9 @@ export const createViewTemplate = (path) => {
123
137
  export const dropViewTemplate = (path) => {
124
138
  return `DROP VIEW \`${path}\`;`;
125
139
  };
140
+ export const dropAsyncReplicationTemplate = (path) => {
141
+ return `DROP ASYNC REPLICATION \`${path}\`;`;
142
+ };
143
+ export const alterAsyncReplicationTemplate = (path) => {
144
+ return `ALTER ASYNC REPLICATION \`${path}\` SET (STATE = "DONE", FAILOVER_MODE = "FORCE");`;
145
+ };
@@ -4,7 +4,7 @@ import { TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID } from '../../../store/reducers/
4
4
  import { setQueryTab, setTenantPage } from '../../../store/reducers/tenant/tenant';
5
5
  import createToast from '../../../utils/createToast';
6
6
  import i18n from '../i18n';
7
- import { alterTableTemplate, alterTopicTemplate, createColumnTableTemplate, createExternalTableTemplate, createTableTemplate, createTopicTemplate, createViewTemplate, dropExternalTableTemplate, dropTopicTemplate, dropViewTemplate, selectQueryTemplate, upsertQueryTemplate, } from './queryTemplates';
7
+ import { alterAsyncReplicationTemplate, alterTableTemplate, alterTopicTemplate, createAsyncReplicationTemplate, createColumnTableTemplate, createExternalTableTemplate, createTableTemplate, createTopicTemplate, createViewTemplate, dropAsyncReplicationTemplate, dropExternalTableTemplate, dropTopicTemplate, dropViewTemplate, selectQueryTemplate, upsertQueryTemplate, } from './queryTemplates';
8
8
  const bindActions = (path, dispatch, additionalEffects) => {
9
9
  const { setActivePath, setQueryMode } = additionalEffects;
10
10
  const inputQuery = (tmpl, mode) => () => {
@@ -19,6 +19,9 @@ const bindActions = (path, dispatch, additionalEffects) => {
19
19
  return {
20
20
  createTable: inputQuery(createTableTemplate, 'script'),
21
21
  createColumnTable: inputQuery(createColumnTableTemplate, 'script'),
22
+ createAsyncReplication: inputQuery(createAsyncReplicationTemplate, 'script'),
23
+ alterAsyncReplication: inputQuery(alterAsyncReplicationTemplate, 'script'),
24
+ dropAsyncReplication: inputQuery(dropAsyncReplicationTemplate, 'script'),
22
25
  alterTable: inputQuery(alterTableTemplate, 'script'),
23
26
  selectQuery: inputQuery(selectQueryTemplate),
24
27
  upsertQuery: inputQuery(upsertQueryTemplate),
@@ -57,6 +60,10 @@ export const getActions = (dispatch, additionalEffects) => (path, type) => {
57
60
  [
58
61
  { text: i18n('actions.createTable'), action: actions.createTable },
59
62
  { text: i18n('actions.createColumnTable'), action: actions.createColumnTable },
63
+ {
64
+ text: i18n('actions.createAsyncReplication'),
65
+ action: actions.createAsyncReplication,
66
+ },
60
67
  { text: i18n('actions.createTopic'), action: actions.createTopic },
61
68
  { text: i18n('actions.createView'), action: actions.createView },
62
69
  ],
@@ -95,11 +102,18 @@ export const getActions = (dispatch, additionalEffects) => (path, type) => {
95
102
  [{ text: i18n('actions.selectQuery'), action: actions.selectQuery }],
96
103
  [{ text: i18n('actions.dropView'), action: actions.dropView }],
97
104
  ];
105
+ const ASYNC_REPLICATION_SET = [
106
+ [copyItem],
107
+ [
108
+ { text: i18n('actions.alterReplication'), action: actions.alterAsyncReplication },
109
+ { text: i18n('actions.dropReplication'), action: actions.dropAsyncReplication },
110
+ ],
111
+ ];
98
112
  const JUST_COPY = [copyItem];
99
113
  // verbose mapping to guarantee a correct actions set for new node types
100
114
  // TS will error when a new type is added in the lib but is not mapped here
101
115
  const nodeTypeToActions = {
102
- async_replication: JUST_COPY,
116
+ async_replication: ASYNC_REPLICATION_SET,
103
117
  database: DIR_SET,
104
118
  directory: DIR_SET,
105
119
  table: TABLE_SET,
@@ -1,11 +1,16 @@
1
1
  /// <reference types="react" />
2
+ export interface SettingsInfoFieldProps {
3
+ type: 'info';
4
+ title: string;
5
+ description?: React.ReactNode;
6
+ content: React.ReactNode;
7
+ }
2
8
  export type SettingsElementType = 'switch' | 'radio';
3
9
  export interface SettingProps {
4
10
  type?: SettingsElementType;
5
11
  title: string;
6
12
  description?: React.ReactNode;
7
13
  settingKey: string;
8
- helpPopoverContent?: React.ReactNode;
9
14
  options?: {
10
15
  value: string;
11
16
  content: string;
@@ -13,11 +18,4 @@ export interface SettingProps {
13
18
  defaultValue?: unknown;
14
19
  onValueUpdate?: VoidFunction;
15
20
  }
16
- export declare const Setting: ({ type, settingKey, title, description, helpPopoverContent, options, defaultValue, onValueUpdate, }: SettingProps) => import("react/jsx-runtime").JSX.Element;
17
- export interface SettingsInfoFieldProps {
18
- type: 'info';
19
- title: string;
20
- description?: React.ReactNode;
21
- content: React.ReactNode;
22
- }
23
- export declare const SettingsInfoField: ({ title, description, content }: SettingsInfoFieldProps) => import("react/jsx-runtime").JSX.Element;
21
+ export declare const Setting: ({ type, settingKey, options, defaultValue, onValueUpdate, }: SettingProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -1,40 +1,25 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Settings } from '@gravity-ui/navigation';
3
2
  import { RadioButton, Switch } from '@gravity-ui/uikit';
4
- import { LabelWithPopover } from '../../components/LabelWithPopover/LabelWithPopover';
5
3
  import { useSetting } from '../../utils/hooks';
6
- import { b } from './UserSettings';
7
- export const Setting = ({ type = 'switch', settingKey, title, description, helpPopoverContent, options, defaultValue, onValueUpdate, }) => {
4
+ export const Setting = ({ type = 'switch', settingKey, options, defaultValue, onValueUpdate, }) => {
8
5
  const [settingValue, setValue] = useSetting(settingKey, defaultValue);
9
6
  const onUpdate = (value) => {
10
7
  setValue(value);
11
8
  onValueUpdate === null || onValueUpdate === void 0 ? void 0 : onValueUpdate();
12
9
  };
13
- const renderTitleComponent = (value) => {
14
- if (helpPopoverContent) {
15
- return (_jsx(LabelWithPopover, { className: b('item-with-popup'), contentClassName: b('popup'), text: value, popoverContent: helpPopoverContent }));
10
+ switch (type) {
11
+ case 'switch': {
12
+ return _jsx(Switch, { checked: Boolean(settingValue), onUpdate: onUpdate });
16
13
  }
17
- return value;
18
- };
19
- const getSettingsElement = (elementType) => {
20
- switch (elementType) {
21
- case 'switch': {
22
- return _jsx(Switch, { checked: Boolean(settingValue), onUpdate: onUpdate });
23
- }
24
- case 'radio': {
25
- if (!options) {
26
- return null;
27
- }
28
- return (_jsx(RadioButton, { value: String(settingValue), onUpdate: onUpdate, children: options.map(({ value, content }) => {
29
- return (_jsx(RadioButton.Option, { value: value, children: content }, value));
30
- }) }));
31
- }
32
- default:
14
+ case 'radio': {
15
+ if (!options) {
33
16
  return null;
17
+ }
18
+ return (_jsx(RadioButton, { value: String(settingValue), onUpdate: onUpdate, children: options.map(({ value, content }) => {
19
+ return (_jsx(RadioButton.Option, { value: value, children: content }, value));
20
+ }) }));
34
21
  }
35
- };
36
- return (_jsx(Settings.Item, { title: title, highlightedTitle: title, description: description, renderTitleComponent: renderTitleComponent, children: getSettingsElement(type) }));
37
- };
38
- export const SettingsInfoField = ({ title, description, content }) => {
39
- return (_jsx(Settings.Item, { title: title, highlightedTitle: title, description: description, children: content }));
22
+ default:
23
+ return null;
24
+ }
40
25
  };
@@ -1,6 +1,4 @@
1
1
  import type { YDBEmbeddedUISettings } from './settings';
2
- import './UserSettings.scss';
3
- export declare const b: import("@bem-react/classname").ClassNameFormatter;
4
2
  interface UserSettingsProps {
5
3
  settings?: YDBEmbeddedUISettings;
6
4
  }
@@ -1,10 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Settings } from '@gravity-ui/navigation';
3
- import { cn } from '../../utils/cn';
4
- import { Setting, SettingsInfoField } from './Setting';
3
+ import { Setting } from './Setting';
5
4
  import { settings } from './settings';
6
- import './UserSettings.scss';
7
- export const b = cn('ydb-user-settings');
8
5
  export const UserSettings = ({ settings: userSettings = settings }) => {
9
6
  return (_jsx(Settings, { children: userSettings.map((page) => {
10
7
  const { id, title, icon, sections = [] } = page;
@@ -12,9 +9,9 @@ export const UserSettings = ({ settings: userSettings = settings }) => {
12
9
  const { title: sectionTitle, settings: sectionSettings = [] } = section;
13
10
  return (_jsx(Settings.Section, { title: sectionTitle, children: sectionSettings.map((setting) => {
14
11
  if (setting.type === 'info') {
15
- return (_jsx(SettingsInfoField, Object.assign({}, setting), setting.title));
12
+ return (_jsx(Settings.Item, Object.assign({}, setting, { children: setting.content }), setting.title));
16
13
  }
17
- return _jsx(Setting, Object.assign({}, setting), setting.settingKey);
14
+ return (_jsx(Settings.Item, Object.assign({}, setting, { children: _jsx(Setting, Object.assign({}, setting)) }), setting.title));
18
15
  }) }, id));
19
16
  }) }, id));
20
17
  }) }));
@@ -22,10 +22,10 @@
22
22
  "settings.binaryDataInPlainTextDisplay.description": "Available starting from version 24.1",
23
23
  "settings.invertedDisks.title": "Inverted disks space indicators",
24
24
  "settings.useNodesEndpoint.title": "Break the Nodes tab in Diagnostics",
25
- "settings.useNodesEndpoint.popover": "Use /viewer/json/nodes endpoint for Nodes Tab in diagnostics. It could return incorrect data on some versions",
25
+ "settings.useNodesEndpoint.popover": "Use /viewer/json/nodes endpoint for Nodes tab in diagnostics. It could return incorrect data on versions before 24-1",
26
26
  "settings.useVirtualTables.title": "Use table with data load on scroll for Nodes and Storage tabs",
27
27
  "settings.useVirtualTables.popover": "It will increase performance, but could work unstable",
28
28
  "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",
29
+ "settings.queryUseMultiSchema.popover": "Use 'multi' schema for queries. It enables queries with multiple result sets. It returns nothing on versions 23-3 and older",
30
30
  "settings.about.interfaceVersionInfoField.title": "Interface version"
31
31
  }
@@ -57,17 +57,17 @@ export const invertedDisksSetting = {
57
57
  export const useNodesEndpointSetting = {
58
58
  settingKey: USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
59
59
  title: i18n('settings.useNodesEndpoint.title'),
60
- helpPopoverContent: i18n('settings.useNodesEndpoint.popover'),
60
+ description: i18n('settings.useNodesEndpoint.popover'),
61
61
  };
62
62
  export const useVirtualTables = {
63
63
  settingKey: USE_BACKEND_PARAMS_FOR_TABLES_KEY,
64
64
  title: i18n('settings.useVirtualTables.title'),
65
- helpPopoverContent: i18n('settings.useVirtualTables.popover'),
65
+ description: i18n('settings.useVirtualTables.popover'),
66
66
  };
67
67
  export const queryUseMultiSchemaSetting = {
68
68
  settingKey: QUERY_USE_MULTI_SCHEMA_KEY,
69
69
  title: i18n('settings.queryUseMultiSchema.title'),
70
- helpPopoverContent: i18n('settings.queryUseMultiSchema.popover'),
70
+ description: i18n('settings.queryUseMultiSchema.popover'),
71
71
  };
72
72
  export const enableAutocompleteSetting = {
73
73
  settingKey: ENABLE_AUTOCOMPLETE,
@@ -128,6 +128,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
128
128
  getSchemaAcl({ path }, { concurrentId, signal } = {}) {
129
129
  return this.get(this.getPath('/viewer/json/acl'), {
130
130
  path,
131
+ merge_rules: true,
131
132
  }, { concurrentId: concurrentId || `getSchemaAcl`, requestConfig: { signal } });
132
133
  }
133
134
  getHeatmapData({ path }, { concurrentId, signal } = {}) {
@@ -35,6 +35,11 @@
35
35
  line-height: var(--g-text-subheader-3-line-height);
36
36
  }
37
37
 
38
+ @mixin subheader-2-typography() {
39
+ font-size: var(--g-text-subheader-2-font-size);
40
+ line-height: var(--g-text-subheader-2-line-height);
41
+ }
42
+
38
43
  @mixin header-1-typography() {
39
44
  font-size: var(--g-text-header-1-font-size);
40
45
  line-height: var(--g-text-header-1-line-height);
@@ -7,7 +7,7 @@
7
7
 
8
8
  .g-root {
9
9
  --g-text-header-font-weight: 500;
10
- --g-text-subheader-font-weight: 500;
10
+ --g-text-subheader-font-weight: 600;
11
11
  --g-text-display-font-weight: 500;
12
12
  --g-text-accent-font-weight: 500;
13
13
 
@@ -17,7 +17,8 @@ export interface TMetaCommonInfo {
17
17
  export interface TACE {
18
18
  AccessType: string;
19
19
  AccessRights?: string[];
20
+ AccessRules?: string[];
20
21
  Subject: string;
21
22
  InheritanceType?: string[];
22
- AccessRule: string;
23
+ AccessRule?: string;
23
24
  }
@@ -56,6 +56,7 @@ export interface TPathDescription {
56
56
  /** info about the path itself */
57
57
  Self?: TDirEntry;
58
58
  DomainDescription?: TDomainDescription;
59
+ UserAttributes?: TUserAttribute[];
59
60
  Children?: TDirEntry[];
60
61
  Table?: TTableDescription;
61
62
  TableStats?: TTableStats;
@@ -250,4 +251,8 @@ interface TTablePartition {
250
251
  /** uint64 */
251
252
  DatashardId?: string;
252
253
  }
254
+ interface TUserAttribute {
255
+ Key?: string;
256
+ Value?: string;
257
+ }
253
258
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "6.7.0",
3
+ "version": "6.8.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -12,18 +12,18 @@
12
12
  "dependencies": {
13
13
  "@bem-react/classname": "^1.6.0",
14
14
  "@gravity-ui/axios-wrapper": "^1.4.1",
15
- "@gravity-ui/chartkit": "^5.5.0",
16
- "@gravity-ui/components": "^3.6.2",
17
- "@gravity-ui/date-utils": "^2.4.0",
18
- "@gravity-ui/i18n": "^1.5.0",
19
- "@gravity-ui/icons": "^2.9.1",
20
- "@gravity-ui/navigation": "^2.10.0",
15
+ "@gravity-ui/chartkit": "^5.9.0",
16
+ "@gravity-ui/components": "^3.7.0",
17
+ "@gravity-ui/date-utils": "^2.5.3",
18
+ "@gravity-ui/i18n": "^1.5.1",
19
+ "@gravity-ui/icons": "^2.10.0",
20
+ "@gravity-ui/navigation": "^2.16.0",
21
21
  "@gravity-ui/paranoid": "^2.0.1",
22
22
  "@gravity-ui/react-data-table": "^2.1.1",
23
- "@gravity-ui/uikit": "^6.15.0",
23
+ "@gravity-ui/uikit": "^6.20.1",
24
24
  "@gravity-ui/websql-autocomplete": "^9.1.0",
25
25
  "@reduxjs/toolkit": "^2.2.3",
26
- "axios": "^1.6.8",
26
+ "axios": "^1.7.2",
27
27
  "axios-retry": "^4.4.0",
28
28
  "colord": "^2.9.3",
29
29
  "copy-to-clipboard": "^3.3.3",
@@ -35,17 +35,17 @@
35
35
  "path-to-regexp": "^3.0.0",
36
36
  "qs": "^6.12.0",
37
37
  "react-error-boundary": "^4.0.13",
38
- "react-helmet-async": "2.0.4",
38
+ "react-helmet-async": "^2.0.5",
39
39
  "react-json-inspector": "^7.1.1",
40
40
  "react-list": "^0.8.17",
41
41
  "react-monaco-editor": "^0.55.0",
42
- "react-redux": "^9.1.0",
42
+ "react-redux": "^9.1.2",
43
43
  "react-router": "^5.3.4",
44
44
  "react-router-dom": "^5.3.4",
45
45
  "react-split": "^2.0.14",
46
46
  "redux": "^5.0.1",
47
47
  "redux-location-state": "^2.8.2",
48
- "tslib": "^2.6.2",
48
+ "tslib": "^2.6.3",
49
49
  "url": "^0.11.3",
50
50
  "use-query-params": "^2.2.1",
51
51
  "web-vitals": "^1.1.2",
@@ -122,54 +122,54 @@
122
122
  ]
123
123
  },
124
124
  "devDependencies": {
125
- "@commitlint/cli": "^19.2.1",
126
- "@commitlint/config-conventional": "^19.1.0",
125
+ "@commitlint/cli": "^19.3.0",
126
+ "@commitlint/config-conventional": "^19.2.2",
127
127
  "@gravity-ui/eslint-config": "^3.2.0",
128
128
  "@gravity-ui/prettier-config": "^1.1.0",
129
129
  "@gravity-ui/stylelint-config": "^4.0.1",
130
130
  "@gravity-ui/tsconfig": "^1.0.0",
131
131
  "@playwright/test": "^1.42.1",
132
- "@testing-library/jest-dom": "^6.4.2",
132
+ "@testing-library/jest-dom": "^6.4.6",
133
133
  "@testing-library/react": "^14.2.2",
134
134
  "@testing-library/user-event": "^14.5.2",
135
135
  "@types/jest": "^29.5.12",
136
136
  "@types/lodash": "^4.17.0",
137
137
  "@types/numeral": "^2.0.5",
138
- "@types/qs": "^6.9.14",
139
- "@types/react": "^18.2.73",
140
- "@types/react-dom": "^18.2.23",
138
+ "@types/qs": "^6.9.15",
139
+ "@types/react": "^18.3.3",
140
+ "@types/react-dom": "^18.3.0",
141
141
  "@types/react-router": "^5.1.20",
142
142
  "@types/react-router-dom": "^5.3.3",
143
143
  "copyfiles": "^2.4.1",
144
144
  "http-proxy-middleware": "^2.0.6",
145
145
  "husky": "^9.0.11",
146
146
  "jest-transform-css": "^6.0.1",
147
- "lint-staged": "^15.2.2",
147
+ "lint-staged": "^15.2.7",
148
148
  "npm-run-all": "^4.1.5",
149
149
  "postcss": "^8.4.38",
150
150
  "prettier": "^3.2.5",
151
151
  "prop-types": "^15.8.1",
152
- "react": "^18.2.0",
152
+ "react": "^18.3.1",
153
153
  "react-app-rewired": "^2.2.1",
154
- "react-dom": "^18.2.0",
154
+ "react-dom": "^18.3.1",
155
155
  "react-scripts": "^5.0.1",
156
156
  "sass": "^1.72.0",
157
157
  "source-map-explorer": "^2.5.3",
158
- "stylelint": "^15.0.0",
159
- "ts-jest": "^29.1.2",
158
+ "stylelint": "^15.11.0",
159
+ "ts-jest": "^29.1.5",
160
160
  "typescript": "^5.4.3"
161
161
  },
162
162
  "peerDependencies": {
163
163
  "prop-types": "^15.8.1",
164
- "react": "^18.2.0",
165
- "react-dom": "^18.2.0"
164
+ "react": "^18.3.1",
165
+ "react-dom": "^18.3.1"
166
166
  },
167
167
  "overrides": {
168
168
  "fork-ts-checker-webpack-plugin": "^9.0.2",
169
- "react": "^18.2.0",
170
- "react-dom": "^18.2.0",
171
- "redux": "^5.0.1",
172
- "typescript": "^5.4.3",
173
- "monaco-editor": "^0.48.0"
169
+ "react": "$react",
170
+ "react-dom": "$react-dom",
171
+ "redux": "$redux",
172
+ "typescript": "$typescript",
173
+ "monaco-editor": "$monaco-editor"
174
174
  }
175
175
  }
@@ -1,4 +0,0 @@
1
- {
2
- "common.created": "Создано",
3
- "common.type": "Тип"
4
- }
@@ -1,9 +0,0 @@
1
- .ydb-user-settings {
2
- &__item-with-popup {
3
- max-width: 180px;
4
- }
5
-
6
- &__popup {
7
- max-width: 370px;
8
- }
9
- }