feat(fusion_repairs): flowchart designer node content uses Odoo Wysiwyg

Replace the plain <textarea> in the flowchart designer's node-editor
right-panel with Odoo 19's native rich text editor so admins write
formatted prose / lists / bold / links / inline images without typing
HTML tags. The raw <textarea> stays available behind a toggle for the
power-user case (pasting markup from elsewhere, debugging).

CHANGES

manifest:
  - depends += 'html_editor' (provides @html_editor/wysiwyg)
  - bumped to 19.0.2.2.1

components/flowchart_designer/flowchart_designer.js:
  - import { Wysiwyg } from '@html_editor/wysiwyg'
  - import { MAIN_PLUGINS } from '@html_editor/plugin_sets'
  - register Wysiwyg in static components
  - state.sourceMode boolean (default false = rich text mode)
  - wysiwygConfig getter builds the EditorConfig for the SELECTED node;
    onChange reads editor.getContent() and writes back into the same
    selectedMeta.content_html the rest of the designer already uses,
    so the save path is unchanged
  - onWysiwygLoad(editor) captures the editor instance per dfId so the
    onChange callback can resolve the right one when nodes switch
  - onToggleSource flushes the current editor's content before flipping
    modes so unsaved keystrokes don't get lost

components/flowchart_designer/flowchart_designer.xml:
  - replaced <textarea>...</textarea> with a conditional block:
      sourceMode == false -> <Wysiwyg t-key="'wysiwyg-' + selectedNodeId"
                                       config="wysiwygConfig"
                                       onLoad="onWysiwygLoad.bind(this)"/>
      sourceMode == true  -> <textarea class="font-monospace" rows="10"/>
  - t-key forces the editor to re-mount with the freshly-selected node's
    content; otherwise switching nodes would keep showing the first
    selected node's HTML
  - new toolbar row above the editor has a "HTML Source" / "Rich Text"
    toggle button (eye / code icons) so the user can flip at will
  - hint text updated to reflect what each mode supports

components/flowchart_designer/flowchart_designer.scss:
  - widened the right editor panel from 320px to 360px to give the
    Wysiwyg toolbar room to breathe
  - new .fr-wysiwyg-shell rule frames the embedded editor with the same
    border + background as the other form-controls in the panel, with
    a min-height of 180px and max-height 320px so it scrolls when the
    content grows. Pins .o-we-toolbar inside the shell so it stays in
    view as the user scrolls long content.

The save path, the runtime renderer, and the data model are unchanged -
content_html is still sanitised HTML stored on fusion.repair.flowchart.node.

Verified on local westin-v19:
  - upgrade clean (no errors, no warnings)
  - login serves 200 after restart
  - 4 stale asset bundles flushed; Drawflow JS still served 46KB at
    /fusion_repairs/static/src/lib/drawflow/drawflow.min.js
  - Wysiwyg export confirmed at
    /usr/lib/python3/dist-packages/odoo/addons/html_editor/static/src/wysiwyg.js:25
  - MAIN_PLUGINS export confirmed at plugin_sets.js:103

Bumped to 19.0.2.2.1.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
gsinghpal
2026-05-27 13:18:27 -04:00
parent 134c94fc6c
commit b22bb11b31
4 changed files with 105 additions and 8 deletions

View File

@@ -75,12 +75,35 @@
<option value="order_part" t-att-selected="selectedMeta.outcome_kind === 'order_part'">Order part</option>
</select>
</div>
<div class="mb-2">
<label class="form-label small mb-1">Content (shown to CS)</label>
<textarea class="form-control form-control-sm" rows="6"
t-on-change="(ev) => this.onEditorFieldChange('content_html', ev.target.value)"
t-out="selectedMeta.content_html"/>
<div class="form-text">HTML allowed: lists, bold, links.</div>
<div class="mb-2 fr-content-editor">
<div class="d-flex justify-content-between align-items-center mb-1">
<label class="form-label small mb-0">Content (shown to CS)</label>
<button type="button"
class="btn btn-link btn-sm p-0"
t-on-click="onToggleSource">
<i t-att-class="state.sourceMode ? 'fa fa-eye' : 'fa fa-code'"/>
<t t-if="state.sourceMode"> Rich Text</t>
<t t-else=""> HTML Source</t>
</button>
</div>
<!-- Rich text (default) - re-mounts when selecting a different node via t-key. -->
<t t-if="!state.sourceMode">
<div class="fr-wysiwyg-shell">
<Wysiwyg t-key="'wysiwyg-' + state.selectedNodeId"
config="wysiwygConfig"
onLoad="onWysiwygLoad.bind(this)"
contentClass="'fr-wysiwyg-content'"/>
</div>
<div class="form-text">Bold, italic, lists, links and inline images supported. Click <em>HTML Source</em> to paste raw markup.</div>
</t>
<!-- HTML source mode (toggle) - power user escape hatch. -->
<t t-else="">
<textarea class="form-control form-control-sm font-monospace"
rows="10"
t-on-change="(ev) => this.onEditorFieldChange('content_html', ev.target.value)"
t-out="selectedMeta.content_html"/>
<div class="form-text">Raw HTML mode - what you type is rendered as-is.</div>
</t>
</div>
<div class="mb-2">
<label class="form-label small mb-1">