Skip to content

Commit 9c5fc6d

Browse files
committed
#RI-2577 - Selected renamed key is displayed in tree view with old name
1 parent 36a6435 commit 9c5fc6d

File tree

8 files changed

+243
-86
lines changed

8 files changed

+243
-86
lines changed

redisinsight/ui/src/components/virtual-tree/VirtualTree.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable no-console */
21
import React, { useCallback, useContext, useEffect, useState } from 'react'
32
import AutoSizer from 'react-virtualized-auto-sizer'
43
import { isArray, isEmpty } from 'lodash'
@@ -18,7 +17,7 @@ import KeyLightSVG from 'uiSrc/assets/img/sidebar/browser.svg'
1817
import KeyDarkSVG from 'uiSrc/assets/img/sidebar/browser_active.svg'
1918

2019
import { Node } from './components/Node'
21-
import { NodeMeta, TreeData, TreeNode } from './interfaces'
20+
import { NodeMeta, TreeData, TreeNode, TREE_LEAF_FIELD } from './interfaces'
2221

2322
import styles from './styles.module.scss'
2423

@@ -73,8 +72,6 @@ const VirtualTree = (props: Props) => {
7372
if (!result) {
7473
return
7574
}
76-
// [ToDo] remove after tests
77-
console.timeEnd(timeLabel)
7875

7976
setNodes(result)
8077
setConstructingTree?.(false)
@@ -100,8 +97,6 @@ const VirtualTree = (props: Props) => {
10097
return
10198
}
10299

103-
// [ToDo] remove after tests
104-
console.time(timeLabel)
105100
setConstructingTree(true)
106101
runWebworker?.({ items, separator })
107102
}, [items])
@@ -137,7 +132,7 @@ const VirtualTree = (props: Props) => {
137132
updateStatusOpen: handleUpdateOpen,
138133
leafIcon: theme === Theme.Dark ? KeyDarkSVG : KeyLightSVG,
139134
keyApproximate: node.keyApproximate,
140-
keys: node.keys || node?.['keys:keys'],
135+
keys: node.keys || node?.[TREE_LEAF_FIELD],
141136
isSelected: Object.keys(statusSelected)[0] === node.fullName,
142137
isOpenByDefault: statusOpen[node.fullName],
143138
},

redisinsight/ui/src/components/virtual-tree/interfaces.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { FixedSizeNodeData } from 'react-vtree'
22
import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys'
33

4+
export const TREE_LEAF_FIELD = 'keys:keys:'
5+
46
export interface TreeNode {
57
children: TreeNode[]
68
id: number
@@ -9,7 +11,7 @@ export interface TreeNode {
911
fullName: string
1012
name: string
1113
keys: any[]
12-
'keys:keys'?: any
14+
[TREE_LEAF_FIELD]?: any
1315
}
1416

1517
export interface NodeMeta {

redisinsight/ui/src/helpers/tests/constructKeysToTreeMockResult.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { TREE_LEAF_FIELD } from 'uiSrc/components/virtual-tree'
2+
13
export const constructKeysToTreeMockResult = [
24
{
3-
name: 'keys:keys',
5+
name: TREE_LEAF_FIELD,
46
children: [],
57
keys: {
68
keys2: {
@@ -36,7 +38,7 @@ export const constructKeysToTreeMockResult = [
3638
name: 'keys',
3739
children: [
3840
{
39-
name: 'keys:keys',
41+
name: TREE_LEAF_FIELD,
4042
children: [],
4143
keys: {
4244
'keys:1': {
@@ -66,7 +68,7 @@ export const constructKeysToTreeMockResult = [
6668
name: '1',
6769
children: [
6870
{
69-
name: 'keys:keys',
71+
name: TREE_LEAF_FIELD,
7072
children: [],
7173
keys: {
7274
'keys:1:2': {
@@ -103,7 +105,7 @@ export const constructKeysToTreeMockResult = [
103105
name: '',
104106
children: [
105107
{
106-
name: 'keys:keys',
108+
name: TREE_LEAF_FIELD,
107109
children: [],
108110
keys: {
109111
'empty::test': {

redisinsight/ui/src/pages/browser/BrowserPage.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
appContextBrowser,
2525
setBrowserPanelSizes,
2626
setLastPageContext,
27+
updateBrowserTreeSelectedLeaf,
2728
} from 'uiSrc/slices/app/context'
2829
import { appAnalyticsInfoSelector } from 'uiSrc/slices/app/info'
2930
import { resetErrors } from 'uiSrc/slices/app/notifications'
@@ -158,6 +159,14 @@ const BrowserPage = () => {
158159
}
159160
}
160161

162+
const handleEditKey = (key: string, newKey: string) => {
163+
setSelectedKey(newKey)
164+
165+
if (viewType === KeyViewType.Tree) {
166+
dispatch(updateBrowserTreeSelectedLeaf({ key, newKey }))
167+
}
168+
}
169+
161170
return (
162171
<div className={`browserPage ${styles.container}`}>
163172
<InstanceHeader />
@@ -238,7 +247,7 @@ const BrowserPage = () => {
238247
<KeyDetailsWrapper
239248
keyProp={selectedKey}
240249
onCloseKey={closeKey}
241-
onEditKey={(newKey: string) => setSelectedKey(newKey)}
250+
onEditKey={(key: string, newKey: string) => handleEditKey(key, newKey)}
242251
onDeleteKey={() => setSelectedKey(null)}
243252
/>
244253
)}

redisinsight/ui/src/pages/browser/components/key-details/KeyDetailsWrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import KeyDetails from './KeyDetails/KeyDetails'
1818

1919
export interface Props {
2020
onCloseKey: () => void;
21-
onEditKey: (newKey: string) => void;
21+
onEditKey: (key: string, newKey: string) => void;
2222
onDeleteKey: () => void;
2323
keyProp: string | null;
2424
}
@@ -79,7 +79,7 @@ const KeyDetailsWrapper = ({ onCloseKey, onEditKey, onDeleteKey, keyProp }: Prop
7979
dispatch(editKeyTTL(key, ttl))
8080
}
8181
const handleEditKey = (oldKey: string, newKey: string, onFailure?: () => void) => {
82-
dispatch(editKey(oldKey, newKey, () => onEditKey(newKey), onFailure))
82+
dispatch(editKey(oldKey, newKey, () => onEditKey(oldKey, newKey), onFailure))
8383
}
8484

8585
const handleClose = () => {

redisinsight/ui/src/slices/app/context.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { createSlice } from '@reduxjs/toolkit'
2+
import { first } from 'lodash'
23
import { Nullable } from 'uiSrc/utils'
4+
import { TREE_LEAF_FIELD } from 'uiSrc/components/virtual-tree'
35
import { RootState } from '../store'
46
import { StateAppContext } from '../interfaces'
57

@@ -14,6 +16,7 @@ export const initialState: StateAppContext = {
1416
},
1517
panelSizes: {},
1618
tree: {
19+
separator: ':',
1720
panelSizes: {},
1821
openNodes: {},
1922
selectedLeaf: {},
@@ -56,6 +59,29 @@ const appContextSlice = createSlice({
5659
setBrowserTreeSelectedLeaf: (state, { payload }: { payload: any }) => {
5760
state.browser.tree.selectedLeaf = payload
5861
},
62+
updateBrowserTreeSelectedLeaf: (state, { payload }) => {
63+
const { selectedLeaf, separator } = state.browser.tree
64+
const [[selectedLeafField = '', keys = {}]] = Object.entries(selectedLeaf)
65+
const [pattern] = selectedLeafField.split(TREE_LEAF_FIELD)
66+
67+
if (payload.key in keys) {
68+
const isFitNewKey = payload.newKey?.startsWith?.(pattern)
69+
&& (pattern.split(separator)?.length === payload.newKey.split(separator)?.length)
70+
71+
if (!isFitNewKey) {
72+
delete keys[payload.key]
73+
return
74+
}
75+
76+
keys[payload.newKey] = {
77+
...keys[payload.key],
78+
name: payload.newKey
79+
}
80+
delete keys[payload.key]
81+
}
82+
83+
state.browser.tree.selectedLeaf[selectedLeafField] = keys
84+
},
5985
setBrowserTreeNodesOpen: (state, { payload }: { payload: { [key: string]: boolean; } }) => {
6086
state.browser.tree.openNodes = payload
6187
},
@@ -102,6 +128,7 @@ export const {
102128
setBrowserPanelSizes,
103129
setBrowserTreeSelectedLeaf,
104130
setBrowserTreeNodesOpen,
131+
updateBrowserTreeSelectedLeaf,
105132
resetBrowserTree,
106133
setBrowserTreePanelSizes,
107134
setWorkbenchScript,

redisinsight/ui/src/slices/interfaces/app.ts

Lines changed: 59 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,111 +2,114 @@ import { AxiosError } from 'axios'
22
import { Nullable } from 'uiSrc/utils'
33
import { GetServerInfoResponse } from 'apiSrc/dto/server.dto'
44
import { ICommands } from 'uiSrc/constants'
5-
import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys';
5+
import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys'
66

77
export interface IError extends AxiosError {
8-
id: string;
9-
instanceId?: string;
8+
id: string
9+
instanceId?: string
1010
}
1111

1212
export interface IMessage {
13-
id: string;
14-
title: string;
15-
message: string;
16-
group?: string;
13+
id: string
14+
title: string
15+
message: string
16+
group?: string
1717
}
1818

1919
export interface StateAppInfo {
20-
loading: boolean;
21-
error: string;
22-
server: Nullable<GetServerInfoResponse>;
20+
loading: boolean
21+
error: string
22+
server: Nullable<GetServerInfoResponse>
2323
analytics: {
24-
segmentWriteKey: string;
25-
identified: boolean;
26-
};
24+
segmentWriteKey: string
25+
identified: boolean
26+
}
2727
electron: {
28-
isUpdateAvailable: Nullable<boolean>;
29-
updateDownloadedVersion: string;
30-
isReleaseNotesViewed: Nullable<boolean>;
31-
};
32-
isShortcutsFlyoutOpen: boolean;
28+
isUpdateAvailable: Nullable<boolean>
29+
updateDownloadedVersion: string
30+
isReleaseNotesViewed: Nullable<boolean>
31+
}
32+
isShortcutsFlyoutOpen: boolean
3333
}
3434

3535
export interface StateAppContext {
36-
contextInstanceId: string;
37-
lastPage: string;
36+
contextInstanceId: string
37+
lastPage: string
3838
browser: {
3939
keyList: {
40-
isDataLoaded: boolean;
41-
scrollTopPosition: number;
42-
selectedKey: Nullable<string>;
40+
isDataLoaded: boolean
41+
scrollTopPosition: number
42+
selectedKey: Nullable<string>
4343
},
4444
panelSizes: {
45-
[key: string]: number;
45+
[key: string]: number
4646
},
4747
tree: {
48+
separator: string
4849
panelSizes: {
49-
[key: string]: number;
50+
[key: string]: number
5051
},
5152
openNodes: {
52-
[key: string]: boolean;
53+
[key: string]: boolean
5354
},
5455
selectedLeaf: {
55-
[key: string]: IKeyPropTypes[];
56+
[key: string]: {
57+
[key: string]: IKeyPropTypes
58+
}
5659
},
5760
}
5861
},
5962
workbench: {
60-
script: string;
63+
script: string
6164
enablementArea: {
62-
itemPath: string;
63-
itemScrollTop: number;
65+
itemPath: string
66+
itemScrollTop: number
6467
},
6568
panelSizes: {
6669
vertical: {
67-
[key: string]: number;
70+
[key: string]: number
6871
}
6972
}
7073
}
7174
}
7275

7376
export interface StateAppRedisCommands {
74-
loading: boolean;
75-
error: string;
76-
spec: ICommands;
77-
commandsArray: string[];
78-
commandGroups: string[];
77+
loading: boolean
78+
error: string
79+
spec: ICommands
80+
commandsArray: string[]
81+
commandGroups: string[]
7982
}
8083

8184
export interface IPluginVisualization {
82-
id: string;
85+
id: string
8386
uniqId: string
84-
name: string;
85-
plugin: any;
86-
activationMethod: string;
87-
matchCommands: string[];
88-
default?: boolean;
89-
iconDark?: string;
90-
iconLight?: string;
87+
name: string
88+
plugin: any
89+
activationMethod: string
90+
matchCommands: string[]
91+
default?: boolean
92+
iconDark?: string
93+
iconLight?: string
9194
}
9295

9396
export interface PluginsResponse {
94-
static: string;
97+
static: string
9598
plugins: IPlugin[]
9699
}
97100
export interface IPlugin {
98-
name: string;
99-
main: string;
100-
styles: string | string[];
101-
baseUrl: string;
102-
visualizations: any[];
103-
internal?: boolean;
101+
name: string
102+
main: string
103+
styles: string | string[]
104+
baseUrl: string
105+
visualizations: any[]
106+
internal?: boolean
104107
}
105108

106109
export interface StateAppPlugins {
107-
loading: boolean;
108-
error: string;
109-
staticPath: string;
110-
plugins: IPlugin[];
111-
visualizations: IPluginVisualization[];
110+
loading: boolean
111+
error: string
112+
staticPath: string
113+
plugins: IPlugin[]
114+
visualizations: IPluginVisualization[]
112115
}

0 commit comments

Comments
 (0)