Skip to content

Commit 1a26af4

Browse files
AmirAllayarovSofteqmariasergeenkoegor-zalenski
authored
#RI-4795 - add json format component (#2480)
* #RI-4795 - add json format component --------- Co-authored-by: mariasergeenko <[email protected]> Co-authored-by: mariasergeenko <[email protected]> Co-authored-by: zalenskiSofteq <[email protected]>
1 parent f5e87b4 commit 1a26af4

File tree

39 files changed

+705
-74
lines changed

39 files changed

+705
-74
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
"@types/ioredis": "^4.26.0",
130130
"@types/is-glob": "^4.0.2",
131131
"@types/jest": "^27.5.2",
132+
"@types/json-bigint": "^1.0.1",
132133
"@types/jsonpath": "^0.2.0",
133134
"@types/lodash": "^4.14.171",
134135
"@types/node": "14.14.10",
@@ -247,6 +248,7 @@
247248
"html-react-parser": "^1.2.4",
248249
"java-object-serialization": "^0.1.1",
249250
"jpickle": "^0.4.1",
251+
"json-bigint": "^1.0.0",
250252
"jsonpath": "^1.1.1",
251253
"lodash": "^4.17.21",
252254
"lz4js": "^0.2.0",
@@ -257,7 +259,6 @@
257259
"react-contenteditable": "^3.3.5",
258260
"react-dom": "^18.2.0",
259261
"react-hotkeys-hook": "^3.3.1",
260-
"react-json-pretty": "^2.2.0",
261262
"react-jsx-parser": "^1.28.4",
262263
"react-monaco-editor": "^0.45.0",
263264
"react-redux": "^7.2.2",

redisinsight/ui/src/components/json-viewer/JSONViewer.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import cx from 'classnames'
22
import React from 'react'
3-
import JSONPretty from 'react-json-pretty'
3+
import JSONBigInt from 'json-bigint'
4+
5+
import JsonPretty from 'uiSrc/components/json-viewer/components/json-pretty'
46

57
interface Props {
68
value: string
@@ -12,12 +14,12 @@ const JSONViewer = (props: Props) => {
1214
const { value, expanded = false, space = 2 } = props
1315

1416
try {
15-
JSON.parse(value)
17+
const data = JSONBigInt({ useNativeBigInt: true }).parse(value)
1618

1719
return {
1820
value: (
1921
<div className={cx('jsonViewer', { 'jsonViewer-collapsed': !expanded })} data-testid="value-as-json">
20-
<JSONPretty json={value} space={space} />
22+
<JsonPretty data={data} space={space} />
2123
</div>
2224
),
2325
isValid: true
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react'
2+
import { render, screen } from 'uiSrc/utils/test-utils'
3+
4+
import JsonArray from './JsonArray'
5+
6+
const mockArray = [123]
7+
8+
describe('JsonArray', () => {
9+
it('should render JsonArray', () => {
10+
expect(render(<JsonArray data={mockArray} />)).toBeTruthy()
11+
})
12+
13+
it('should render jsonObjectComponent', () => {
14+
render(<JsonArray data={mockArray} gap={8} />)
15+
16+
expect(screen.getByTestId('json-array-component')).toHaveTextContent('[ 123 ]')
17+
})
18+
19+
it('should render coma', () => {
20+
render(<JsonArray data={mockArray} lastElement={false} />)
21+
22+
expect(screen.getByTestId('json-array-component')).toHaveTextContent('[ 123 ],')
23+
})
24+
25+
it('should not render coma', () => {
26+
render(<JsonArray data={mockArray} lastElement />)
27+
28+
expect(screen.getByTestId('json-array-component')).toHaveTextContent('[ 123 ]')
29+
})
30+
31+
it('should not render empty space and line break', () => {
32+
render(<JsonArray data={[]} lastElement />)
33+
34+
expect(screen.getByTestId('json-array-component')).toHaveTextContent('[', { normalizeWhitespace: false })
35+
})
36+
37+
it('should render empty space and line break', () => {
38+
const renderedArray = '[\n 123\n]'
39+
render(<JsonArray data={mockArray} lastElement />)
40+
41+
expect(screen.getByTestId('json-array-component')).toHaveTextContent(renderedArray, { normalizeWhitespace: false })
42+
})
43+
})
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React, { Fragment } from 'react'
2+
3+
import JsonPretty from 'uiSrc/components/json-viewer/components/json-pretty'
4+
import { IJsonArrayProps } from 'uiSrc/components/json-viewer/interfaces'
5+
6+
const JsonArray = ({ data, space = 2, gap = 0, lastElement = true }: IJsonArrayProps) => (
7+
<span data-testid="json-array-component">
8+
[
9+
{!!data.length && '\n'}
10+
{data.map((value, idx) => (
11+
// eslint-disable-next-line react/no-array-index-key
12+
<Fragment key={idx}>
13+
{!!space && Array.from({ length: space + gap }, () => ' ')}
14+
<JsonPretty
15+
data={value}
16+
lastElement={idx === data.length - 1}
17+
space={space}
18+
gap={gap + space}
19+
/>
20+
</Fragment>
21+
))}
22+
{!!data.length && !!gap && Array.from({ length: gap }, () => ' ')}
23+
]
24+
{!lastElement && ','}
25+
{'\n'}
26+
</span>
27+
)
28+
29+
export default JsonArray
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import JsonArray from './JsonArray'
2+
3+
export default JsonArray
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react'
2+
import { render, screen } from 'uiSrc/utils/test-utils'
3+
4+
import JsonObject from './JsonObject'
5+
6+
const mockJson = { value: JSON.stringify({}) }
7+
8+
describe('JsonObject', () => {
9+
it('should render jsonObjectComponent', () => {
10+
expect(render(<JsonObject data={mockJson} />)).toBeTruthy()
11+
})
12+
13+
it('should render jsonObjectComponent', () => {
14+
render(<JsonObject data={mockJson} gap={8} />)
15+
16+
expect(screen.getByTestId('json-object-component')).toHaveTextContent('{ "value": "{}" }')
17+
})
18+
19+
it('should render coma', () => {
20+
render(<JsonObject data={mockJson} lastElement={false} />)
21+
22+
expect(screen.getByTestId('json-object-component')).toHaveTextContent('{ "value": "{}" },')
23+
})
24+
25+
it('should not render coma', () => {
26+
render(<JsonObject data={mockJson} lastElement />)
27+
28+
expect(screen.getByTestId('json-object-component')).toHaveTextContent('{ "value": "{}" }')
29+
})
30+
31+
it('should not render empty space and line break', () => {
32+
render(<JsonObject data={{}} lastElement />)
33+
34+
expect(screen.getByTestId('json-object-component')).toHaveTextContent('{}', { normalizeWhitespace: false })
35+
})
36+
37+
it('should render empty space and line break', () => {
38+
const renderedObject = '{\n "value": "{}"\n}'
39+
render(<JsonObject data={mockJson} lastElement />)
40+
41+
expect(screen.getByTestId('json-object-component')).toHaveTextContent(renderedObject, { normalizeWhitespace: false })
42+
})
43+
})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React, { Fragment } from 'react'
2+
3+
import JsonPretty from 'uiSrc/components/json-viewer/components/json-pretty'
4+
import { IJsonObjectProps } from 'uiSrc/components/json-viewer/interfaces'
5+
6+
const JsonObject = ({ data, space = 2, gap = 0, lastElement = true }: IJsonObjectProps) => {
7+
const keys = Object.keys(data)
8+
9+
return (
10+
<span data-testid="json-object-component">
11+
{'{'}
12+
{!!keys.length && '\n'}
13+
{keys.map((key, idx) => (
14+
<Fragment key={key}>
15+
{!!space && Array.from({ length: space + gap }, () => ' ')}
16+
<span className="json-pretty__key">
17+
{`"${key}"`}
18+
</span>
19+
{': '}
20+
<JsonPretty
21+
data={data[key]}
22+
lastElement={idx === keys.length - 1}
23+
space={space}
24+
gap={gap + space}
25+
/>
26+
</Fragment>
27+
))}
28+
{!!keys.length && !!gap && Array.from({ length: gap }, () => ' ')}
29+
{'}'}
30+
{!lastElement && ','}
31+
{'\n'}
32+
</span>
33+
)
34+
}
35+
36+
export default JsonObject
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import JsonObject from './JsonObject'
2+
3+
export default JsonObject
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react'
2+
import { render, screen } from 'uiSrc/utils/test-utils'
3+
4+
import JsonPretty from './JsonPretty'
5+
6+
describe('JsonPretty', () => {
7+
it('should render jsonObjectComponent', () => {
8+
const json = { value: JSON.stringify({}) }
9+
render(<JsonPretty data={json} />)
10+
11+
expect(screen.getByTestId('json-object-component')).toBeInTheDocument()
12+
})
13+
14+
it('should render json array component', () => {
15+
const json = ['123']
16+
render(<JsonPretty data={json} />)
17+
18+
expect(screen.getByTestId('json-array-component')).toBeInTheDocument()
19+
})
20+
21+
it('should render json primitive component', () => {
22+
const json = null
23+
render(<JsonPretty data={json} />)
24+
25+
expect(screen.getByTestId('json-primitive-component')).toBeInTheDocument()
26+
})
27+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react'
2+
3+
import JsonPrimitive from 'uiSrc/components/json-viewer/components/json-primitive'
4+
import JsonArray from 'uiSrc/components/json-viewer/components/json-array'
5+
import JsonObject from 'uiSrc/components/json-viewer/components/json-object'
6+
import { isArray, isObject } from 'uiSrc/components/json-viewer/utils'
7+
import { IDefaultProps } from 'uiSrc/components/json-viewer/interfaces'
8+
9+
const JsonPretty = ({ data, ...props }: IDefaultProps) => {
10+
if (isArray(data)) {
11+
return <JsonArray data={data} {...props} />
12+
}
13+
14+
if (isObject(data)) {
15+
return <JsonObject data={data} {...props} />
16+
}
17+
18+
return <JsonPrimitive data={data} {...props} />
19+
}
20+
21+
export default JsonPretty

0 commit comments

Comments
 (0)