Skip to content

Commit 0717d70

Browse files
add action components
1 parent 25c263a commit 0717d70

File tree

6 files changed

+262
-206
lines changed

6 files changed

+262
-206
lines changed

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

Lines changed: 29 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,9 @@ import {
88
EuiForm,
99
EuiLoadingSpinner,
1010
EuiOutsideClickDetector,
11-
EuiTextArea,
1211
EuiWindowEvent
1312
} from '@elastic/eui'
14-
import { bufferToString, createDeleteFieldHeader, createDeleteFieldMessage } from 'uiSrc/utils'
1513

16-
import PopoverDelete from 'uiSrc/pages/browser/components/popover-delete/PopoverDelete'
1714
import FieldMessage from 'uiSrc/components/field-message/FieldMessage'
1815
import {
1916
REJSONResponse,
@@ -29,6 +26,10 @@ import {
2926
} from 'uiSrc/pages/browser/modules/key-details/components/rejson-details/utils'
3027
import { JSONErrors } from 'uiSrc/pages/browser/modules/key-details/components/rejson-details/constants'
3128

29+
import {
30+
EditEntireItemAction,
31+
AddItemFieldAction, EditItemFieldAction
32+
} from 'uiSrc/pages/browser/modules/key-details/components/rejson-details/rejson-details-actions'
3233
import styles from '../styles.module.scss'
3334

3435
const RejsonArrayComponent = (props: JSONArrayProps) => {
@@ -188,7 +189,7 @@ const RejsonArrayComponent = (props: JSONArrayProps) => {
188189

189190
return (
190191
<>
191-
<div className={styles.row}>
192+
<div className={styles.row} key={keyName + parentPath}>
192193
<div className={styles.rowContainer}>
193194
<div className={styles.quotedKeyName} style={{ paddingLeft: `${leftPadding}em` }}>
194195
<span
@@ -215,27 +216,16 @@ const RejsonArrayComponent = (props: JSONArrayProps) => {
215216
</div>
216217
<>
217218
{!editEntireArray && !loading && (
218-
<div className={styles.actionButtons}>
219-
<EuiButtonIcon
220-
iconType="documentEdit"
221-
className={styles.jsonButtonStyle}
222-
onClick={onClickEditEntireArray}
223-
aria-label="Edit field"
224-
color="primary"
225-
data-testid="btn-edit-field"
226-
/>
227-
<PopoverDelete
228-
header={createDeleteFieldHeader(keyName.toString())}
229-
text={createDeleteFieldMessage(bufferToString(selectedKey))}
230-
item={keyName.toString()}
231-
suffix="array"
232-
deleting={deleting}
233-
closePopover={() => setDeleting('')}
234-
updateLoading={false}
235-
showPopover={(item) => { setDeleting(`${item}array`) }}
236-
handleDeleteItem={() => handleSubmitRemoveKey(path, keyName.toString())}
237-
/>
238-
</div>
219+
<EditItemFieldAction
220+
type="array"
221+
keyName={keyName.toString()}
222+
selectedKey={selectedKey}
223+
path={path}
224+
deleting={deleting}
225+
setDeleting={setDeleting}
226+
handleSubmitRemoveKey={handleSubmitRemoveKey}
227+
onClickEditEntireItem={onClickEditEntireArray}
228+
/>
239229
)}
240230
</>
241231
<>
@@ -251,68 +241,15 @@ const RejsonArrayComponent = (props: JSONArrayProps) => {
251241
</div>
252242
<>
253243
{editEntireArray ? (
254-
<div className={styles.row}>
255-
<div style={{ width: '100%', padding: '10px 0' }}>
256-
<EuiOutsideClickDetector onOutsideClick={() => { setEditEntireArray(false) }}>
257-
<div style={{ marginBottom: '34px' }}>
258-
<EuiWindowEvent event="keydown" handler={(e) => handleOnEsc(e, 'edit')} />
259-
<EuiFocusTrap>
260-
<EuiForm
261-
component="form"
262-
className="relative"
263-
onSubmit={(e) => handleUpdateValueFormSubmit(e)}
264-
noValidate
265-
>
266-
<EuiFlexItem grow component="span">
267-
<EuiTextArea
268-
isInvalid={!!error}
269-
style={{ height: '150px', width: '100%', maxWidth: 'none' }}
270-
value={valueOfEntireArray ? valueOfEntireArray.toString() : ''}
271-
placeholder="Enter JSON value"
272-
onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => setValueOfEntireArray(event.target.value)}
273-
data-testid="json-value"
274-
/>
275-
</EuiFlexItem>
276-
<div className={cx(styles.controls, styles.controlsBottom)}>
277-
<EuiButtonIcon
278-
iconSize="m"
279-
iconType="cross"
280-
color="primary"
281-
aria-label="Cancel add"
282-
className={styles.declineBtn}
283-
onClick={() => {
284-
setError(null)
285-
setEditEntireArray(false)
286-
}}
287-
/>
288-
<EuiButtonIcon
289-
iconSize="m"
290-
iconType="check"
291-
color="primary"
292-
type="submit"
293-
aria-label="Apply"
294-
className={styles.applyBtn}
295-
data-testid="apply-edit-btn"
296-
/>
297-
</div>
298-
</EuiForm>
299-
{error && (
300-
<div className={cx(styles.errorMessage, styles.errorMessageForTextArea)}>
301-
<FieldMessage
302-
scrollViewOnAppear
303-
icon="alert"
304-
testID="edit-json-error"
305-
>
306-
{error}
307-
</FieldMessage>
308-
</div>
309-
)}
310-
</EuiFocusTrap>
311-
</div>
312-
313-
</EuiOutsideClickDetector>
314-
</div>
315-
</div>
244+
<EditEntireItemAction
245+
error={error}
246+
setError={setError}
247+
handleOnEsc={handleOnEsc}
248+
handleUpdateValueFormSubmit={handleUpdateValueFormSubmit}
249+
valueOfEntireItem={valueOfEntireArray}
250+
setValueOfEntireItem={setValueOfEntireArray}
251+
setEditEntireItem={setEditEntireArray}
252+
/>
316253
) : null}
317254
</>
318255
<>
@@ -405,19 +342,11 @@ const RejsonArrayComponent = (props: JSONArrayProps) => {
405342
</>
406343
<>
407344
{openIndex && !editEntireArray ? (
408-
<div
409-
className={styles.row}
410-
style={{ paddingLeft: `${leftPadding}em` }}
411-
>
412-
<span className={styles.defaultFont}>&#93;</span>
413-
<EuiButtonIcon
414-
iconType="plus"
415-
className={styles.jsonButtonStyle}
416-
onClick={onClickSetKVPair}
417-
aria-label="Add field"
418-
data-testid="add-field-btn"
419-
/>
420-
</div>
345+
<AddItemFieldAction
346+
leftPadding={leftPadding}
347+
type="array"
348+
onClickSetKVPair={onClickSetKVPair}
349+
/>
421350
) : null}
422351
</>
423352
</>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react'
2+
import { EuiButtonIcon } from '@elastic/eui'
3+
import styles from '../../styles.module.scss'
4+
5+
export interface Props {
6+
leftPadding: string;
7+
type: string;
8+
onClickSetKVPair: () => void
9+
}
10+
11+
const AddItemFieldAction = ({
12+
leftPadding,
13+
type,
14+
onClickSetKVPair,
15+
}: Props) => {
16+
const brackets = () => {
17+
if (type === 'object') return <>&#125;</>
18+
if (type === 'array') return <>&#93;</>
19+
return <></>
20+
}
21+
22+
return (
23+
<div
24+
className={styles.row}
25+
style={{ paddingLeft: `${leftPadding}em` }}
26+
>
27+
<span className={styles.defaultFont}>{brackets()}</span>
28+
<EuiButtonIcon
29+
iconType="plus"
30+
className={styles.jsonButtonStyle}
31+
onClick={onClickSetKVPair}
32+
aria-label="Add field"
33+
data-testid="add-field-btn"
34+
/>
35+
</div>
36+
)
37+
}
38+
39+
export { AddItemFieldAction }
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import React, { ChangeEvent, FormEvent } from 'react'
2+
import {
3+
EuiButtonIcon,
4+
EuiFlexItem,
5+
EuiFocusTrap,
6+
EuiForm,
7+
EuiOutsideClickDetector,
8+
EuiTextArea,
9+
EuiWindowEvent
10+
} from '@elastic/eui'
11+
import cx from 'classnames'
12+
13+
import FieldMessage from 'uiSrc/components/field-message/FieldMessage'
14+
import styles from '../../styles.module.scss'
15+
16+
export interface Props {
17+
handleOnEsc: (e: KeyboardEvent, type: string) => void
18+
handleUpdateValueFormSubmit: (e: FormEvent<HTMLFormElement>) => void
19+
setValueOfEntireItem: (value: any) => void
20+
setEditEntireItem: (value: boolean) => void
21+
setError: (error: string | null) => void
22+
error: string | null
23+
valueOfEntireItem: string | null
24+
}
25+
26+
const EditEntireItemAction = ({
27+
handleOnEsc,
28+
handleUpdateValueFormSubmit,
29+
error,
30+
valueOfEntireItem,
31+
setValueOfEntireItem,
32+
setEditEntireItem,
33+
setError
34+
}: Props) => (
35+
<div className={styles.row}>
36+
<div style={{ width: '100%', padding: '10px 0' }}>
37+
<EuiOutsideClickDetector onOutsideClick={() => {
38+
setError(null)
39+
setEditEntireItem(false)
40+
}}
41+
>
42+
<div style={{ marginBottom: '34px' }}>
43+
<EuiWindowEvent event="keydown" handler={(e) => handleOnEsc(e, 'edit')} />
44+
<EuiFocusTrap>
45+
<EuiForm
46+
component="form"
47+
className="relative"
48+
onSubmit={(e) => handleUpdateValueFormSubmit(e)}
49+
noValidate
50+
>
51+
<EuiFlexItem grow component="span">
52+
<EuiTextArea
53+
isInvalid={!!error}
54+
style={{ height: '150px', width: '100%', maxWidth: 'none' }}
55+
value={valueOfEntireItem ? valueOfEntireItem.toString() : ''}
56+
placeholder="Enter JSON value"
57+
onChange={(event: ChangeEvent<HTMLTextAreaElement>) => setValueOfEntireItem(event.target.value)}
58+
data-testid="json-value"
59+
/>
60+
</EuiFlexItem>
61+
<div className={cx(styles.controls, styles.controlsBottom)}>
62+
<EuiButtonIcon
63+
iconSize="m"
64+
iconType="cross"
65+
color="primary"
66+
aria-label="Cancel add"
67+
className={styles.declineBtn}
68+
onClick={() => {
69+
setError(null)
70+
setEditEntireItem(false)
71+
}}
72+
/>
73+
<EuiButtonIcon
74+
iconSize="m"
75+
iconType="check"
76+
color="primary"
77+
type="submit"
78+
aria-label="Apply"
79+
className={styles.applyBtn}
80+
data-testid="apply-edit-btn"
81+
/>
82+
</div>
83+
</EuiForm>
84+
{error && (
85+
<div className={cx(styles.errorMessage, styles.errorMessageForTextArea)}>
86+
<FieldMessage
87+
scrollViewOnAppear
88+
icon="alert"
89+
testID="edit-json-error"
90+
>
91+
{error}
92+
</FieldMessage>
93+
</div>
94+
)}
95+
</EuiFocusTrap>
96+
</div>
97+
98+
</EuiOutsideClickDetector>
99+
</div>
100+
</div>
101+
)
102+
103+
export { EditEntireItemAction }
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React from 'react'
2+
import { EuiButtonIcon } from '@elastic/eui'
3+
import PopoverDelete from 'uiSrc/pages/browser/components/popover-delete/PopoverDelete'
4+
import { bufferToString, createDeleteFieldHeader, createDeleteFieldMessage } from 'uiSrc/utils'
5+
import { RedisResponseBuffer } from 'uiSrc/slices/interfaces'
6+
import styles from '../../styles.module.scss'
7+
8+
export interface Props {
9+
type: string;
10+
keyName: string;
11+
selectedKey: string | RedisResponseBuffer;
12+
path: string,
13+
deleting: string,
14+
setDeleting: (value: string) => void;
15+
handleSubmitRemoveKey: (path: string, jsonKeyName: string) => void;
16+
onClickEditEntireItem: () => void;
17+
}
18+
19+
const EditItemFieldAction = ({
20+
type,
21+
keyName,
22+
selectedKey,
23+
path,
24+
deleting,
25+
setDeleting,
26+
handleSubmitRemoveKey,
27+
onClickEditEntireItem
28+
}: Props) => {
29+
const dataTestId = () => {
30+
if (type === 'object') return 'edit-object-btn'
31+
if (type === 'array') return 'btn-edit-field'
32+
return ''
33+
}
34+
35+
return (
36+
<div className={styles.actionButtons}>
37+
<EuiButtonIcon
38+
iconType="documentEdit"
39+
className={styles.jsonButtonStyle}
40+
onClick={onClickEditEntireItem}
41+
aria-label="Edit field"
42+
color="primary"
43+
data-testid={dataTestId}
44+
/>
45+
<PopoverDelete
46+
header={createDeleteFieldHeader(keyName)}
47+
text={createDeleteFieldMessage(bufferToString(selectedKey))}
48+
item={keyName}
49+
suffix={type}
50+
deleting={deleting}
51+
closePopover={() => setDeleting('')}
52+
updateLoading={false}
53+
showPopover={(item) => { setDeleting(`${item}${type}`) }}
54+
handleDeleteItem={() => handleSubmitRemoveKey(path, keyName)}
55+
/>
56+
</div>
57+
)
58+
}
59+
60+
export { EditItemFieldAction }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { AddItemFieldAction } from './add-item-field-action/AddItemFieldAction'
2+
export { EditEntireItemAction } from './edit-entire-item-action/EditEntireItemAction'
3+
export { EditItemFieldAction } from './edit-item-field-action/EditItemFieldAction'

0 commit comments

Comments
 (0)