feat(settings): add JSON editor indentation option (2 or 4 spaces)#200
feat(settings): add JSON editor indentation option (2 or 4 spaces)#200Pranav-0440 wants to merge 2 commits intoeclipse-editdor:masterfrom
Conversation
- Added new 'JSON Editor' section in Settings - Introduced jsonIndentation (2 | 4) in SettingsData - Connected indentation setting to Monaco editor tabSize - Auto-format JSON using selected indentation - Prevent infinite formatting loop - Apply changes immediately after saving settings Closes eclipse-editdor#185 Signed-off-by: Pranav-0440 <pranavghorpade61@gmail.com>
✅ Deploy Preview for editdor ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR adds a JSON editor indentation configuration option to allow users to choose between 2 or 4 space indentation. The feature includes a new "JSON Editor" settings section with a dropdown selector, integration with Monaco editor's tabSize option, and automatic formatting of JSON content according to the selected indentation.
Changes:
- Added jsonIndentation property (2 | 4) to SettingsData interface
- Created new JSON Editor settings section with indentation selector
- Integrated indentation setting with Monaco editor tabSize configuration
- Implemented automatic JSON formatting with selected indentation on content changes
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| src/components/App/Settings.tsx | Added jsonIndentation property to SettingsData interface, implemented handler and UI for indentation selection |
| src/components/Editor/JsonEditor.tsx | Extracted jsonIndentation from context, applied to Monaco editor options, added formatting logic in onChange handler |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/components/App/Settings.tsx
Outdated
| <div className="my-4 rounded-md bg-black bg-opacity-80 p-2"> | ||
| <h1 className="font-bold">JSON Editor</h1> | ||
| <div className="px-4"> | ||
| <label | ||
| htmlFor="json-indentation-select" | ||
| className="mb-1 block text-sm text-gray-300" | ||
| > | ||
| Space indentation | ||
| </label> | ||
| <select | ||
| id="json-indentation-select" | ||
| value={data.jsonIndentation} | ||
| onChange={handleJsonIndentationChange} | ||
| className="w-full rounded-md border-2 border-gray-600 bg-gray-600 p-2 text-white focus:border-blue-500 focus:outline-none sm:text-sm" | ||
| > | ||
| <option value={2}>2 spaces</option> | ||
| <option value={4}>4 spaces</option> | ||
| </select> | ||
| </div> | ||
| </div>; |
There was a problem hiding this comment.
The JSX code for the JSON Editor section is not placed inside the component's return statement. This code is currently positioned between the handler function definition and the return statement, which means it will never be rendered. The entire div block (lines 141-160) needs to be moved inside the return statement, likely after the "Path to value" section and before the closing div tag.
| const JsonEditor: React.FC<JsonEditorProps> = ({ editorRef }) => { | ||
| const context = useContext(ediTDorContext); | ||
|
|
||
| const jsonIndentation = context.settings?.jsonIndentation ?? 2; |
There was a problem hiding this comment.
The context object does not have a 'settings' property. The code is trying to access 'context.settings?.jsonIndentation' but this property doesn't exist in the IEdiTDorContext interface or in the GlobalState implementation. To fix this, you need to: 1) Add a 'settings' property of type SettingsData to the IEdiTDorContext interface in src/types/context.d.ts, 2) Add a corresponding state and update function in GlobalState.tsx, 3) Update the SettingsDialog to save the jsonIndentation to localStorage and update the context, 4) Load the jsonIndentation from localStorage when initializing the context.
| export interface SettingsData { | ||
| northboundUrl: string; | ||
| southboundUrl: string; | ||
| pathToValue: string; | ||
| jsonIndentation: 2 | 4; | ||
| } |
There was a problem hiding this comment.
The global SettingsData interface in src/types/context.d.ts (lines 156-160) has not been updated to include the jsonIndentation property. This interface needs to be updated to match the SettingsData interface in this file, otherwise there will be type inconsistencies across the codebase. The global interface should include 'jsonIndentation: 2 | 4;'.
| context.updateOfflineTD(formatted); | ||
| } else { | ||
| context.updateOfflineTD(editorText); |
There was a problem hiding this comment.
The onChange handler always calls context.updateOfflineTD, which could trigger a re-render and call onChange again, creating a potential infinite loop. The localTextState is only set when there's a JSON parsing error (line 215), but it's never set when the JSON is valid. This means that when formatted JSON is different from the input, updateOfflineTD is called, which could trigger onChange again with the formatted text. To prevent this, you should also set localTextState when the JSON is successfully parsed and formatted, like: 'setLocalTextState(formatted)' after calling context.updateOfflineTD(formatted).
| context.updateOfflineTD(formatted); | |
| } else { | |
| context.updateOfflineTD(editorText); | |
| context.updateOfflineTD(formatted); | |
| setLocalTextState(formatted); | |
| } else { | |
| context.updateOfflineTD(editorText); | |
| setLocalTextState(editorText); |
| automaticLayout: true, | ||
| lineDecorationsWidth: 20, | ||
| tabSize: jsonIndentation, | ||
| insertSpaces: true, |
There was a problem hiding this comment.
The Monaco editor options should include 'detectIndentation: false' to ensure that the editor respects the tabSize setting. By default, Monaco editor can auto-detect indentation from the content, which might override the tabSize setting. Adding 'detectIndentation: false' will ensure that the configured tabSize is always used.
| insertSpaces: true, | |
| insertSpaces: true, | |
| detectIndentation: false, |
| options={{ | ||
| selectOnLineNumbers: true, | ||
| automaticLayout: true, | ||
| lineDecorationsWidth: 20, | ||
| tabSize: jsonIndentation, | ||
| insertSpaces: true, | ||
| }} |
There was a problem hiding this comment.
The editor options object is being created inline on every render. Since jsonIndentation is derived from context.settings and could change, consider wrapping the options object in a useMemo hook with jsonIndentation as a dependency. This will prevent unnecessary re-renders of the Monaco editor when other unrelated state changes occur. Example: 'const editorOptions = useMemo(() => ({ ... }), [jsonIndentation]);'
| initialData = { | ||
| northboundUrl: "", | ||
| southboundUrl: "", | ||
| pathToValue: "/", | ||
| jsonIndentation: 2, | ||
| }, |
There was a problem hiding this comment.
The initial default value for jsonIndentation in SettingsDialog (line 26-30) is missing. This should be initialized with 'jsonIndentation: 2,' to match the default defined in the Settings component. Without this, when the SettingsDialog is opened for the first time or when localStorage is empty, the jsonIndentation field will be undefined, which could cause issues.
| const JsonEditor: React.FC<JsonEditorProps> = ({ editorRef }) => { | ||
| const context = useContext(ediTDorContext); | ||
|
|
||
| const jsonIndentation = context.settings?.jsonIndentation ?? 2; |
There was a problem hiding this comment.
When jsonIndentation changes (e.g., from 2 to 4 spaces or vice versa), the existing JSON in the editor won't be automatically reformatted until the user makes an edit. Consider adding a useEffect that watches for changes to jsonIndentation and triggers a reformat of the current offlineTD content. This would provide immediate visual feedback when the user changes the indentation setting, as mentioned in the issue requirements.
Signed-off-by: Pranav-0440 <pranavghorpade61@gmail.com>
|
If you need to understand what the code does instead of blindly trust the output of an AI. Here is a sample file to test |

Closes #185