diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.test.ts b/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.test.ts index d44d1c45492..83c30c31a20 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.test.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.test.ts @@ -10,7 +10,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { getDecodedFqn, getEncodedFqn } from './StringsUtils'; +import { formatJsonString, getDecodedFqn, getEncodedFqn } from './StringsUtils'; describe('StringsUtils', () => { it('getEncodedFqn should return encoded Fqn', () => { @@ -40,4 +40,36 @@ describe('StringsUtils', () => { expect(getDecodedFqn(fqn, true)).toEqual(decodedFqn); }); + + describe('formatJsonString', () => { + it('should format a simple JSON string', () => { + const jsonString = JSON.stringify({ key1: 'value1', key2: 'value2' }); + const expectedOutput = '[key1]: value1\n[key2]: value2\n'; + + expect(formatJsonString(jsonString)).toStrictEqual(expectedOutput); + }); + + it('should format a deeply nested JSON string', () => { + const jsonString = JSON.stringify({ + key1: 'value1', + key2: { + subKey1: 'subValue1', + subKey2: { + subSubKey1: 'subSubValue1', + subSubKey2: 'subSubValue2', + }, + }, + }); + const expectedOutput = + '[key1]: value1\n[key2]:\n [subKey1]: subValue1\n [subKey2]:\n [subSubKey1]: subSubValue1\n [subSubKey2]: subSubValue2\n'; + + expect(formatJsonString(jsonString)).toStrictEqual(expectedOutput); + }); + + it('should return the original string if it is not valid JSON', () => { + const jsonString = 'not valid JSON'; + + expect(formatJsonString(jsonString)).toStrictEqual(jsonString); + }); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.ts index c742101b67e..f7aaa6f90a5 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/StringsUtils.ts @@ -226,19 +226,26 @@ export const escapeESReservedCharacters = (text?: string) => { }; /** - * @description Format JSON string to pretty print format with 2 spaces indentation. + * @description Format JSON string to a readable format * if the JSON string is invalid, return the original JSON string * @param jsonString - JSON string to format + * @param indent - Indentation string * @returns Formatted JSON string + * @example formatJsonString('{"key1": "value1", "key2": "value2"}') => '[key1]: value1\n[key2]: value2\n' */ -export const formatJsonString = (jsonString: string) => { +export const formatJsonString = (jsonString: string, indent = '') => { try { let formattedJson = ''; const jsonObj = JSON.parse(jsonString); - // loop through the keys and values and format append the formatted string to formattedJson like [key]: [value] for (const [key, value] of Object.entries(jsonObj)) { - formattedJson += `[${key}]: ${value}\n`; + if (typeof value === 'object' && value !== null) { + formattedJson += `${indent}[${key}]:\n`; + // Recursively format nested objects + formattedJson += formatJsonString(JSON.stringify(value), indent + ' '); + } else { + formattedJson += `${indent}[${key}]: ${value}\n`; + } } return formattedJson;