Skip to content

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

Open
Arunkoo wants to merge 4 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 4 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
  • Popup supports both vertical and horizontal scroll for large JSON payloads
  • Added supporting styles in QueryResultTable.scss

Before

Popup shows:
pretty json2

After

Popup shows:
3609 issue

Testing

  1. Run a query that returns a JSON column
  2. Click on a cell — popup shows formatted JSON with a copy button
  3. Large JSON scrolls vertically and wide JSON scrolls horizontally
  4. Copy button copies the pretty-printed version
  5. Non-JSON values and primitive types (numbers, booleans) are unaffected

Greptile Summary

This PR adds JSON pretty-printing and a copy button to the cell popup in QueryResultTable. When a cell value is a valid JSON object or array, the popup renders it formatted in a <pre> block; primitives (null, numbers, booleans) are correctly excluded. The primitive guard and useMemo memoization are well-implemented, and the previous concern about primitive false-positives is resolved.

Confidence Score: 5/5

Safe to merge — all remaining findings are minor style suggestions with no impact on correctness or runtime behavior.

The core logic is sound: JSON parsing is safe, primitive values are correctly excluded, and memoization is applied. The two open findings (copy button visibility scope and display: flex on the button) are P2 style concerns that do not affect functionality.

No files require special attention.

Important Files Changed

Filename Overview
src/components/QueryResultTable/Cell/Cell.tsx Adds JSON detection (tryFormatJson), pretty-print rendering in a <pre> block, and a ClipboardButton; primitive guard and memoization are correct; copy button is rendered unconditionally for all cell types.
src/components/QueryResultTable/QueryResultTable.scss Adds BEM-consistent styles for JSON pre-block (max-height, overflow-x scroll) and copy button; display: flex on the copy button may stretch it to full popup width.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Cell receives string value] --> B[tryFormatJson called via useMemo]
    B --> C{JSON.parse succeeds?}
    C -- No --> D[formatted = value\nisJson = false]
    C -- Yes --> E{typeof parsed === 'object'\nAND parsed !== null?}
    E -- No primitive --> D
    E -- Yes object or array --> F[formatted = JSON.stringify parsed null 2\nisJson = true]
    D --> G[Popup renders plain text\n+ ClipboardButton copies value]
    F --> H[Popup renders pre block\nwith pretty JSON\n+ ClipboardButton copies formatted]
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/components/QueryResultTable/Cell/Cell.tsx
Line: 51

Comment:
**Copy button shown for all cell types**

The `ClipboardButton` is rendered unconditionally, so every cell popup — whether it contains JSON, plain text, or a number — shows a copy button. The PR description says the button is intended to "copy the formatted JSON value." If the intent is JSON-only, moving it inside the `isJson` branch avoids showing it for non-JSON cells:

```suggestion
                    {isJson ? (
                        <>
                            <pre className={b('cell-popup-json')}>{formatted}</pre>
                            <ClipboardButton text={formatted} size="s" className={b('cell-popup-copy')} />
                        </>
                    ) : formatted}
```

If showing the copy button for all cells is intentional, no change is needed — it does work correctly since `formatted === value` for non-JSON cells.

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

---

This is a comment left during a code review.
Path: src/components/QueryResultTable/QueryResultTable.scss
Line: 28-32

Comment:
**`display: flex` stretches copy button to full popup width**

`display: flex` on a block-level element (a `<button>`) makes it a block-level flex container that stretches to the parent's full width (up to 300 px here). This is likely unintentional — the button should be compact. Use `display: inline-flex` to keep it sized to its content:

```suggestion
    &__cell-popup-copy {
        display: inline-flex;

        margin-top: 8px;
    }
```

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

Reviews (3): Last reviewed commit: "Merge remote-tracking branch 'upstream/m..." | Re-trigger Greptile

Comment thread src/components/QueryResultTable/Cell/Cell.tsx
<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.

@Arunkoo
Copy link
Copy Markdown
Contributor Author

Arunkoo commented Apr 19, 2026

hi @astandrik , @Raubzeug Gentle ping — happy to address any feedback when you get a chance.

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