diff --git a/fusion_repairs/__manifest__.py b/fusion_repairs/__manifest__.py index f8c2cc6b..bf802654 100644 --- a/fusion_repairs/__manifest__.py +++ b/fusion_repairs/__manifest__.py @@ -4,7 +4,7 @@ { 'name': 'Fusion Repairs', - 'version': '19.0.2.2.0', + 'version': '19.0.2.2.1', 'category': 'Inventory/Repairs', 'summary': 'Guided medical equipment repair intake, dispatch, maintenance, and self-service portal', 'description': """ @@ -52,6 +52,7 @@ Copyright (C) 2024-2026 Nexa Systems Inc. All rights reserved. 'depends': [ 'base', 'mail', + 'html_editor', 'portal', 'website', 'sale_management', diff --git a/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.js b/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.js index 532de5a6..07777bc9 100644 --- a/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.js +++ b/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.js @@ -24,6 +24,8 @@ import { registry } from "@web/core/registry"; import { rpc } from "@web/core/network/rpc"; import { useService } from "@web/core/utils/hooks"; import { loadJS, loadCSS } from "@web/core/assets"; +import { Wysiwyg } from "@html_editor/wysiwyg"; +import { MAIN_PLUGINS } from "@html_editor/plugin_sets"; const DRAWFLOW_JS = "/fusion_repairs/static/src/lib/drawflow/drawflow.min.js"; const DRAWFLOW_CSS = "/fusion_repairs/static/src/lib/drawflow/drawflow.min.css"; @@ -43,6 +45,7 @@ const OUTCOME_COLORS = { export class FlowchartDesigner extends Component { static template = "fusion_repairs.FlowchartDesigner"; + static components = { Wysiwyg }; static props = ["*"]; setup() { @@ -63,6 +66,8 @@ export class FlowchartDesigner extends Component { selectedNodeId: null, dirty: false, saving: false, + // Default to rich-text mode; the user can toggle to raw HTML. + sourceMode: false, // client_id -> drawflow numeric id mapping for new nodes (those // without a DB id yet, created via "Add Node") clientToDfId: {}, @@ -70,6 +75,54 @@ export class FlowchartDesigner extends Component { // outcome_kind, media_ids} nodeMeta: {}, }); + // Per-selected-node Wysiwyg editor instance captured via onLoad. + // Keyed by dfId so switching nodes correctly reads the right editor. + this.wysiwygEditors = {}; + } + + // ------------------------------------------------------------------ + // RICH TEXT EDITOR INTEGRATION + // ------------------------------------------------------------------ + /** + * Build the config object the component expects for the + * currently selected node. Recomputed each render so switching nodes + * re-mounts the editor with the right content (via the t-key on the + * template). + */ + get wysiwygConfig() { + const meta = this.selectedMeta; + return { + content: meta?.content_html || "", + Plugins: MAIN_PLUGINS, + // onChange fires after each edit step - read the current HTML + // from the editor and persist it to selectedMeta + dirty flag. + onChange: () => { + if (!this.state.selectedNodeId) return; + const editor = this.wysiwygEditors[this.state.selectedNodeId]; + if (!editor) return; + const html = editor.getContent(); + this.onEditorFieldChange("content_html", html); + }, + }; + } + + onWysiwygLoad(editor) { + if (this.state.selectedNodeId) { + this.wysiwygEditors[this.state.selectedNodeId] = editor; + } + } + + onToggleSource() { + // Before flipping modes, persist the current editor's content so we + // don't lose unsaved keystrokes. + if (!this.state.sourceMode && this.state.selectedNodeId) { + const editor = this.wysiwygEditors[this.state.selectedNodeId]; + if (editor) { + this.onEditorFieldChange("content_html", editor.getContent()); + } + } + this.state.sourceMode = !this.state.sourceMode; + } onMounted(async () => { await Promise.all([loadJS(DRAWFLOW_JS), loadCSS(DRAWFLOW_CSS)]); diff --git a/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.scss b/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.scss index 874d026a..d5c95cbb 100644 --- a/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.scss +++ b/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.scss @@ -60,7 +60,7 @@ $fr-panel: var(--fr-panel-bg, #{$_fr_panel-hex}); } .fr-designer-editor { - width: 320px; + width: 360px; border-left: 1px solid $fr-border; background: $fr-panel; padding: 12px 14px; @@ -68,6 +68,26 @@ $fr-panel: var(--fr-panel-bg, #{$_fr_panel-hex}); h6 { margin-bottom: 8px; font-weight: 700; } } +// Frame the embedded Odoo Wysiwyg so it visually matches the other +// form-control fields in the right panel (border, padding, scrollable). +.fr-wysiwyg-shell { + border: 1px solid $fr-border; + border-radius: 4px; + background: $fr-card; + min-height: 180px; + max-height: 320px; + overflow-y: auto; + .odoo-editor-editable, .fr-wysiwyg-content { + min-height: 160px; + padding: 8px 10px; + outline: none; + } + .o-we-toolbar, .o_we_toolbar { + // Pin the Wysiwyg toolbar inside the shell so it scrolls with content. + z-index: 2; + } +} + // ----- Node card styling (inside Drawflow's drawflow_content_node) ----- .drawflow .drawflow-node { background: transparent !important; diff --git a/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.xml b/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.xml index 073a64b9..2af756d0 100644 --- a/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.xml +++ b/fusion_repairs/static/src/components/flowchart_designer/flowchart_designer.xml @@ -75,12 +75,35 @@ -
- -