Skip to content

Commit da4194d

Browse files
#RI-4061 - resolve comments
1 parent 2e03fff commit da4194d

File tree

7 files changed

+131
-41
lines changed

7 files changed

+131
-41
lines changed

redisinsight/ui/src/components/monaco-json/MonacoJson.tsx

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useContext, useEffect, useRef, useState } from 'react'
1+
import React, { useContext, useEffect, useRef } from 'react'
22
import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api'
33
import MonacoEditor, { monaco } from 'react-monaco-editor'
44
import cx from 'classnames'
@@ -12,22 +12,19 @@ import styles from './styles.modules.scss'
1212

1313
export interface Props {
1414
value: string
15-
updatedValue: string
1615
onChange: (value: string) => void
1716
disabled?: boolean
1817
wrapperClassName?: string
1918
'data-testid'?: string
2019
}
2120
const MonacoJson = (props: Props) => {
2221
const {
23-
value: valueProp,
24-
updatedValue,
22+
value,
2523
onChange,
2624
disabled,
2725
wrapperClassName,
2826
'data-testid': dataTestId
2927
} = props
30-
const [value, setValue] = useState<string>(valueProp)
3128
const monacoObjects = useRef<Nullable<IEditorMount>>(null)
3229

3330
const { theme } = useContext(ThemeContext)
@@ -36,15 +33,6 @@ const MonacoJson = (props: Props) => {
3633
monacoObjects.current?.editor.updateOptions({ readOnly: disabled })
3734
}, [disabled])
3835

39-
useEffect(() => {
40-
setValue(updatedValue)
41-
}, [updatedValue])
42-
43-
const handleChange = (val: string) => {
44-
setValue(val)
45-
onChange(val)
46-
}
47-
4836
const editorDidMount = (
4937
editor: monacoEditor.editor.IStandaloneCodeEditor,
5038
monaco: typeof monacoEditor,
@@ -89,7 +77,7 @@ const MonacoJson = (props: Props) => {
8977
language="json"
9078
theme={theme === Theme.Dark ? 'dark' : 'light'}
9179
value={value}
92-
onChange={handleChange}
80+
onChange={onChange}
9381
options={options}
9482
className="json-monaco-editor"
9583
editorDidMount={editorDidMount}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react'
2+
import { instance, mock } from 'ts-mockito'
3+
import { render } from 'uiSrc/utils/test-utils'
4+
5+
import UploadFile, { Props } from './UploadFile'
6+
7+
const mockedProps = mock<Props>()
8+
9+
describe('UploadFile', () => {
10+
it('should render', () => {
11+
expect(
12+
render(<UploadFile {...instance(mockedProps)} />)
13+
).toBeTruthy()
14+
})
15+
})
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react'
2+
import { EuiButtonEmpty, EuiText } from '@elastic/eui'
3+
4+
import styles from './styles.module.scss'
5+
6+
export interface Props {
7+
onFileChange: ({ target: { files } }: { target: { files: FileList | null } }) => void
8+
onClick: () => void
9+
}
10+
11+
const UploadFile = ({ onFileChange, onClick }: Props) => (
12+
<EuiButtonEmpty
13+
iconType="folderOpen"
14+
className={styles.emptyBtn}
15+
>
16+
<label htmlFor="upload-input-file" className={styles.uploadBtn}>
17+
<EuiText className={styles.label}>Upload</EuiText>
18+
<input
19+
type="file"
20+
id="upload-input-file"
21+
data-testid="upload-input-file"
22+
accept="application/json, text/plain"
23+
onChange={onFileChange}
24+
onClick={onClick}
25+
className={styles.fileDrop}
26+
aria-label="Select file"
27+
/>
28+
</label>
29+
</EuiButtonEmpty>
30+
)
31+
32+
export default UploadFile
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import UploadFile from './UploadFile'
2+
3+
export default UploadFile
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.fileDrop {
2+
display: none;
3+
}
4+
5+
.uploadBtn {
6+
display: flex;
7+
cursor: pointer;
8+
}
9+
10+
.emptyBtn:global(.euiButtonEmpty) {
11+
height: 22px;
12+
margin-top: 7px;
13+
}
14+
15+
.emptyBtn:global(.euiButtonEmpty .euiButtonEmpty__content) {
16+
padding: 0 12px;
17+
}
18+
19+
:global(.euiButtonEmpty.euiButtonEmpty--primary).emptyBtn .label {
20+
color: var(--inputTextColor) !important;
21+
line-height: 16px !important;
22+
font-weight: 400 !important;
23+
font-size: 12px !important;
24+
}

redisinsight/ui/src/pages/browser/components/add-key/AddKeyReJSON/AddKeyReJSON.spec.tsx

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React from 'react'
2+
import userEvent from '@testing-library/user-event'
23
import { instance, mock } from 'ts-mockito'
34

4-
import { fireEvent, render, screen } from 'uiSrc/utils/test-utils'
5+
import { fireEvent, render, screen, waitFor } from 'uiSrc/utils/test-utils'
56
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
67

78
import AddKeyReJSON, { Props } from './AddKeyReJSON'
@@ -83,4 +84,54 @@ describe('AddKeyReJSON', () => {
8384
}
8485
})
8586
})
87+
88+
it('should load file', async () => {
89+
render(<AddKeyReJSON {...instance(mockedProps)} keyName="name" />)
90+
91+
const jsonString = JSON.stringify({ a: 12 })
92+
const blob = new Blob([jsonString])
93+
const file = new File([blob], 'empty.json', {
94+
type: 'application/JSON',
95+
})
96+
const fileInput = screen.getByTestId('upload-input-file')
97+
98+
expect(fileInput).toHaveAttribute('accept', 'application/json, text/plain')
99+
expect(fileInput.files.length).toBe(0)
100+
101+
await userEvent.upload(fileInput, file)
102+
103+
expect(fileInput.files.length).toBe(1)
104+
})
105+
106+
it('should set the incorrect value from json file', async () => {
107+
render(<AddKeyReJSON {...instance(mockedProps)} keyName="name" />)
108+
109+
const jsonString = JSON.stringify({ a: 12 })
110+
const blob = new Blob([jsonString])
111+
const file = new File([blob], 'empty.json', {
112+
type: 'application/JSON',
113+
})
114+
const fileInput = screen.getByTestId('upload-input-file')
115+
116+
expect(fileInput).toHaveAttribute('accept', 'application/json, text/plain')
117+
118+
await userEvent.upload(fileInput, file)
119+
120+
await waitFor(() => expect(screen.getByTestId('json-value')).toHaveValue('{"a":12}'))
121+
})
122+
123+
it('should set the value from json file', async () => {
124+
render(<AddKeyReJSON {...instance(mockedProps)} keyName="name" />)
125+
126+
const jsonString = JSON.stringify('{ a: 12')
127+
const blob = new Blob([jsonString])
128+
const file = new File([blob], 'empty.json', {
129+
type: 'application/JSON',
130+
})
131+
const fileInput = screen.getByTestId('upload-input-file')
132+
133+
await userEvent.upload(fileInput, file)
134+
135+
await waitFor(() => expect(screen.getByTestId('json-value')).toHaveValue('"{ a: 12"'))
136+
})
86137
})

redisinsight/ui/src/pages/browser/components/add-key/AddKeyReJSON/AddKeyReJSON.tsx

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import { useDispatch, useSelector } from 'react-redux'
33
import { useParams } from 'react-router-dom'
44
import {
55
EuiButton,
6-
EuiButtonEmpty,
76
EuiFormRow,
8-
EuiText,
97
EuiTextColor,
108
EuiForm,
119
EuiFlexGroup,
@@ -17,6 +15,7 @@ import { Maybe, stringToBuffer } from 'uiSrc/utils'
1715
import { addKeyStateSelector, addReJSONKey, } from 'uiSrc/slices/browser/keys'
1816

1917
import MonacoJson from 'uiSrc/components/monaco-json'
18+
import UploadFile from 'uiSrc/components/uploadFile'
2019
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
2120
import { CreateRejsonRlWithExpireDto } from 'apiSrc/modules/browser/dto'
2221

@@ -26,8 +25,6 @@ import {
2625

2726
import AddKeyFooter from '../AddKeyFooter/AddKeyFooter'
2827

29-
import styles from './styles.module.scss'
30-
3128
export interface Props {
3229
keyName: string
3330
keyTTL: Maybe<number>
@@ -38,7 +35,6 @@ const AddKeyReJSON = (props: Props) => {
3835
const { keyName = '', keyTTL, onCancel } = props
3936
const { loading } = useSelector(addKeyStateSelector)
4037
const [ReJSONValue, setReJSONValue] = useState<string>('')
41-
const [valueFromFile, setValueFromFile] = useState<string>('')
4238
const [isFormValid, setIsFormValid] = useState<boolean>(false)
4339

4440
const dispatch = useDispatch()
@@ -80,7 +76,6 @@ const AddKeyReJSON = (props: Props) => {
8076
if (files && files[0]) {
8177
const reader = new FileReader()
8278
reader.onload = async (e) => {
83-
setValueFromFile(e?.target?.result as string)
8479
setReJSONValue(e?.target?.result as string)
8580
}
8681
reader.readAsText(files[0])
@@ -102,31 +97,13 @@ const AddKeyReJSON = (props: Props) => {
10297
<>
10398
<MonacoJson
10499
value={ReJSONValue}
105-
updatedValue={valueFromFile}
106100
onChange={setReJSONValue}
107101
disabled={loading}
108102
data-testid="json-value"
109103
/>
110104
<EuiFlexGroup justifyContent="flexEnd">
111105
<EuiFlexItem grow={false}>
112-
<EuiButtonEmpty
113-
iconType="folderOpen"
114-
className={styles.emptyBtn}
115-
>
116-
<label htmlFor="upload-input-file" className={styles.uploadBtn}>
117-
<EuiText className={styles.label}>Upload</EuiText>
118-
<input
119-
type="file"
120-
id="upload-input-file"
121-
data-testid="upload-input-file"
122-
accept="application/json, text/plain"
123-
onChange={onFileChange}
124-
onClick={onClick}
125-
className={styles.fileDrop}
126-
aria-label="Select file"
127-
/>
128-
</label>
129-
</EuiButtonEmpty>
106+
<UploadFile onClick={onClick} onFileChange={onFileChange} />
130107
</EuiFlexItem>
131108
</EuiFlexGroup>
132109
</>

0 commit comments

Comments
 (0)