Skip to content

Commit afac58d

Browse files
#RI-4061 - add json upload
1 parent 4621f8a commit afac58d

File tree

5 files changed

+105
-7
lines changed

5 files changed

+105
-7
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import styles from './styles.modules.scss'
1212

1313
export interface Props {
1414
value: string
15+
updatedValue: string
1516
onChange: (value: string) => void
1617
disabled?: boolean
1718
wrapperClassName?: string
@@ -20,6 +21,7 @@ export interface Props {
2021
const MonacoJson = (props: Props) => {
2122
const {
2223
value: valueProp,
24+
updatedValue,
2325
onChange,
2426
disabled,
2527
wrapperClassName,
@@ -34,6 +36,10 @@ const MonacoJson = (props: Props) => {
3436
monacoObjects.current?.editor.updateOptions({ readOnly: disabled })
3537
}, [disabled])
3638

39+
useEffect(() => {
40+
setValue(updatedValue)
41+
}, [updatedValue])
42+
3743
const handleChange = (val: string) => {
3844
setValue(val)
3945
onChange(val)

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react'
22
import { instance, mock } from 'ts-mockito'
33

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

67
import AddKeyReJSON, { Props } from './AddKeyReJSON'
78
import AddKeyFooter from '../AddKeyFooter/AddKeyFooter'
@@ -14,6 +15,11 @@ jest.mock('../AddKeyFooter/AddKeyFooter', () => ({
1415
default: jest.fn()
1516
}))
1617

18+
jest.mock('uiSrc/telemetry', () => ({
19+
...jest.requireActual('uiSrc/telemetry'),
20+
sendEventTelemetry: jest.fn(),
21+
}))
22+
1723
const MockAddKeyFooter = (props: any) => (
1824
<div {...props} />
1925
)
@@ -61,4 +67,20 @@ describe('AddKeyReJSON', () => {
6167
)
6268
expect(screen.getByTestId('add-key-json-btn')).not.toBeDisabled()
6369
})
70+
71+
it('should call proper telemetry events after click Upload', () => {
72+
const sendEventTelemetryMock = jest.fn()
73+
sendEventTelemetry.mockImplementation(() => sendEventTelemetryMock)
74+
75+
render(<AddKeyReJSON {...instance(mockedProps)} />)
76+
77+
fireEvent.click(screen.getByTestId('upload-input-file'))
78+
79+
expect(sendEventTelemetry).toBeCalledWith({
80+
event: TelemetryEvent.BROWSER_JSON_VALUE_IMPORT_CLICKED,
81+
eventData: {
82+
databaseId: 'instanceId',
83+
}
84+
})
85+
})
6486
})

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

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import React, { FormEvent, useEffect, useState } from 'react'
22
import { useDispatch, useSelector } from 'react-redux'
3+
import { useParams } from 'react-router-dom'
34
import {
45
EuiButton,
56
EuiFormRow,
7+
EuiIcon,
8+
EuiText,
69
EuiTextColor,
710
EuiForm,
811
EuiFlexGroup,
912
EuiFlexItem,
1013
EuiPanel,
1114
} from '@elastic/eui'
15+
1216
import { Maybe, stringToBuffer } from 'uiSrc/utils'
1317
import { addKeyStateSelector, addReJSONKey, } from 'uiSrc/slices/browser/keys'
1418

1519
import MonacoJson from 'uiSrc/components/monaco-json'
20+
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
1621
import { CreateRejsonRlWithExpireDto } from 'apiSrc/modules/browser/dto'
1722

1823
import {
@@ -21,6 +26,8 @@ import {
2126

2227
import AddKeyFooter from '../AddKeyFooter/AddKeyFooter'
2328

29+
import styles from './styles.module.scss'
30+
2431
export interface Props {
2532
keyName: string
2633
keyTTL: Maybe<number>
@@ -31,10 +38,11 @@ const AddKeyReJSON = (props: Props) => {
3138
const { keyName = '', keyTTL, onCancel } = props
3239
const { loading } = useSelector(addKeyStateSelector)
3340
const [ReJSONValue, setReJSONValue] = useState<string>('')
34-
41+
const [valueFromFile, setValueFromFile] = useState<string>('')
3542
const [isFormValid, setIsFormValid] = useState<boolean>(false)
3643

3744
const dispatch = useDispatch()
45+
const { instanceId } = useParams<{ instanceId: string }>()
3846

3947
useEffect(() => {
4048
try {
@@ -68,15 +76,56 @@ const AddKeyReJSON = (props: Props) => {
6876
dispatch(addReJSONKey(data, onCancel))
6977
}
7078

79+
const onFileChange = ({ target: { files } }: { target: { files: FileList | null } }) => {
80+
if (files && files[0]) {
81+
const reader = new FileReader()
82+
reader.onload = async (e) => {
83+
setValueFromFile(e?.target?.result as string)
84+
setReJSONValue(e?.target?.result as string)
85+
}
86+
reader.readAsText(files[0])
87+
}
88+
}
89+
90+
const onClick = () => {
91+
sendEventTelemetry({
92+
event: TelemetryEvent.BROWSER_JSON_VALUE_IMPORT_CLICKED,
93+
eventData: {
94+
databaseId: instanceId,
95+
}
96+
})
97+
}
98+
7199
return (
72100
<EuiForm component="form" onSubmit={onFormSubmit}>
73101
<EuiFormRow label={config.value.label} fullWidth>
74-
<MonacoJson
75-
value={ReJSONValue}
76-
onChange={setReJSONValue}
77-
disabled={loading}
78-
data-testid="json-value"
79-
/>
102+
<>
103+
<MonacoJson
104+
value={ReJSONValue}
105+
updatedValue={valueFromFile}
106+
onChange={setReJSONValue}
107+
disabled={loading}
108+
data-testid="json-value"
109+
/>
110+
<EuiFlexGroup justifyContent="flexEnd">
111+
<EuiFlexItem grow={false}>
112+
<label htmlFor="upload-input-file" className={styles.uploadBtn}>
113+
<EuiIcon className={styles.uploadIcon} type="folderOpen" />
114+
<EuiText className={styles.label}>Upload</EuiText>
115+
<input
116+
type="file"
117+
id="upload-input-file"
118+
data-testid="upload-input-file"
119+
accept="application/json, text/plain"
120+
onChange={onFileChange}
121+
onClick={onClick}
122+
className={styles.fileDrop}
123+
aria-label="Select file"
124+
/>
125+
</label>
126+
</EuiFlexItem>
127+
</EuiFlexGroup>
128+
</>
80129
</EuiFormRow>
81130

82131
<EuiButton type="submit" fill style={{ display: 'none' }}>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.fileDrop {
2+
display: none;
3+
}
4+
5+
.uploadBtn {
6+
display: flex;
7+
margin-top: 20px;
8+
cursor: pointer;
9+
}
10+
11+
.uploadIcon {
12+
margin-right: 4px;
13+
}
14+
15+
.label {
16+
color: var(--inputTextColor) !important;
17+
line-height: 16px !important;
18+
font-weight: 400 !important;
19+
font-size: 12px !important;
20+
}

redisinsight/ui/src/telemetry/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export enum TelemetryEvent {
6161
BROWSER_JSON_PROPERTY_EDITED = 'BROWSER_JSON_PROPERTY_EDITED',
6262
BROWSER_JSON_PROPERTY_DELETED = 'BROWSER_JSON_PROPERTY_DELETED',
6363
BROWSER_JSON_PROPERTY_ADDED = 'BROWSER_JSON_PROPERTY_ADDED',
64+
BROWSER_JSON_VALUE_IMPORT_CLICKED = 'BROWSER_JSON_VALUE_IMPORT_CLICKED',
6465
BROWSER_KEYS_SCANNED = 'BROWSER_KEYS_SCANNED',
6566
BROWSER_KEYS_ADDITIONALLY_SCANNED = 'BROWSER_KEYS_ADDITIONALLY_SCANNED',
6667
BROWSER_KEYS_SCANNED_WITH_FILTER_ENABLED = 'BROWSER_KEYS_SCANNED_WITH_FILTER_ENABLED',

0 commit comments

Comments
 (0)