diff --git a/addons/web/static/src/views/view_dialogs/export_data_dialog.js b/addons/web/static/src/views/view_dialogs/export_data_dialog.js index ac7047a0eda..371a52378ae 100644 --- a/addons/web/static/src/views/view_dialogs/export_data_dialog.js +++ b/addons/web/static/src/views/view_dialogs/export_data_dialog.js @@ -27,15 +27,21 @@ class ExportDataItem extends Component { }); } - async onClick(ev) { + async onClick() { if (this.props.isFieldExpandable(this.props.field)) { - this.subFields = await this.props.onClick(ev); - this.state.isExpanded = this.props.isFieldExpanded(this.props.field.name); + this.subFields = await this.props.onClick(this.props.field.id); + this.state.isExpanded = this.props.isFieldExpanded(this.props.field.id); + } + } + + onDoubleClick(fieldId) { + if (!this.props.isFieldExpandable(this.props.field) && !this.isFieldSelected(fieldId)) { + this.props.onAdd(fieldId); } } isFieldSelected(current) { - return this.props.exportList.find(({ name }) => name === current); + return this.props.exportList.find(({ id }) => id === current); } } ExportDataItem.template = "web.ExportDataItem"; @@ -94,7 +100,7 @@ export class ExportDataDialog extends Component { (e) => e && Object.values(this.state.exportList).findIndex( - ({ name }) => name === e.dataset.field_id + ({ id }) => id === e.dataset.field_id ) ); let target; @@ -103,7 +109,7 @@ export class ExportDataDialog extends Component { } else { target = next ? indexes[2] : this.state.exportList.length - 1; } - this.onDraggingEnd([indexes[0], target]); + this.onDraggingEnd(indexes[0], target); }, }); @@ -154,7 +160,7 @@ export class ExportDataDialog extends Component { this.state.search = []; this.knownFields = {}; await this.loadFields(); - this.setDefaultExportList(); + await this.setDefaultExportList(); if (this.searchRef.el) { this.searchRef.el.value = ""; } @@ -177,8 +183,8 @@ export class ExportDataDialog extends Component { return this.expandedFields[id] && !this.expandedFields[id].hidden; } - isFieldExpandable({ name }) { - return this.knownFields[name].children && name.split("/").length < 3; + isFieldExpandable({ id }) { + return this.knownFields[id].children && id.split("/").length < 3; } async loadExportList(value) { @@ -219,7 +225,6 @@ export class ExportDataDialog extends Component { parentParams ); for (const field of fields) { - field.name = field.id; field.label = field.string; field.parent = parentField; if (!this.knownFields[field.id]) { @@ -232,22 +237,19 @@ export class ExportDataDialog extends Component { return fields; } - onDraggingEnd([item, target]) { + onDraggingEnd(item, target) { this.state.exportList.splice(target, 0, this.state.exportList.splice(item, 1)[0]); } - onAddItemExportList(ev) { - const field = ev.target.closest(".o_export_tree_item").dataset.field_id; - this.state.exportList.push(this.knownFields[field]); + onAddItemExportList(fieldId) { + this.state.exportList.push(this.knownFields[fieldId]); this.state.search = []; this.searchRef.el.value = ""; this.enterTemplateEdition(); } - onRemoveItemExportList(ev) { - const item = this.state.exportList.findIndex( - ({ name }) => name === ev.target.parentElement.dataset.field_id - ); + onRemoveItemExportList(fieldId) { + const item = this.state.exportList.findIndex(({ id }) => id === fieldId); this.state.exportList.splice(item, 1); this.enterTemplateEdition(); } @@ -272,7 +274,7 @@ export class ExportDataDialog extends Component { 0, 0, { - name: field.name, + name: field.id, }, ]), resource: this.props.root.resModel, @@ -334,25 +336,19 @@ export class ExportDataDialog extends Component { ); } - async onToggleCompatibleExport(value) { + onToggleCompatibleExport(value) { this.state.isCompatible = value; - await this.fetchFields(); + this.fetchFields(); } - async onToggleExpandField(ev) { - const id = ev.target.closest(".o_export_tree_item").dataset.field_id; - const fields = await this.loadFields(id); - return fields; + onToggleExpandField(id) { + return this.loadFields(id); } - setDefaultExportList() { - if (this.state.isCompatible) { - this.state.exportList = this.state.exportList.filter( - ({ name }) => this.knownFields[name] - ); - } else { - this.state.exportList = this.props.defaultExportList; - } + async setDefaultExportList() { + this.state.exportList = Object.values(this.knownFields).filter( + (e) => e.default_export || this.props.defaultExportList.find((i) => i.name === e.id) + ); } setFormat(ev) { diff --git a/addons/web/static/src/views/view_dialogs/export_data_dialog.xml b/addons/web/static/src/views/view_dialogs/export_data_dialog.xml index 7e0ac756a7b..a91432fcc15 100644 --- a/addons/web/static/src/views/view_dialogs/export_data_dialog.xml +++ b/addons/web/static/src/views/view_dialogs/export_data_dialog.xml @@ -12,15 +12,15 @@ -
+
- +
- +
- +
    - -
  • + +
  • - +
diff --git a/addons/web/static/tests/views/view_dialogs/export_data_dialog_tests.js b/addons/web/static/tests/views/view_dialogs/export_data_dialog_tests.js index 569c1cfd2b4..3a6ee190f5c 100644 --- a/addons/web/static/tests/views/view_dialogs/export_data_dialog_tests.js +++ b/addons/web/static/tests/views/view_dialogs/export_data_dialog_tests.js @@ -98,7 +98,7 @@ QUnit.module("ViewDialogs", (hooks) => { }, { children: false, - field_type: "char", + field_type: "boolean", id: "bar", relation_field: null, required: false, @@ -636,7 +636,19 @@ QUnit.module("ViewDialogs", (hooks) => { } if (route === "/web/export/get_fields") { if (!args.parent_field) { - return Promise.resolve(fetchedFields.root); + return Promise.resolve([ + ...fetchedFields.root, + { + id: "not_exportable", + string: "Not exportable", + type: "char", + exportable: false, + }, + { + id: "exportable", + string: "Exportable", + }, + ]); } if (args.prefix === "partner_ids") { assert.step("fetch fields for 'partner_ids'"); @@ -973,4 +985,46 @@ QUnit.module("ViewDialogs", (hooks) => { "the field to export corresponds to the field displayed in the list view" ); }); + + QUnit.test( + "Export dialog: export list contains field with 'default_export: true'", + async function (assert) { + await makeView({ + serverData, + type: "list", + resModel: "partner", + arch: ` + + `, + actionMenus: {}, + mockRPC(route, args) { + if (route === "/web/export/formats") { + return Promise.resolve([{ tag: "csv", label: "CSV" }]); + } + if (route === "/web/export/get_fields") { + if (!args.parent_field) { + return Promise.resolve([ + ...fetchedFields.root, + { + id: "default_exportable", + string: "Default exportable", + type: "char", + default_export: true, + }, + ]); + } + return Promise.resolve(fetchedFields[args.prefix]); + } + }, + }); + + await openExportDataDialog(); + assert.containsN(target, ".o_export_field", 2, "two fields are selected in the list"); + assert.strictEqual( + target.querySelector(".o_fields_list").textContent, + "FooDefault exportable", + "values are the correct ones" + ); + } + ); });