From 211ad0477309386e40ca5fcfbbcc8d22aeb98aaf Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Thu, 16 Feb 2023 14:53:41 +0000 Subject: [PATCH] [FIX] web: Many2One in dialog: open related record in dialog The external button of the Many2one field has been changed with the "always edit" feature of the form view, s.t. it displays by default another icon (a right arrow) and when clicked, opens the related record in another plain screen action instead of a FormViewDialog. However, this doesn't work for Many2One fields that are already in dialogs, because 1) if it's an action dialog (target="new"), that dialog will be closed when opening the related record and the user loses its working context 2) if it's another type of dialog (e.g. FormViewDialog), the related record opens in the background and the dialog remains open, which is obviously a bad UX experiment. This had been locally fixes at some places [2]. This commit fixes the issue by automatically opening the related record in a FormViewDialog if the Many2One is itself already in a dialog. This commit also fixes an issue with the scenario where the related record opens in a dialog: if there were changes done in the main record, those changes where lost when the user clicked on "Save" in the dialog of the related record. We now only reload the display_name of the related record, and apply it to the model. [2] https://github.com/odoo/enterprise/commit/ba0e95fe42696dcf44b8feddeb302f04876fcbdc Task 3191319 closes odoo/odoo#112959 Related: odoo/enterprise#37213 Signed-off-by: Aaron Bohy (aab) --- .../src/views/basic_relational_model.js | 25 ++ .../views/fields/many2one/many2one_field.js | 20 +- .../views/fields/many2one/many2one_field.xml | 2 +- .../views/fields/many2one_field_tests.js | 276 ++++++++++++------ .../views/fields/one2many_field_tests.js | 14 +- .../views/fields/reference_field_tests.js | 71 ++--- .../tests/views/form/form_view_tests.js | 149 ++++++---- addons/web/static/tests/views/helpers.js | 51 +++- .../web/static/tests/views/list_view_tests.js | 55 ++-- .../view_dialogs/form_view_dialog_tests.js | 11 +- .../webclient/actions/window_action_tests.js | 16 +- 11 files changed, 451 insertions(+), 239 deletions(-) diff --git a/addons/web/static/src/views/basic_relational_model.js b/addons/web/static/src/views/basic_relational_model.js index ba4c4ddafce..381dda3096d 100644 --- a/addons/web/static/src/views/basic_relational_model.js +++ b/addons/web/static/src/views/basic_relational_model.js @@ -507,6 +507,31 @@ export class Record extends DataPoint { for (const [fieldName, value] of Object.entries(changes)) { const fieldType = this.fields[fieldName].type; data[fieldName] = mapWowlValueToLegacy(value, fieldType); + // special case for many2ones: they can be updated with a new name (e.g. if edited from + // the dialog), but in the basic_model it worked differently, we had a datapoint for the + // many2one value and we reloaded it directly. In the new model, we directly update the + // value [id, display_name], so we reload beforehand, in the many2one field itself. In + // the next few lines, we thus manually apply the renaming on the legacy datapoint. + if (this.fields[fieldName].type === "many2one" && Array.isArray(changes[fieldName])) { + const newName = changes[fieldName][1]; + if (newName || newName === "") { + const bm = this.model.__bm__; + const m2oDatapointId = bm.get(this.__bm_handle__).data[fieldName].id; + const m2oDatapoint = bm.localData[m2oDatapointId]; + if (m2oDatapoint && m2oDatapoint.data.id === changes[fieldName][0]) { + m2oDatapoint.data.display_name = newName; + } + } + } + // same for reference fields + if (this.fields[fieldName].type === "reference" && changes[fieldName].displayName) { + const bm = this.model.__bm__; + const m2oDatapointId = bm.get(this.__bm_handle__).data[fieldName].id; + const m2oDatapoint = bm.localData[m2oDatapointId]; + if (m2oDatapoint) { + m2oDatapoint.data.display_name = changes[fieldName].displayName; + } + } } if (this._urgentSave) { const fieldNames = await this.model.__bm__.notifyChanges(this.__bm_handle__, data, { diff --git a/addons/web/static/src/views/fields/many2one/many2one_field.js b/addons/web/static/src/views/fields/many2one/many2one_field.js index 360034e22c2..acd6625e1e9 100644 --- a/addons/web/static/src/views/fields/many2one/many2one_field.js +++ b/addons/web/static/src/views/fields/many2one/many2one_field.js @@ -58,11 +58,6 @@ export class Many2OneField extends Component { string: { type: String, optional: true }, canScanBarcode: { type: Boolean, optional: true }, update: { type: Function, optional: true }, - openTarget: { - type: String, - validate: (v) => ["current", "new"].includes(v), - optional: true, - }, }; static defaultProps = { canOpen: true, @@ -74,7 +69,6 @@ export class Many2OneField extends Component { searchLimit: 7, string: "", canScanBarcode: false, - openTarget: "current", }; static SEARCH_MORE_LIMIT = 320; @@ -101,8 +95,11 @@ export class Many2OneField extends Component { activeActions: this.state.activeActions, isToMany: false, onRecordSaved: async (record) => { - await this.props.record.load(); - await this.updateRecord(m2oTupleFromData(record.data)); + const resId = this.props.value[0]; + const fields = ["display_name"]; + const context = this.props.record.getFieldContext(this.props.name); + const records = await this.orm.read(this.relation, [resId], fields, { context }); + await this.updateRecord(m2oTupleFromData(records[0])); if (this.props.record.model.root.id !== this.props.record.id) { this.props.record.switchMode("readonly"); } @@ -237,10 +234,10 @@ export class Many2OneField extends Component { } } onExternalBtnClick() { - if (this.props.openTarget === "current") { - this.openAction(); - } else { + if (this.env.inDialog) { this.openDialog(this.resId); + } else { + this.openAction(); } } async onBarcodeBtnClick() { @@ -309,7 +306,6 @@ export const many2OneField = { canCreateEdit: canCreate && !options.no_create_edit, nameCreateField: options.create_name_field, canScanBarcode: !!options.can_scan_barcode, - openTarget: attrs.open_target, string, }; }, diff --git a/addons/web/static/src/views/fields/many2one/many2one_field.xml b/addons/web/static/src/views/fields/many2one/many2one_field.xml index 7b2f9593381..e65e29427ad 100644 --- a/addons/web/static/src/views/fields/many2one/many2one_field.xml +++ b/addons/web/static/src/views/fields/many2one/many2one_field.xml @@ -46,7 +46,7 @@