Skip to content

feat(portal): add formatted and raw JSON views - #5657

Merged
mergify[bot] merged 6 commits into
apolloconfig:masterfrom
klboke:feat/json-view-tabs
Aug 20, 2026
Merged

mergify[bot] merged 6 commits into
apolloconfig:masterfrom
klboke:feat/json-view-tabs

Conversation

@klboke

@klboke klboke commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

What's the purpose of this PR

Add a formatted/raw value switch to the Portal text viewer for JSON configuration values.

Valid JSON values without duplicate keys open in the formatted view and can be switched to the exact raw value returned by the interface. Invalid JSON, duplicate-key JSON, and plain text remain raw-only. Text diff behavior is unchanged.

Which issue(s) this PR fixes:

None.

Brief changelog

  • Add Formatted and Raw tabs to the text viewer for format-safe JSON values.
  • Preserve the original value for raw inspection.
  • Add Chinese and English labels.
  • Add focused JavaScript coverage for formatted, raw, plain-text, and duplicate-key behavior.
  • Update CHANGES.md.

Validation

  • node apollo-portal/src/test/resources/static/scripts/test_hasDuplicateKeys.js
  • node apollo-portal/src/test/resources/static/scripts/test_showTextModal.js
  • ./mvnw -Dmaven.gitcommitid.skip=true spotless:check
  • ./mvnw -Dmaven.gitcommitid.skip=true clean test
  • ./mvnw -Dmaven.gitcommitid.skip=true spotless:apply

The git commit ID plugin is skipped locally because its legacy version cannot resolve HEAD from a Git worktree.

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Read the Contributing Guide before making this pull request.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit tests to verify the code.
  • Run mvn clean test to make sure this pull request doesn't break anything.
  • Run mvn spotless:apply to format your code.
  • Update the CHANGES log.

Summary by CodeRabbit

  • New Features

    • Added formatted and raw views for configuration values in the Portal.
    • Formatted viewing is available for valid JSON without duplicate keys.
    • Added English and Chinese localization for the new view options.
  • Bug Fixes

    • Improved handling of invalid, empty, or duplicate-key JSON by displaying it as raw text.
    • Improved parsing of signed, decimal, exponent-form, and extended numeric values.
    • View selection now resets correctly when opening configuration values.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 52ce8e74-0f99-41a8-ab1f-bf0f2757951a

📥 Commits

Reviewing files that changed from the base of the PR and between 60962bc and 7f461ba.

📒 Files selected for processing (3)
  • CHANGES.md
  • apollo-portal/src/main/resources/static/scripts/directive/show-text-modal-directive.js
  • apollo-portal/src/test/resources/static/scripts/test_showTextModal.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGES.md

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The Portal show-text modal now supports formatted and raw JSON views. The directive validates JSON and duplicate keys before enabling formatting. The template adds localized view tabs. Tests cover view modes, fallback behavior, numeric handling, and bindings.

Changes

Portal JSON view modes

Layer / File(s) Summary
Formatted and raw modal views
apollo-portal/src/main/resources/static/scripts/directive/show-text-modal-directive.js, apollo-portal/src/main/resources/static/views/component/show-text-modal.html, apollo-portal/src/main/resources/static/i18n/*.json, CHANGES.md
The directive validates JSON, duplicate keys, and extended numeric forms. It manages canFormat and viewMode. The template renders localized formatted and raw tabs. The release note documents the feature.
View mode validation coverage
apollo-portal/src/test/resources/static/scripts/test_showTextModal.js
Tests cover JSON filtering, formatted and raw modes, duplicate-key and invalid-input fallback, numeric preservation, and template bindings.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 7f461

The PR adds formatted and raw views for eligible JSON values while preserving raw-only behavior for invalid, duplicate-key, and plain-text values; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant ShowTextModal as show-text-modal.html
  participant Directive as show-text-modal-directive.js
  User->>ShowTextModal: Select formatted or raw tab
  ShowTextModal->>Directive: Call scope.setViewMode(viewMode)
  Directive->>Directive: Update viewMode
  Directive-->>ShowTextModal: Render selected value view
Loading

Possibly related PRs

Suggested labels: lgtm

Suggested reviewers: nobodyiam

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding formatted and raw JSON views to the Portal.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@klboke
klboke marked this pull request as ready for review August 10, 2026 11:10
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 10, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apollo-portal/src/test/resources/static/scripts/test_showTextModal.js (1)

79-83: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover invalid and plain-text input.

Lines 79-83 only test duplicate-key JSON. Add cases for malformed JSON and non-JSON text. Assert canFormat === false and viewMode === 'raw' for both cases.

Proposed test cases
+    const invalidJson = createScope();
+    invalidJson.scope.text = '{"a":';
+    invalidJson.refresh();
+    assert.strictEqual(invalidJson.scope.canFormat, false);
+    assert.strictEqual(invalidJson.scope.viewMode, 'raw');
+
+    const plainTextValue = createScope();
+    plainTextValue.scope.text = 'not JSON';
+    plainTextValue.refresh();
+    assert.strictEqual(plainTextValue.scope.canFormat, false);
+    assert.strictEqual(plainTextValue.scope.viewMode, 'raw');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apollo-portal/src/test/resources/static/scripts/test_showTextModal.js` around
lines 79 - 83, Add test cases alongside the duplicate-key case in the plainText
scope tests for malformed JSON and ordinary non-JSON text. For each input, call
refresh() and assert canFormat is false and viewMode remains raw, reusing the
existing createScope setup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apollo-portal/src/main/resources/static/scripts/directive/show-text-modal-directive.js`:
- Around line 89-92: Update the validation condition in the show-text modal flow
around isJsonText so all successfully parsed JSON values—including strings,
numbers, booleans, and null—can enter the formatted view. Preserve the
duplicate-key check for object JSON and keep assigning jsonObject, canFormat,
and viewMode as in the existing branch.

---

Nitpick comments:
In `@apollo-portal/src/test/resources/static/scripts/test_showTextModal.js`:
- Around line 79-83: Add test cases alongside the duplicate-key case in the
plainText scope tests for malformed JSON and ordinary non-JSON text. For each
input, call refresh() and assert canFormat is false and viewMode remains raw,
reusing the existing createScope setup.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 55bbad54-f29d-4c79-9b90-b2926031c2df

📥 Commits

Reviewing files that changed from the base of the PR and between d95fc18 and c79fcc6.

📒 Files selected for processing (6)
  • CHANGES.md
  • apollo-portal/src/main/resources/static/i18n/en.json
  • apollo-portal/src/main/resources/static/i18n/zh-CN.json
  • apollo-portal/src/main/resources/static/scripts/directive/show-text-modal-directive.js
  • apollo-portal/src/main/resources/static/views/component/show-text-modal.html
  • apollo-portal/src/test/resources/static/scripts/test_showTextModal.js

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
apollo-portal/src/test/resources/static/scripts/test_showTextModal.js (1)

117-121: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Verify the value bindings in the template.

The checks only verify labels and view-mode conditions. They do not verify that raw mode binds text or that formatted mode binds jsonObject | json:4 | jsonBigIntFilter. A binding regression can pass this test.

Proposed test addition
     assert.ok(template.includes("viewMode == 'formatted'"));
     assert.ok(template.includes("viewMode == 'raw'"));
+    assert.ok(template.includes('ng-bind="text"'));
+    assert.ok(template.includes('ng-bind="jsonObject | json:4 | jsonBigIntFilter"'));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apollo-portal/src/test/resources/static/scripts/test_showTextModal.js` around
lines 117 - 121, Extend the template assertions in the test around the existing
Component.ShowText and viewMode checks to verify the raw-mode binding uses text
and the formatted-mode binding uses jsonObject piped through json:4 and
jsonBigIntFilter. Keep the current label and mode-condition assertions
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apollo-portal/src/test/resources/static/scripts/test_showTextModal.js`:
- Around line 117-121: Extend the template assertions in the test around the
existing Component.ShowText and viewMode checks to verify the raw-mode binding
uses text and the formatted-mode binding uses jsonObject piped through json:4
and jsonBigIntFilter. Keep the current label and mode-condition assertions
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b6d4c5e-e5cd-4c5e-99c9-40cf3fdf1c06

📥 Commits

Reviewing files that changed from the base of the PR and between c79fcc6 and 24d96a0.

📒 Files selected for processing (2)
  • apollo-portal/src/main/resources/static/scripts/directive/show-text-modal-directive.js
  • apollo-portal/src/test/resources/static/scripts/test_showTextModal.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • apollo-portal/src/main/resources/static/scripts/directive/show-text-modal-directive.js

@nobodyiam

Copy link
Copy Markdown
Member

Automated follow-up on the current head 24d96a0: I reviewed the formatted/raw JSON view flow and found no blocking issue. Both focused Node test suites pass locally (including all 29 duplicate-key cases), current CI is green, and the prior functional review thread is resolved. The remaining suggestion to assert the exact template bindings is non-blocking test hardening.

Note: this reply was generated and posted automatically by AI for initial triage; a maintainer will follow up if needed.

@nobodyiam

Copy link
Copy Markdown
Member

Follow-up on the current head 61745946c: the remaining non-blocking template-binding test suggestion is now covered. Both focused Node test suites pass locally, current CI is green, and there are no active unresolved review threads. I found no blocking issue in this follow-up.

Note: this reply was generated and posted automatically by AI for initial triage; a maintainer will follow up if needed.

@nobodyiam nobodyiam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The default formatted path can silently display a different value for signed integers outside JavaScript's safe range. On the current head, -9007199254740993 is rendered as -9007199254740992: parseBigInt only protects unsigned digit-only integers, while this PR now sends all valid JSON scalars through the formatted view by default. Before this change, top-level numbers remained raw.

Please fix this blocker before updating:

  1. Preserve signed unsafe integers through the formatting pipeline, or keep values that cannot be formatted losslessly in raw mode.
  2. Add a focused regression test that asserts the exact displayed/formatted value, rather than only canFormat, viewMode, and the retained raw text.

@klboke

klboke commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the signed unsafe integer blocker in 60962bc3f:

  • Preserve negative integer tokens through the existing parseBigInt / jsonBigIntFilter marker pipeline, including marker-like string escaping.
  • Add a full formatting-pipeline regression assertion that -9007199254740993 is displayed unchanged.

Validated with all static JavaScript tests, ./mvnw spotless:apply, and the Apollo Portal package build.

@klboke
klboke requested a review from nobodyiam August 17, 2026 01:56

@nobodyiam nobodyiam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks—the signed unsafe-integer blocker is fixed on 60962bc3f. I verified the top-level, nested, array, and marker-like string cases. Two blockers remain before approval:

  1. show-text-modal-directive.js:129-133 still protects only number tokens matching ^-?\d+$. Because this PR now defaults every valid JSON scalar to the formatted view, valid fractional and exponent forms can still lose precision: 9007199254740993.0 and 9.007199254740993e15 both display as 9007199254740992. Before this PR, these top-level numeric scalars remained raw. Please preserve JSON numbers that cannot round-trip losslessly, or keep them raw-only, and add exact-output coverage for fractional/exponent cases.
  2. Move the #5657 entry from the top of the Apollo 3.0.0 section to the bottom of that section. The branch is currently one commit behind master, so please place it after the latest entry when updating the branch.

@klboke
klboke force-pushed the feat/json-view-tabs branch from 60962bc to 7f461ba Compare August 20, 2026 06:14
@klboke

klboke commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Addressed both blockers from review 4979523400 in 7f461ba7e:

  1. Extended the existing number-marker pipeline to the full JSON number grammar, so fractional and exponent forms remain lossless. Exact display assertions now cover 9007199254740993.0 and 9.007199254740993e15, plus an exponent marker-like string collision case.
  2. Rebasing onto current master brought in the latest 3.0.0 entry, and the feat(portal): add formatted and raw JSON views #5657 CHANGES.md entry is now placed at the bottom of that section after feat(portal): support revoking non-properties namespace changes #5656.

Local validation passed: all static JavaScript tests, ./mvnw spotless:apply, and the Apollo Portal package build.

@klboke
klboke requested a review from nobodyiam August 20, 2026 06:15

@nobodyiam nobodyiam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Re-reviewed the current head 7f461ba7e. Both requested blockers are resolved: the formatter now preserves integer, fractional, and exponent-form JSON numbers through the full display pipeline, including marker-like string cases, and the #5657 CHANGES.md entry is now appended after #5656 at the bottom of the Apollo 3.0.0 section.

The focused tests and additional numeric boundary checks pass, all required CI checks are green, the branch is up to date with master, and no active unresolved review threads remain. I found no blocking issues.

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Aug 20, 2026
@mergify

mergify Bot commented Aug 20, 2026 •

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • ✅ Entered queue — 2026-08-20 06:24 UTC · Rule: multi-commit · triggered by merge protections
  • ✅ Checks skipped · PR is already up-to-date
  • ✅ Merged — 2026-08-20 06:24 UTC · at 7f461ba7ee435479257fd2c92714fe50ee8e13ee · squash

This pull request spent 16 seconds in the queue, including 2 seconds running CI.

Required conditions to merge

@mergify
mergify Bot merged commit 1a1840e into apolloconfig:master Aug 20, 2026
13 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 20, 2026
@nobodyiam nobodyiam added this to the 3.0.0 milestone Sep 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

lgtm This PR has been approved by a maintainer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants