Skip to content

Commit b204d83

Browse files
authored
Merge pull request #1447 from RedisInsight/fe/bugfix/RI-3842_Wrong_selected_key
#RI-3842 - Selected key not displayed in key list when switching between pages/views
2 parents 3915d04 + 8fa03e3 commit b204d83

File tree

5 files changed

+120
-26
lines changed

5 files changed

+120
-26
lines changed

redisinsight/ui/src/pages/browser/components/key-list/KeyList.tsx

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
formatLongName,
2020
bufferToString,
2121
bufferFormatRangeItems,
22-
isEqualBuffers,
2322
Nullable,
2423
} from 'uiSrc/utils'
2524
import {
@@ -33,9 +32,7 @@ import {
3332
fetchKeysMetadata,
3433
keysDataSelector,
3534
keysSelector,
36-
resetKeysData,
3735
selectedKeySelector,
38-
setLastBatchKeys,
3936
sourceKeysFetch,
4037
} from 'uiSrc/slices/browser/keys'
4138
import {
@@ -126,18 +123,6 @@ const KeyList = forwardRef((props: Props, ref) => {
126123
rerender({})
127124
}, [keysState.keys])
128125

129-
useEffect(() => {
130-
if (!selectedKey || !selectedKey?.data) return
131-
132-
const indexKeyForUpdate = itemsRef.current.findIndex(({ name }) =>
133-
isEqualBuffers(name, selectedKey?.data?.name))
134-
135-
if (indexKeyForUpdate === -1) return
136-
137-
itemsRef.current[indexKeyForUpdate] = selectedKey.data
138-
rerender({})
139-
}, [selectedKey])
140-
141126
const cancelAllMetadataRequests = () => {
142127
controller.current?.abort()
143128
}

redisinsight/ui/src/slices/browser/keys.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { fetchStreamEntries, setStreamInitialState } from './stream'
4141
import {
4242
deleteRedisearchKeyFromList,
4343
editRedisearchKeyFromList,
44+
editRedisearchKeyTTLFromList,
4445
fetchMoreRedisearchKeysAction,
4546
fetchRedisearchKeysAction,
4647
resetRedisearchKeysData,
@@ -253,6 +254,20 @@ const keysSlice = createSlice({
253254
}
254255
},
255256

257+
editPatternKeyTTLFromList: (state, { payload: [key, ttl] }: PayloadAction<[RedisResponseBuffer, number]>) => {
258+
const keys = state.data.keys.map((keyData) => {
259+
if (isEqualBuffers(keyData.name, key)) {
260+
keyData.ttl = ttl
261+
}
262+
return keyData
263+
})
264+
265+
state.data = {
266+
...state.data,
267+
keys,
268+
}
269+
},
270+
256271
// update length for Selected Key
257272
updateSelectedKeyLength: (state, { payload }) => {
258273
state.selectedKey = {
@@ -367,6 +382,7 @@ export const {
367382
deleteKeyFailure,
368383
deletePatternKeyFromList,
369384
editPatternKeyFromList,
385+
editPatternKeyTTLFromList,
370386
updateSelectedKeyLength,
371387
setPatternSearchMatch,
372388
setFilter,
@@ -797,7 +813,7 @@ export function deleteKeyAction(key: RedisResponseBuffer, onSuccessAction?: () =
797813
}
798814
})
799815
dispatch(deleteKeySuccess())
800-
dispatch(deleteKeyFromList(key))
816+
dispatch<any>(deleteKeyFromList(key))
801817
onSuccessAction?.()
802818
dispatch(addMessageNotification(successMessages.DELETED_KEY(key)))
803819
}
@@ -832,7 +848,7 @@ export function editKey(
832848
)
833849

834850
if (isStatusSuccessful(status)) {
835-
dispatch(editKeyFromList({ key, newKey }))
851+
dispatch<any>(editKeyFromList({ key, newKey }))
836852
onSuccess?.()
837853
}
838854
} catch (error) {
@@ -845,7 +861,7 @@ export function editKey(
845861
}
846862

847863
// Asynchronous thunk action
848-
export function editKeyTTL(key: string, ttl: number) {
864+
export function editKeyTTL(key: RedisResponseBuffer, ttl: number) {
849865
return async (dispatch: AppDispatch, stateInit: () => RootState) => {
850866
dispatch(defaultSelectedKeyAction())
851867

@@ -874,10 +890,11 @@ export function editKeyTTL(key: string, ttl: number) {
874890
}
875891
})
876892
if (ttl !== 0) {
893+
dispatch<any>(editKeyTTLFromList([key, ttl]))
877894
dispatch<any>(fetchKeyInfo(key))
878895
} else {
879896
dispatch(deleteKeySuccess())
880-
dispatch(deleteKeyFromList(key))
897+
dispatch<any>(deleteKeyFromList(key))
881898
}
882899
dispatch(defaultSelectedKeyActionSuccess())
883900
}
@@ -932,8 +949,8 @@ export function fetchKeys(
932949
const isRedisearchExists = isRedisearchAvailable(state.connections.instances.connectedInstance.modules)
933950

934951
return searchMode === SearchMode.Pattern || !isRedisearchExists
935-
? dispatch(fetchPatternKeysAction(cursor, count, onSuccess, onFailed))
936-
: dispatch(fetchRedisearchKeysAction(cursor, count, onSuccess, onFailed))
952+
? dispatch<any>(fetchPatternKeysAction(cursor, count, onSuccess, onFailed))
953+
: dispatch<any>(fetchRedisearchKeysAction(cursor, count, onSuccess, onFailed))
937954
}
938955
}
939956

@@ -977,12 +994,22 @@ export function deleteKeyFromList(key: RedisResponseBuffer) {
977994
}
978995
}
979996

980-
export function editKeyFromList(key: RedisResponseBuffer) {
997+
export function editKeyFromList(data: { key: RedisResponseBuffer, newKey: RedisResponseBuffer }) {
998+
return async (dispatch: AppDispatch, stateInit: () => RootState) => {
999+
const state = stateInit()
1000+
1001+
return state.browser.keys?.searchMode === SearchMode.Pattern
1002+
? dispatch(editPatternKeyFromList(data))
1003+
: dispatch(editRedisearchKeyFromList(data))
1004+
}
1005+
}
1006+
1007+
export function editKeyTTLFromList(data: [RedisResponseBuffer, number]) {
9811008
return async (dispatch: AppDispatch, stateInit: () => RootState) => {
9821009
const state = stateInit()
9831010

9841011
return state.browser.keys?.searchMode === SearchMode.Pattern
985-
? dispatch(editPatternKeyFromList(key))
986-
: dispatch(editRedisearchKeyFromList(key))
1012+
? dispatch(editPatternKeyTTLFromList(data))
1013+
: dispatch(editRedisearchKeyTTLFromList(data))
9871014
}
9881015
}

redisinsight/ui/src/slices/browser/redisearch.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ const redisearchSlice = createSlice({
183183
keys,
184184
}
185185
},
186+
187+
editRedisearchKeyTTLFromList: (state, { payload: [key, ttl] }: PayloadAction<[RedisResponseBuffer, number]>) => {
188+
const keys = state.data.keys.map((keyData) => {
189+
if (isEqualBuffers(keyData.name, key)) {
190+
keyData.ttl = ttl
191+
}
192+
return keyData
193+
})
194+
195+
state.data = {
196+
...state.data,
197+
keys,
198+
}
199+
},
186200
},
187201
})
188202

@@ -207,6 +221,7 @@ export const {
207221
resetRedisearchKeysData,
208222
deleteRedisearchKeyFromList,
209223
editRedisearchKeyFromList,
224+
editRedisearchKeyTTLFromList,
210225
} = redisearchSlice.actions
211226

212227
// Selectors

redisinsight/ui/src/slices/tests/browser/keys.spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { cloneDeep } from 'lodash'
22
import { AxiosError } from 'axios'
33
import { KeyTypes, KeyValueFormat } from 'uiSrc/constants'
44
import { apiService } from 'uiSrc/services'
5-
import { parseKeysListResponse, stringToBuffer } from 'uiSrc/utils'
5+
import { parseKeysListResponse, stringToBuffer, UTF8ToBuffer } from 'uiSrc/utils'
66
import { cleanup, initialStateDefault, mockedStore } from 'uiSrc/utils/test-utils'
77
import { addErrorNotification, addMessageNotification } from 'uiSrc/slices/app/notifications'
88
import successMessages from 'uiSrc/components/notifications/success-messages'
@@ -59,6 +59,7 @@ import reducer, {
5959
resetKeyInfo,
6060
resetKeys,
6161
fetchKeysMetadata,
62+
editPatternKeyTTLFromList,
6263
} from '../../browser/keys'
6364
import { getString } from '../../browser/string'
6465

@@ -750,6 +751,37 @@ describe('keys slice', () => {
750751
})
751752
})
752753

754+
describe('editPatternKeyTTLFromList', () => {
755+
it('should properly set the state before the edit key ttl', () => {
756+
// Arrange
757+
758+
const key = UTF8ToBuffer('key')
759+
const ttl = 12000
760+
761+
const initialStateMock = {
762+
...initialState,
763+
data: {
764+
keys: [{ name: key }],
765+
},
766+
}
767+
const state = {
768+
...initialState,
769+
data: {
770+
keys: [{ name: key, ttl }],
771+
},
772+
}
773+
774+
// Act
775+
const nextState = reducer(initialStateMock, editPatternKeyTTLFromList([key, ttl]))
776+
777+
// Assert
778+
const rootState = Object.assign(initialStateDefault, {
779+
browser: { keys: nextState },
780+
})
781+
expect(keysSelector(rootState)).toEqual(state)
782+
})
783+
})
784+
753785
describe('resetKeyInfo', () => {
754786
it('should properly save viewFormat', () => {
755787
// Arrange
@@ -1256,6 +1288,7 @@ describe('keys slice', () => {
12561288
const expectedActions = [
12571289
defaultSelectedKeyAction(),
12581290
// fetch keyInfo
1291+
editPatternKeyTTLFromList([key, ttl]),
12591292
defaultSelectedKeyAction(),
12601293
defaultSelectedKeyActionSuccess(),
12611294
]

redisinsight/ui/src/slices/tests/browser/redisearch.spec.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import successMessages from 'uiSrc/components/notifications/success-messages'
44
import { apiService } from 'uiSrc/services'
55
import { cleanup, initialStateDefault, mockedStore, mockStore } from 'uiSrc/utils/test-utils'
66
import { addErrorNotification, addMessageNotification } from 'uiSrc/slices/app/notifications'
7-
import { stringToBuffer } from 'uiSrc/utils'
7+
import { stringToBuffer, UTF8ToBuffer } from 'uiSrc/utils'
88
import { REDISEARCH_LIST_DATA_MOCK } from 'uiSrc/mocks/handlers/browser/redisearchHandlers'
99
import { SearchMode } from 'uiSrc/slices/interfaces/keys'
1010
import { fetchKeys, fetchMoreKeys } from 'uiSrc/slices/browser/keys'
@@ -35,6 +35,7 @@ import reducer, {
3535
resetRedisearchKeysData,
3636
deleteRedisearchKeyFromList,
3737
editRedisearchKeyFromList,
38+
editRedisearchKeyTTLFromList,
3839
} from '../../browser/redisearch'
3940

4041
let store: typeof mockedStore
@@ -713,6 +714,39 @@ describe('redisearch slice', () => {
713714
})
714715
})
715716

717+
describe('editRedisearchKeyTTLFromList', () => {
718+
it('should properly set the state before the edit key ttl', () => {
719+
// Arrange
720+
721+
const key = UTF8ToBuffer('key')
722+
const ttl = 12000
723+
724+
const prevState = {
725+
...initialState,
726+
data: {
727+
...initialState.data,
728+
keys: [{ name: key }],
729+
},
730+
}
731+
const state = {
732+
...initialState,
733+
data: {
734+
...initialState.data,
735+
keys: [{ name: key, ttl }],
736+
},
737+
}
738+
739+
// Act
740+
const nextState = reducer(prevState, editRedisearchKeyTTLFromList([key, ttl]))
741+
742+
// Assert
743+
const rootState = Object.assign(initialStateDefault, {
744+
browser: { redisearch: nextState },
745+
})
746+
expect(redisearchSelector(rootState)).toEqual(state)
747+
})
748+
})
749+
716750
describe('thunks', () => {
717751
describe('fetchRedisearchListAction', () => {
718752
it('call both fetchRedisearchListAction, loadListSuccess when fetch is successed', async () => {

0 commit comments

Comments
 (0)