Skip to content

Commit c178df4

Browse files
authored
Merge pull request #3313 from RedisInsight/fe/bugfix/RI-5668_RI-5674
#RI-5568 - fix editing null value
2 parents 40834dd + 727473a commit c178df4

File tree

10 files changed

+71
-29
lines changed

10 files changed

+71
-29
lines changed

redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const KeyDetailsHeader = ({
7272
const dispatch = useDispatch()
7373

7474
const handleRefreshKey = () => {
75-
dispatch(refreshKey(keyBuffer!, type))
75+
dispatch(refreshKey(keyBuffer!, type, undefined, length))
7676
}
7777

7878
const handleEditTTL = (key: RedisResponseBuffer, ttl: number) => {

redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/RejsonDetailsWrapper.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react'
1+
import React, { useEffect, useState } from 'react'
22
import { useSelector } from 'react-redux'
33
import { EuiProgress } from '@elastic/eui'
44

@@ -22,12 +22,16 @@ const RejsonDetailsWrapper = (props: Props) => {
2222
const keyType = KeyTypes.ReJSON
2323
const { loading } = useSelector(rejsonSelector)
2424
const { data, downloaded, type, path } = useSelector(rejsonDataSelector)
25-
const { name: selectedKey } = useSelector(selectedKeyDataSelector) || {}
25+
const { name: selectedKey, nameString, length } = useSelector(selectedKeyDataSelector) || {}
2626
const { id: instanceId } = useSelector(connectedInstanceSelector)
2727
const { viewType } = useSelector(keysSelector)
2828

2929
const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set())
3030

31+
useEffect(() => {
32+
setExpandedRows(new Set())
33+
}, [nameString])
34+
3135
const reportJSONKeyCollapsed = (level: number) => {
3236
sendEventTelemetry({
3337
event: getBasedOnViewTypeEvent(
@@ -56,7 +60,7 @@ const RejsonDetailsWrapper = (props: Props) => {
5660
})
5761
}
5862

59-
const reportJsonKeyExpandAndCollapse = (isExpanded: boolean, path: string) => {
63+
const handleJsonKeyExpandAndCollapse = (isExpanded: boolean, path: string) => {
6064
const matchedPath = path.match(/\[.+?\]/g)
6165
const levelFromPath = matchedPath ? matchedPath.length - 1 : 0
6266
if (isExpanded) {
@@ -100,9 +104,10 @@ const RejsonDetailsWrapper = (props: Props) => {
100104
selectedKey={selectedKey || stringToBuffer('')}
101105
dataType={type || ''}
102106
data={data as IJSONData}
107+
length={length}
103108
parentPath={path}
104109
expadedRows={expandedRows}
105-
onJsonKeyExpandAndCollapse={reportJsonKeyExpandAndCollapse}
110+
onJsonKeyExpandAndCollapse={handleJsonKeyExpandAndCollapse}
106111
isDownloaded={downloaded}
107112
/>
108113
)}

redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const EditEntireItemAction = (props: Props) => {
5555
<div className={styles.row}>
5656
<div className={styles.fullWidthContainer}>
5757
<EuiOutsideClickDetector onOutsideClick={() => onCancel?.()}>
58-
<div style={{ marginBottom: '34px' }}>
58+
<div>
5959
<EuiWindowEvent event="keydown" handler={(e) => handleOnEsc(e)} />
6060
<EuiFocusTrap>
6161
<EuiForm

redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ interface UpdateValueBody {
3636
export type IJSONData = IJSONValue | IJSONDocument | IJSONDocument[]
3737

3838
export interface BaseProps {
39+
length?: number
3940
data: IJSONData
4041
dataType: string
4142
parentPath?: string

redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/rejson-details/RejsonDetails.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const RejsonDetails = (props: BaseProps) => {
2020
const {
2121
data,
2222
selectedKey,
23+
length,
2324
dataType,
2425
parentPath,
2526
isDownloaded,
@@ -35,11 +36,11 @@ const RejsonDetails = (props: BaseProps) => {
3536
dispatch<any>(fetchVisualisationResults(path, forceRetrieve))
3637

3738
const handleAppendRejsonArrayItemAction = (keyName: RedisResponseBuffer, path: string, data: string) => {
38-
dispatch(appendReJSONArrayItemAction(keyName, path, data))
39+
dispatch(appendReJSONArrayItemAction(keyName, path, data, length))
3940
}
4041

4142
const handleSetRejsonDataAction = (keyName: RedisResponseBuffer, path: string, data: string) => {
42-
dispatch(setReJSONDataAction(keyName, path, data))
43+
dispatch(setReJSONDataAction(keyName, path, data, length))
4344
}
4445

4546
const handleFormSubmit = ({ key, value }: { key?: string, value: string }) => {
@@ -56,7 +57,7 @@ const RejsonDetails = (props: BaseProps) => {
5657
}
5758

5859
const onClickRemoveKey = (path: string, keyName: string) => {
59-
dispatch(removeReJSONKeyAction(selectedKey, path || '.', keyName))
60+
dispatch(removeReJSONKeyAction(selectedKey, path || '.', keyName, length))
6061
}
6162

6263
const onClickSetRootKVPair = () => {

redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/rejson-object/RejsonObject.tsx

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,22 @@ const RejsonObject = (props: JSONObjectProps) => {
4040
const [valueOfEntireObject, setValueOfEntireObject] = useState<any>('')
4141
const [addNewKeyValuePair, setAddNewKeyValuePair] = useState<boolean>(false)
4242
const [loading, setLoading] = useState<boolean>(false)
43-
const [isExpanded, setIsExpanded] = useState<boolean>(expadedRows?.has(path) || false)
43+
const [isExpanded, setIsExpanded] = useState<boolean>(false)
4444

4545
useEffect(() => {
46-
if (!isExpanded) {
46+
if (!expadedRows?.has(path)) {
4747
setValue(defaultValue)
4848
return
4949
}
5050

5151
if (isDownloaded) {
5252
setValue(currentValue)
53-
} else {
54-
fetchObject()
53+
setIsExpanded(expadedRows?.has(path))
54+
return
5555
}
56-
}, [isExpanded, isDownloaded])
56+
57+
fetchObject()
58+
}, [])
5759

5860
const handleFormSubmit = ({ key, value }: { key?: string, value: string }) => {
5961
setAddNewKeyValuePair(false)
@@ -82,8 +84,23 @@ const RejsonObject = (props: JSONObjectProps) => {
8284
}
8385

8486
const onClickExpandCollapse = (path: string) => {
85-
onJsonKeyExpandAndCollapse(!isExpanded, path)
86-
setIsExpanded((v) => !v)
87+
if (isExpanded) {
88+
onJsonKeyExpandAndCollapse(false, path)
89+
setIsExpanded(false)
90+
setValue(defaultValue)
91+
92+
return
93+
}
94+
95+
if (isDownloaded) {
96+
onJsonKeyExpandAndCollapse(true, path)
97+
setIsExpanded(true)
98+
setValue(currentValue)
99+
100+
return
101+
}
102+
103+
fetchObject()
87104
}
88105

89106
const fetchObject = async () => {
@@ -96,6 +113,7 @@ const RejsonObject = (props: JSONObjectProps) => {
96113
setDownloaded(downloaded)
97114
clearTimeout(spinnerDelay)
98115
setLoading(false)
116+
setIsExpanded(true)
99117
} catch {
100118
clearTimeout(spinnerDelay)
101119
setIsExpanded(false)
@@ -188,4 +206,4 @@ const RejsonObject = (props: JSONObjectProps) => {
188206
)
189207
}
190208

191-
export default RejsonObject
209+
export default React.memo(RejsonObject)

redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/rejson-scalar/RejsonScalar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
22
import { useDispatch } from 'react-redux'
33
import cx from 'classnames'
44

5-
import { isString } from 'lodash'
5+
import { isNull, isString } from 'lodash'
66
import { setReJSONDataAction } from 'uiSrc/slices/browser/rejson'
77
import InlineItemEditor from 'uiSrc/components/inline-item-editor/InlineItemEditor'
88
import PopoverDelete from 'uiSrc/pages/browser/components/popover-delete/PopoverDelete'
@@ -35,7 +35,7 @@ const RejsonScalar = (props: JSONScalarProps) => {
3535
const dispatch = useDispatch()
3636

3737
useEffect(() => {
38-
setChangedValue(isString(value) ? `"${value}"` : value)
38+
setChangedValue(isString(value) ? `"${value}"` : isNull(value) ? 'null' : value)
3939
}, [value])
4040

4141
const onDeclineChanges = () => {

redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/styles.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
.controlsBottom {
8080
background-color: var(--euiColorLightestShade);
8181
height: 24px !important;
82+
margin-bottom: 4px !important;
8283
z-index: 2;
8384
display: flex;
8485
align-items: center;

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ export function fetchKeyInfo(key: RedisResponseBuffer, resetData?: boolean) {
683683
dispatch<any>(fetchSetMembers(key, 0, SCAN_COUNT_DEFAULT, '*', resetData))
684684
}
685685
if (data.type === KeyTypes.ReJSON) {
686-
dispatch<any>(fetchReJSON(key, '.', resetData))
686+
dispatch<any>(fetchReJSON(key, '.', data.length, resetData))
687687
}
688688
if (data.type === KeyTypes.Stream) {
689689
const { viewType } = state.browser.stream
@@ -1255,7 +1255,12 @@ export function editKeyTTLFromList(data: [RedisResponseBuffer, number]) {
12551255
}
12561256
}
12571257

1258-
export function refreshKey(key: RedisResponseBuffer, type: KeyTypes | ModulesKeyTypes, args?: IFetchKeyArgs) {
1258+
export function refreshKey(
1259+
key: RedisResponseBuffer,
1260+
type: KeyTypes | ModulesKeyTypes,
1261+
args?: IFetchKeyArgs,
1262+
length?: number
1263+
) {
12591264
return async (dispatch: AppDispatch) => {
12601265
const resetData = false
12611266
dispatch(refreshKeyInfoAction(key))
@@ -1281,7 +1286,7 @@ export function refreshKey(key: RedisResponseBuffer, type: KeyTypes | ModulesKey
12811286
break
12821287
}
12831288
case KeyTypes.ReJSON: {
1284-
dispatch(fetchReJSON(key, '.', true))
1289+
dispatch(fetchReJSON(key, '.', length, true))
12851290
break
12861291
}
12871292
case KeyTypes.Stream: {

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'
22
import axios, { AxiosError, CancelTokenSource } from 'axios'
33
import * as jsonpath from 'jsonpath'
44

5+
import { isNumber } from 'lodash'
56
import { ApiEndpoints } from 'uiSrc/constants'
67
import { apiService } from 'uiSrc/services'
78
import { getBasedOnViewTypeEvent, sendEventTelemetry, TelemetryEvent, getJsonPathLevel } from 'uiSrc/telemetry'
@@ -24,6 +25,8 @@ import { InitialStateRejson, RedisResponseBuffer } from '../interfaces'
2425
import { addErrorNotification, addMessageNotification } from '../app/notifications'
2526
import { AppDispatch, RootState } from '../store'
2627

28+
const JSON_LENGTH_TO_FORCE_RETRIEVE = 200
29+
2730
export const initialState: InitialStateRejson = {
2831
loading: false,
2932
error: null,
@@ -123,7 +126,12 @@ export default rejsonSlice.reducer
123126
export let sourceRejson: Nullable<CancelTokenSource> = null
124127

125128
// Asynchronous thunk action
126-
export function fetchReJSON(key: RedisResponseBuffer, path = '.', resetData?: boolean) {
129+
export function fetchReJSON(
130+
key: RedisResponseBuffer,
131+
path = '.',
132+
length?: number,
133+
resetData?: boolean,
134+
) {
127135
return async (dispatch: AppDispatch, stateInit: () => RootState) => {
128136
dispatch(loadRejsonBranch(resetData))
129137

@@ -143,7 +151,7 @@ export function fetchReJSON(key: RedisResponseBuffer, path = '.', resetData?: bo
143151
{
144152
keyName: key,
145153
path,
146-
forceRetrieve: false,
154+
forceRetrieve: isNumber(length) && length > JSON_LENGTH_TO_FORCE_RETRIEVE,
147155
encoding,
148156
},
149157
{ cancelToken: sourceRejson.token }
@@ -168,6 +176,7 @@ export function setReJSONDataAction(
168176
key: RedisResponseBuffer,
169177
path: string,
170178
data: string,
179+
length?: number,
171180
onSuccessAction?: () => void,
172181
onFailAction?: () => void
173182
) {
@@ -207,7 +216,7 @@ export function setReJSONDataAction(
207216
}
208217

209218
dispatch(setReJSONDataSuccess())
210-
dispatch<any>(fetchReJSON(key, '.'))
219+
dispatch<any>(fetchReJSON(key, '.', length))
211220
dispatch<any>(refreshKeyInfoAction(key))
212221
onSuccessAction?.()
213222
}
@@ -224,7 +233,8 @@ export function setReJSONDataAction(
224233
export function appendReJSONArrayItemAction(
225234
key: RedisResponseBuffer,
226235
path: string,
227-
data: string
236+
data: string,
237+
length?: number
228238
) {
229239
return async (dispatch: AppDispatch, stateInit: () => RootState) => {
230240
dispatch(appendReJSONArrayItem())
@@ -257,7 +267,7 @@ export function appendReJSONArrayItemAction(
257267
}
258268
})
259269
dispatch(appendReJSONArrayItemSuccess())
260-
dispatch<any>(fetchReJSON(key, '.'))
270+
dispatch<any>(fetchReJSON(key, '.', length))
261271
dispatch<any>(refreshKeyInfoAction(key))
262272
}
263273
} catch (error) {
@@ -272,7 +282,8 @@ export function appendReJSONArrayItemAction(
272282
export function removeReJSONKeyAction(
273283
key: RedisResponseBuffer,
274284
path = '.',
275-
jsonKeyName = ''
285+
jsonKeyName = '',
286+
length?: number
276287
) {
277288
return async (dispatch: AppDispatch, stateInit: () => RootState) => {
278289
dispatch(removeRejsonKey())
@@ -305,7 +316,7 @@ export function removeReJSONKeyAction(
305316
}
306317
})
307318
dispatch(removeRejsonKeySuccess())
308-
dispatch<any>(fetchReJSON(key, '.'))
319+
dispatch<any>(fetchReJSON(key, '.', length))
309320
dispatch<any>(refreshKeyInfoAction(key))
310321
dispatch(
311322
addMessageNotification(

0 commit comments

Comments
 (0)