ydb-embedded-ui 1.7.1 → 1.8.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.8.1...v1.8.2) (2022-07-07)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **Tenant:** 3 tabs for indexes ([9280384](https://github.com/ydb-platform/ydb-embedded-ui/commit/9280384733938c4bd269bf6f9adf23efb552c6e8))
9
+ * **Tenant:** hide preview button for index tables ([a25e0ea](https://github.com/ydb-platform/ydb-embedded-ui/commit/a25e0ea0413277e27c54d123e2be7a15b8a2aaa4))
10
+
11
+ ## [1.8.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.8.0...v1.8.1) (2022-07-06)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * **Tenant:** diagnostics view for table indexes ([63d3133](https://github.com/ydb-platform/ydb-embedded-ui/commit/63d3133c0d61f6d39186f0c5df2eb6983a9c8bf7))
17
+ * **Tenant:** own context actions for table indexes ([3cd946a](https://github.com/ydb-platform/ydb-embedded-ui/commit/3cd946a333be402cec70569affef5865b0dd8934))
18
+
19
+ ## [1.8.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.7.1...v1.8.0) (2022-07-05)
20
+
21
+
22
+ ### Features
23
+
24
+ * add Illustration component ([7d10880](https://github.com/ydb-platform/ydb-embedded-ui/commit/7d10880cd4d9f945e7c8a7232327d8db68f0865c))
25
+ * **Tenant:** proper 403 error page ([d822a2b](https://github.com/ydb-platform/ydb-embedded-ui/commit/d822a2b6e3e18c24882ecf30db399087053b83b3))
26
+
27
+
28
+ ### Bug Fixes
29
+
30
+ * fix empty state illustration layout ([7cfd97e](https://github.com/ydb-platform/ydb-embedded-ui/commit/7cfd97e13ebcaa703478bd7b4e29774150bd569e))
31
+
3
32
  ## [1.7.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.7.0...v1.7.1) (2022-07-05)
4
33
 
5
34
 
@@ -0,0 +1 @@
1
+ <svg width="349" height="356" fill="none" xmlns="http://www.w3.org/2000/svg"><g opacity=".8"><path d="M275.008 84.928c0 24.7-9.9 83.9-9.9 117.1 0 33.2 0 106.3-27.8 134.1-27.8 27.8-61.9 16.1-61.9 16.1s-46.7 13-76.3-14.8c-29.6-27.8-60.1-83.5-69.1-115.3-9.9-35-26.5-49.3-27.8-56.5-1.3-7.2 3.6-12.1 12.1-12.6 8.5-.4 22.9 4 34.5 22 11.6 18 17.5 26 23.8 35.9 6.3 9.9 20.6 23.3 20.6 23.3s.4-44.9 1.3-64.1c.9-19.3-1.8-111.7 1.8-132.3 3.6-20.6 26.5-20.2 28.7-4 2.2 16.1 8.8 66.8 9.8 79.8s3.7 44.4 3.7 44.4l7.6-2.7s-.9-105.8-.9-132.9c0-29.2 28.7-29.2 32.3-4 3.6 25.2 6.7 142.8 6.7 142.8l6.7 2.7s2.2-111.7 5.8-129.6c3.6-17.9 26.5-17.5 30.1 4.9 3.6 22.4 1.3 72.2.9 94.2s-.9 43.5-.9 43.5l5.4 4s11-73.3 14.4-99.1c3.7-27.8 28.4-21.5 28.4 3.1z" fill="#fff" fill-opacity=".07"/><path d="M279.207 266.428l-216.9 12c-7.3.4-13.3-5.2-13.3-12.5v-167.4c0-7.3 6-12.9 13.3-12.5l216.9 12c5.6.3 10.1 5.7 10.1 12v144.4c0 6.3-4.5 11.7-10.1 12z" fill="#FF4645"/><path d="M191.308 139.226l-32.3-1.4c-1.9-.1-3.8.6-5.2 1.9l-24.3 22.8c-1.4 1.3-2.2 3.2-2.2 5.2v33.7c0 2 .8 3.8 2.2 5.2l24.3 22.8c1.4 1.3 3.3 2 5.2 1.9l32.3-1.4c1.8-.1 3.6-.9 4.9-2.2l21.5-22.8c1.2-1.3 1.9-3.1 1.9-4.9v-31c0-1.8-.7-3.6-1.9-4.9l-21.5-22.8c-1.3-1.3-3.1-2.1-4.9-2.1z" fill="#fff"/><path d="M203.408 195.526l-58.1.6c-1.6 0-3-1.3-3-3v-17.2c0-1.6 1.3-3 3-3l58.1.6c1.6 0 2.9 1.3 2.9 3v16c0 1.7-1.3 3-2.9 3z" fill="#FF4645"/><path fill-rule="evenodd" clip-rule="evenodd" d="M74.707 103.727c0 3.4-2.7 6-6.1 5.8-3.4-.1-6.1-3-6.1-6.4 0-3.4 2.8-6 6.1-5.8 3.4.2 6.1 3 6.1 6.4zm19.7.9c0 3.3-2.7 5.9-6 5.8-3.3-.1-6-3-6-6.3s2.7-5.9 6-5.8c3.3.1 6 2.9 6 6.3zm13.4 6.499c3.2.2 5.8-2.4 5.8-5.7 0-3.3-2.6-6.1-5.8-6.2-3.3-.2-5.9 2.4-5.9 5.7 0 3.3 2.7 6.1 5.9 6.2z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M248.707 247.329h84.6v-62c0-22.5-18.3-40.7-40.7-40.7h-3.2c-22.5 0-40.7 18.3-40.7 40.7v62zm70.2-14.3h-56v-47.7c0-14.6 11.9-26.4 26.4-26.4h3.2c14.6 0 26.4 11.9 26.4 26.4v47.7z" fill="#DEB700"/><path d="M340.507 205.528s-16.3-2.7-17.3-2.7l-78.6 1.1c-7 .1-13.7 6.5-13.7 13.1v58.6c0 4.7 2.9 8.5 7 10.1 1.5.6 3.1.9 4.8.9l12.5 2.3 7.6-3.7 60.4-4.3c6.2-.4 11.2-5.8 11.2-11.9v-43.3l6.1-20.2z" fill="#DEB700"/><path d="M337.607 283.43l-79.6 5.7c-7 .5-12.7-4.4-12.7-11v-59.6c0-6.6 5.7-12 12.7-12.1l79.6-1.1c6.2-.1 11.2 4.8 11.2 10.9v55.4c-.1 6-5 11.3-11.2 11.8z" fill="#FBC900"/><path d="M313.007 236.029c0-6.3-5.2-11.4-11.7-11.4-6.7 0-12.3 5.4-12.3 12 0 5 3.2 9.1 7.6 10.7v15.5c0 2.5 2.1 4.4 4.7 4.2 2.6-.2 4.6-2.5 4.6-4.9v-15.1c4.3-2.1 7.1-6.3 7.1-11z" fill="#00236B"/><path d="M308.307 236.028c0-5.5-4-10.1-9.3-11.2-5.6 1.1-10 6-10 11.8 0 5 3.2 9.1 7.6 10.7v15.5c0 1.5.8 2.8 2 3.5 1.6-.9 2.6-2.5 2.6-4.3v-15.1c4.2-2 7.1-6.2 7.1-10.9z" fill="#18123D"/><path d="M21.708 40.727a2 2 0 1 0-4 0h4zm-4 8.2a2 2 0 0 0 4 0h-4zm4 17.198a2 2 0 0 0-4 0h4zm-4 8.9a2 2 0 1 0 4 0h-4zm19.2-15.197a2 2 0 1 0 0-4v4zm-8.3-4a2 2 0 0 0 0 4v-4zm-17.8 4a2 2 0 1 0 0-4v4zm-8.3-4a2 2 0 0 0 0 4v-4zm15.2-15.101v8.2h4v-8.2h-4zm0 25.398v8.9h4v-8.9h-4zm19.2-10.297h-8.3v4h8.3v-4zm-26.1 0h-8.3v4h8.3v-4zm284.199 259.098a2 2 0 1 0-4 0h4zm-4 6.2a2 2 0 0 0 4 0h-4zm4 13.1a2 2 0 1 0-4 0h4zm-4 6.8a2 2 0 0 0 4 0h-4zm15-11.1a2 2 0 0 0 0-4v4zm-6.2-4a2 2 0 0 0 0 4v-4zm-13.6 4a2 2 0 0 0 0-4v4zm-6.3-4a2 2 0 0 0 0 4v-4zm11.1-11v6.2h4v-6.2h-4zm0 19.3v6.8h4v-6.8h-4zm15-8.3h-6.2v4h6.2v-4zm-19.8 0h-6.3v4h6.3v-4z" fill="#2EE5C0"/><path clip-rule="evenodd" d="M15.207 325.426c7.18 0 13-5.821 13-13 0-7.18-5.82-13-13-13s-13 5.82-13 13c0 7.179 5.82 13 13 13z" stroke="#2EE5C0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.207 310.426a2 2 0 1 0 0 4v-4zm35.2 2h2a2 2 0 0 0-2-2v2zm-2 12.2a2 2 0 0 0 4 0h-4zm-17.1 0a2 2 0 0 0 4 0h-4zm4-12.2a2 2 0 1 0-4 0h4zm-20.1 2h35.2v-4h-35.2v4zm33.2-2v12.2h4v-12.2h-4zm-13.1 12.2v-12.2h-4v12.2h4z" fill="#2EE5C0"/></g></svg>
@@ -0,0 +1 @@
1
+ <svg width="349" height="357" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M275.033 85.83c0 24.7-9.9 83.9-9.9 117.1 0 33.2 0 106.3-27.8 134.1-27.8 27.8-61.9 16.1-61.9 16.1s-46.7 13-76.3-14.8c-29.6-27.8-60.1-83.5-69.1-115.3-9.9-35-26.5-49.3-27.8-56.5-1.3-7.2 3.6-12.1 12.1-12.6 8.5-.4 22.9 4 34.5 22 11.6 18 17.5 26 23.8 35.9 6.3 9.9 20.6 23.3 20.6 23.3s.4-44.9 1.3-64.1c.9-19.3-1.8-111.7 1.8-132.3 3.6-20.6 26.5-20.2 28.7-4 2.2 16.1 8.8 66.8 9.8 79.8s3.7 44.4 3.7 44.4l7.6-2.7s-.9-105.8-.9-132.9c0-29.2 28.7-29.2 32.3-4 3.6 25.2 6.7 142.8 6.7 142.8l6.7 2.7s2.2-111.7 5.8-129.6c3.6-17.9 26.5-17.5 30.1 4.9 3.6 22.4 1.3 72.2.9 94.2s-.9 43.5-.9 43.5l5.4 4s11-73.3 14.4-99.1c3.7-27.8 28.4-21.5 28.4 3.1z" fill="#ECF2F9"/><path d="M279.233 267.33l-216.9 12c-7.3.4-13.3-5.2-13.3-12.5V99.43c0-7.3 6-12.9 13.3-12.5l216.9 12c5.6.3 10.1 5.7 10.1 12v144.4c0 6.3-4.5 11.7-10.1 12z" fill="#FF4645"/><path d="M191.333 140.128l-32.3-1.4c-1.9-.1-3.8.6-5.2 1.9l-24.3 22.8c-1.4 1.3-2.2 3.2-2.2 5.2v33.7c0 2 .8 3.8 2.2 5.2l24.3 22.8c1.4 1.3 3.3 2 5.2 1.9l32.3-1.4c1.8-.1 3.6-.9 4.9-2.2l21.5-22.8c1.2-1.3 1.9-3.1 1.9-4.9v-31c0-1.8-.7-3.6-1.9-4.9l-21.5-22.8c-1.3-1.3-3.1-2.1-4.9-2.1z" fill="#fff"/><path d="M203.433 196.428l-58.1.6c-1.6 0-3-1.3-3-3v-17.2c0-1.6 1.3-3 3-3l58.1.6c1.6 0 2.9 1.3 2.9 3v16c0 1.7-1.3 3-2.9 3z" fill="#FF4645"/><path fill-rule="evenodd" clip-rule="evenodd" d="M74.733 104.63c0 3.4-2.7 6-6.1 5.8-3.4-.1-6.1-3-6.1-6.4 0-3.4 2.8-6 6.1-5.8 3.4.2 6.1 3 6.1 6.4zm19.7.9c0 3.3-2.7 5.9-6 5.8-3.3-.1-6-3-6-6.3s2.7-5.9 6-5.8c3.3.1 6 2.9 6 6.3zm13.4 6.498c3.2.2 5.8-2.4 5.8-5.7 0-3.3-2.6-6.1-5.8-6.2-3.3-.2-5.9 2.4-5.9 5.7 0 3.3 2.7 6.1 5.9 6.2z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M248.733 248.231h84.6v-62c0-22.5-18.3-40.7-40.7-40.7h-3.2c-22.5 0-40.7 18.3-40.7 40.7v62zm70.2-14.3h-56v-47.7c0-14.6 11.9-26.4 26.4-26.4h3.2c14.6 0 26.4 11.9 26.4 26.4v47.7z" fill="#DEB700"/><path d="M340.533 206.43s-16.3-2.7-17.3-2.7l-78.6 1.1c-7 .1-13.7 6.5-13.7 13.1v58.6c0 4.7 2.9 8.5 7 10.1 1.5.6 3.1.9 4.8.9l12.5 2.3 7.6-3.7 60.4-4.3c6.2-.4 11.2-5.8 11.2-11.9v-43.3l6.1-20.2z" fill="#DEB700"/><path d="M337.633 284.332l-79.6 5.7c-7 .5-12.7-4.4-12.7-11v-59.6c0-6.6 5.7-12 12.7-12.1l79.6-1.1c6.2-.1 11.2 4.8 11.2 10.9v55.4c-.1 6-5 11.3-11.2 11.8z" fill="#FBC900"/><path d="M313.033 236.931c0-6.3-5.2-11.4-11.7-11.4-6.7 0-12.3 5.4-12.3 12 0 5 3.2 9.1 7.6 10.7v15.5c0 2.5 2.1 4.4 4.7 4.2 2.6-.2 4.6-2.5 4.6-4.9v-15.1c4.3-2.1 7.1-6.3 7.1-11z" fill="#00236B"/><path d="M308.333 236.93c0-5.5-4-10.1-9.3-11.2-5.6 1.1-10 6-10 11.8 0 5 3.2 9.1 7.6 10.7v15.5c0 1.5.8 2.8 2 3.5 1.6-.9 2.6-2.5 2.6-4.3v-15.1c4.2-2 7.1-6.2 7.1-10.9z" fill="#18123D"/><path d="M21.733 41.629a2 2 0 0 0-4 0h4zm-4 8.2a2 2 0 1 0 4 0h-4zm4 17.198a2 2 0 0 0-4 0h4zm-4 8.9a2 2 0 1 0 4 0h-4zm19.2-15.197a2 2 0 0 0 0-4v4zm-8.3-4a2 2 0 1 0 0 4v-4zm-17.8 4a2 2 0 0 0 0-4v4zm-8.3-4a2 2 0 1 0 0 4v-4zm15.2-15.101v8.2h4v-8.2h-4zm0 25.398v8.9h4v-8.9h-4zm19.2-10.297h-8.3v4h8.3v-4zm-26.1 0h-8.3v4h8.3v-4zm284.2 259.098a2 2 0 0 0-4 0h4zm-4 6.2a2 2 0 1 0 4 0h-4zm4 13.1a2 2 0 0 0-4 0h4zm-4 6.8a2 2 0 1 0 4 0h-4zm15-11.1a2 2 0 0 0 0-4v4zm-6.2-4a2 2 0 0 0 0 4v-4zm-13.6 4a2 2 0 0 0 0-4v4zm-6.3-4a2 2 0 0 0 0 4v-4zm11.1-11v6.2h4v-6.2h-4zm0 19.3v6.8h4v-6.8h-4zm15-8.3h-6.2v4h6.2v-4zm-19.8 0h-6.3v4h6.3v-4z" fill="#2EE5C0"/><path clip-rule="evenodd" d="M15.233 326.328c7.18 0 13-5.82 13-13s-5.82-13-13-13-13 5.82-13 13 5.82 13 13 13z" stroke="#2EE5C0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.233 311.328a2 2 0 0 0 0 4v-4zm35.2 2h2a2 2 0 0 0-2-2v2zm-2 12.2a2 2 0 1 0 4 0h-4zm-17.1 0a2 2 0 1 0 4 0h-4zm4-12.2a2 2 0 0 0-4 0h4zm-20.1 2h35.2v-4h-35.2v4zm33.2-2v12.2h4v-12.2h-4zm-13.1 12.2v-12.2h-4v12.2h4z" fill="#2EE5C0"/></svg>
@@ -16,16 +16,18 @@ export default function EmptyState({image, title, description, actions, size}) {
16
16
  return (
17
17
  <div className={block({size})}>
18
18
  <div className={block('wrapper', {size})}>
19
- {image ? (
20
- image
21
- ) : (
22
- <Icon
23
- viewBox="0 0 383 396"
24
- name="emptyState"
25
- width={sizes[size]}
26
- height={sizes[size]}
27
- />
28
- )}
19
+ <div className={block('image')}>
20
+ {image ? (
21
+ image
22
+ ) : (
23
+ <Icon
24
+ viewBox="0 0 383 396"
25
+ name="emptyState"
26
+ width={sizes[size]}
27
+ height={sizes[size]}
28
+ />
29
+ )}
30
+ </div>
29
31
 
30
32
  <div className={block('title', {size})}>{title}</div>
31
33
  <div className={block('description')}>{description}</div>
@@ -0,0 +1,47 @@
1
+ import {useEffect, useState} from 'react';
2
+ import cn from 'bem-cn-lite';
3
+ import {useThemeValue} from '@yandex-cloud/uikit';
4
+
5
+ export interface IllustrationProps {
6
+ name: string;
7
+ className?: string;
8
+ }
9
+
10
+ type IllustrationStore = Record<string, Record<string, () => Promise<{default: any}>>>;
11
+
12
+ const store: IllustrationStore = {
13
+ light: {
14
+ 403: () => import('../../assets/illustrations/light/403.svg'),
15
+ },
16
+ dark: {
17
+ 403: () => import('../../assets/illustrations/dark/403.svg'),
18
+ },
19
+ };
20
+
21
+ const b = cn('kv-illustration');
22
+
23
+ export const Illustration = ({name, className, ...props}: IllustrationProps) => {
24
+ const theme = useThemeValue();
25
+ const [src, setSrc] = useState('');
26
+ const srcGetter = store[theme] && store[theme][name];
27
+
28
+ useEffect(() => {
29
+ if (typeof srcGetter === 'function') {
30
+ srcGetter()
31
+ .then((svg) => setSrc(svg.default))
32
+ .catch((e) => {
33
+ console.error(e);
34
+ setSrc('');
35
+ });
36
+ }
37
+ }, [srcGetter]);
38
+
39
+ return (
40
+ <img
41
+ alt={name}
42
+ src={src}
43
+ className={b(null, className)}
44
+ {...props}
45
+ />
46
+ );
47
+ }
@@ -0,0 +1 @@
1
+ export * from './Illustration';
@@ -30,9 +30,8 @@ import Tablets from '../../Tablets/Tablets';
30
30
 
31
31
  import routes, {createHref} from '../../../routes';
32
32
  import type {EPathType} from '../../../types/api/schema';
33
- import {isTableType} from '../utils/schema';
34
33
  import {TenantGeneralTabsIds, TenantTabsGroups} from '../TenantPages';
35
- import {GeneralPagesIds, DATABASE_PAGES, TABLE_PAGES, DIR_PAGES} from './DiagnosticsPages';
34
+ import {GeneralPagesIds, DATABASE_PAGES, getPagesByType} from './DiagnosticsPages';
36
35
  //@ts-ignore
37
36
  import {enableAutorefresh, disableAutorefresh} from '../../../store/reducers/schema';
38
37
  import {setTopLevelTab, setDiagnosticsTab} from '../../../store/reducers/tenant';
@@ -66,20 +65,15 @@ function Diagnostics(props: DiagnosticsProps) {
66
65
 
67
66
  const {name: tenantName} = queryParams;
68
67
 
69
- const isDatabase = currentSchemaPath === tenantName;
68
+ const isRoot = currentSchemaPath === tenantName;
70
69
 
71
70
  const pages = useMemo(() => {
72
- const isTable = isTableType(props.type);
73
-
74
- let pages = DIR_PAGES;
75
-
76
- if (isDatabase) {
77
- pages = DATABASE_PAGES;
78
- } else if (isTable) {
79
- pages = TABLE_PAGES;
71
+ if (isRoot) {
72
+ return DATABASE_PAGES;
80
73
  }
81
- return pages;
82
- }, [props.type, isDatabase]);
74
+
75
+ return getPagesByType(props.type);
76
+ }, [props.type, isRoot]);
83
77
 
84
78
  const forwardToDiagnosticTab = (tab: GeneralPagesIds) => {
85
79
  dispatch(setDiagnosticsTab(tab));
@@ -1,3 +1,5 @@
1
+ import {EPathType} from "../../../types/api/schema";
2
+
1
3
  export enum GeneralPagesIds {
2
4
  'overview' = 'Overview',
3
5
  'topQueries' = 'topQueries',
@@ -73,3 +75,18 @@ export const DATABASE_PAGES = [
73
75
  export const TABLE_PAGES = [overview, topShards, graph, tablets, hotKeys, describe];
74
76
 
75
77
  export const DIR_PAGES = [overview, topShards, describe];
78
+
79
+ export const getPagesByType = (type?: EPathType) => {
80
+ switch (type) {
81
+ case EPathType.EPathTypeColumnStore:
82
+ case EPathType.EPathTypeSubDomain:
83
+ return DATABASE_PAGES;
84
+ case EPathType.EPathTypeColumnTable:
85
+ case EPathType.EPathTypeTable:
86
+ return TABLE_PAGES;
87
+ case EPathType.EPathTypeDir:
88
+ case EPathType.EPathTypeTableIndex:
89
+ default:
90
+ return DIR_PAGES;
91
+ }
92
+ }
@@ -16,8 +16,8 @@ import CopyToClipboard from '../../../components/CopyToClipboard/CopyToClipboard
16
16
  import InfoViewer from '../../../components/InfoViewer/InfoViewer';
17
17
  import Icon from '../../../components/Icon/Icon';
18
18
 
19
- import type {EPathType} from '../../../types/api/schema';
20
- import {isColumnEntityType, isTableType} from '../utils/schema';
19
+ import type {EPathSubType, EPathType} from '../../../types/api/schema';
20
+ import {isColumnEntityType, isIndexTable, isTableType} from '../utils/schema';
21
21
 
22
22
  import {
23
23
  DEFAULT_IS_TENANT_COMMON_INFO_COLLAPSED,
@@ -71,6 +71,7 @@ function prepareOlapTableSchema(tableSchema: any) {
71
71
 
72
72
  interface ObjectSummaryProps {
73
73
  type?: EPathType;
74
+ subType?: EPathSubType;
74
75
  onCollapseSummary: VoidFunction;
75
76
  onExpandSummary: VoidFunction;
76
77
  isCollapsed: boolean;
@@ -229,10 +230,10 @@ function ObjectSummary(props: ObjectSummaryProps) {
229
230
  };
230
231
 
231
232
  const renderCommonInfoControls = () => {
232
- const isTable = isTableType(props.type);
233
+ const showPreview = isTableType(props.type) && !isIndexTable(props.subType);
233
234
  return (
234
235
  <React.Fragment>
235
- {isTable && (
236
+ {showPreview && (
236
237
  <Button view="flat-secondary" onClick={onOpenPreview} title="Show preview">
237
238
  <Icon name="tablePreview" viewBox={'0 0 16 16'} height={16} width={16} />
238
239
  </Button>
@@ -32,9 +32,9 @@ export function SchemaTree(props: SchemaTreeProps) {
32
32
  {concurrentId: `NavigationTree.getSchema|${path}`},
33
33
  )
34
34
  .then(({PathDescription: {Children = []} = {}}) => {
35
- return Children.map(({Name = '', PathType}) => ({
35
+ return Children.map(({Name = '', PathType, PathSubType}) => ({
36
36
  name: Name,
37
- type: mapPathTypeToNavigationTreeType(PathType),
37
+ type: mapPathTypeToNavigationTreeType(PathType, PathSubType),
38
38
  // FIXME: should only be explicitly set to true for tables with indexes
39
39
  // at the moment of writing there is no property to determine this, fix later
40
40
  expandable: true,
@@ -4,6 +4,9 @@ import cn from 'bem-cn-lite';
4
4
  import {useLocation} from 'react-router';
5
5
  import qs from 'qs';
6
6
 
7
+ import EmptyState from '../../components/EmptyState/EmptyState';
8
+ import {Illustration} from '../../components/Illustration';
9
+
7
10
  import ObjectSummary from './ObjectSummary/ObjectSummary';
8
11
  import {setHeader} from '../../store/reducers/header';
9
12
  import ObjectGeneral from './ObjectGeneral/ObjectGeneral';
@@ -53,6 +56,9 @@ function Tenant(props: TenantProps) {
53
56
  (state: any) => state.schema,
54
57
  );
55
58
 
59
+ const {data: {status: tenantStatus = 200} = {}} = useSelector((state: any) => state.tenant);
60
+ const {error: {status: schemaStatus = 200} = {}} = useSelector((state: any) => state.schema);
61
+
56
62
  const dispatch = useDispatch();
57
63
 
58
64
  const location = useLocation();
@@ -98,7 +104,10 @@ function Tenant(props: TenantProps) {
98
104
  };
99
105
  }, [tenantName, dispatch]);
100
106
 
101
- const currentPathType = (currentItem as TEvDescribeSchemeResult).PathDescription?.Self?.PathType;
107
+ const {
108
+ PathType: currentPathType,
109
+ PathSubType: currentPathSubType,
110
+ } = (currentItem as TEvDescribeSchemeResult).PathDescription?.Self || {};
102
111
 
103
112
  const onCollapseSummaryHandler = () => {
104
113
  dispatchSummaryVisibilityAction(PaneVisibilityActionTypes.triggerCollapse);
@@ -111,29 +120,40 @@ function Tenant(props: TenantProps) {
111
120
  dispatchSummaryVisibilityAction(PaneVisibilityActionTypes.clear);
112
121
  };
113
122
 
123
+ const showBlockingError = tenantStatus === 403 || schemaStatus === 403;
124
+
114
125
  return (
115
126
  <div className={b()}>
116
- <SplitPane
117
- defaultSizePaneKey={DEFAULT_SIZE_TENANT_KEY}
118
- defaultSizes={[25, 75]}
119
- triggerCollapse={summaryVisibilityState.triggerCollapse}
120
- triggerExpand={summaryVisibilityState.triggerExpand}
121
- minSize={[36, 200]}
122
- onSplitStartDragAdditional={onSplitStartDragAdditional}
123
- >
124
- <ObjectSummary
125
- type={currentPathType}
126
- onCollapseSummary={onCollapseSummaryHandler}
127
- onExpandSummary={onExpandSummaryHandler}
128
- isCollapsed={summaryVisibilityState.collapsed}
129
- additionalTenantInfo={props.additionalTenantInfo}
130
- />
131
- <ObjectGeneral
132
- type={currentPathType}
133
- additionalTenantInfo={props.additionalTenantInfo}
134
- additionalNodesInfo={props.additionalNodesInfo}
127
+ {showBlockingError ? (
128
+ <EmptyState
129
+ image={<Illustration name="403" />}
130
+ title="Access denied"
131
+ description="You don’t have the necessary roles to view this page."
135
132
  />
136
- </SplitPane>
133
+ ) : (
134
+ <SplitPane
135
+ defaultSizePaneKey={DEFAULT_SIZE_TENANT_KEY}
136
+ defaultSizes={[25, 75]}
137
+ triggerCollapse={summaryVisibilityState.triggerCollapse}
138
+ triggerExpand={summaryVisibilityState.triggerExpand}
139
+ minSize={[36, 200]}
140
+ onSplitStartDragAdditional={onSplitStartDragAdditional}
141
+ >
142
+ <ObjectSummary
143
+ type={currentPathType}
144
+ subType={currentPathSubType}
145
+ onCollapseSummary={onCollapseSummaryHandler}
146
+ onExpandSummary={onExpandSummaryHandler}
147
+ isCollapsed={summaryVisibilityState.collapsed}
148
+ additionalTenantInfo={props.additionalTenantInfo}
149
+ />
150
+ <ObjectGeneral
151
+ type={currentPathType}
152
+ additionalTenantInfo={props.additionalTenantInfo}
153
+ additionalNodesInfo={props.additionalNodesInfo}
154
+ />
155
+ </SplitPane>
156
+ )}
137
157
  </div>
138
158
  );
139
159
  }
@@ -1,8 +1,19 @@
1
1
  import type {NavigationTreeNodeType} from 'ydb-ui-components';
2
- import {EPathType} from '../../../types/api/schema';
2
+ import {EPathSubType, EPathType} from '../../../types/api/schema';
3
+
4
+ const mapTablePathSubTypeToNavigationTreeType = (subType?: EPathSubType) => {
5
+ switch (subType) {
6
+ case EPathSubType.EPathSubTypeSyncIndexImplTable:
7
+ case EPathSubType.EPathSubTypeAsyncIndexImplTable:
8
+ return 'index_table';
9
+ default:
10
+ return 'table';
11
+ }
12
+ };
3
13
 
4
14
  export const mapPathTypeToNavigationTreeType = (
5
15
  type: EPathType = EPathType.EPathTypeDir,
16
+ subType?: EPathSubType,
6
17
  defaultType: NavigationTreeNodeType = 'directory'
7
18
  ): NavigationTreeNodeType => {
8
19
  switch (type) {
@@ -10,11 +21,12 @@ export const mapPathTypeToNavigationTreeType = (
10
21
  return 'database';
11
22
  case EPathType.EPathTypeTable:
12
23
  case EPathType.EPathTypeColumnTable:
13
- return 'table';
24
+ return mapTablePathSubTypeToNavigationTreeType(subType);
14
25
  case EPathType.EPathTypeDir:
15
26
  case EPathType.EPathTypeColumnStore:
16
- case EPathType.EPathTypeTableIndex:
17
27
  return 'directory';
28
+ case EPathType.EPathTypeTableIndex:
29
+ return 'index';
18
30
  default:
19
31
  return defaultType;
20
32
  }
@@ -23,6 +35,9 @@ export const mapPathTypeToNavigationTreeType = (
23
35
  export const isTableType = (type?: EPathType) =>
24
36
  mapPathTypeToNavigationTreeType(type) === 'table';
25
37
 
38
+ export const isIndexTable = (subType?: EPathSubType) =>
39
+ mapTablePathSubTypeToNavigationTreeType(subType) === 'index_table';
40
+
26
41
  export const isColumnEntityType = (type?: EPathType) =>
27
42
  type === EPathType.EPathTypeColumnStore ||
28
43
  type === EPathType.EPathTypeColumnTable;
@@ -15,7 +15,6 @@ const createTableTemplate = (path: string) => {
15
15
  PRIMARY KEY (\`id\`)
16
16
  );`;
17
17
  };
18
-
19
18
  const alterTableTemplate = (path: string) => {
20
19
  return `ALTER TABLE \`${path}\`
21
20
  ADD COLUMN is_deleted Bool;`;
@@ -32,40 +31,23 @@ const upsertQueryTemplate = (path: string) => {
32
31
  VALUES ( );`;
33
32
  };
34
33
 
35
- export const getActions = (
34
+ const bindActions = (
35
+ path: string,
36
36
  dispatch: Dispatch<any>,
37
37
  setActivePath: (path: string) => void,
38
- ) =>
39
- (path: string, type: NavigationTreeNodeType) => {
40
- const switchTabToQuery = () => {
41
- dispatch(setTopLevelTab(TenantGeneralTabsIds.query));
42
- };
43
-
44
- const onCreateTableClick = () => {
45
- dispatch(changeUserInput({input: createTableTemplate(path)}));
46
- switchTabToQuery();
47
- setActivePath(path);
48
- };
38
+ ) => {
39
+ const inputQuery = (tmpl: (path: string) => string) => () => {
40
+ dispatch(changeUserInput({input: tmpl(path)}));
41
+ dispatch(setTopLevelTab(TenantGeneralTabsIds.query))
42
+ setActivePath(path);
43
+ }
49
44
 
50
- const onAlterTableClick = () => {
51
- dispatch(changeUserInput({input: alterTableTemplate(path)}));
52
- switchTabToQuery();
53
- setActivePath(path);
54
- };
55
-
56
- const onSelectQueryClick = () => {
57
- dispatch(changeUserInput({input: selectQueryTemplate(path)}));
58
- switchTabToQuery();
59
- setActivePath(path);
60
- };
61
-
62
- const onUpsertQueryClick = () => {
63
- dispatch(changeUserInput({input: upsertQueryTemplate(path)}));
64
- switchTabToQuery();
65
- setActivePath(path);
66
- };
67
-
68
- const onCopyPathClick = () => {
45
+ return {
46
+ createTable: inputQuery(createTableTemplate),
47
+ alterTable: inputQuery(alterTableTemplate),
48
+ selectQuery: inputQuery(selectQueryTemplate),
49
+ upsertQuery: inputQuery(upsertQueryTemplate),
50
+ copyPath: () => {
69
51
  navigator.clipboard
70
52
  .writeText(path)
71
53
  .then(() => {
@@ -82,34 +64,52 @@ export const getActions = (
82
64
  type: 'error',
83
65
  });
84
66
  });
85
- };
86
-
87
- const onOpenPreviewClick = () => {
67
+ },
68
+ openPreview: () => {
88
69
  dispatch(setShowPreview(true));
89
- switchTabToQuery();
70
+ dispatch(setTopLevelTab(TenantGeneralTabsIds.query))
90
71
  setActivePath(path);
91
- };
72
+ },
73
+ };
74
+ };
92
75
 
93
- const copyItem = {text: 'Copy path', action: onCopyPathClick};
76
+ export const getActions = (
77
+ dispatch: Dispatch<any>,
78
+ setActivePath: (path: string) => void,
79
+ ) =>
80
+ (path: string, type: NavigationTreeNodeType) => {
81
+ const actions = bindActions(path, dispatch, setActivePath);
82
+ const copyItem = {text: 'Copy path', action: actions.copyPath};
94
83
 
95
- return type === 'table'
96
- ? [
97
- [
98
- {text: 'Open preview', action: onOpenPreviewClick},
99
- copyItem,
100
- ],
101
- [
102
- {text: 'Alter table...', action: onAlterTableClick},
103
- {text: 'Select query...', action: onSelectQueryClick},
104
- {text: 'Upsert query...', action: onUpsertQueryClick},
105
- ],
106
- ]
107
- : [
108
- [
84
+ switch (type) {
85
+ case 'database':
86
+ case 'directory':
87
+ return [
88
+ [
89
+ copyItem,
90
+ ],
91
+ [
92
+ {text: 'Create table...', action: actions.createTable},
93
+ ],
94
+ ];
95
+ case 'table':
96
+ return [
97
+ [
98
+ {text: 'Open preview', action: actions.openPreview},
99
+ copyItem,
100
+ ],
101
+ [
102
+ {text: 'Alter table...', action: actions.alterTable},
103
+ {text: 'Select query...', action: actions.selectQuery},
104
+ {text: 'Upsert query...', action: actions.upsertQuery},
105
+ ],
106
+ ];
107
+ case 'index_table':
108
+ return [
109
109
  copyItem,
110
- ],
111
- [
112
- {text: 'Create table...', action: onCreateTableClick},
113
- ],
114
- ];
110
+ ];
111
+ case 'index':
112
+ default:
113
+ return [];
114
+ }
115
115
  };
@@ -91,7 +91,7 @@ export enum EPathType {
91
91
  EPathTypeTableIndex = 'EPathTypeTableIndex',
92
92
  }
93
93
 
94
- enum EPathSubType {
94
+ export enum EPathSubType {
95
95
  EPathSubTypeEmpty = 'EPathSubTypeEmpty',
96
96
  EPathSubTypeSyncIndexImplTable = 'EPathSubTypeSyncIndexImplTable',
97
97
  EPathSubTypeAsyncIndexImplTable = 'EPathSubTypeAsyncIndexImplTable',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "1.7.1",
3
+ "version": "1.8.2",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -40,7 +40,7 @@
40
40
  "reselect": "4.0.0",
41
41
  "sass": "1.32.8",
42
42
  "web-vitals": "1.1.2",
43
- "ydb-ui-components": "2.1.0"
43
+ "ydb-ui-components": "2.2.0"
44
44
  },
45
45
  "scripts": {
46
46
  "start": "react-app-rewired start",