Skip to content

feat: pretty-print JSON and add copy button in cell popup#3801

Open
Arunkoo wants to merge 2 commits intoydb-platform:mainfrom
Arunkoo:fix/pretty-print-json-cell-tooltip
Open

feat: pretty-print JSON and add copy button in cell popup#3801
Arunkoo wants to merge 2 commits intoydb-platform:mainfrom
Arunkoo:fix/pretty-print-json-cell-tooltip

Conversation

@Arunkoo
Copy link
Copy Markdown
Contributor

@Arunkoo Arunkoo commented Apr 12, 2026

Problem

When a query result cell contains a JSON value, it is displayed as a minified string in both the cell and the popup tooltip, making it hard to read — especially for large JSON payloads.

Closes #3594

Changes

  • Detect if a cell value is valid JSON object or array in Cell.tsx (primitives like 42, true, null are intentionally excluded)
  • If JSON, display it pretty-printed with JSON.stringify(parsed, null, 2) inside a <pre> block in the popup
  • Added a ClipboardButton in the popup to copy the formatted JSON value
  • Added supporting styles in QueryResultTable.scss

Before

Popup shows:
pretty json2

After

Popup shows:
pretty json

Greptile Summary

Adds JSON pretty-printing (with a correct primitive guard) and a ClipboardButton to the cell popup. The logic in Cell.tsx looks correct; the main concern is in the stylesheet where word-break: break-word from the parent .cell-popup is inherited by .cell-popup-json, causing long JSON tokens to wrap rather than trigger the horizontal scrollbar, defeating overflow-x: auto.

Confidence Score: 4/5

Safe to merge with one minor CSS fix recommended to ensure horizontal scrolling works as intended.

The only remaining finding is a P2 CSS inheritance issue (word-break) that affects the horizontal-scroll UX for wide JSON but doesn't break functionality. Prior P1 concerns (primitive guard, copy text) have been resolved in the current code.

QueryResultTable.scss — add word-break: normal to &__cell-popup-json

Important Files Changed

Filename Overview
src/components/QueryResultTable/Cell/Cell.tsx Adds JSON pretty-printing via tryFormatJson and a ClipboardButton; primitive guard (null/number/boolean) is correctly handled; copy button copies the formatted string.
src/components/QueryResultTable/QueryResultTable.scss Adds BEM-consistent classes for JSON pre-block and copy button; word-break: break-word is inherited from .cell-popup and should be reset to normal to let overflow-x: auto work correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Cell renders with value] --> B[tryFormatJson]
    B --> C{JSON.parse succeeds?}
    C -- No --> D[formatted = value, isJson = false]
    C -- Yes --> E{typeof parsed === 'object' && parsed !== null?}
    E -- No primitive --> D
    E -- Yes --> F[formatted = JSON.stringify pretty, isJson = true]
    D --> G[Popup: plain text + ClipboardButton copies formatted]
    F --> H[Popup: pre block + ClipboardButton copies formatted]
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/components/QueryResultTable/QueryResultTable.scss
Line: 16-25

Comment:
**`word-break` inheritance defeats horizontal scroll**

`.cell-popup` sets `word-break: break-word`, which is inherited by `.cell-popup-json`. Combined with `white-space: pre`, this causes long JSON tokens (keys, string values) to wrap at arbitrary character boundaries rather than triggering the horizontal scrollbar — the `overflow-x: auto` rule never gets a chance to fire. Add `word-break: normal` to reset the inherited value.

```suggestion
    &__cell-popup-json {
        overflow-x: auto;

        max-height: 300px;
        margin: 0;

        font-family: monospace;
        font-size: 12px;
        white-space: pre;
        word-break: normal;
    }
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (2): Last reviewed commit: "fix: guard primitive JSON values and cop..." | Re-trigger Greptile

<div className={b('cell-popup')}>{value}</div>
<div className={b('cell-popup')}>
{isJson ? <pre className={b('cell-popup-json')}>{formatted}</pre> : formatted}
<ClipboardButton text={formatted} size="s" className={b('cell-popup-copy')} />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Copy button copies pretty-printed form, not original value

The PR description says "copy the cell value," but text={formatted} copies the indented multi-line JSON (with extra whitespace) rather than the original compact string from the query result. Users pasting into code or a query editor will get the reformatted version instead of the raw value. Use text={value} to copy the original.

Suggested change
<ClipboardButton text={formatted} size="s" className={b('cell-popup-copy')} />
<ClipboardButton text={value} size="s" className={b('cell-popup-copy')} />
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/QueryResultTable/Cell/Cell.tsx
Line: 48

Comment:
**Copy button copies pretty-printed form, not original value**

The PR description says "copy the cell value," but `text={formatted}` copies the indented multi-line JSON (with extra whitespace) rather than the original compact string from the query result. Users pasting into code or a query editor will get the reformatted version instead of the raw value. Use `text={value}` to copy the original.

```suggestion
                    <ClipboardButton text={value} size="s" className={b('cell-popup-copy')} />
```

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pretty-print json content in query results

1 participant