Skip to content

Bugfixes/misc UI issues#2729

Open
essweine wants to merge 6 commits intomainfrom
bugfixes/misc-ui-issues
Open

Bugfixes/misc UI issues#2729
essweine wants to merge 6 commits intomainfrom
bugfixes/misc-ui-issues

Conversation

@essweine
Copy link
Copy Markdown
Collaborator

No description provided.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

The PR removes Monaco Editor dependencies and replaces them with CodeMirror editor components across multiple frontend views and components. Adds CodeMirror language extensions for JSON, Python, and XML, plus a merge/diff UI library. Also introduces dynamic schema option population from task data in ReactFormBuilder.

Changes

Cohort / File(s) Summary
Dependencies
spiffworkflow-frontend/package.json
Added CodeMirror libraries (@codemirror/lang-{json,python,xml}, @codemirror/state), React wrapper (@uiw/react-codemirror), and merge/diff support (react-codemirror-merge).
Editor Migration – JSON Editors
spiffworkflow-frontend/src/components/AuthenticationConfiguration.tsx, spiffworkflow-frontend/src/views/Extension.tsx
Replaced Monaco Editor with CodeMirror for JSON editing; switched to controlled component pattern with value/onChange handlers and JSON syntax highlighting extensions.
Editor Migration – Multi-format
spiffworkflow-frontend/src/views/ReactFormEditor.tsx
Replaced Monaco with CodeMirror for non-Markdown files; added dynamic language extension selection (JSON, XML); integrated TextareaAutosize for Markdown editor component.
Editor Migration – Complex
spiffworkflow-frontend/src/components/ReactFormBuilder/ReactFormBuilder.tsx, spiffworkflow-frontend/src/views/ProcessInstanceShow.tsx, spiffworkflow-frontend/src/views/ProcessModelEditDiagram.tsx
Replaced Monaco Editor/DiffEditor with CodeMirror and CodeMirrorMerge; added read-only mode enforcement via extensions and content attributes; introduced addOptionsToSchema() function to dynamically populate form schema options from task data.
Documentation
spiffworkflow-frontend/src/resources/json_schema_examples/dropdown-schema.json
Updated dropdown schema description to remove task-data-specific guidance and generalize label/value attribute requirements.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • burnettk
  • jasquat
🚥 Pre-merge checks | ❌ 3

❌ Failed checks (1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Bugfixes/misc UI issues' is vague and generic, using non-descriptive terms like 'misc' that fail to convey meaningful information about the substantial changeset. Replace with a specific title describing the primary change, such as 'Replace Monaco Editor with CodeMirror across frontend components' or 'Migrate JSON editors from Monaco to CodeMirror'.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess whether the description relates to the changeset. Add a description explaining the rationale for replacing Monaco Editor with CodeMirror, any performance or maintenance benefits, and testing performed.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfixes/misc-ui-issues

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
spiffworkflow-frontend/src/views/ReactFormEditor.tsx (1)

265-269: Use strict equality (===) for string comparisons.

Lines 265 and 267 use loose equality (==) instead of strict equality (===) for comparing strings.

Proposed fix
     const extensions = [];
-    if (editorDefaultLanguage == 'json') {
+    if (editorDefaultLanguage === 'json') {
       extensions.push(json());
-    } else if (editorDefaultLanguage == 'xml') {
+    } else if (editorDefaultLanguage === 'xml') {
       extensions.push(xml());
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spiffworkflow-frontend/src/views/ReactFormEditor.tsx` around lines 265 - 269,
The comparisons against editorDefaultLanguage use loose equality (==); update
both conditional checks to use strict equality (===) so string comparisons are
exact: replace occurrences of "editorDefaultLanguage == 'json'" and
"editorDefaultLanguage == 'xml'" with strict checks "editorDefaultLanguage ===
'json'" and "editorDefaultLanguage === 'xml'" in the ReactFormEditor component
where extensions.push(json()) and extensions.push(xml()) are invoked.
spiffworkflow-frontend/src/components/ReactFormBuilder/ReactFormBuilder.tsx (1)

354-380: Use forEach instead of map for side-effect-only iterations, and consider deep cloning.

  1. Object.keys().map() on line 357 is used purely for side effects (modifying item.anyOf). Use forEach instead, as map is intended for transformations that return values.

  2. The shallow copy on line 355 ({ ...schema }) doesn't deep-clone schema.properties, so mutations to item.anyOf will affect the original schema object. This could cause unexpected behavior if postJsonSchema is used elsewhere.

  3. Line 364 directly replaces the prefix without first verifying the string starts with 'options_from_task_data_var:'.

Proposed fix
   function addOptionsToSchema(schema: any, data: any) {
-    const newSchema = { ...schema };
+    const newSchema = JSON.parse(JSON.stringify(schema));
     if (typeof schema.properties === 'object') {
-      Object.keys(schema.properties).map((key) => {
+      Object.keys(newSchema.properties).forEach((key) => {
         const item = newSchema.properties[key];
         if (
           Array.isArray(item.anyOf) &&
           item.anyOf.length > 0 &&
-          typeof item.anyOf[0] === 'string'
+          typeof item.anyOf[0] === 'string' &&
+          item.anyOf[0].startsWith('options_from_task_data_var:')
         ) {
           const name = item.anyOf[0].replace('options_from_task_data_var:', '');
           if (Array.isArray(data[name])) {
-            item.anyOf = data[name].map((opt) => {
+            item.anyOf = data[name].map((opt: { value: string; label: string }) => {
               return {
                 type: 'string',
                 enum: [opt.value],
                 title: opt.label,
               };
             });
           } else {
             item.anyOf = [];
           }
         }
       });
     }
     return newSchema;
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spiffworkflow-frontend/src/components/ReactFormBuilder/ReactFormBuilder.tsx`
around lines 354 - 380, In addOptionsToSchema, replace the misuse of
Object.keys(...).map (used only for side effects) with forEach, deep-clone the
incoming schema (not just with {...schema}) so mutations to schema.properties
and item.anyOf don't affect the caller, and guard the string replacement by
checking that item.anyOf[0] is a string that
startsWith('options_from_task_data_var:') before calling replace; specifically,
deep-clone schema (including schema.properties), iterate
Object.keys(newSchema.properties).forEach to locate each item, check
Array.isArray(item.anyOf) && typeof item.anyOf[0] === 'string' &&
item.anyOf[0].startsWith('options_from_task_data_var:'), compute name by slicing
or replace, and then set item.anyOf from data[name] (or [] if missing) so
original schema remains untouched.
spiffworkflow-frontend/package.json (1)

17-17: Remove unused Monaco dependencies to reduce bundle size.

The PR adds CodeMirror packages, and Monaco dependencies (@monaco-editor/react on line 17 and monaco-editor on line 49) are no longer imported anywhere in the codebase. These can be safely removed.

Also applies to: 49-49

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spiffworkflow-frontend/package.json` at line 17, Remove the unused Monaco
packages from package.json by deleting the dependency entries for
"@monaco-editor/react" and "monaco-editor"; before committing, search the
codebase for any remaining imports/usages of "@monaco-editor/react" or
"monaco-editor" (e.g., import statements, dynamic requires) to ensure nothing
breaks, and update lockfile (run npm/yarn install) to regenerate
package-lock.json or yarn.lock so the unused packages are actually removed from
the lockfile.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@spiffworkflow-frontend/src/resources/json_schema_examples/dropdown-schema.json`:
- Line 3: Typo in the JSON "description" value: change the word "form" to "from"
in the dropdown schema's description field (the "description" property in
dropdown-schema.json) so it reads "A dropdown list with options pulled from
existing Task Data. Each item should have label and value attributes."; update
only that string value to correct the spelling.

In `@spiffworkflow-frontend/src/views/ProcessModelEditDiagram.tsx`:
- Around line 758-764: The CodeMirror component's height prop has a typo
('500ps') causing invalid styling; update the height prop on the CodeMirror
instance (the JSX where CodeMirror is rendered with value={inputJson} and
onChange={handleEditorScriptTestUnitInputChange}) to use the correct units
'500px' instead of '500ps' so the editor displays at the intended height.

In `@spiffworkflow-frontend/src/views/ReactFormEditor.tsx`:
- Around line 271-278: The CodeMirror component is passing a numeric height
(600) but expects a CSS string; update the JSX where CodeMirror is rendered (the
CodeMirror element using props height, value bound to processModelFileContents
and onChange calling setProcessModelFileContents) to pass a string with units
like "600px" (or another appropriate unit) instead of the number so the height
prop is correctly interpreted.

---

Nitpick comments:
In `@spiffworkflow-frontend/package.json`:
- Line 17: Remove the unused Monaco packages from package.json by deleting the
dependency entries for "@monaco-editor/react" and "monaco-editor"; before
committing, search the codebase for any remaining imports/usages of
"@monaco-editor/react" or "monaco-editor" (e.g., import statements, dynamic
requires) to ensure nothing breaks, and update lockfile (run npm/yarn install)
to regenerate package-lock.json or yarn.lock so the unused packages are actually
removed from the lockfile.

In `@spiffworkflow-frontend/src/components/ReactFormBuilder/ReactFormBuilder.tsx`:
- Around line 354-380: In addOptionsToSchema, replace the misuse of
Object.keys(...).map (used only for side effects) with forEach, deep-clone the
incoming schema (not just with {...schema}) so mutations to schema.properties
and item.anyOf don't affect the caller, and guard the string replacement by
checking that item.anyOf[0] is a string that
startsWith('options_from_task_data_var:') before calling replace; specifically,
deep-clone schema (including schema.properties), iterate
Object.keys(newSchema.properties).forEach to locate each item, check
Array.isArray(item.anyOf) && typeof item.anyOf[0] === 'string' &&
item.anyOf[0].startsWith('options_from_task_data_var:'), compute name by slicing
or replace, and then set item.anyOf from data[name] (or [] if missing) so
original schema remains untouched.

In `@spiffworkflow-frontend/src/views/ReactFormEditor.tsx`:
- Around line 265-269: The comparisons against editorDefaultLanguage use loose
equality (==); update both conditional checks to use strict equality (===) so
string comparisons are exact: replace occurrences of "editorDefaultLanguage ==
'json'" and "editorDefaultLanguage == 'xml'" with strict checks
"editorDefaultLanguage === 'json'" and "editorDefaultLanguage === 'xml'" in the
ReactFormEditor component where extensions.push(json()) and
extensions.push(xml()) are invoked.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ff2bedd2-bdcd-4383-8eda-ab6128f1b004

📥 Commits

Reviewing files that changed from the base of the PR and between aa6405a and 16aed97.

⛔ Files ignored due to path filters (1)
  • spiffworkflow-frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • spiffworkflow-frontend/package.json
  • spiffworkflow-frontend/src/components/AuthenticationConfiguration.tsx
  • spiffworkflow-frontend/src/components/ReactFormBuilder/ReactFormBuilder.tsx
  • spiffworkflow-frontend/src/resources/json_schema_examples/dropdown-schema.json
  • spiffworkflow-frontend/src/views/Extension.tsx
  • spiffworkflow-frontend/src/views/ProcessInstanceShow.tsx
  • spiffworkflow-frontend/src/views/ProcessModelEditDiagram.tsx
  • spiffworkflow-frontend/src/views/ReactFormEditor.tsx

{
"title": "Dropdown list",
"description": "A dropdown list with options pulled form existing Task Data. IMPORTANT - Add 'fruits' to Task Data before using this component!!!",
"description": "A dropdown list with options pulled form existing Task Data. Each item should have label and value attributes.",
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.

⚠️ Potential issue | 🟡 Minor

Typo in description: "form" should be "from".

The description contains a typo: "pulled form existing Task Data" should be "pulled from existing Task Data".

Proposed fix
-  "description": "A dropdown list with options pulled form existing Task Data. Each item should have label and value attributes.",
+  "description": "A dropdown list with options pulled from existing Task Data. Each item should have label and value attributes.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"description": "A dropdown list with options pulled form existing Task Data. Each item should have label and value attributes.",
"description": "A dropdown list with options pulled from existing Task Data. Each item should have label and value attributes.",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@spiffworkflow-frontend/src/resources/json_schema_examples/dropdown-schema.json`
at line 3, Typo in the JSON "description" value: change the word "form" to
"from" in the dropdown schema's description field (the "description" property in
dropdown-schema.json) so it reads "A dropdown list with options pulled from
existing Task Data. Each item should have label and value attributes."; update
only that string value to correct the spelling.

Comment on lines +758 to 764
<CodeMirror
height={'500ps'}
width="auto"
defaultLanguage="json"
options={Object.assign(jsonEditorOptions(), {})}
defaultValue={inputJson}
value={inputJson}
extensions={[json()]}
onChange={handleEditorScriptTestUnitInputChange}
/>
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.

⚠️ Potential issue | 🟡 Minor

Typo in height prop: '500ps' should be '500px'.

Line 759 has a typo in the height value.

Proposed fix
               <CodeMirror
-                height={'500ps'}
+                height={'500px'}
                 width="auto"
                 value={inputJson}
                 extensions={[json()]}
                 onChange={handleEditorScriptTestUnitInputChange}
               />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<CodeMirror
height={'500ps'}
width="auto"
defaultLanguage="json"
options={Object.assign(jsonEditorOptions(), {})}
defaultValue={inputJson}
value={inputJson}
extensions={[json()]}
onChange={handleEditorScriptTestUnitInputChange}
/>
<CodeMirror
height={'500px'}
width="auto"
value={inputJson}
extensions={[json()]}
onChange={handleEditorScriptTestUnitInputChange}
/>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spiffworkflow-frontend/src/views/ProcessModelEditDiagram.tsx` around lines
758 - 764, The CodeMirror component's height prop has a typo ('500ps') causing
invalid styling; update the height prop on the CodeMirror instance (the JSX
where CodeMirror is rendered with value={inputJson} and
onChange={handleEditorScriptTestUnitInputChange}) to use the correct units
'500px' instead of '500ps' so the editor displays at the intended height.

Comment on lines +271 to 278
<CodeMirror
height={600}
width="auto"
defaultLanguage={editorDefaultLanguage}
defaultValue={processModelFileContents || ''}
value={processModelFileContents || ''}
extensions={extensions}
onChange={(value) => setProcessModelFileContents(value || '')}
/>
);
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.

⚠️ Potential issue | 🟡 Minor

CodeMirror height prop should be a string with units.

The height prop is set to the numeric value 600, but CodeMirror expects a string with CSS units (e.g., '600px'). Other editors in this PR use string values like '600px' or '30rem'.

Proposed fix
     return (
       <CodeMirror
-        height={600}
+        height="600px"
         width="auto"
         value={processModelFileContents || ''}
         extensions={extensions}
         onChange={(value) => setProcessModelFileContents(value || '')}
       />
     );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<CodeMirror
height={600}
width="auto"
defaultLanguage={editorDefaultLanguage}
defaultValue={processModelFileContents || ''}
value={processModelFileContents || ''}
extensions={extensions}
onChange={(value) => setProcessModelFileContents(value || '')}
/>
);
<CodeMirror
height="600px"
width="auto"
value={processModelFileContents || ''}
extensions={extensions}
onChange={(value) => setProcessModelFileContents(value || '')}
/>
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spiffworkflow-frontend/src/views/ReactFormEditor.tsx` around lines 271 - 278,
The CodeMirror component is passing a numeric height (600) but expects a CSS
string; update the JSX where CodeMirror is rendered (the CodeMirror element
using props height, value bound to processModelFileContents and onChange calling
setProcessModelFileContents) to pass a string with units like "600px" (or
another appropriate unit) instead of the number so the height prop is correctly
interpreted.

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.

1 participant