Skip to content

Commit e381fbb

Browse files
committed
Merge branch 'feature/RI-4616-rdi-support' into fe/feature/RI-5770_Enchance_autocomplite_sqlite
2 parents 48cf4ff + 785d08e commit e381fbb

File tree

18 files changed

+311
-53
lines changed

18 files changed

+311
-53
lines changed

redisinsight/__mocks__/monacoMock.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,19 @@ const editor = {
1616
updateOptions: jest.fn(),
1717
setSelection: jest.fn(),
1818
createDecorationsCollection: jest.fn(),
19+
getValue: jest.fn().mockReturnValue(''),
20+
getModel: jest.fn().mockReturnValue({}),
21+
getPosition: jest.fn(),
22+
trigger: jest.fn(),
1923
}
2024

2125
const monacoEditor = {
22-
Range: jest.fn().mockImplementation(() => ({})),
26+
Range: jest.fn().mockImplementation((startLineNumber, startColumn, endLineNumber, endColumn) => ({
27+
startLineNumber,
28+
startColumn,
29+
endLineNumber,
30+
endColumn,
31+
})),
2332
languages: {
2433
getLanguages: jest.fn(),
2534
register: jest.fn(),
@@ -71,5 +80,6 @@ export const monaco = {
7180
colorize: jest.fn().mockImplementation((data) => Promise.resolve(data)),
7281
defineTheme: jest.fn(),
7382
setTheme: jest.fn()
74-
}
83+
},
84+
Range: monacoEditor.Range
7585
}

redisinsight/ui/src/components/monaco-editor/MonacoEditor.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export interface CommonProps {
3131
dedicatedEditorKeywords?: string[]
3232
dedicatedEditorFunctions?: monacoEditor.languages.CompletionItem[]
3333
onChangeLanguage?: (langId: DSL) => void
34+
shouldOpenDedicatedEditor?: boolean
35+
onOpenDedicatedEditor?: () => void
36+
onSubmitDedicatedEditor?: (langId: DSL) => void
37+
onCloseDedicatedEditor?: (langId: DSL) => void
3438
'data-testid'?: string
3539
}
3640

@@ -60,6 +64,10 @@ const MonacoEditor = (props: Props) => {
6064
dedicatedEditorLanguages = [],
6165
dedicatedEditorKeywords = [],
6266
dedicatedEditorFunctions = [],
67+
shouldOpenDedicatedEditor,
68+
onOpenDedicatedEditor,
69+
onSubmitDedicatedEditor,
70+
onCloseDedicatedEditor,
6371
'data-testid': dataTestId = 'monaco-editor'
6472
} = props
6573

@@ -82,6 +90,13 @@ const MonacoEditor = (props: Props) => {
8290
monacoObjects.current?.editor.updateOptions({ readOnly: !isEditing && (disabled || readOnly) })
8391
}, [disabled, readOnly, isEditing])
8492

93+
useEffect(() => {
94+
if (shouldOpenDedicatedEditor) {
95+
setIsDedicatedEditorOpen(true)
96+
onOpenDedicatedEditor?.()
97+
}
98+
}, [shouldOpenDedicatedEditor])
99+
85100
const editorDidMount = (
86101
editor: monacoEditor.editor.IStandaloneCodeEditor,
87102
monaco: typeof monacoEditor,
@@ -130,6 +145,7 @@ const MonacoEditor = (props: Props) => {
130145
const { editor } = monacoObjects?.current
131146

132147
setIsDedicatedEditorOpen(true)
148+
onOpenDedicatedEditor?.()
133149
editor.updateOptions({ readOnly: true })
134150
}
135151

@@ -140,13 +156,12 @@ const MonacoEditor = (props: Props) => {
140156
editor.focus()
141157
}
142158

143-
const updateArgFromDedicatedEditor = (value: string = '') => {
159+
const updateArgFromDedicatedEditor = (value: string, selectedLang: DSL) => {
144160
if (!monacoObjects.current) return
145161
const { editor } = monacoObjects?.current
146162

147163
const model = editor.getModel()
148164
if (!model) return
149-
150165
const position = editor.getPosition()
151166

152167
editor.updateOptions({ readOnly: false })
@@ -163,15 +178,17 @@ const MonacoEditor = (props: Props) => {
163178
])
164179
setIsDedicatedEditorOpen(false)
165180
triggerUpdateCursorPosition(editor)
181+
onSubmitDedicatedEditor?.(selectedLang)
166182
}
167183

168-
const onCancelDedicatedEditor = () => {
184+
const onCancelDedicatedEditor = (selectedLang: DSL) => {
169185
setIsDedicatedEditorOpen(false)
170186
if (!monacoObjects.current) return
171187
const { editor } = monacoObjects?.current
172188

173189
editor.updateOptions({ readOnly: false })
174190
triggerUpdateCursorPosition(editor)
191+
onCloseDedicatedEditor?.(selectedLang)
175192
}
176193

177194
if (monacoEditor?.editor) {

redisinsight/ui/src/components/monaco-editor/components/dedicated-editor/DedicatedEditor.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ export interface Props {
2424
langId?: DSL
2525
langs?: DSL[]
2626
onChangeLanguage?: (langId: DSL) => void
27-
onSubmit: (query?: string) => void
28-
onCancel: () => void
27+
onSubmit: (query: string, langId: DSL) => void
28+
onCancel: (langId: DSL) => void
2929
initialHeight: number
3030
customOptions?: monacoEditor.editor.IStandaloneEditorConstructionOptions
3131
keywords?: string[]
@@ -109,7 +109,7 @@ const DedicatedEditor = (props: Props) => {
109109

110110
const handleKeyDown = (e: React.KeyboardEvent) => {
111111
if (e.key === 'Escape') {
112-
onCancel()
112+
onCancel(selectedLang.id as DSL)
113113
}
114114
}
115115

@@ -119,7 +119,7 @@ const DedicatedEditor = (props: Props) => {
119119
.split('\n')
120120
.map((line: string, i: number) => ((i > 0 && !notCommandRegEx.test(line)) ? `\t${line}` : line))
121121
.join('\n')
122-
onSubmit(val || '')
122+
onSubmit(val || '', selectedLang.id as DSL)
123123
}
124124

125125
const editorDidMount = (
@@ -258,7 +258,7 @@ const DedicatedEditor = (props: Props) => {
258258
color="primary"
259259
aria-label="Cancel editing"
260260
className={styles.declineBtn}
261-
onClick={onCancel}
261+
onClick={() => onCancel(selectedLang.id as DSL)}
262262
data-testid="cancel-btn"
263263
/>
264264
<EuiButtonIcon

redisinsight/ui/src/components/query/Query/Query.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ const Query = (props: Props) => {
466466
>
467467
<div className={styles.input} data-testid="query-input-container" ref={input}>
468468
<MonacoEditor
469-
language={MonacoLanguage.Redis}
469+
language={MonacoLanguage.Redis as string}
470470
theme={theme === Theme.Dark ? 'dark' : 'light'}
471471
value={query}
472472
options={options}

redisinsight/ui/src/constants/keyboardShortcuts.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ const COMMON_SHORTCUTS = {
6262
description: 'Use Non-Redis Editor',
6363
keys: ['Shift', 'Space'],
6464
}
65+
},
66+
rdi: {
67+
openDedicatedEditor: {
68+
description: 'Open a dedicated SQL or JMESPath editor:',
69+
keys: ['Shift', 'Space']
70+
}
6571
}
6672
}
6773

@@ -125,6 +131,12 @@ const MAC_SHORTCUTS = {
125131
description: 'Use Non-Redis Editor',
126132
keys: [(<span className="shiftSymbol"></span>), 'Space'],
127133
}
134+
},
135+
rdi: {
136+
openDedicatedEditor: {
137+
description: 'Open a dedicated SQL or JMESPath editor',
138+
keys: [(<span className="shiftSymbol"></span>), 'Space']
139+
}
128140
}
129141
}
130142

redisinsight/ui/src/pages/rdi/home/RdiPage.spec.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,28 @@ describe('RdiPage', () => {
206206
)
207207
})
208208

209+
it('should not pass password when password did not changed', async () => {
210+
render(<RdiPage />)
211+
212+
fireEvent.click(screen.getByTestId('edit-instance-1'))
213+
await screen.findByTestId('connection-form')
214+
215+
await act(() => {
216+
fireEvent.change(screen.getByTestId('connection-form-name-input'), { target: { value: 'name' } })
217+
218+
// submit form
219+
fireEvent.click(screen.getByTestId('connection-form-add-button'))
220+
})
221+
222+
expect(editInstanceAction).toBeCalledWith(
223+
'1',
224+
{
225+
name: 'name',
226+
},
227+
expect.any(Function)
228+
)
229+
})
230+
209231
it('should call create instance when editInstance is not provided', async () => {
210232
render(<RdiPage />)
211233

redisinsight/ui/src/pages/rdi/home/RdiPage.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
sendPageViewTelemetry
1818
} from 'uiSrc/telemetry'
1919
import HomePageTemplate from 'uiSrc/templates/home-page-template'
20-
import { getFormUpdates, setTitle } from 'uiSrc/utils'
20+
import { setTitle } from 'uiSrc/utils'
2121
import EmptyMessage from './empty-message/EmptyMessage'
2222
import ConnectionForm from './connection-form/ConnectionForm'
2323
import RdiHeader from './header/RdiHeader'
@@ -60,8 +60,7 @@ const RdiPage = () => {
6060
}
6161

6262
if (editInstance) {
63-
const payload = getFormUpdates(instance, editInstance)
64-
dispatch(editInstanceAction(editInstance.id, payload, onSuccess))
63+
dispatch(editInstanceAction(editInstance.id, instance, onSuccess))
6564
} else {
6665
dispatch(createInstanceAction({ ...instance }, onSuccess))
6766
}

redisinsight/ui/src/pages/rdi/home/connection-form/ConnectionForm.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ import {
1212
} from '@elastic/eui'
1313
import { Field, FieldInputProps, FieldMetaProps, Form, Formik, FormikErrors, FormikHelpers } from 'formik'
1414
import React, { useEffect, useState } from 'react'
15-
1615
import cx from 'classnames'
16+
import { isNull } from 'lodash'
17+
1718
import { SECURITY_FIELD } from 'uiSrc/constants'
1819
import { RdiInstance } from 'uiSrc/slices/interfaces'
20+
import { getFormUpdates, Nullable } from 'uiSrc/utils'
1921
import ValidationTooltip from './components/ValidationTooltip'
2022

2123
import styles from './styles.module.scss'
@@ -24,7 +26,7 @@ export interface ConnectionFormValues {
2426
name: string
2527
url: string
2628
username: string
27-
password: string
29+
password: Nullable<string>
2830
}
2931

3032
export interface Props {
@@ -38,7 +40,7 @@ const getInitialValues = (values: RdiInstance | null): ConnectionFormValues => (
3840
name: values?.name || '',
3941
url: values?.url || '',
4042
username: values?.username || '',
41-
password: !values ? '' : SECURITY_FIELD
43+
password: values ? null : ''
4244
})
4345

4446
const UrlTooltip = () => (
@@ -89,20 +91,26 @@ const ConnectionForm = (props: Props) => {
8991
if (!values.username) {
9092
errors.username = 'Username'
9193
}
92-
if (!values.password) {
94+
// password is security field we did not received it from BE
95+
if (!values.password && !isNull(values.password)) {
9396
errors.password = 'Password'
9497
}
9598

9699
return errors
97100
}
98101

102+
const handleSubmit = (values: ConnectionFormValues) => {
103+
const updates = getFormUpdates(values, editInstance || {})
104+
onSubmit(updates)
105+
}
106+
99107
return (
100108
<Formik
101109
enableReinitialize
102110
initialValues={initialFormValues}
103111
validateOnMount
104112
validate={validate}
105-
onSubmit={onSubmit}
113+
onSubmit={handleSubmit}
106114
>
107115
{({ isValid, errors }) => (
108116
<Form className={styles.form}>
@@ -169,8 +177,9 @@ const ConnectionForm = (props: Props) => {
169177
placeholder="Enter Password"
170178
maxLength={500}
171179
{...field}
180+
value={isNull(field.value) ? SECURITY_FIELD : field.value}
172181
onFocus={() => {
173-
if (field.value === SECURITY_FIELD && !meta.touched) {
182+
if (isNull(field.value) && !meta.touched) {
174183
form.setFieldValue('password', '')
175184
}
176185
}}

redisinsight/ui/src/pages/rdi/pipeline-management/components/fetch-pipeline-popover/FetchPipelinePopover.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const FetchPipelinePopover = () => {
7676
aria-labelledby="Upload pipeline button"
7777
data-testid="upload-pipeline-btn"
7878
>
79-
Upload from server
79+
Download from server
8080
</EuiButtonEmpty>
8181
)}
8282
onButtonClick={handleRefreshWarning}

redisinsight/ui/src/pages/rdi/pipeline-management/components/source-pipeline-dialog/SourcePipelineModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ const SourcePipelineDialog = () => {
103103
data-testid="server-source-pipeline-dialog"
104104
>
105105
<EuiIcon type={UploadIcon} size="xl" className={styles.icon} />
106-
<EuiText className={styles.text}>Upload from server</EuiText>
106+
<EuiText className={styles.text}>Download from server</EuiText>
107107
</div>
108108
<div
109109
role="button"

0 commit comments

Comments
 (0)