Skip to content

feat: Add syntax highlighting, formatting, auto-indentation for Cloud Config parameter values of type Object and Array - #3176

Merged
mtrezza merged 18 commits into
parse-community:alphafrom
mtrezza:feat/format-value
Feb 5, 2026
Merged

mtrezza merged 18 commits into
parse-community:alphafrom
mtrezza:feat/format-value

Conversation

@mtrezza

@mtrezza mtrezza commented Feb 5, 2026 •

Copy link
Copy Markdown
Member

Pull Request

Feature

Add syntax highlight and formatting for Cloud Config parameter value.

Summary by CodeRabbit

  • New Features

    • New editable JSON editor with real-time syntax highlighting, auto-indentation, synchronized scrolling, change events and optional word-wrap.
    • Per-token syntax color customization with color pickers, save/reset controls and persisted settings.
  • Enhancements

    • Config dialog: Format/Compact actions, word-wrap toggle, JSON auto-format on open and inline error handling.
    • Modal now uses a custom footer.
    • Toggle control accepts custom left/right colors for a gradient-styled switch.

@parse-github-assistant

parse-github-assistant Bot commented Feb 5, 2026 •

Copy link
Copy Markdown

🚀 Thanks for opening this pull request!

@parseplatformorg

parseplatformorg commented Feb 5, 2026 •

Copy link
Copy Markdown
Contributor

✅ Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai

coderabbitai Bot commented Feb 5, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a new JsonEditor component and stylesheet; integrates it into ConfigDialog replacing Object/Array editors with formatting, compacting, word-wrap, error state, and syntax color propagation; extends CloudConfigSettings with per-token syntax color persistence and UI; and adds color props to Toggle.

Changes

Cohort / File(s) Summary
New JsonEditor component
src/components/JsonEditor/JsonEditor.react.js, src/components/JsonEditor/JsonEditor.scss
Adds a new JsonEditor: overlay textarea + Prism.js highlighted layer, synchronized scrolling, Enter auto-indent, onChange propagation, optional wordWrap, and syntax color overrides via syntaxColors prop.
ConfigDialog integration & JSON UX
src/dashboard/Data/Config/ConfigDialog.react.js
Replaces Object/Array editors with JsonEditor; updates EDITORS.Object/EDITORS.Array signatures to (value, onChange, wordWrap, syntaxColors); adds wordWrap, error, syntaxColors state, auto-format-on-open, formatValue(), compactValue(), canFormatValue(), and a custom modal footer with Format/Compact/Word wrap controls.
Cloud config syntax color settings
src/dashboard/Settings/CloudConfigSettings.react.js
Adds syntaxColors state and UI for per-token color pickers; introduces FORMATTING_CONFIG_KEY, default colors, serialized save queue, handleSyntaxColorChange, saveSyntaxColor, and resetSyntaxColors to persist/delete formatting config.
Toggle styling props
src/components/Toggle/Toggle.react.js
Adds colorLeft and colorRight props; applies gradient inline style to the switch when provided and preserves existing colored-class behavior when custom colors are absent.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant Dialog as ConfigDialog
  participant Editor as JsonEditor
  participant Prism as Prism.js

  User->>Dialog: Open modal for Object/Array param
  Dialog->>Dialog: formatValue() if value parses as JSON
  Dialog->>Editor: render(value, wordWrap, syntaxColors)
  Editor->>Prism: request highlight(JSON)
  Prism-->>Editor: return highlighted HTML
  User->>Editor: Type / Enter / Scroll
  Editor->>Editor: handleKeyDown / handleChange / syncScroll
  Editor-->>Dialog: onChange(updated JSON string)
  User->>Dialog: Click Save/Create
  Dialog->>Dialog: compactValue() or persist current value
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete. It uses a vague general statement instead of following the template structure with Issue, Approach, and Tasks sections. Fill in the complete template: add the issue link under 'Closes:', describe the approach with implementation details, and mark relevant tasks to complete the PR description.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main changes: syntax highlighting, formatting, and auto-indentation for Cloud Config parameter values of types Object and Array.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/dashboard/Data/Config/ConfigDialog.react.js`:
- Around line 360-402: The Modal is missing the onCancel and onConfirm callbacks
so its keyboard handlers will be undefined; update the Modal instantiation in
ConfigDialog.react.js to pass this.props.onCancel as onCancel and the
component's submit method (this.submit.bind(this)) as onConfirm (while keeping
existing props like type/Modal.Types.INFO, title, icon, customFooter) so ESC
triggers onCancel and Cmd+Enter triggers onConfirm.

Comment thread src/dashboard/Data/Config/ConfigDialog.react.js
@mtrezza mtrezza changed the title feat: Add syntax highlight and formatting for Cloud Config parameter value feat: Add syntax highlighting and formatting for Cloud Config parameter value Feb 5, 2026
@mtrezza mtrezza changed the title feat: Add syntax highlighting and formatting for Cloud Config parameter value feat: Add syntax highlighting, formatting, auto-indentation for Cloud Config parameter value Feb 5, 2026
@mtrezza mtrezza changed the title feat: Add syntax highlighting, formatting, auto-indentation for Cloud Config parameter value feat: Add syntax highlighting, formatting, auto-indentation for Cloud Config parameter values of type Object and Array Feb 5, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Feb 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/JsonEditor/JsonEditor.react.js`:
- Around line 115-141: In getSyntaxColorStyles, validate and sanitize the
syntaxColors prop before building the style tag: iterate over syntaxColors
entries, accept only strict hex color strings (`#RGB` or `#RRGGBB`,
case-insensitive) and ignore or replace invalid values with the safe defaults
currently used for each token (property, string, number, boolean, null,
punctuation, operator); do not directly inject unvalidated values into the
template string for the style tag—use the sanitized/fallback values when
composing CSS for .{styles.highlightLayer} .token.* selectors to prevent CSS
parsing errors or style injection vulnerabilities.

In `@src/dashboard/Settings/CloudConfigSettings.react.js`:
- Around line 135-169: The allColorsMatchDefaults function currently fails when
keys are missing because it compares undefined to defaults; update
allColorsMatchDefaults to treat missing entries as default by using the fallback
(e.g., const actual = colors?.[key] ?? defaultColor) and compare
actual.toLowerCase() === defaultColor.toLowerCase(); then saveSyntaxColor logic
can continue building the merged colors object as it does—no other changes
needed.
🧹 Nitpick comments (1)
src/dashboard/Data/Config/ConfigDialog.react.js (1)

118-137: Add type checking before JSON.parse for robustness.

The current code assumes props.value is always a string for Object/Array types. While parseValueForModal() in Config.react.js correctly stringifies values before passing them, it's safer to validate the type before parsing. If a non-string value somehow reaches this code, JSON.parse will throw and fail silently in the catch block, leaving the textarea with no formatting.

🛠️ Suggested fix
-      let initialValue = props.value;
-      if ((props.type === 'Object' || props.type === 'Array') && initialValue) {
+      let initialValue = props.value;
+      if ((props.type === 'Object' || props.type === 'Array') && initialValue != null) {
         try {
-          const parsed = JSON.parse(initialValue);
+          const parsed =
+            typeof initialValue === 'string' ? JSON.parse(initialValue) : initialValue;
           initialValue = JSON.stringify(parsed, null, 2);
         } catch {
           // Value is not valid JSON, keep original
         }
       }

Comment thread src/components/JsonEditor/JsonEditor.react.js
Comment thread src/dashboard/Settings/CloudConfigSettings.react.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/dashboard/Settings/CloudConfigSettings.react.js`:
- Around line 135-184: The saveSyntaxColor method has a race condition from
concurrent read-modify-write cycles; serialize saves by introducing a per-key
promise queue so each save waits for the previous write to complete before
reading and writing. Implement a small queue or map of pending promises (e.g., a
private static or instance map like pendingSaves keyed by FORMATTING_CONFIG_KEY
or tokenType) and in saveSyntaxColor chain the new operation onto
pendingSaves[key] (await previous promise) before calling
serverStorage.getConfig, building colors, and calling setConfig/deleteConfig,
then resolve and replace pendingSaves[key] with the returned promise; keep the
existing validation, default-removal logic, and showNote/error handling
unchanged but ensure every save awaits the queue to prevent lost updates.
- Around line 259-309: Compute a validated displayColor before rendering each
color picker by testing this.state.syntaxColors[tokenType] against a hex regex
(e.g. /^#([0-9A-Fa-f]{6})$/) and falling back to
DEFAULT_SYNTAX_COLORS[tokenType] when invalid; then use that displayColor as the
value prop for the <input type="color"> so the picker always receives a valid
`#RRGGBB` string while leaving the TextInput bound to the raw
this.state.syntaxColors[tokenType] (keep existing handlers
handleSyntaxColorChange and saveSyntaxColor unchanged).

Comment thread src/dashboard/Settings/CloudConfigSettings.react.js
Comment thread src/dashboard/Settings/CloudConfigSettings.react.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/dashboard/Settings/CloudConfigSettings.react.js`:
- Around line 197-207: The resetSyntaxColors method must wait for any in-flight
blur-triggered save so the delete isn't overwritten; modify resetSyntaxColors to
first await (this.pendingSyntaxColorSave || Promise.resolve()) before calling
this.serverStorage.deleteConfig, then perform this.setState({ syntaxColors: {
...DEFAULT_SYNTAX_COLORS } }) and this.showNote as before; optionally after
successful delete clear or replace this.pendingSyntaxColorSave with
Promise.resolve() so future saves are not tied to the old promise.

Comment thread src/dashboard/Settings/CloudConfigSettings.react.js
@mtrezza
mtrezza merged commit 538e8b3 into parse-community:alpha Feb 5, 2026
12 checks passed
parseplatformorg pushed a commit that referenced this pull request Feb 5, 2026
# [8.4.0-alpha.1](8.3.0...8.4.0-alpha.1) (2026-02-05)

### Features

* Add syntax highlighting, formatting, auto-indentation for Cloud Config parameter values of type Object and Array ([#3176](#3176)) ([538e8b3](538e8b3))
@parseplatformorg

Copy link
Copy Markdown
Contributor

🎉 This change has been released in version 8.4.0-alpha.1

@parseplatformorg parseplatformorg added the state:released-alpha Released as alpha version label Feb 5, 2026
@mtrezza
mtrezza deleted the feat/format-value branch February 5, 2026 21:38
parseplatformorg pushed a commit that referenced this pull request Feb 5, 2026
# [8.4.0](8.3.0...8.4.0) (2026-02-05)

### Features

* Add syntax highlighting, formatting, auto-indentation for Cloud Config parameter values of type Object and Array ([#3176](#3176)) ([538e8b3](538e8b3))
@parseplatformorg

Copy link
Copy Markdown
Contributor

🎉 This change has been released in version 8.4.0

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

Labels

state:released Released as stable version state:released-alpha Released as alpha version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants