From 795fe5156df3a071b3690609e224cd3f59023df7 Mon Sep 17 00:00:00 2001 From: Artem Date: Mon, 31 Jul 2023 14:05:10 +0300 Subject: [PATCH 01/13] #RI-4803 fix analytics event --- .circleci/redisstack/build_modules.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/redisstack/build_modules.sh b/.circleci/redisstack/build_modules.sh index f6ff5c0f7b..5eb96b4c7e 100755 --- a/.circleci/redisstack/build_modules.sh +++ b/.circleci/redisstack/build_modules.sh @@ -24,6 +24,7 @@ rm -rf redisinsight/build.zip cp LICENSE ./redisinsight cd redisinsight && tar -czvf build.tar.gz \ +--exclude="api/node_modules/**/build/node_gyp_bins/python3" \ api/node_modules \ api/dist \ ui/dist \ From f4debb7825752fe2ba2f99dc312b9b9080952057 Mon Sep 17 00:00:00 2001 From: Zalenski Egor Date: Tue, 8 Aug 2023 11:41:23 +0300 Subject: [PATCH 02/13] a new test mas build --- electron-builder.json | 2 +- resources/entitlements.mas.plist | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/electron-builder.json b/electron-builder.json index dc87c24635..b0bff5e992 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -29,7 +29,7 @@ "type": "distribution", "hardenedRuntime": true, "darkModeSupport": true, - "bundleVersion": "70", + "bundleVersion": "90", "icon": "resources/icon.icns", "artifactName": "${productName}-${os}-${arch}.${ext}", "entitlements": "resources/entitlements.mac.plist", diff --git a/resources/entitlements.mas.plist b/resources/entitlements.mas.plist index 9c2171e43e..f0f869d99a 100644 --- a/resources/entitlements.mas.plist +++ b/resources/entitlements.mas.plist @@ -28,10 +28,5 @@ UUK47G4BAZ.com.redis.RedisInsight com.apple.developer.team-identifier UUK47G4BAZ - com.apple.security.temporary-exception.files.home-relative-path.read-write - - /.redisinsight-v2/ - /.redisinsight-v2-stage/ - From b3cfe5fe0bf2c24abe713bfa556e80b2e68fb54f Mon Sep 17 00:00:00 2001 From: Zalenski Egor Date: Tue, 8 Aug 2023 13:45:45 +0300 Subject: [PATCH 03/13] Update package.json --- redisinsight/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisinsight/package.json b/redisinsight/package.json index 90ae4bcc1e..a91c23dd86 100644 --- a/redisinsight/package.json +++ b/redisinsight/package.json @@ -2,7 +2,7 @@ "name": "redisinsight", "productName": "RedisInsight", "private": true, - "version": "2.30.0", + "version": "2.30.1", "description": "RedisInsight", "main": "./dist/main/main.js", "author": { From 7c364ab2cb3c1c1aacbbb61a8d89e823f3ce9b4e Mon Sep 17 00:00:00 2001 From: Zalenski Egor Date: Wed, 9 Aug 2023 18:20:42 +0300 Subject: [PATCH 04/13] increase bundleVersion --- electron-builder.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron-builder.json b/electron-builder.json index b0bff5e992..40dd0b85e9 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -29,7 +29,7 @@ "type": "distribution", "hardenedRuntime": true, "darkModeSupport": true, - "bundleVersion": "90", + "bundleVersion": "88678", "icon": "resources/icon.icns", "artifactName": "${productName}-${os}-${arch}.${ext}", "entitlements": "resources/entitlements.mac.plist", From a43ec84ebd16c6322f65334991b0a6df9490cd26 Mon Sep 17 00:00:00 2001 From: Zalenski Egor Date: Fri, 18 Aug 2023 13:22:46 +0300 Subject: [PATCH 05/13] remove bundleVersion --- electron-builder.json | 1 - 1 file changed, 1 deletion(-) diff --git a/electron-builder.json b/electron-builder.json index 5784369d08..a9aa24d2f9 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -35,7 +35,6 @@ "type": "distribution", "hardenedRuntime": true, "darkModeSupport": true, - "bundleVersion": "88678", "icon": "resources/icon.icns", "artifactName": "${productName}-${os}-${arch}.${ext}", "entitlements": "resources/entitlements.mac.plist", From 7a81ad917bf996390f0dafeb3b6bbe61e6908538 Mon Sep 17 00:00:00 2001 From: vlad-dargel Date: Fri, 18 Aug 2023 12:31:12 +0200 Subject: [PATCH 06/13] resolve conflicts --- redisinsight/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisinsight/package.json b/redisinsight/package.json index 9bdf5bf9e0..950ea58b40 100644 --- a/redisinsight/package.json +++ b/redisinsight/package.json @@ -2,7 +2,7 @@ "name": "redisinsight", "productName": "RedisInsight", "private": true, - "version": "2.30.1", + "version": "2.32.0", "description": "RedisInsight", "main": "./dist/main/main.js", "author": { From 12f5a5b9b6e864e0b0e37ab29402ff7496eb2c56 Mon Sep 17 00:00:00 2001 From: Artem Date: Fri, 18 Aug 2023 14:05:49 +0300 Subject: [PATCH 07/13] add additional env to circle ci --- redisinsight/api/src/modules/server/server.service.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/redisinsight/api/src/modules/server/server.service.spec.ts b/redisinsight/api/src/modules/server/server.service.spec.ts index 20fd11cbb4..51cc182edb 100644 --- a/redisinsight/api/src/modules/server/server.service.spec.ts +++ b/redisinsight/api/src/modules/server/server.service.spec.ts @@ -115,6 +115,7 @@ describe('ServerService', () => { anonymousId: mockServer.id, sessionId, appType: SERVER_CONFIG.buildType, + appVersion: SERVER_CONFIG.appVersion, controlNumber: mockControlNumber, controlGroup: mockControlGroup, }, From 93367ed7e6470c527f3384e64e74dec3ec716b91 Mon Sep 17 00:00:00 2001 From: Amir Allayarov <100589048+AmirAllayarovSofteq@users.noreply.github.com> Date: Fri, 18 Aug 2023 19:21:25 +0800 Subject: [PATCH 08/13] fix ui test for release-2.32.0 (#2488) --- redisinsight/ui/src/utils/tests/recommendation/utils.spec.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/redisinsight/ui/src/utils/tests/recommendation/utils.spec.tsx b/redisinsight/ui/src/utils/tests/recommendation/utils.spec.tsx index a5b9b5d250..c325462df4 100644 --- a/redisinsight/ui/src/utils/tests/recommendation/utils.spec.tsx +++ b/redisinsight/ui/src/utils/tests/recommendation/utils.spec.tsx @@ -1,5 +1,6 @@ import { fireEvent, render, screen } from 'uiSrc/utils/test-utils' import { IRecommendationContent } from 'uiSrc/slices/interfaces/recommendations' +import { MOCK_RECOMMENDATIONS } from 'uiSrc/constants/mocks/mock-recommendations' import { addUtmToLink, sortRecommendations, @@ -8,8 +9,6 @@ import { renderRecommendationBadges, renderRecommendationContent, } from '../../recommendation/utils' -import { IRecommendationContent } from 'uiSrc/slices/interfaces/recommendations' -import { MOCK_RECOMMENDATIONS } from 'uiSrc/constants/mocks/mock-recommendations' const mockTelemetryName = 'name' From 46259bc1a0c76fc356deb72948e24cbeb5cfd2d4 Mon Sep 17 00:00:00 2001 From: Artem Date: Fri, 18 Aug 2023 16:16:22 +0300 Subject: [PATCH 09/13] possible fix ITests --- redisinsight/api/test/api/feature/GET-features.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/redisinsight/api/test/api/feature/GET-features.test.ts b/redisinsight/api/test/api/feature/GET-features.test.ts index cc19032b1e..ce0d670e04 100644 --- a/redisinsight/api/test/api/feature/GET-features.test.ts +++ b/redisinsight/api/test/api/feature/GET-features.test.ts @@ -61,6 +61,7 @@ describe('GET /features', () => { // remove all configs await featureConfigRepository.delete({}); + await featureRepository.delete({}); await syncEndpoint(); await waitForFlags({ features: { From e367c552ed8b8bb5999b3fb1db8042c138f5c71e Mon Sep 17 00:00:00 2001 From: Artem Date: Fri, 18 Aug 2023 16:26:15 +0300 Subject: [PATCH 10/13] proper fix --- .circleci/config.yml | 4 ++-- .../api/test/api/feature/GET-features.test.ts | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea38933ad0..c3666a88b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1029,8 +1029,8 @@ workflows: parameters: rte: *iTestsNamesShort name: ITest - << matrix.rte >> (code) - requires: - - UTest - API +# requires: +# - UTest - API # E2E tests for "e2e/feature" or "e2e/bugfix" branches only e2e-tests: jobs: diff --git a/redisinsight/api/test/api/feature/GET-features.test.ts b/redisinsight/api/test/api/feature/GET-features.test.ts index ce0d670e04..278a75b9b3 100644 --- a/redisinsight/api/test/api/feature/GET-features.test.ts +++ b/redisinsight/api/test/api/feature/GET-features.test.ts @@ -16,10 +16,16 @@ const updateSettings = (data) => request(server).patch('/settings').send(data); const mainCheckFn = getMainCheckFn(endpoint); -const waitForFlags = async (flags: any) => { +const waitForFlags = async (flags: any, action?: Function) => { const client = await getSocket(''); await new Promise((res, rej) => { + try { + action?.()?.catch(rej); + } catch (e) { + rej(e); + } + client.once('features', (data) => { expect(flags).to.deep.eq(data); res(true); @@ -62,7 +68,6 @@ describe('GET /features', () => { // remove all configs await featureConfigRepository.delete({}); await featureRepository.delete({}); - await syncEndpoint(); await waitForFlags({ features: { insightsRecommendations: { @@ -74,7 +79,7 @@ describe('GET /features', () => { name: 'cloudSso', }, }, - }); + }, syncEndpoint); }, statusCode: 200, responseBody: { @@ -112,7 +117,6 @@ describe('GET /features', () => { // remove all configs - await syncEndpoint(); await waitForFlags({ features: { insightsRecommendations: { @@ -124,7 +128,7 @@ describe('GET /features', () => { name: 'cloudSso', }, }, - }); + }, syncEndpoint); }, statusCode: 200, responseBody: { @@ -165,7 +169,6 @@ describe('GET /features', () => { }, })).catch(console.error); - await syncEndpoint(); await waitForFlags({ features: { insightsRecommendations: { @@ -177,7 +180,7 @@ describe('GET /features', () => { name: 'cloudSso', }, }, - }); + }, syncEndpoint); }, statusCode: 200, responseBody: { From a4d8ee505b1a40e56b55eabe75260117ac69999b Mon Sep 17 00:00:00 2001 From: Artem Date: Fri, 18 Aug 2023 16:35:39 +0300 Subject: [PATCH 11/13] keep the same order for be tests --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c3666a88b3..ea38933ad0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1029,8 +1029,8 @@ workflows: parameters: rte: *iTestsNamesShort name: ITest - << matrix.rte >> (code) -# requires: -# - UTest - API + requires: + - UTest - API # E2E tests for "e2e/feature" or "e2e/bugfix" branches only e2e-tests: jobs: From 1a26af47ee2c6a2a48ad13712155d3337777d9f3 Mon Sep 17 00:00:00 2001 From: Amir Allayarov <100589048+AmirAllayarovSofteq@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:11:05 +0800 Subject: [PATCH 12/13] #RI-4795 - add json format component (#2480) * #RI-4795 - add json format component --------- Co-authored-by: mariasergeenko Co-authored-by: mariasergeenko <129392901+mariasergeenko@users.noreply.github.com> Co-authored-by: zalenskiSofteq --- package.json | 3 +- .../src/components/json-viewer/JSONViewer.tsx | 8 +- .../components/json-array/JsonArray.spec.tsx | 43 +++++++++++ .../components/json-array/JsonArray.tsx | 29 +++++++ .../components/json-array/index.ts | 3 + .../json-object/JsonObject.spec.tsx | 43 +++++++++++ .../components/json-object/JsonObject.tsx | 36 +++++++++ .../components/json-object/index.ts | 3 + .../json-pretty/JsonPretty.spec.tsx | 27 +++++++ .../components/json-pretty/JsonPretty.tsx | 21 +++++ .../components/json-pretty/index.ts | 3 + .../json-primitive/JsonPrimitive.spec.tsx | 71 +++++++++++++++++ .../json-primitive/JsonPrimitive.tsx | 37 +++++++++ .../components/json-primitive/index.ts | 3 + .../src/components/json-viewer/interfaces.ts | 14 ++++ .../src/components/json-viewer/utils.spec.ts | 77 +++++++++++++++++++ .../ui/src/components/json-viewer/utils.ts | 5 ++ .../ui/src/packages/clients-list/package.json | 4 +- .../src/components/json-view/JSONView.tsx | 7 +- .../components/json-array/JsonArray.tsx | 29 +++++++ .../json-view/components/json-array/index.ts | 3 + .../components/json-object/JsonObject.tsx | 35 +++++++++ .../json-view/components/json-object/index.ts | 3 + .../components/json-pretty/JsonPretty.tsx | 21 +++++ .../json-view/components/json-pretty/index.ts | 3 + .../json-primitive/JsonPrimitive.tsx | 37 +++++++++ .../components/json-primitive/index.ts | 3 + .../src/components/json-view/interfaces.ts | 14 ++++ .../src/components/json-view/utils.ts | 5 ++ .../clients-list/src/styles/styles.scss | 38 +++++++++ .../ui/src/packages/clients-list/yarn.lock | 24 ++++-- .../ui/src/styles/components/_json_view.scss | 62 +++++++-------- redisinsight/ui/src/utils/formatters/json.ts | 6 +- redisinsight/ui/src/utils/formatters/utils.ts | 5 -- .../src/utils/formatters/valueFormatters.tsx | 12 +-- tests/e2e/test-data/formatters-data.ts | 5 +- .../critical-path/browser/formatters.e2e.ts | 5 ++ .../triggers-and-functions/libraries.e2e.ts | 8 +- yarn.lock | 24 ++++-- 39 files changed, 705 insertions(+), 74 deletions(-) create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.spec.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-array/index.ts create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.spec.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-object/index.ts create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.spec.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-pretty/index.ts create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.spec.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.tsx create mode 100644 redisinsight/ui/src/components/json-viewer/components/json-primitive/index.ts create mode 100644 redisinsight/ui/src/components/json-viewer/interfaces.ts create mode 100644 redisinsight/ui/src/components/json-viewer/utils.spec.ts create mode 100644 redisinsight/ui/src/components/json-viewer/utils.ts create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/JsonArray.tsx create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/index.ts create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/JsonObject.tsx create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/index.ts create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/JsonPretty.tsx create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/index.ts create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/JsonPrimitive.tsx create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/index.ts create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/interfaces.ts create mode 100644 redisinsight/ui/src/packages/clients-list/src/components/json-view/utils.ts diff --git a/package.json b/package.json index 32420e22c9..9e481caaca 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "@types/ioredis": "^4.26.0", "@types/is-glob": "^4.0.2", "@types/jest": "^27.5.2", + "@types/json-bigint": "^1.0.1", "@types/jsonpath": "^0.2.0", "@types/lodash": "^4.14.171", "@types/node": "14.14.10", @@ -247,6 +248,7 @@ "html-react-parser": "^1.2.4", "java-object-serialization": "^0.1.1", "jpickle": "^0.4.1", + "json-bigint": "^1.0.0", "jsonpath": "^1.1.1", "lodash": "^4.17.21", "lz4js": "^0.2.0", @@ -257,7 +259,6 @@ "react-contenteditable": "^3.3.5", "react-dom": "^18.2.0", "react-hotkeys-hook": "^3.3.1", - "react-json-pretty": "^2.2.0", "react-jsx-parser": "^1.28.4", "react-monaco-editor": "^0.45.0", "react-redux": "^7.2.2", diff --git a/redisinsight/ui/src/components/json-viewer/JSONViewer.tsx b/redisinsight/ui/src/components/json-viewer/JSONViewer.tsx index 6d8ef318c3..cf6a7b5763 100644 --- a/redisinsight/ui/src/components/json-viewer/JSONViewer.tsx +++ b/redisinsight/ui/src/components/json-viewer/JSONViewer.tsx @@ -1,6 +1,8 @@ import cx from 'classnames' import React from 'react' -import JSONPretty from 'react-json-pretty' +import JSONBigInt from 'json-bigint' + +import JsonPretty from 'uiSrc/components/json-viewer/components/json-pretty' interface Props { value: string @@ -12,12 +14,12 @@ const JSONViewer = (props: Props) => { const { value, expanded = false, space = 2 } = props try { - JSON.parse(value) + const data = JSONBigInt({ useNativeBigInt: true }).parse(value) return { value: (
- +
), isValid: true diff --git a/redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.spec.tsx b/redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.spec.tsx new file mode 100644 index 0000000000..3e3c557deb --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.spec.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import { render, screen } from 'uiSrc/utils/test-utils' + +import JsonArray from './JsonArray' + +const mockArray = [123] + +describe('JsonArray', () => { + it('should render JsonArray', () => { + expect(render()).toBeTruthy() + }) + + it('should render jsonObjectComponent', () => { + render() + + expect(screen.getByTestId('json-array-component')).toHaveTextContent('[ 123 ]') + }) + + it('should render coma', () => { + render() + + expect(screen.getByTestId('json-array-component')).toHaveTextContent('[ 123 ],') + }) + + it('should not render coma', () => { + render() + + expect(screen.getByTestId('json-array-component')).toHaveTextContent('[ 123 ]') + }) + + it('should not render empty space and line break', () => { + render() + + expect(screen.getByTestId('json-array-component')).toHaveTextContent('[', { normalizeWhitespace: false }) + }) + + it('should render empty space and line break', () => { + const renderedArray = '[\n 123\n]' + render() + + expect(screen.getByTestId('json-array-component')).toHaveTextContent(renderedArray, { normalizeWhitespace: false }) + }) +}) diff --git a/redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.tsx b/redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.tsx new file mode 100644 index 0000000000..24ffb10495 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-array/JsonArray.tsx @@ -0,0 +1,29 @@ +import React, { Fragment } from 'react' + +import JsonPretty from 'uiSrc/components/json-viewer/components/json-pretty' +import { IJsonArrayProps } from 'uiSrc/components/json-viewer/interfaces' + +const JsonArray = ({ data, space = 2, gap = 0, lastElement = true }: IJsonArrayProps) => ( + + [ + {!!data.length && '\n'} + {data.map((value, idx) => ( + // eslint-disable-next-line react/no-array-index-key + + {!!space && Array.from({ length: space + gap }, () => ' ')} + + + ))} + {!!data.length && !!gap && Array.from({ length: gap }, () => ' ')} + ] + {!lastElement && ','} + {'\n'} + +) + +export default JsonArray diff --git a/redisinsight/ui/src/components/json-viewer/components/json-array/index.ts b/redisinsight/ui/src/components/json-viewer/components/json-array/index.ts new file mode 100644 index 0000000000..0e7932a002 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-array/index.ts @@ -0,0 +1,3 @@ +import JsonArray from './JsonArray' + +export default JsonArray diff --git a/redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.spec.tsx b/redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.spec.tsx new file mode 100644 index 0000000000..655521efff --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.spec.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import { render, screen } from 'uiSrc/utils/test-utils' + +import JsonObject from './JsonObject' + +const mockJson = { value: JSON.stringify({}) } + +describe('JsonObject', () => { + it('should render jsonObjectComponent', () => { + expect(render()).toBeTruthy() + }) + + it('should render jsonObjectComponent', () => { + render() + + expect(screen.getByTestId('json-object-component')).toHaveTextContent('{ "value": "{}" }') + }) + + it('should render coma', () => { + render() + + expect(screen.getByTestId('json-object-component')).toHaveTextContent('{ "value": "{}" },') + }) + + it('should not render coma', () => { + render() + + expect(screen.getByTestId('json-object-component')).toHaveTextContent('{ "value": "{}" }') + }) + + it('should not render empty space and line break', () => { + render() + + expect(screen.getByTestId('json-object-component')).toHaveTextContent('{}', { normalizeWhitespace: false }) + }) + + it('should render empty space and line break', () => { + const renderedObject = '{\n "value": "{}"\n}' + render() + + expect(screen.getByTestId('json-object-component')).toHaveTextContent(renderedObject, { normalizeWhitespace: false }) + }) +}) diff --git a/redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.tsx b/redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.tsx new file mode 100644 index 0000000000..b1a2002275 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-object/JsonObject.tsx @@ -0,0 +1,36 @@ +import React, { Fragment } from 'react' + +import JsonPretty from 'uiSrc/components/json-viewer/components/json-pretty' +import { IJsonObjectProps } from 'uiSrc/components/json-viewer/interfaces' + +const JsonObject = ({ data, space = 2, gap = 0, lastElement = true }: IJsonObjectProps) => { + const keys = Object.keys(data) + + return ( + + {'{'} + {!!keys.length && '\n'} + {keys.map((key, idx) => ( + + {!!space && Array.from({ length: space + gap }, () => ' ')} + + {`"${key}"`} + + {': '} + + + ))} + {!!keys.length && !!gap && Array.from({ length: gap }, () => ' ')} + {'}'} + {!lastElement && ','} + {'\n'} + + ) +} + +export default JsonObject diff --git a/redisinsight/ui/src/components/json-viewer/components/json-object/index.ts b/redisinsight/ui/src/components/json-viewer/components/json-object/index.ts new file mode 100644 index 0000000000..ceeb8aa282 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-object/index.ts @@ -0,0 +1,3 @@ +import JsonObject from './JsonObject' + +export default JsonObject diff --git a/redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.spec.tsx b/redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.spec.tsx new file mode 100644 index 0000000000..459ba5da52 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.spec.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import { render, screen } from 'uiSrc/utils/test-utils' + +import JsonPretty from './JsonPretty' + +describe('JsonPretty', () => { + it('should render jsonObjectComponent', () => { + const json = { value: JSON.stringify({}) } + render() + + expect(screen.getByTestId('json-object-component')).toBeInTheDocument() + }) + + it('should render json array component', () => { + const json = ['123'] + render() + + expect(screen.getByTestId('json-array-component')).toBeInTheDocument() + }) + + it('should render json primitive component', () => { + const json = null + render() + + expect(screen.getByTestId('json-primitive-component')).toBeInTheDocument() + }) +}) diff --git a/redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.tsx b/redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.tsx new file mode 100644 index 0000000000..4ee9c477a2 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-pretty/JsonPretty.tsx @@ -0,0 +1,21 @@ +import React from 'react' + +import JsonPrimitive from 'uiSrc/components/json-viewer/components/json-primitive' +import JsonArray from 'uiSrc/components/json-viewer/components/json-array' +import JsonObject from 'uiSrc/components/json-viewer/components/json-object' +import { isArray, isObject } from 'uiSrc/components/json-viewer/utils' +import { IDefaultProps } from 'uiSrc/components/json-viewer/interfaces' + +const JsonPretty = ({ data, ...props }: IDefaultProps) => { + if (isArray(data)) { + return + } + + if (isObject(data)) { + return + } + + return +} + +export default JsonPretty diff --git a/redisinsight/ui/src/components/json-viewer/components/json-pretty/index.ts b/redisinsight/ui/src/components/json-viewer/components/json-pretty/index.ts new file mode 100644 index 0000000000..cac10d7d09 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-pretty/index.ts @@ -0,0 +1,3 @@ +import JsonPretty from './JsonPretty' + +export default JsonPretty diff --git a/redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.spec.tsx b/redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.spec.tsx new file mode 100644 index 0000000000..3896886443 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.spec.tsx @@ -0,0 +1,71 @@ +import React from 'react' +import { render, screen } from 'uiSrc/utils/test-utils' + +import JsonPrimitive from './JsonPrimitive' + +describe('JsonPrimitive', () => { + it('should render', () => { + expect(render()).toBeTruthy() + }) + + it('should render proper text and value for null', () => { + render() + + expect(screen.getByTestId('json-primitive-value')).toHaveTextContent('null') + expect(screen.getByTestId('json-primitive-value')).toHaveClass('json-pretty__null-value') + }) + + it('should render proper text and value for number', () => { + render() + + expect(screen.getByTestId('json-primitive-value')).toHaveTextContent('1') + expect(screen.getByTestId('json-primitive-value')).toHaveClass('json-pretty__number-value') + }) + + it('should render proper text and value for boolean', () => { + render() + + expect(screen.getByTestId('json-primitive-value')).toHaveTextContent('false') + expect(screen.getByTestId('json-primitive-value')).toHaveClass('json-pretty__boolean-value') + }) + + it('should render proper text and value for string', () => { + render() + + expect(screen.getByTestId('json-primitive-value')).toHaveTextContent('"123"') + expect(screen.getByTestId('json-primitive-value')).toHaveClass('json-pretty__string-value') + }) + + it('should render proper text and value for bigint', () => { + render() + + expect(screen.getByTestId('json-primitive-value')).toHaveTextContent('123') + expect(screen.getByTestId('json-primitive-value')).toHaveClass('json-pretty__bigint-value') + }) + + it('should render proper text and value for other types', () => { + render() + + expect(screen.getByTestId('json-primitive-value')).toHaveTextContent('[object Map]') + expect(screen.getByTestId('json-primitive-value')).toHaveClass('json-pretty__other-value') + }) + + it('should render proper text and value for true', () => { + render() + + expect(screen.getByTestId('json-primitive-value')).toHaveTextContent('true') + expect(screen.getByTestId('json-primitive-value')).toHaveClass('json-pretty__boolean-value') + }) + + it('should render coma', () => { + render() + + expect(screen.getByTestId('json-primitive-component')).toHaveTextContent('true,') + }) + + it('should not render coma', () => { + render() + + expect(screen.getByTestId('json-primitive-component')).toHaveTextContent('true') + }) +}) diff --git a/redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.tsx b/redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.tsx new file mode 100644 index 0000000000..ca214623a6 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-primitive/JsonPrimitive.tsx @@ -0,0 +1,37 @@ +import React from 'react' +import { isString, isBoolean, isNull, isNumber } from 'lodash' +import { isBigInt } from 'uiSrc/components/json-viewer/utils' +import { IDefaultProps } from 'uiSrc/components/json-viewer/interfaces' + +const JsonPrimitive = ({ data, lastElement = true }: IDefaultProps) => { + let stringValue = data + let valueStyle = 'json-pretty__other-value' + + if (isNull(data)) { + stringValue = 'null' + valueStyle = 'json-pretty__null-value' + } else if (isString(data)) { + stringValue = `"${data}"` + valueStyle = 'json-pretty__string-value' + } else if (isBoolean(data)) { + stringValue = data ? 'true' : 'false' + valueStyle = 'json-pretty__boolean-value' + } else if (isNumber(data)) { + stringValue = data.toString() + valueStyle = 'json-pretty__number-value' + } else if (isBigInt(data)) { + stringValue = data.toString() + valueStyle = 'json-pretty__bigint-value' + } else { + stringValue = data.toString() + } + return ( + + {stringValue} + {!lastElement && ','} + {'\n'} + + ) +} + +export default JsonPrimitive diff --git a/redisinsight/ui/src/components/json-viewer/components/json-primitive/index.ts b/redisinsight/ui/src/components/json-viewer/components/json-primitive/index.ts new file mode 100644 index 0000000000..19849cdd8f --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/components/json-primitive/index.ts @@ -0,0 +1,3 @@ +import JsonPrimitive from './JsonPrimitive' + +export default JsonPrimitive diff --git a/redisinsight/ui/src/components/json-viewer/interfaces.ts b/redisinsight/ui/src/components/json-viewer/interfaces.ts new file mode 100644 index 0000000000..ef04cb3a4a --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/interfaces.ts @@ -0,0 +1,14 @@ +export interface IDefaultProps { + data: any + space?: number + gap?: number + lastElement?: boolean +} + +export interface IJsonArrayProps extends IDefaultProps { + data: Array +} + +export interface IJsonObjectProps extends IDefaultProps { + data: Record +} diff --git a/redisinsight/ui/src/components/json-viewer/utils.spec.ts b/redisinsight/ui/src/components/json-viewer/utils.spec.ts new file mode 100644 index 0000000000..4de3f60f55 --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/utils.spec.ts @@ -0,0 +1,77 @@ +import { + isBigInt, + isArray, + isObject, +} from './utils' + +const isBigIntTests = [ + ['', false], + [true, false], + [false, false], + [0, false], + ['123', false], + [123, false], + [[], false], + [[123], false], + [{}, false], + [{ name: 'something' }, false], + [BigInt(1), true], + [Infinity, false], + [NaN, false], +] + +const isArrayTests = [ + ['', false], + [true, false], + [false, false], + [0, false], + ['123', false], + [123, false], + [[], true], + [[123], true], + [{}, false], + [{ name: 'something' }, false], + [BigInt(1), false], + [Infinity, false], + [NaN, false], +] + +const isObjectTests = [ + ['', false], + [true, false], + [false, false], + [0, false], + ['123', false], + [123, false], + [[], false], + [[123], false], + [{}, true], + [{ name: 'something' }, true], + [BigInt(1), false], + [Infinity, false], + [NaN, false], +] + +describe('isBigInt', () => { + it.each(isBigIntTests)('for input: %s (name), should be output: %s', + (value, expected) => { + const result = isBigInt(value) + expect(result).toBe(expected) + }) +}) + +describe('isArray', () => { + it.each(isArrayTests)('for input: %s (name), should be output: %s', + (value, expected) => { + const result = isArray(value) + expect(result).toBe(expected) + }) +}) + +describe('isObject', () => { + it.each(isObjectTests)('for input: %s (name), should be output: %s', + (value, expected) => { + const result = isObject(value) + expect(result).toBe(expected) + }) +}) diff --git a/redisinsight/ui/src/components/json-viewer/utils.ts b/redisinsight/ui/src/components/json-viewer/utils.ts new file mode 100644 index 0000000000..2340ce80aa --- /dev/null +++ b/redisinsight/ui/src/components/json-viewer/utils.ts @@ -0,0 +1,5 @@ +export const isBigInt = (data: any) => typeof data === 'bigint' || data instanceof BigInt +export const isArray = (data: any) => Array.isArray(data) +export const isObject = (data: any) => typeof data === 'object' + && data !== null + && !Array.isArray(data) diff --git a/redisinsight/ui/src/packages/clients-list/package.json b/redisinsight/ui/src/packages/clients-list/package.json index 4ed56f8b78..2b0517fae2 100644 --- a/redisinsight/ui/src/packages/clients-list/package.json +++ b/redisinsight/ui/src/packages/clients-list/package.json @@ -70,6 +70,7 @@ "devDependencies": { "@babel/core": "^7.12.0", "@parcel/transformer-sass": "2.8.3", + "@types/json-bigint": "^1.0.1", "@types/node": "^17.0.21", "@types/react": "^17.0.40", "@types/react-dom": "^17.0.13", @@ -85,10 +86,11 @@ "@elastic/eui": "34.6.0", "buffer": "^6.0.3", "classnames": "^2.3.1", + "json-bigint": "^1.0.0", + "lodash": "^4.17.21", "moment": "^2.29.1", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-json-pretty": "^2.2.0", "redisinsight-plugin-sdk": "^1.1.0" }, "resolutions": { diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/JSONView.tsx b/redisinsight/ui/src/packages/clients-list/src/components/json-view/JSONView.tsx index b639ed83bb..f5dca26a97 100644 --- a/redisinsight/ui/src/packages/clients-list/src/components/json-view/JSONView.tsx +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/JSONView.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react' -import JSONPretty from 'react-json-pretty' +import JSONBigInt from 'json-bigint' import { formatRedisReply } from 'redisinsight-plugin-sdk' +import JsonPretty from './components/json-pretty' interface Props { value: string @@ -14,7 +15,7 @@ const JSONView = (props: Props) => { useEffect(() => { try { - JSON.parse(value) + JSONBigInt({ useNativeBigInt: true }).parse(value) } catch (_err) { const formatResponse = async () => { const formattedResponse = await formatRedisReply(value, command) @@ -31,7 +32,7 @@ const JSONView = (props: Props) => { )} {!formattedValue && (
- +
)} diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/JsonArray.tsx b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/JsonArray.tsx new file mode 100644 index 0000000000..fce9e3c8dd --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/JsonArray.tsx @@ -0,0 +1,29 @@ +import React, { Fragment } from 'react' + +import { IJsonArrayProps } from '../../interfaces' +import JsonPretty from '../json-pretty' + +const JsonArray = ({ data, space = 2, gap = 0, lastElement = true }: IJsonArrayProps) => ( + + [ + {!!data.length && '\n'} + {data.map((value, idx) => ( + // eslint-disable-next-line react/no-array-index-key + + {!!space && Array.from({ length: space + gap }, () => ' ')} + + + ))} + {!!data.length && !!gap && Array.from({ length: gap }, () => ' ')} + ] + {!lastElement && ','} + {'\n'} + +) + +export default JsonArray diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/index.ts b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/index.ts new file mode 100644 index 0000000000..0e7932a002 --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-array/index.ts @@ -0,0 +1,3 @@ +import JsonArray from './JsonArray' + +export default JsonArray diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/JsonObject.tsx b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/JsonObject.tsx new file mode 100644 index 0000000000..1e07cfecf0 --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/JsonObject.tsx @@ -0,0 +1,35 @@ +import React, { Fragment } from 'react' + +import JsonPretty from '../json-pretty' +import { IJsonObjectProps } from '../../interfaces' + +const JsonObject = ({ data, space = 2, gap = 0, lastElement = true }: IJsonObjectProps) => { + const keys = Object.keys(data) + return ( + + {'{'} + {!!keys.length && '\n'} + {keys.map((key, idx) => ( + + {!!space && Array.from({ length: space + gap }, () => ' ')} + + {`"${key}"`} + + {': '} + + + ))} + {!!keys.length && !!gap && Array.from({ length: gap }, () => ' ')} + {'}'} + {!lastElement && ','} + {'\n'} + + ) +} + +export default JsonObject diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/index.ts b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/index.ts new file mode 100644 index 0000000000..ceeb8aa282 --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-object/index.ts @@ -0,0 +1,3 @@ +import JsonObject from './JsonObject' + +export default JsonObject diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/JsonPretty.tsx b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/JsonPretty.tsx new file mode 100644 index 0000000000..bcbd1e90b9 --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/JsonPretty.tsx @@ -0,0 +1,21 @@ +import React from 'react' + +import { IDefaultProps } from '../../interfaces' +import { isArray, isObject } from '../../utils' +import JsonPrimitive from '../json-primitive' +import JsonArray from '../json-array' +import JsonObject from '../json-object' + +const JsonPretty = ({ data, ...props }: IDefaultProps) => { + if (isArray(data)) { + return + } + + if (isObject(data)) { + return + } + + return +} + +export default JsonPretty diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/index.ts b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/index.ts new file mode 100644 index 0000000000..cac10d7d09 --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-pretty/index.ts @@ -0,0 +1,3 @@ +import JsonPretty from './JsonPretty' + +export default JsonPretty diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/JsonPrimitive.tsx b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/JsonPrimitive.tsx new file mode 100644 index 0000000000..fb9b5515e3 --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/JsonPrimitive.tsx @@ -0,0 +1,37 @@ +import React from 'react' +import { isString, isBoolean, isNull, isNumber } from 'lodash' +import { isBigInt } from '../../utils' +import { IDefaultProps } from '../../interfaces' + +const JsonPrimitive = ({ data, lastElement = true }: IDefaultProps) => { + let stringValue = data + let valueStyle = 'json-pretty__other_value' + + if (isNull(data)) { + stringValue = 'null' + valueStyle = 'json-pretty__null-value' + } else if (isString(data)) { + stringValue = `"${data}"` + valueStyle = 'json-pretty__string-value' + } else if (isBoolean(data)) { + stringValue = data ? 'true' : 'false' + valueStyle = 'json-pretty__boolean-value' + } else if (isNumber(data)) { + stringValue = data.toString() + valueStyle = 'json-pretty__number-value' + } else if (isBigInt(data)) { + stringValue = data.toString() + valueStyle = 'json-pretty__bigint-value' + } else { + stringValue = data.toString() + } + return ( + + {stringValue} + {!lastElement && ','} + {'\n'} + + ) +} + +export default JsonPrimitive diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/index.ts b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/index.ts new file mode 100644 index 0000000000..19849cdd8f --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/components/json-primitive/index.ts @@ -0,0 +1,3 @@ +import JsonPrimitive from './JsonPrimitive' + +export default JsonPrimitive diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/interfaces.ts b/redisinsight/ui/src/packages/clients-list/src/components/json-view/interfaces.ts new file mode 100644 index 0000000000..ef04cb3a4a --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/interfaces.ts @@ -0,0 +1,14 @@ +export interface IDefaultProps { + data: any + space?: number + gap?: number + lastElement?: boolean +} + +export interface IJsonArrayProps extends IDefaultProps { + data: Array +} + +export interface IJsonObjectProps extends IDefaultProps { + data: Record +} diff --git a/redisinsight/ui/src/packages/clients-list/src/components/json-view/utils.ts b/redisinsight/ui/src/packages/clients-list/src/components/json-view/utils.ts new file mode 100644 index 0000000000..2340ce80aa --- /dev/null +++ b/redisinsight/ui/src/packages/clients-list/src/components/json-view/utils.ts @@ -0,0 +1,5 @@ +export const isBigInt = (data: any) => typeof data === 'bigint' || data instanceof BigInt +export const isArray = (data: any) => Array.isArray(data) +export const isObject = (data: any) => typeof data === 'object' + && data !== null + && !Array.isArray(data) diff --git a/redisinsight/ui/src/packages/clients-list/src/styles/styles.scss b/redisinsight/ui/src/packages/clients-list/src/styles/styles.scss index 12a018dfda..cd1024b487 100644 --- a/redisinsight/ui/src/packages/clients-list/src/styles/styles.scss +++ b/redisinsight/ui/src/packages/clients-list/src/styles/styles.scss @@ -95,3 +95,41 @@ html { .cli-output-response-success { font-family: Inconsolata, serif !important; } + +.jsonViewer { + font: normal normal normal 13px/18px Inconsolata, monospace; + letter-spacing: 0.15px; + padding: 0; + background: transparent; + color: var(--euiTextSubduedColor); + margin-bottom: 0; + white-space: pre-wrap; + + &-collapsed { + white-space: nowrap; + text-overflow: ellipsis; + width: 100%; + overflow: hidden; + line-height: inherit; + } + + .key { + color: var(--jsonKeyNameColor); + } + + .number, + .bigint, + .undefined, + .null { + color: var(--jsonNumberColor); + } + + .string { + color: var(--jsonStringColor); + } + + .boolean { + color: var(--jsonBooleanColor); + } +} + diff --git a/redisinsight/ui/src/packages/clients-list/yarn.lock b/redisinsight/ui/src/packages/clients-list/yarn.lock index 10130034f9..5ff98373f3 100644 --- a/redisinsight/ui/src/packages/clients-list/yarn.lock +++ b/redisinsight/ui/src/packages/clients-list/yarn.lock @@ -985,6 +985,11 @@ "@types/react" "*" hoist-non-react-statics "^3.3.0" +"@types/json-bigint@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/json-bigint/-/json-bigint-1.0.1.tgz#201062a6990119a8cc18023cfe1fed12fc2fc8a7" + integrity sha512-zpchZLNsNuzJHi6v64UBoFWAvQlPhch7XAi36FkH6tL1bbbmimIF+cS7vwkzY4u5RaSWMoflQfu+TshMPPw8uw== + "@types/lodash@^4.14.160": version "4.14.194" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.194.tgz#b71eb6f7a0ff11bff59fc987134a093029258a76" @@ -1190,6 +1195,11 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bignumber.js@^9.0.0: + version "9.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" + integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -1956,6 +1966,13 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -2489,13 +2506,6 @@ react-is@~16.3.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.3.2.tgz#f4d3d0e2f5fbb6ac46450641eb2e25bf05d36b22" integrity sha512-ybEM7YOr4yBgFd6w8dJqwxegqZGJNBZl6U27HnGKuTZmDvVrD5quWOK/wAnMywiZzW+Qsk+l4X2c70+thp/A8Q== -react-json-pretty@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/react-json-pretty/-/react-json-pretty-2.2.0.tgz#9ba907d2b08d87e90456d87b6025feeceb8f63cf" - integrity sha512-3UMzlAXkJ4R8S4vmkRKtvJHTewG4/rn1Q18n0zqdu/ipZbUPLVZD+QwC7uVcD/IAY3s8iNVHlgR2dMzIUS0n1A== - dependencies: - prop-types "^15.6.2" - react-redux@^7.2.0: version "7.2.9" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" diff --git a/redisinsight/ui/src/styles/components/_json_view.scss b/redisinsight/ui/src/styles/components/_json_view.scss index 4dca5263ad..46fe878e94 100644 --- a/redisinsight/ui/src/styles/components/_json_view.scss +++ b/redisinsight/ui/src/styles/components/_json_view.scss @@ -1,44 +1,36 @@ .jsonViewer { - .__json { - &-pretty__, - &-pretty-error__ { - font: normal normal normal 13px/18px Inconsolata, monospace; - letter-spacing: 0.15px; - padding: 0; - background: transparent; - color: var(--euiTextSubduedColor); - margin-bottom: 0; - white-space: pre-wrap; - } + font: normal normal normal 13px/18px Inconsolata, monospace; + letter-spacing: 0.15px; + padding: 0; + background: transparent; + color: var(--euiTextSubduedColor); + margin-bottom: 0; + white-space: pre-wrap; - &-pretty-error__ { - white-space: normal; - } - - &-key__ { - color: var(--jsonKeyNameColor); - } + &-collapsed { + white-space: nowrap; + text-overflow: ellipsis; + width: 100%; + overflow: hidden; + line-height: inherit; + } - &-value__ { - color: var(--jsonNumberColor); - } + .json-pretty__key { + color: var(--jsonKeyNameColor); + } - &-string__ { - color: var(--jsonStringColor); - } + .json-pretty__number-value, + .json-pretty__bigint-value, + .json-pretty__null-value, + .json-pretty__other-value { + color: var(--jsonNumberColor); + } - &-boolean__ { - color: var(--jsonBooleanColor); - } + .json-pretty__string-value { + color: var(--jsonStringColor); } - &-collapsed { - .__json-pretty__ { - white-space: nowrap; - text-overflow: ellipsis; - width: 100%; - overflow: hidden; - line-height: inherit; - } + .json-pretty__boolean-value { + color: var(--jsonBooleanColor); } } diff --git a/redisinsight/ui/src/utils/formatters/json.ts b/redisinsight/ui/src/utils/formatters/json.ts index 7491b568b8..8a10bfb374 100644 --- a/redisinsight/ui/src/utils/formatters/json.ts +++ b/redisinsight/ui/src/utils/formatters/json.ts @@ -1,7 +1,9 @@ +import JSONBigInt from 'json-bigint' + export const reSerializeJSON = (val: string, space?: number) => { try { - const json = JSON.parse(val) - return JSON.stringify(json, null, space) + const json = JSONBigInt({ useNativeBigInt: true }).parse(val) + return JSONBigInt.stringify(json, null, space) } catch (e) { return val } diff --git a/redisinsight/ui/src/utils/formatters/utils.ts b/redisinsight/ui/src/utils/formatters/utils.ts index f74f5c8b8f..f81824b5dd 100644 --- a/redisinsight/ui/src/utils/formatters/utils.ts +++ b/redisinsight/ui/src/utils/formatters/utils.ts @@ -11,8 +11,3 @@ export const bufferFormatRangeItems = ( return newItems } - -export const replaceBigIntWithString = (obj: Object) => JSON.parse(JSON.stringify(obj, (_, value) => ( - typeof value === 'bigint' - ? value.toString() - : value))) diff --git a/redisinsight/ui/src/utils/formatters/valueFormatters.tsx b/redisinsight/ui/src/utils/formatters/valueFormatters.tsx index 54d6827864..d49036137e 100644 --- a/redisinsight/ui/src/utils/formatters/valueFormatters.tsx +++ b/redisinsight/ui/src/utils/formatters/valueFormatters.tsx @@ -5,6 +5,7 @@ import { isUndefined } from 'lodash' import { serialize, unserialize } from 'php-serialize' import { getData } from 'rawproto' import { loads as loadsPickle } from 'jpickle' +import JSONBigInt from 'json-bigint' import JSONViewer from 'uiSrc/components/json-viewer/JSONViewer' import { KeyValueFormat } from 'uiSrc/constants' @@ -19,7 +20,6 @@ import { hexToBuffer, stringToBuffer, binaryToBuffer, - replaceBigIntWithString } from 'uiSrc/utils' import { reSerializeJSON } from 'uiSrc/utils/formatters/json' @@ -73,7 +73,7 @@ const formattingBuffer = ( case KeyValueFormat.Msgpack: { try { const decoded = decode(reply.data) - const value = JSON.stringify(decoded) + const value = JSONBigInt.stringify(decoded) return JSONViewer({ value, ...props }) } catch (e) { return { value: bufferToUTF8(reply), isValid: false } @@ -82,7 +82,7 @@ const formattingBuffer = ( case KeyValueFormat.PHP: { try { const decoded = unserialize(Buffer.from(reply.data), { encoding: 'binary' }) - const value = JSON.stringify(decoded) + const value = JSONBigInt.stringify(decoded) return JSONViewer({ value, ...props }) } catch (e) { return { value: bufferToUTF8(reply), isValid: false } @@ -91,7 +91,7 @@ const formattingBuffer = ( case KeyValueFormat.JAVA: { try { const decoded = bufferToJava(reply) - const value = JSON.stringify(replaceBigIntWithString(decoded)) + const value = JSONBigInt.stringify(decoded) return JSONViewer({ value, ...props }) } catch (e) { return { value: bufferToUTF8(reply), isValid: false } @@ -100,7 +100,7 @@ const formattingBuffer = ( case KeyValueFormat.Protobuf: { try { const decoded = getData(Buffer.from(reply.data)) - const value = JSON.stringify(decoded) + const value = JSONBigInt.stringify(decoded) return JSONViewer({ value, ...props }) } catch (e) { return { value: bufferToUTF8(reply), isValid: false } @@ -117,7 +117,7 @@ const formattingBuffer = ( } } - const value = JSON.stringify(decoded) + const value = JSONBigInt.stringify(decoded) return JSONViewer({ value, ...props }) } catch (e) { return { value: bufferToUTF8(reply), isValid: false } diff --git a/tests/e2e/test-data/formatters-data.ts b/tests/e2e/test-data/formatters-data.ts index 567f0154d8..af2f54ba44 100644 --- a/tests/e2e/test-data/formatters-data.ts +++ b/tests/e2e/test-data/formatters-data.ts @@ -4,7 +4,8 @@ export const formatters = [{ format: 'JSON', fromText: '{ "field": "value" }', - fromTextEdit: '{ "field": "value123" }' + fromTextEdit: '{ "field": "value123" }', + fromBigInt: '{ "field": 248480010225057793 }' }, { format: 'Msgpack', @@ -27,7 +28,7 @@ export const formatters = [{ { format: 'Java serialized', fromHexText: 'aced000573720008456d706c6f796565025e743467c6123c0200034900066e756d6265724c0007616464726573737400124c6a6176612f6c616e672f537472696e673b4c00046e616d6571007e000178700000006574001950686f6b6b61204b75616e2c20416d62656874612050656572740009526579616e20416c69', - formattedText: '{ "fields": [ { "number": 101 }, { "address": "Phokka Kuan, Ambehta Peer" }, { "name": "Reyan Ali" } ], "annotations": [], "className": "Employee", "serialVersionUid": "170701604314812988" }' + formattedText: '{ "fields": [ { "number": 101 }, { "address": "Phokka Kuan, Ambehta Peer" }, { "name": "Reyan Ali" } ], "annotations": [], "className": "Employee", "serialVersionUid": 170701604314812988 }' }, { format: 'ASCII', diff --git a/tests/e2e/tests/critical-path/browser/formatters.e2e.ts b/tests/e2e/tests/critical-path/browser/formatters.e2e.ts index fb98ad5cdc..6f814852d3 100644 --- a/tests/e2e/tests/critical-path/browser/formatters.e2e.ts +++ b/tests/e2e/tests/critical-path/browser/formatters.e2e.ts @@ -104,6 +104,11 @@ formattersForEditSet.forEach(formatter => { // Verify that valid value can be edited to another valid value await t.expect(browserPage.hashFieldValue.innerText).contains(formatter.fromTextEdit ?? '', `Valid ${formatter.format} value is not saved`); await t.expect(browserPage.hashFieldValue.find(browserPage.cssJsonValue).exists).ok(`Value is not formatted to ${formatter.format}`); + if(formatter.format === 'JSON'){ + // bigInt can be displayed for JSON format + await browserPage.editHashKeyValue(formatter.fromBigInt ?? ''); + await t.expect(browserPage.hashFieldValue.innerText).contains(formatter.fromBigInt ?? '', `Valid ${formatter.format} value is not saved`); + } }); }); formattersWithTooltipSet.forEach(formatter => { diff --git a/tests/e2e/tests/regression/triggers-and-functions/libraries.e2e.ts b/tests/e2e/tests/regression/triggers-and-functions/libraries.e2e.ts index 058f90f1e3..47b516285e 100644 --- a/tests/e2e/tests/regression/triggers-and-functions/libraries.e2e.ts +++ b/tests/e2e/tests/regression/triggers-and-functions/libraries.e2e.ts @@ -25,6 +25,7 @@ const triggersAndFunctionsFunctionsPage = new TriggersAndFunctionsFunctionsPage( const libraryName = Common.generateWord(5); const streamKeyName = Common.generateWord(5); +const libNameFromFile = 'lib'; const filePathes = { upload: path.join('..', '..', '..', 'test-data', 'triggers-and-functions', 'library.txt'), @@ -140,10 +141,13 @@ test('Verify that library and functions can be deleted', async t => { await t.click(triggersAndFunctionsLibrariesPage.functionsLink); await t.expect(await triggersAndFunctionsFunctionsPage.getFunctionsNameSelector(LIBRARIES_LIST[1].name).exists).notOk(`the functions ${LIBRARIES_LIST[1].name} was not deleted`); }); -test('Verify that library can be uploaded', async t => { +test.after(async() => { + await browserPage.Cli.sendCommandInCli(`TFUNCTION DELETE ${libNameFromFile}`); + // Delete database + await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneRedisGears); +})('Verify that library can be uploaded', async t => { const configuration = '{"redisgears_2.lock-redis-timeout": 1000}'; const functionNameFromFile = 'function'; - const libNameFromFile = 'lib'; await t.click(browserPage.NavigationPanel.triggeredFunctionsButton); await t.expect(triggersAndFunctionsFunctionsPage.noLibrariesLink.exists).ok('no libraries title is displayed'); diff --git a/yarn.lock b/yarn.lock index 7640ac6a2a..240e70bc70 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2568,6 +2568,11 @@ "@types/parse5" "^6.0.3" "@types/tough-cookie" "*" +"@types/json-bigint@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/json-bigint/-/json-bigint-1.0.1.tgz#201062a6990119a8cc18023cfe1fed12fc2fc8a7" + integrity sha512-zpchZLNsNuzJHi6v64UBoFWAvQlPhch7XAi36FkH6tL1bbbmimIF+cS7vwkzY4u5RaSWMoflQfu+TshMPPw8uw== + "@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -3894,6 +3899,11 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +bignumber.js@^9.0.0: + version "9.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" + integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -9065,6 +9075,13 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -11764,13 +11781,6 @@ react-is@~16.3.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.3.2.tgz#f4d3d0e2f5fbb6ac46450641eb2e25bf05d36b22" integrity sha512-ybEM7YOr4yBgFd6w8dJqwxegqZGJNBZl6U27HnGKuTZmDvVrD5quWOK/wAnMywiZzW+Qsk+l4X2c70+thp/A8Q== -react-json-pretty@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/react-json-pretty/-/react-json-pretty-2.2.0.tgz#9ba907d2b08d87e90456d87b6025feeceb8f63cf" - integrity sha512-3UMzlAXkJ4R8S4vmkRKtvJHTewG4/rn1Q18n0zqdu/ipZbUPLVZD+QwC7uVcD/IAY3s8iNVHlgR2dMzIUS0n1A== - dependencies: - prop-types "^15.6.2" - react-jsx-parser@^1.28.4: version "1.29.0" resolved "https://registry.yarnpkg.com/react-jsx-parser/-/react-jsx-parser-1.29.0.tgz#12f9d42675bfaa50f818259c5304478ec8bb80f1" From 4935faa5edb59e01bc900355f6f3acae6d4e9c66 Mon Sep 17 00:00:00 2001 From: Amir Allayarov <100589048+AmirAllayarovSofteq@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:44:24 +0800 Subject: [PATCH 13/13] remove deprecated recommendation request (#2498) * remove deprecated recommendation request --- redisinsight/ui/src/pages/instance/InstancePage.tsx | 6 +----- .../components/cloud-settings/CloudSettings.spec.tsx | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/redisinsight/ui/src/pages/instance/InstancePage.tsx b/redisinsight/ui/src/pages/instance/InstancePage.tsx index de7a8d2ca5..16646d9de9 100644 --- a/redisinsight/ui/src/pages/instance/InstancePage.tsx +++ b/redisinsight/ui/src/pages/instance/InstancePage.tsx @@ -12,10 +12,7 @@ import { getDatabaseConfigInfoAction, instancesSelector, } from 'uiSrc/slices/instances/instances' -import { - fetchRecommendationsAction, - resetRecommendationsHighlighting, -} from 'uiSrc/slices/recommendations/recommendations' +import { resetRecommendationsHighlighting } from 'uiSrc/slices/recommendations/recommendations' import { appContextSelector, setAppContextConnectedInstanceId, @@ -82,7 +79,6 @@ const InstancePage = ({ routes = [] }: Props) => { })) dispatch(getDatabaseConfigInfoAction(connectionInstanceId)) dispatch(fetchConnectedInstanceInfoAction(connectionInstanceId)) - dispatch(fetchRecommendationsAction(connectionInstanceId)) if (contextInstanceId && contextInstanceId !== connectionInstanceId) { resetContext() diff --git a/redisinsight/ui/src/pages/settings/components/cloud-settings/CloudSettings.spec.tsx b/redisinsight/ui/src/pages/settings/components/cloud-settings/CloudSettings.spec.tsx index 697f95291d..1581fabae2 100644 --- a/redisinsight/ui/src/pages/settings/components/cloud-settings/CloudSettings.spec.tsx +++ b/redisinsight/ui/src/pages/settings/components/cloud-settings/CloudSettings.spec.tsx @@ -65,7 +65,7 @@ describe('CloudSettings', () => { fireEvent.click(screen.getByTestId('delete-key-confirm-btn')) - expect(store.getActions()).toEqual([getCapiKeys(), removeAllCapiKeys()]) + expect(store.getActions().slice(-1)).toEqual([removeAllCapiKeys()]) }) it('should call proper telemetry events', async () => {