diff --git a/.eslintignore b/.eslintignore index edecb37034..5dfa77e5b7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,9 +2,6 @@ build coverage packages/plexus/src/LayoutManager/layout.worker*js* -# Ignore forked file -packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/jsonMarkup.js - # Ignore generated files packages/jaeger-ui/index.d.ts packages/plexus/dist diff --git a/packages/jaeger-ui/package.json b/packages/jaeger-ui/package.json index 59d3139aee..1f1848c57d 100644 --- a/packages/jaeger-ui/package.json +++ b/packages/jaeger-ui/package.json @@ -84,6 +84,7 @@ "react-helmet": "^6.1.0", "react-icons": "^4.10.1", "react-is": "^18.2.0", + "react-json-view-lite": "^0.9.8", "react-redux": "^5.0.6", "react-router-dom": "4.3.1", "react-router-redux": "5.0.0-alpha.8", diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx index 8c04a7305c..f09a679ead 100644 --- a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +/* eslint-disable import/no-extraneous-dependencies */ import * as React from 'react'; import { Dropdown, Menu } from 'antd'; import { ExportOutlined, ProfileOutlined } from '@ant-design/icons'; -import { jsonMarkup } from './jsonMarkup'; +import { JsonView, allExpanded, collapseAllNested, defaultStyles } from 'react-json-view-lite'; import CopyIcon from '../../../common/CopyIcon'; @@ -57,15 +58,6 @@ const stringMarkup = (value: string) => ( ); -function _jsonMarkup(value: any) { - const markup = { __html: jsonMarkup(value) }; - - return ( - // eslint-disable-next-line react/no-danger -
- ); -} - function formatValue(key: string, value: any) { let content; let parsed = value; @@ -79,7 +71,28 @@ function formatValue(key: string, value: any) { } else if (Array.isArray(parsed) && shouldDisplayAsStringList(key)) { content = stringListMarkup(parsed); } else { - content = _jsonMarkup(parsed); + const shouldJsonTreeExpand = Object.keys(parsed).length <= 10; + + content = ( + + ); } return
{content}
; @@ -114,6 +127,7 @@ type KeyValuesTableProps = { export default function KeyValuesTable(props: KeyValuesTableProps) { const { data, linksGetter } = props; + return (
@@ -122,7 +136,7 @@ export default function KeyValuesTable(props: KeyValuesTableProps) { const jsonTable = formatValue(row.key, row.value); const links = linksGetter ? linksGetter(data, i) : null; let valueMarkup; - if (links && links.length === 1) { + if (links?.length === 1) { valueMarkup = (
diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/__snapshots__/KeyValuesTable.test.js.snap b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/__snapshots__/KeyValuesTable.test.js.snap index a1d7609346..5489bf5811 100644 --- a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/__snapshots__/KeyValuesTable.test.js.snap +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/__snapshots__/KeyValuesTable.test.js.snap @@ -4,27 +4,42 @@ exports[` renders the expected text for each span value 1`] = `
-
{ - \\"hello\\": \\"world\\", - \\"<xss>\\": \\"safe\\", - \\"link\\": \\"https://example.com/\\", - \\"xss_link\\": \\"https://example.com with \\"quotes\\"\\", - \\"boolean\\": true, - \\"number\\": 42, - \\"null\\": null, - \\"array\\": [ - \\"x\\", - \\"y\\", - \\"z\\" - ], - \\"object\\": { - \\"a\\": \\"b\\", - \\"x\\": \\"y\\" + "": "safe", + "array": Array [ + "x", + "y", + "z", + ], + "boolean": true, + "hello": "world", + "link": "https://example.com", + "null": null, + "number": 42, + "object": Object { + "a": "b", + "x": "y", + }, + "xss_link": "https://example.com with \\"quotes\\"", + } } -}
", + shouldInitiallyExpand={[Function]} + style={ + Object { + "basicChildStyle": "json-markup-child", + "booleanValue": "json-markup-bool", + "container": "json-markup", + "expander": "json-markup-expander", + "label": "json-markup-key", + "nullValue": "json-markup-null", + "numberValue": "json-markup-number", + "otherValue": "json-markup-other", + "pointer": "_1MFti", + "punctuation": "json-markup-puncuation", + "stringValue": "json-markup-string", + "undefinedValue": "json-markup-undefined", } } /> diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/jsonMarkup.js b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/jsonMarkup.js deleted file mode 100644 index c112c278b4..0000000000 --- a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/SpanDetail/jsonMarkup.js +++ /dev/null @@ -1,113 +0,0 @@ -// Forked from https://github.com/mafintosh/json-markup/blob/master/index.js -// -// The MIT License (MIT) -// -// Copyright (c) 2023 The Jaeger Authors -// Copyright (c) 2014 Mathias Buus -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// 'use strict' - -const INDENT = ' '; - -function type(doc) { - if (doc === null) return 'null'; - if (Array.isArray(doc)) return 'array'; - if (typeof doc === 'string' && /^https?:/.test(doc)) { - try { - const u = new URL(doc); - return 'link'; - } catch { - // malformed URL - return 'string'; - } - } - return typeof doc; -} - -function escape(str) { - return str.replace(//g, '>'); -} - -export function jsonMarkup(doc, styleFile) { - var indent = ''; - function style(cssClass) { - return 'class="' + cssClass + '"'; - } - - var forEach = function (list, start, end, fn) { - if (!list.length) return start + ' ' + end; - - var out = start + '\n'; - - indent += INDENT; - list.forEach(function (key, i) { - out += indent + fn(key) + (i < list.length - 1 ? ',' : '') + '\n'; - }); - indent = indent.slice(0, -INDENT.length); - - return out + indent + end; - }; - - function visit(obj) { - if (obj === undefined) return ''; - - switch (type(obj)) { - case 'boolean': - return '' + obj + ''; - - case 'number': - return '' + obj + ''; - - case 'null': - return 'null'; - - case 'string': - return ( - '"' + - escape(obj.replace(/\n/g, '\n' + indent)) + - '"' - ); - - case 'link': - let url = new URL(obj); - return ( - '"' + url.href + '"' - ); - - case 'array': - return forEach(obj, '[', ']', visit); - - case 'object': - var keys = Object.keys(obj).filter(function (key) { - return obj[key] !== undefined; - }); - - return forEach(keys, '{', '}', function (key) { - return '"' + escape(key) + '": ' + visit(obj[key]); - }); - } - - return ''; - } - - return '
' + visit(doc) + '
'; -} diff --git a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.css b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.css index 3165611e24..ed25d101cd 100644 --- a/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.css +++ b/packages/jaeger-ui/src/components/TracePage/TraceTimelineViewer/index.css @@ -22,21 +22,50 @@ limitations under the License. line-height: 17px; font-size: 13px; font-family: monospace; + white-space: pre-wrap; + word-break: break-all; + word-wrap: break-word; } + .json-markup-key { font-weight: bold; + margin-right: 0.5rem; } + .json-markup-bool { color: firebrick; } + .json-markup-string { color: teal; } -.json-markup-null { + +.json-markup-null, +.json-markup-undefined { color: gray; } + .json-markup-number { color: blue; } + +.json-markup-other { + color: lightgrey; +} + +.json-markup-expander { + font-size: 1.2em; + margin-right: 5px; + user-select: none; +} + +.json-markup-child { + margin: 0.25rem 2.5rem; + padding: 0; +} + +.json-markup-puncuation { + font-weight: bold; +} diff --git a/packages/jaeger-ui/tsconfig.lint.json b/packages/jaeger-ui/tsconfig.lint.json index c2aac22772..d0e759daad 100644 --- a/packages/jaeger-ui/tsconfig.lint.json +++ b/packages/jaeger-ui/tsconfig.lint.json @@ -41,7 +41,6 @@ "src/components/SearchTracePage/SearchResults/ScatterPlot.jsx", "src/components/SearchTracePage/SearchResults/index.markers.js", "src/components/SearchTracePage/SearchResults/ResultItem.markers.js", - "src/components/TracePage/TraceTimelineViewer/SpanDetail/jsonMarkup.js", "src/middlewares/index.js", "src/model/order-by.js", "src/propTypes/dependencies.js", diff --git a/yarn.lock b/yarn.lock index 725aebbea1..e139e9991b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10506,6 +10506,11 @@ react-is@^17.0.0, react-is@^17.0.1, react-is@^17.0.2: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-json-view-lite@^0.9.8: + version "0.9.8" + resolved "https://registry.yarnpkg.com/react-json-view-lite/-/react-json-view-lite-0.9.8.tgz#d3d91bc16d62ef774a7b5c4ad95ccaaa623362d6" + integrity sha512-4D0UgQ5SjanNi2KzgEsEKOb9kj0L9HQz/3IshwIZN5reZsSU62t6sp8c+vskV42lXjGQCi7qGfoXIpNRsON7LA== + react-lazy-load@^3.0.13: version "3.1.14" resolved "https://registry.yarnpkg.com/react-lazy-load/-/react-lazy-load-3.1.14.tgz#536047d295f578614540a5b417b70b1155f36d9a"