diff --git a/package.json b/package.json
index ce2886a365..6400f0e4be 100644
--- a/package.json
+++ b/package.json
@@ -236,6 +236,7 @@
"@elastic/eui": "34.6.0",
"@reduxjs/toolkit": "^1.6.2",
"@stablelib/snappy": "^1.0.2",
+ "@types/json-dup-key-validator": "^1.0.2",
"ajv": "^8.17.1",
"axios": "^1.8.4",
"brotli-dec-wasm": "^2.3.0",
@@ -259,6 +260,7 @@
"java-object-serialization": "^0.1.2",
"js-yaml": "^4.1.0",
"json-bigint": "^1.0.0",
+ "json-dup-key-validator": "^1.0.3",
"jsonpath": "^1.1.1",
"jszip": "^3.10.1",
"lodash": "^4.17.21",
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.spec.tsx
index 0d889de7cd..46f669b8ca 100644
--- a/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.spec.tsx
+++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.spec.tsx
@@ -51,4 +51,32 @@ describe('EditEntireItemAction', () => {
)
expect(handleUpdateValueFormSubmit).not.toHaveBeenCalled()
})
+
+ it('should show confirmation modal when JSON has duplicate keys, and confirm submit on confirm', () => {
+ const handleUpdateValueFormSubmit = jest.fn()
+
+ const duplicateKeyJson = `
+ {
+ "test": "one",
+ "test": "two"
+ }
+ `
+
+ render(
+ ,
+ )
+
+ fireEvent.submit(screen.getByTestId('json-entire-form'))
+
+ expect(screen.getByText(/Duplicate JSON key detected/i)).toBeInTheDocument()
+
+ const confirmButton = screen.getByLabelText(/overwrite/i)
+ fireEvent.click(confirmButton)
+
+ expect(handleUpdateValueFormSubmit).toHaveBeenCalledWith(duplicateKeyJson)
+ })
})
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.tsx
index bbd2924870..6ef6b5b3e9 100644
--- a/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.tsx
+++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/components/edit-entire-item-action/EditEntireItemAction.tsx
@@ -1,11 +1,7 @@
import React, { ChangeEvent, useState } from 'react'
-import {
- EuiButtonIcon,
- EuiForm,
- EuiTextArea,
- keys,
-} from '@elastic/eui'
+import { EuiButtonIcon, EuiForm, EuiTextArea, keys } from '@elastic/eui'
import cx from 'classnames'
+import jsonValidator from 'json-dup-key-validator'
import FieldMessage from 'uiSrc/components/field-message/FieldMessage'
import { Nullable } from 'uiSrc/utils'
@@ -17,6 +13,7 @@ import { isValidJSON } from '../../utils'
import { JSONErrors } from '../../constants'
import styles from '../../styles.module.scss'
+import ConfirmOverwrite from '../add-item/ConfirmOverwrite'
export interface Props {
initialValue: string
@@ -28,6 +25,8 @@ const EditEntireItemAction = (props: Props) => {
const { initialValue, onCancel, onSubmit } = props
const [value, setValue] = useState(initialValue)
const [error, setError] = useState>(null)
+ const [isConfirmationVisible, setIsConfirmationVisible] =
+ useState(false)
const handleOnEsc = (e: KeyboardEvent) => {
if (e.code?.toLowerCase() === keys.ESCAPE) {
@@ -44,6 +43,17 @@ const EditEntireItemAction = (props: Props) => {
return
}
+ const validationError = jsonValidator.validate(value, false)
+
+ if (validationError) {
+ setIsConfirmationVisible(true)
+ return
+ }
+
+ onSubmit(value)
+ }
+
+ const confirmApply = () => {
onSubmit(value)
}
@@ -73,26 +83,32 @@ const EditEntireItemAction = (props: Props) => {
data-testid="json-value"
/>
-
-
-
-
+ setIsConfirmationVisible(false)}
+ onConfirm={confirmApply}
+ >
+
+
+
+
+
{error && (