ydb-embedded-ui 3.4.2 → 3.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +31 -10
  3. package/dist/components/CriticalActionDialog/CriticalActionDialog.scss +1 -1
  4. package/dist/components/CriticalActionDialog/{CriticalActionDialog.js → CriticalActionDialog.tsx} +21 -16
  5. package/dist/components/CriticalActionDialog/index.ts +1 -0
  6. package/dist/containers/App/Content.js +1 -1
  7. package/dist/containers/Nodes/Nodes.scss +4 -0
  8. package/dist/containers/Nodes/Nodes.tsx +17 -10
  9. package/dist/containers/Storage/PDisk/PDisk.tsx +9 -4
  10. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +2 -2
  11. package/dist/containers/Storage/StorageNodes/StorageNodes.scss +4 -0
  12. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +2 -1
  13. package/dist/containers/Storage/VDisk/VDisk.tsx +2 -2
  14. package/dist/containers/Storage/VDiskPopup/VDiskPopup.tsx +2 -2
  15. package/dist/containers/Tablet/Tablet.tsx +121 -0
  16. package/dist/containers/Tablet/TabletControls/TabletControls.tsx +159 -0
  17. package/dist/containers/Tablet/TabletControls/index.ts +1 -0
  18. package/dist/containers/Tablet/TabletInfo/TabletInfo.tsx +80 -0
  19. package/dist/containers/Tablet/TabletInfo/index.ts +1 -0
  20. package/dist/containers/Tablet/TabletTable/TabletTable.tsx +59 -0
  21. package/dist/containers/Tablet/TabletTable/index.ts +1 -0
  22. package/dist/containers/Tablet/i18n/en.json +10 -0
  23. package/dist/containers/Tablet/i18n/index.ts +11 -0
  24. package/dist/containers/Tablet/i18n/ru.json +10 -0
  25. package/dist/containers/Tablet/index.ts +1 -0
  26. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +2 -1
  27. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +4 -4
  28. package/dist/store/reducers/storage.js +1 -0
  29. package/dist/types/api/nodes.ts +1 -1
  30. package/dist/utils/nodes.ts +7 -0
  31. package/dist/utils/storage.ts +1 -1
  32. package/package.json +5 -2
  33. package/dist/containers/Tablet/Tablet.js +0 -448
@@ -0,0 +1,80 @@
1
+ import {Link} from 'react-router-dom';
2
+
3
+ import {Link as UIKitLink} from '@gravity-ui/uikit';
4
+
5
+ import {ETabletState, TTabletStateInfo} from '../../../types/api/tablet';
6
+ import {InfoViewer, InfoViewerItem} from '../../../components/InfoViewer';
7
+ import routes, {createHref} from '../../../routes';
8
+ import {calcUptime} from '../../../utils';
9
+ import {getDefaultNodePath} from '../../Node/NodePages';
10
+
11
+ import {b} from '../Tablet';
12
+
13
+ interface TabletInfoProps {
14
+ tablet: TTabletStateInfo;
15
+ tenantPath: string;
16
+ }
17
+
18
+ export const TabletInfo = ({tablet, tenantPath}: TabletInfoProps) => {
19
+ const {
20
+ ChangeTime,
21
+ Generation,
22
+ FollowerId,
23
+ NodeId,
24
+ HiveId,
25
+ State,
26
+ Type,
27
+ TenantId: {SchemeShard} = {},
28
+ } = tablet;
29
+
30
+ const hasHiveId = HiveId && HiveId !== '0';
31
+ const hasUptime = State === ETabletState.Active;
32
+
33
+ const tabletInfo: InfoViewerItem[] = [{label: 'Database', value: tenantPath}];
34
+
35
+ if (hasHiveId) {
36
+ tabletInfo.push({
37
+ label: 'HiveId',
38
+ value: (
39
+ <UIKitLink href={createHref(routes.tablet, {id: HiveId})} target="_blank">
40
+ {HiveId}
41
+ </UIKitLink>
42
+ ),
43
+ });
44
+ }
45
+
46
+ if (SchemeShard) {
47
+ tabletInfo.push({
48
+ label: 'SchemeShard',
49
+ value: (
50
+ <UIKitLink href={createHref(routes.tablet, {id: SchemeShard})} target="_blank">
51
+ {SchemeShard}
52
+ </UIKitLink>
53
+ ),
54
+ });
55
+ }
56
+
57
+ tabletInfo.push({label: 'Type', value: Type}, {label: 'State', value: State});
58
+
59
+ if (hasUptime) {
60
+ tabletInfo.push({label: 'Uptime', value: calcUptime(ChangeTime)});
61
+ }
62
+
63
+ tabletInfo.push(
64
+ {label: 'Generation', value: Generation},
65
+ {
66
+ label: 'Node',
67
+ value: (
68
+ <Link className={b('link')} to={getDefaultNodePath(String(NodeId))}>
69
+ {NodeId}
70
+ </Link>
71
+ ),
72
+ },
73
+ );
74
+
75
+ if (FollowerId) {
76
+ tabletInfo.push({label: 'Follower', value: FollowerId});
77
+ }
78
+
79
+ return <InfoViewer info={tabletInfo} />;
80
+ };
@@ -0,0 +1 @@
1
+ export * from './TabletInfo';
@@ -0,0 +1,59 @@
1
+ import DataTable, {Column} from '@gravity-ui/react-data-table';
2
+
3
+ import type {ITabletPreparedHistoryItem} from '../../../types/store/tablet';
4
+ import {calcUptime} from '../../../utils';
5
+
6
+ const columns: Column<ITabletPreparedHistoryItem>[] = [
7
+ {
8
+ name: 'Generation',
9
+ align: DataTable.RIGHT,
10
+ render: ({row}) => row.generation,
11
+ },
12
+ {
13
+ name: 'Node ID',
14
+ align: DataTable.RIGHT,
15
+ sortable: false,
16
+ render: ({row}) => row.nodeId,
17
+ },
18
+ {
19
+ name: 'Change time',
20
+ align: DataTable.RIGHT,
21
+ sortable: false,
22
+ render: ({row}) => calcUptime(row.changeTime),
23
+ },
24
+ {
25
+ name: 'State',
26
+ sortable: false,
27
+ render: ({row}) => row.state,
28
+ },
29
+ {
30
+ name: 'Follower ID',
31
+ sortable: false,
32
+ render: ({row}) => {
33
+ return row.leader ? 'leader' : row.followerId;
34
+ },
35
+ },
36
+ ];
37
+
38
+ const TABLE_SETTINGS = {
39
+ displayIndices: false,
40
+ };
41
+
42
+ interface TabletTableProps {
43
+ history: ITabletPreparedHistoryItem[];
44
+ }
45
+
46
+ export const TabletTable = ({history}: TabletTableProps) => {
47
+ return (
48
+ <DataTable
49
+ theme="yandex-cloud"
50
+ data={history}
51
+ columns={columns}
52
+ settings={TABLE_SETTINGS}
53
+ initialSortOrder={{
54
+ columnId: 'Generation',
55
+ order: DataTable.DESCENDING,
56
+ }}
57
+ />
58
+ );
59
+ };
@@ -0,0 +1 @@
1
+ export * from './TabletTable';
@@ -0,0 +1,10 @@
1
+ {
2
+ "tablet.header": "Tablet",
3
+ "controls.kill": "Restart",
4
+ "controls.stop": "Stop",
5
+ "controls.resume": "Resume",
6
+ "dialog.kill": "The tablet will be restarted. Do you want to proceed?",
7
+ "dialog.stop": "The tablet will be stopped. Do you want to proceed?",
8
+ "dialog.resume": "The tablet will be resumed. Do you want to proceed?",
9
+ "emptyState": "The tablet was not found"
10
+ }
@@ -0,0 +1,11 @@
1
+ import {i18n, Lang} from '../../../utils/i18n';
2
+
3
+ import en from './en.json';
4
+ import ru from './ru.json';
5
+
6
+ const COMPONENT = 'ydb-tablet-page';
7
+
8
+ i18n.registerKeyset(Lang.En, COMPONENT, en);
9
+ i18n.registerKeyset(Lang.Ru, COMPONENT, ru);
10
+
11
+ export default i18n.keyset(COMPONENT);
@@ -0,0 +1,10 @@
1
+ {
2
+ "tablet.header": "Таблетка",
3
+ "controls.kill": "Перезапустить",
4
+ "controls.stop": "Остановить",
5
+ "controls.resume": "Запустить",
6
+ "dialog.kill": "Таблетка будет перезапущена. Вы хотите продолжить?",
7
+ "dialog.stop": "Таблетка будет остановлена. Вы хотите продолжить?",
8
+ "dialog.resume": "Таблетка будет запущена. Вы хотите продолжить?",
9
+ "emptyState": "Таблетка не найдена"
10
+ }
@@ -0,0 +1 @@
1
+ export * from './Tablet';
@@ -131,7 +131,8 @@ function Diagnostics(props: DiagnosticsProps) {
131
131
  case GeneralPagesIds.nodes: {
132
132
  return (
133
133
  <Nodes
134
- tenantPath={tenantNameString}
134
+ path={currentSchemaPath}
135
+ type={type}
135
136
  additionalNodesInfo={props.additionalNodesInfo}
136
137
  />
137
138
  );
@@ -89,12 +89,12 @@ export const DATABASE_PAGES = [
89
89
  describe,
90
90
  ];
91
91
 
92
- export const TABLE_PAGES = [overview, topShards, graph, tablets, hotKeys, describe];
92
+ export const TABLE_PAGES = [overview, topShards, nodes, graph, tablets, hotKeys, describe];
93
93
 
94
- export const DIR_PAGES = [overview, topShards, describe];
94
+ export const DIR_PAGES = [overview, topShards, nodes, describe];
95
95
 
96
- export const CDC_STREAM_PAGES = [overview, consumers, partitions, describe];
97
- export const TOPIC_PAGES = [overview, consumers, partitions, describe];
96
+ export const CDC_STREAM_PAGES = [overview, consumers, partitions, nodes, describe];
97
+ export const TOPIC_PAGES = [overview, consumers, partitions, nodes, describe];
98
98
 
99
99
  // verbose mapping to guarantee correct tabs for new path types
100
100
  // TS will error when a new type is added but not mapped here
@@ -313,6 +313,7 @@ export const getFlatListStorageNodes = createSelector([getStorageNodes], (storag
313
313
  }).length;
314
314
  return {
315
315
  NodeId: node.NodeId,
316
+ SystemState: systemState.SystemState,
316
317
  FQDN: systemState.Host,
317
318
  DataCenter: systemState.DataCenter,
318
319
  Rack: systemState.Rack,
@@ -7,7 +7,7 @@ import {TVDiskStateInfo} from './vdisk';
7
7
  // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
8
8
 
9
9
  export interface TNodesInfo {
10
- Overall: EFlag;
10
+ Overall?: EFlag;
11
11
  Nodes?: TNodeInfo[];
12
12
 
13
13
  /** uint64 */
@@ -1,3 +1,7 @@
1
+ import type {TSystemStateInfo} from '../types/api/nodes';
2
+ import type {INodesPreparedEntity} from '../types/store/nodes';
3
+ import {EFlag} from '../types/api/enums';
4
+
1
5
  export enum NodesUptimeFilterValues {
2
6
  'All' = 'All',
3
7
  'SmallUptime' = 'SmallUptime',
@@ -7,3 +11,6 @@ export const NodesUptimeFilterTitles = {
7
11
  [NodesUptimeFilterValues.All]: 'All',
8
12
  [NodesUptimeFilterValues.SmallUptime]: 'Uptime < 1h',
9
13
  };
14
+
15
+ export const isUnavailableNode = (node: INodesPreparedEntity | TSystemStateInfo) =>
16
+ !node.SystemState || node.SystemState === EFlag.Grey;
@@ -1,7 +1,7 @@
1
1
  import type {TVSlotId, TVDiskStateInfo} from '../types/api/vdisk';
2
2
  import type {IStoragePoolGroup} from '../types/store/storage';
3
3
 
4
- export const isFullVDiksData = (disk: TVDiskStateInfo | TVSlotId): disk is TVDiskStateInfo =>
4
+ export const isFullVDiskData = (disk: TVDiskStateInfo | TVSlotId): disk is TVDiskStateInfo =>
5
5
  'VDiskId' in disk;
6
6
 
7
7
  export const getUsage = (data: IStoragePoolGroup, step = 1) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "3.4.2",
3
+ "version": "3.4.4",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -53,7 +53,9 @@
53
53
  "eject": "react-scripts eject",
54
54
  "prepublishOnly": "npm run package",
55
55
  "typecheck": "tsc --noEmit",
56
- "prepare": "husky install"
56
+ "prepare": "husky install",
57
+ "test:e2e:install": "npx playwright install --with-deps chromium",
58
+ "test:e2e": "npx playwright test --config=playwright.config.ts"
57
59
  },
58
60
  "lint-staged": {
59
61
  "*.{scss}": [
@@ -104,6 +106,7 @@
104
106
  "@gravity-ui/stylelint-config": "^1.0.1",
105
107
  "@gravity-ui/tsconfig": "^1.0.0",
106
108
  "@gravity-ui/uikit": "^3.20.2",
109
+ "@playwright/test": "^1.31.1",
107
110
  "@testing-library/jest-dom": "^5.15.0",
108
111
  "@testing-library/react": "^11.2.7",
109
112
  "@testing-library/user-event": "^12.8.3",