Repository: provectus/kafka-ui
Issue: Fields previews: make the paths work as json paths
Labels: scope/frontend
status/accepted
type/chore

currently they work without `$`

Issue comments:
The problem is not only with the `$` , any bit complex jsonPath does not work with it , cause it uses `Lodash` `get` method, instead of an actually JsonPath identifier, hence other stuff will fail as well.

Example `reddit-comments-avro` from topics messages check the `$.map.array[1:2]`, `map.array[1:2]` stuff like this will not work cause lodash does not support it.

Expressions such as

* `[?(expression)]`
* `[-n:]`


Method will itself will return  undefined over that particular JSON hence the bug.

One of the solution is to integrate a JSON PATH library , but those tend to be larger in size hence it will increase our download time of javascript bundle.



<br class="Apple-interchange-newline">


@armenuikafka please double-check the test case has this case.
> @armenuikafka please double-check the test case has this case.

@BulatKha test case for this issue - https://app.qase.io/case/KAFKAUI-270

Pull request review comments:

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/package.json b/kafka-ui-react-app/package.json
index 5c51e700076..94759221dfd 100644
--- a/kafka-ui-react-app/package.json
+++ b/kafka-ui-react-app/package.json
@@ -26,6 +26,7 @@
     "jest": "^29.0.3",
     "jest-watch-typeahead": "^2.0.0",
     "json-schema-faker": "^0.5.0-rcv.44",
+    "jsonpath-plus": "^7.2.0",
     "lodash": "^4.17.21",
     "pretty-ms": "7.0.1",
     "react": "^18.1.0",
diff --git a/kafka-ui-react-app/pnpm-lock.yaml b/kafka-ui-react-app/pnpm-lock.yaml
index 52390df0cde..eb9b03c0447 100644
--- a/kafka-ui-react-app/pnpm-lock.yaml
+++ b/kafka-ui-react-app/pnpm-lock.yaml
@@ -63,6 +63,7 @@ specifiers:
   jest-styled-components: ^7.0.8
   jest-watch-typeahead: ^2.0.0
   json-schema-faker: ^0.5.0-rcv.44
+  jsonpath-plus: ^7.2.0
   lint-staged: ^13.0.2
   lodash: ^4.17.21
   prettier: ^2.3.1
@@ -116,6 +117,7 @@ dependencies:
   jest: 29.0.3_yqiaopbgmqcuvx27p5xxvum6wm
   jest-watch-typeahead: 2.0.0_jest@29.0.3
   json-schema-faker: 0.5.0-rcv.44
+  jsonpath-plus: 7.2.0
   lodash: 4.17.21
   pretty-ms: 7.0.1
   react: 18.1.0
@@ -7058,6 +7060,11 @@ packages:
     engines: {node: '>=10.0.0'}
     dev: false
 
+  /jsonpath-plus/7.2.0:
+    resolution: {integrity: sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==}
+    engines: {node: '>=12.0.0'}
+    dev: false
+
   /jsx-ast-utils/3.3.0:
     resolution: {integrity: sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==}
     engines: {node: '>=4.0'}
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Messages/Message.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Messages/Message.tsx
index 82a705c3a33..cb2dbbb3c0c 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Messages/Message.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Messages/Message.tsx
@@ -1,4 +1,3 @@
-import get from 'lodash/get';
 import React from 'react';
 import styled from 'styled-components';
 import useDataSaver from 'lib/hooks/useDataSaver';
@@ -7,6 +6,7 @@ import MessageToggleIcon from 'components/common/Icons/MessageToggleIcon';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
 import { Dropdown, DropdownItem } from 'components/common/Dropdown';
 import { formatTimestamp } from 'lib/dateTimeHelpers';
+import { JSONPath } from 'jsonpath-plus';
 
 import MessageContent from './MessageContent/MessageContent';
 import * as S from './MessageContent/MessageContent.styled';
@@ -88,9 +88,12 @@ const Message: React.FC<Props> = ({
     return (
       <>
         {filters.map((item) => (
-          <div>
-            {item.field}: {get(parsedJson, item.path)}
-          </div>
+          <span key={`${item.path}--${item.field}`}>
+            {item.field}:{' '}
+            {JSON.stringify(
+              JSONPath({ path: item.path, json: parsedJson, wrap: false })
+            )}
+          </span>
         ))}
       </>
     );
@@ -116,7 +119,7 @@ const Message: React.FC<Props> = ({
         <StyledDataCell title={key}>
           {renderFilteredJson(key, keyFilters)}
         </StyledDataCell>
-        <StyledDataCell>
+        <StyledDataCell title={content}>
           <S.Metadata>
             <S.MetadataValue>
               {renderFilteredJson(content, contentFilters)}
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Messages/MessagesTable.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Messages/MessagesTable.tsx
index 96e9f40d73d..10e4f4dfa17 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Messages/MessagesTable.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Messages/MessagesTable.tsx
@@ -52,7 +52,18 @@ const MessagesTable: React.FC = () => {
   };
 
   return (
-    <>
+    <div style={{ position: 'relative' }}>
+      {previewFor !== null && (
+        <PreviewModal
+          values={previewFor === 'key' ? keyFilters : contentFilters}
+          toggleIsOpen={() => setPreviewFor(null)}
+          setFilters={(payload: PreviewFilter[]) =>
+            previewFor === 'key'
+              ? setKeyFilters(payload)
+              : setContentFilters(payload)
+          }
+        />
+      )}
       <Table isFullwidth>
         <thead>
           <tr>
@@ -77,18 +88,6 @@ const MessagesTable: React.FC = () => {
               onPreview={() => setPreviewFor('content')}
             />
             <TableHeaderCell> </TableHeaderCell>
-
-            {previewFor !== null && (
-              <PreviewModal
-                values={previewFor === 'key' ? keyFilters : contentFilters}
-                toggleIsOpen={() => setPreviewFor(null)}
-                setFilters={(payload: PreviewFilter[]) =>
-                  previewFor === 'key'
-                    ? setKeyFilters(payload)
-                    : setContentFilters(payload)
-                }
-              />
-            )}
           </tr>
         </thead>
         <tbody>
@@ -139,7 +138,7 @@ const MessagesTable: React.FC = () => {
           </Button>
         </S.Pages>
       </S.Pagination>
-    </>
+    </div>
   );
 };
 
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Messages/PreviewModal.styled.ts b/kafka-ui-react-app/src/components/Topics/Topic/Messages/PreviewModal.styled.ts
index 35f221ddeab..c1cecfbbd05 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Messages/PreviewModal.styled.ts
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Messages/PreviewModal.styled.ts
@@ -7,6 +7,7 @@ export const PreviewModal = styled.div`
   background: ${({ theme }) => theme.modal.backgroundColor};
   position: absolute;
   left: 25%;
+  top: 30px; // some margin
   border: 1px solid ${({ theme }) => theme.modal.border.contrast};
   box-shadow: ${({ theme }) => theme.modal.shadow};
   padding: 32px;


Test patch: