diff options
| author | Aaron Bohy <aab@odoo.com> | 2015-06-24 10:41:00 +0200 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2015-06-25 15:44:42 +0200 |
| commit | 230af351544d5486c305d8b3d340d8f1b00abdd7 (patch) | |
| tree | fc773bb31398f644b451f5482c223b84aaad87b7 /addons/web/static/src/js/views | |
| parent | 5490aad0c943af255424c71247d7b09b7a95f628 (diff) | |
[IMP] web: ViewManager for One2Many and Many2Many fields
This rev. generalizes the notions of FieldOne2Many to FieldX2Many and of One2ManyViewManager
to X2ManyViewManager. The same logic is now applied both for One2Many and Many2Many fields.
This allows Many2Many list and kanban views to have a pager, as the pager is instanciated
by the view, on demand of the ViewManager.
Diffstat (limited to 'addons/web/static/src/js/views')
| -rw-r--r-- | addons/web/static/src/js/views/form_relational_widgets.js | 733 |
1 files changed, 320 insertions, 413 deletions
diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js index 771851f5b9b..5dc1a76decf 100644 --- a/addons/web/static/src/js/views/form_relational_widgets.js +++ b/addons/web/static/src/js/views/form_relational_widgets.js @@ -433,67 +433,6 @@ var FieldMany2One = common.AbstractField.extend(common.CompletionFieldMixin, com }); /** - * Abstract-ish ListView.List subclass adding an "Add an item" row to replace - * the big ugly button in the header. - * - * Requires the implementation of a ``is_readonly`` method (usually a proxy to - * the corresponding field's readonly or effective_readonly property) to - * decide whether the special row should or should not be inserted. - * - * Optionally an ``_add_row_class`` attribute can be set for the class(es) to - * set on the insertion row. - */ -var AddAnItemList = ListView.List.extend({ - pad_table_to: function (count) { - if (!this.view.is_action_enabled('create') || this.is_readonly()) { - this._super(count); - return; - } - - this._super(count > 0 ? count - 1 : 0); - - var self = this; - var columns = _(this.columns).filter(function (column) { - return column.invisible !== '1'; - }).length; - if (this.options.selectable) { columns++; } - if (this.options.deletable) { columns++; } - - var $cell = $('<td>', { - colspan: columns, - 'class': this._add_row_class || '' - }).append( - $('<a>', {href: '#'}).text(_t("Add an item")) - .mousedown(function () { - // FIXME: needs to be an official API somehow - if (self.view.editor.is_editing()) { - self.view.__ignore_blur = true; - } - }) - .click(function (e) { - e.preventDefault(); - e.stopPropagation(); - // FIXME: there should also be an API for that one - if (self.view.editor.form.__blur_timeout) { - clearTimeout(self.view.editor.form.__blur_timeout); - self.view.editor.form.__blur_timeout = false; - } - self.view.ensure_saved().done(function () { - self.view.do_add_record(); - }); - })); - - var $padding = this.$current.find('tr:not([data-id]):first'); - var $newrow = $('<tr>').append($cell); - if ($padding.length) { - $padding.before($newrow); - } else { - this.$current.append($newrow); - } - } -}); - -/** * A Abstract field for one2many and many2many field * For all fields on2many or many2many: * - this.get('value') contains a list of ids and virtual ids @@ -503,8 +442,8 @@ var AbstractManyField = common.AbstractField.extend({ init: function(field_manager, node) { var self = this; this._super(field_manager, node); - this.dataset = new One2ManyDataSet(this, this.field.relation, this.build_context()); - this.dataset.o2m = this; + this.dataset = new X2ManyDataSet(this, this.field.relation, this.build_context()); + this.dataset.x2m = this; this.dataset.parent_view = this.view; this.dataset.child_name = this.name; this.set('value', []); @@ -748,10 +687,12 @@ var AbstractManyField = common.AbstractField.extend({ } }); - -var FieldOne2Many = AbstractManyField.extend({ +var FieldX2Many = AbstractManyField.extend({ multi_selection: false, disable_utility_classes: true, + x2many_views: {}, + view_options: {}, + default_view: 'tree', init: function(field_manager, node) { this._super(field_manager, node); @@ -762,11 +703,11 @@ var FieldOne2Many = AbstractManyField.extend({ }, start: function() { this._super.apply(this, arguments); - this.$el.addClass('oe_form_field oe_form_field_one2many'); + this.$el.addClass('oe_form_field'); var self = this; - self.load_views(); + this.load_views(); var destroy = function() { self.is_loaded = self.is_loaded.then(function() { self.viewmanager.destroy(); @@ -778,27 +719,27 @@ var FieldOne2Many = AbstractManyField.extend({ this.is_loaded.done(function() { self.on("change:effective_readonly", self, destroy); }); - this.view.on("on_button_cancel", self, destroy); + this.view.on("on_button_cancel", this, destroy); this.is_started = true; this.reload_current_view(); }, load_views: function() { var self = this; - var modes = this.node.attrs.mode; - modes = !!modes ? modes.split(",") : ["tree"]; + var view_types = this.node.attrs.mode; + view_types = !!view_types ? view_types.split(",") : [this.default_view]; var views = []; - _.each(modes, function(mode) { - if (! _.include(["list", "tree", "graph", "kanban"], mode)) { - throw new Error(_.str.sprintf(_t("View type '%s' is not supported in One2Many."), mode)); + _.each(view_types, function(view_type) { + if (! _.include(["list", "tree", "graph", "kanban"], view_type)) { + throw new Error(_.str.sprintf(_t("View type '%s' is not supported in X2Many."), view_type)); } var view = { view_id: false, - view_type: mode == "tree" ? "list" : mode, + view_type: view_type === "tree" ? "list" : view_type, options: {} }; - if (self.field.views && self.field.views[mode]) { - view.embedded_view = self.field.views[mode]; + if (self.field.views && self.field.views[view_type]) { + view.embedded_view = self.field.views[view_type]; } if(view.view_type === "list") { _.extend(view.options, { @@ -831,13 +772,13 @@ var FieldOne2Many = AbstractManyField.extend({ }); this.views = views; - this.viewmanager = new One2ManyViewManager(this, this.dataset, views, {}); - this.viewmanager.o2m = self; + this.viewmanager = new X2ManyViewManager(this, this.dataset, views, this.view_options, this.x2many_views); + this.viewmanager.x2m = self; var def = $.Deferred().done(function() { self.initial_is_loaded.resolve(); }); this.viewmanager.on("controller_inited", self, function(view_type, controller) { - controller.o2m = self; + controller.x2m = self; if (view_type == "list") { if (self.get("effective_readonly")) { controller.on('edit:before', self, function (e) { @@ -927,9 +868,9 @@ var FieldOne2Many = AbstractManyField.extend({ }, }); -var One2ManyDataSet = data.BufferedDataSet.extend({ +var X2ManyDataSet = data.BufferedDataSet.extend({ get_context: function() { - this.context = this.o2m.build_context(); + this.context = this.x2m.build_context(); return this.context; }, create: function(data, options) { @@ -944,29 +885,62 @@ var One2ManyDataSet = data.BufferedDataSet.extend({ }, }); -var One2ManyListView = ListView.extend({ - _template: 'One2Many.listview', - init: function (parent, dataset, view_id, options) { - this._super(parent, dataset, view_id, _.extend(options || {}, { - GroupsType: One2ManyGroups, - ListType: One2ManyList - })); - this.on('edit:after', this, this.proxy('_after_edit')); - this.on('save:before cancel:before', this, this.proxy('_before_unedit')); - - /* detect if the user try to exit the one2many widget */ +var X2ManyViewManager = ViewManager.extend({ + init: function(parent, dataset, views, flags, x2many_views) { + // By default, render buttons and pager in X2M fields, but no sidebar + var flags = _.extend({}, flags, { + headless: false, + search_view: false, + action_buttons: true, + pager: true, + sidebar: false, + }); + this.control_panel = new ControlPanel(parent, "X2ManyControlPanel"); + this.set_cp_bus(this.control_panel.get_bus()); + this._super(parent, dataset, views, flags); + this.registry = core.view_registry.extend(x2many_views); + this.__ignore_blur = false; + }, + start: function() { + this.control_panel.prependTo(this.$el); + return this._super(); + }, + switch_mode: function(mode, unused) { + if (mode !== 'form') { + return this._super(mode, unused); + } var self = this; - this._mousedown_blur_line = function (event) { - if (self.__focus) { - self.__ignore_blur = true; - if ($(event.target).closest("button, *:not(.oe_form_field_one2many_list_row_add) > a").length || - (!$(event.target).closest(self.editor.$el[0]).length && !$(event.target).closest(self.$el[0]).length)) { - self.__ignore_blur = false; - } - } - }; - $(document).on('mousedown', this._mousedown_blur_line); + var id = self.x2m.dataset.index !== null ? self.x2m.dataset.ids[self.x2m.dataset.index] : null; + var pop = new common.FormViewDialog(this, { + res_model: self.x2m.field.relation, + res_id: id, + context: self.x2m.build_context(), + + title: _t("Open: ") + self.x2m.string, + create_function: function(data, options) { + return self.x2m.data_create(data, options); + }, + write_function: function(id, data, options) { + return self.x2m.data_update(id, data, {}).done(function() { + self.x2m.reload_current_view(); + }); + }, + alternative_form_view: self.x2m.field.views ? self.x2m.field.views.form : undefined, + parent_view: self.x2m.view, + child_name: self.x2m.name, + read_function: function(ids, fields, options) { + return self.x2m.data_read(ids, fields, options); + }, + form_view_options: {'not_interactible_on_create':true}, + readonly: self.x2m.get("effective_readonly") + }).open(); + pop.on("elements_selected", self, function() { + self.x2m.reload_current_view(); + }); }, +}); + +var X2ManyListView = ListView.extend({ is_valid: function () { var self = this; if (!this.fields_view || !this.editable()){ @@ -998,29 +972,108 @@ var One2ManyListView = ListView.extend({ }); return valid; }, +}); + +/** + * ListView.List subclass adding an "Add an item" row to replace the Create + * button in the ControlPanel. + */ +var X2ManyList = ListView.List.extend({ + pad_table_to: function (count) { + if (!this.view.is_action_enabled('create') || this.view.x2m.get('effective_readonly')) { + this._super(count); + return; + } + + this._super(count > 0 ? count - 1 : 0); + + var self = this; + var columns = _(this.columns).filter(function (column) { + return column.invisible !== '1'; + }).length; + if (this.options.selectable) { columns++; } + if (this.options.deletable) { columns++; } + + var $cell = $('<td>', { + colspan: columns, + 'class': 'oe_form_field_x2many_list_row_add' + }).append( + $('<a>', {href: '#'}).text(_t("Add an item")) + .mousedown(function () { + // FIXME: needs to be an official API somehow + if (self.view.editor.is_editing()) { + self.view.__ignore_blur = true; + } + }) + .click(function (e) { + e.preventDefault(); + e.stopPropagation(); + // FIXME: there should also be an API for that one + if (self.view.editor.form.__blur_timeout) { + clearTimeout(self.view.editor.form.__blur_timeout); + self.view.editor.form.__blur_timeout = false; + } + self.view.ensure_saved().done(function () { + self.view.do_add_record(); + }); + })); + + var $padding = this.$current.find('tr:not([data-id]):first'); + var $newrow = $('<tr>').append($cell); + if ($padding.length) { + $padding.before($newrow); + } else { + this.$current.append($newrow); + } + }, +}); + +var One2ManyListView = X2ManyListView.extend({ + _template: 'One2Many.listview', + init: function (parent, dataset, view_id, options) { + this._super(parent, dataset, view_id, _.extend(options || {}, { + GroupsType: One2ManyGroups, + ListType: X2ManyList + })); + this.on('edit:after', this, this.proxy('_after_edit')); + this.on('save:before cancel:before', this, this.proxy('_before_unedit')); + + /* detect if the user try to exit the one2many widget */ + var self = this; + this._mousedown_blur_line = function (event) { + if (self.__focus) { + self.__ignore_blur = true; + if ($(event.target).closest("button, *:not(.oe_form_field_x2many_list_row_add) > a").length || + (!$(event.target).closest(self.editor.$el[0]).length && !$(event.target).closest(self.$el[0]).length)) { + self.__ignore_blur = false; + } + } + }; + $(document).on('mousedown', this._mousedown_blur_line); + }, do_add_record: function () { if (this.editable()) { this._super.apply(this, arguments); } else { var self = this; new common.SelectCreateDialog(this, { - res_model: self.o2m.field.relation, - domain: self.o2m.build_domain(), - context: self.o2m.build_context(), - title: _t("Create: ") + self.o2m.string, + res_model: self.x2m.field.relation, + domain: self.x2m.build_domain(), + context: self.x2m.build_context(), + title: _t("Create: ") + self.x2m.string, initial_view: "form", - alternative_form_view: self.o2m.field.views ? self.o2m.field.views.form : undefined, + alternative_form_view: self.x2m.field.views ? self.x2m.field.views.form : undefined, create_function: function(data, options) { - return self.o2m.data_create(data, options); + return self.x2m.data_create(data, options); }, read_function: function(ids, fields, options) { - return self.o2m.data_read(ids, fields, options); + return self.x2m.data_read(ids, fields, options); }, - parent_view: self.o2m.view, - child_name: self.o2m.name, + parent_view: self.x2m.view, + child_name: self.x2m.name, form_view_options: {'not_interactible_on_create':true}, on_selected: function() { - self.o2m.reload_current_view(); + self.x2m.reload_current_view(); } }).open(); } @@ -1028,23 +1081,23 @@ var One2ManyListView = ListView.extend({ do_activate_record: function(index, id) { var self = this; new common.FormViewDialog(self, { - res_model: self.o2m.field.relation, + res_model: self.x2m.field.relation, res_id: id, - context: self.o2m.build_context(), - title: _t("Open: ") + self.o2m.string, + context: self.x2m.build_context(), + title: _t("Open: ") + self.x2m.string, write_function: function(id, data) { - return self.o2m.data_update(id, data, {}).done(function() { - self.o2m.reload_current_view(); + return self.x2m.data_update(id, data, {}).done(function() { + self.x2m.reload_current_view(); }); }, - alternative_form_view: self.o2m.field.views ? self.o2m.field.views.form : undefined, - parent_view: self.o2m.view, - child_name: self.o2m.name, + alternative_form_view: self.x2m.field.views ? self.x2m.field.views.form : undefined, + parent_view: self.x2m.view, + child_name: self.x2m.name, read_function: function(ids, fields, options) { - return self.o2m.data_read(ids, fields, options); + return self.x2m.data_read(ids, fields, options); }, form_view_options: {'not_interactible_on_create':true}, - readonly: !this.is_action_enabled('edit') || self.o2m.get("effective_readonly") + readonly: !this.is_action_enabled('edit') || self.x2m.get("effective_readonly") }).open(); }, do_button_action: function (name, id, callback) { @@ -1054,7 +1107,7 @@ var One2ManyListView = ListView.extend({ _t("The o2m record must be saved before an action can be used")); return; } - var parent_form = this.o2m.view; + var parent_form = this.x2m.view; var self = this; this.ensure_saved().then(function () { if (parent_form) @@ -1062,15 +1115,15 @@ var One2ManyListView = ListView.extend({ else return $.when(); }).done(function () { - var ds = self.o2m.dataset; + var ds = self.x2m.dataset; var cached_records = _.any([ds.to_create, ds.to_delete, ds.to_write], function(value) { return value.length; }); - if (!self.o2m.options.reload_on_button && !cached_records) { + if (!self.x2m.options.reload_on_button && !cached_records) { self.handle_button(name, id, callback); }else { self.handle_button(name, id, function(){ - self.o2m.view.reload(); + self.x2m.view.reload(); }); } }); @@ -1092,7 +1145,7 @@ var One2ManyListView = ListView.extend({ return this._super(); }, _on_focus_one2many: function () { - this.dataset.o2m.internal_dataset_changed = true; + this.dataset.x2m.internal_dataset_changed = true; this.__focus = true; }, _on_blur_one2many: function (force) { @@ -1105,7 +1158,7 @@ var One2ManyListView = ListView.extend({ } this.__focus = false; - this.dataset.o2m.internal_dataset_changed = false; + this.dataset.x2m.internal_dataset_changed = false; if (this.editor.form.is_dirty()) { def = this.ensure_saved(); @@ -1114,7 +1167,7 @@ var One2ManyListView = ListView.extend({ } def.then(function () { - if (self.dataset.o2m.has_not_committed_changes) { + if (self.dataset.x2m.has_not_committed_changes) { self.dataset.trigger('dataset_changed'); } }); @@ -1124,7 +1177,7 @@ var One2ManyListView = ListView.extend({ this.editor.form.on('blurred', this, this._on_blur_one2many); // The form's blur thing may be jiggered during the edition setup, - // potentially leading to the o2m instasaving the row. Cancel any + // potentially leading to the x2m instasaving the row. Cancel any // blurring triggered the edition startup here this.editor.form.widgetFocused(); }, @@ -1156,19 +1209,12 @@ var One2ManyListView = ListView.extend({ var One2ManyGroups = ListView.Groups.extend({ setup_resequence_rows: function () { - if (!this.view.o2m.get('effective_readonly')) { + if (!this.view.x2m.get('effective_readonly')) { this._super.apply(this, arguments); } } }); -var One2ManyList = AddAnItemList.extend({ - _add_row_class: 'oe_form_field_one2many_list_row_add', - is_readonly: function () { - return this.view.o2m.get('effective_readonly'); - }, -}); - var One2ManyFormView = FormView.extend({ form_template: 'One2Many.formview', load_form: function(data) { @@ -1187,62 +1233,96 @@ var One2ManyFormView = FormView.extend({ } }); -var One2ManyViewManager = ViewManager.extend({ - init: function(parent, dataset, views, flags) { - // By default, render buttons and pager in O2M fields, but no sidebar - var flags = _.extend({}, flags, { - headless: false, - search_view: false, - action_buttons: true, - pager: true, - sidebar: false, - }); - this.control_panel = new ControlPanel(parent, "One2ManyControlPanel"); - this.set_cp_bus(this.control_panel.get_bus()); - this._super(parent, dataset, views, flags); - this.registry = core.view_registry.extend({ - list: One2ManyListView, - form: One2ManyFormView, - }); - this.__ignore_blur = false; +var FieldOne2Many = FieldX2Many.extend({ + x2many_views: { + list: One2ManyListView, + form: One2ManyFormView, }, start: function() { - this.control_panel.prependTo(this.$el); - return this._super(); + this.$el.addClass('oe_form_field_one2many'); + return this._super.apply(this, arguments); + } +}); + +/** + * @class + * @extends instance.web.ListView + */ +var Many2ManyListView = X2ManyListView.extend(/** @lends instance.web.form.Many2ManyListView# */{ + init: function (parent, dataset, view_id, options) { + this._super(parent, dataset, view_id, _.extend(options || {}, { + ListType: X2ManyList, + })); }, - switch_mode: function(mode, unused) { - if (mode !== 'form') { - return this._super(mode, unused); - } + do_add_record: function () { + var self = this; + + new common.SelectCreateDialog(this, { + res_model: this.model, + domain: new data.CompoundDomain(this.x2m.build_domain(), ["!", ["id", "in", this.x2m.dataset.ids]]), + context: this.x2m.build_context(), + title: _t("Add: ") + this.x2m.string, + alternative_form_view: this.x2m.field.views ? this.x2m.field.views.form : undefined, + no_create: this.x2m.options.no_create, + on_selected: function(element_ids) { + return self.x2m.data_link_multi(element_ids).then(function() { + self.x2m.reload_current_view(); + }); + } + }).open(); + }, + do_activate_record: function(index, id) { var self = this; - var id = self.o2m.dataset.index !== null ? self.o2m.dataset.ids[self.o2m.dataset.index] : null; var pop = new common.FormViewDialog(this, { - res_model: self.o2m.field.relation, + res_model: this.dataset.model, res_id: id, - context: self.o2m.build_context(), - - title: _t("Open: ") + self.o2m.string, - create_function: function(data, options) { - return self.o2m.data_create(data, options); - }, - write_function: function(id, data, options) { - return self.o2m.data_update(id, data, {}).done(function() { - self.o2m.reload_current_view(); - }); - }, - alternative_form_view: self.o2m.field.views ? self.o2m.field.views.form : undefined, - parent_view: self.o2m.view, - child_name: self.o2m.name, - read_function: function(ids, fields, options) { - return self.o2m.data_read(ids, fields, options); - }, - form_view_options: {'not_interactible_on_create':true}, - readonly: self.o2m.get("effective_readonly") + context: this.x2m.build_context(), + title: _t("Open: ") + this.x2m.string, + alternative_form_view: this.x2m.field.views ? this.x2m.field.views.form : undefined, + readonly: !this.is_action_enabled('edit') || self.x2m.get("effective_readonly"), }).open(); - pop.on("elements_selected", self, function() { - self.o2m.reload_current_view(); + pop.on('write_completed', self, function () { + self.dataset.evict_record(id); + self.reload_content(); }); }, + do_button_action: function(name, id, callback) { + var self = this; + var _sup = _.bind(this._super, this); + if (! this.x2m.options.reload_on_button) { + return _sup(name, id, callback); + } else { + return this.x2m.view.save().then(function() { + return _sup(name, id, function() { + self.x2m.view.reload(); + }); + }); + } + }, +}); + +var FieldMany2Many = FieldX2Many.extend({ + init: function() { + this._super.apply(this, arguments); + this.x2many_views = { + list: Many2ManyListView, + kanban: core.view_registry.get('many2many_kanban'), + }; + }, + start: function() { + this.$el.addClass('oe_form_field_many2many'); + return this._super.apply(this, arguments); + } +}); + +var FieldMany2ManyKanban = FieldMany2Many.extend({ + default_view: 'kanban', + init: function() { + this._super.apply(this, arguments); + this.view_options = _.extend({}, this.view_options, { + 'create_text': _t("Add"), + }); + } }); var FieldMany2ManyTags = AbstractManyField.extend(common.CompletionFieldMixin, common.ReinitializeFieldMixin, { @@ -1343,234 +1423,6 @@ var FieldMany2ManyTags = AbstractManyField.extend(common.CompletionFieldMixin, c }); /** - widget options: - - reload_on_button: Reload the whole form view if click on a button in a list view. - If you see this options, do not use it, it's basically a dirty hack to make one - precise o2m to behave the way we want. -*/ -var FieldMany2Many = AbstractManyField.extend(common.ReinitializeFieldMixin, { - multi_selection: false, - disable_utility_classes: true, - init: function(field_manager, node) { - this._super(field_manager, node); - this.is_loaded = $.Deferred(); - this.set_value([]); - this.list_dm = new utils.DropMisordered(); - this.render_value_dm = new utils.DropMisordered(); - }, - initialize_content: function() { - var self = this; - - this.$el.addClass('oe_form_field oe_form_field_many2many'); - - this.list_view = new Many2ManyListView(this, this.dataset, false, { - 'addable': null, - 'deletable': this.get("effective_readonly") ? false : true, - 'selectable': this.multi_selection, - 'sortable': false, - 'reorderable': false, - 'import_enabled': false, - }); - var embedded = (this.field.views || {}).tree; - if (embedded) { - this.list_view.set_embedded_view(embedded); - } - this.list_view.m2m_field = this; - var loaded = $.Deferred(); - this.list_view.on("list_view_loaded", this, function() { - loaded.resolve(); - }); - this.list_view.appendTo(this.$el); - - var old_def = self.is_loaded; - self.is_loaded = $.Deferred().done(function() { - old_def.resolve(); - }); - this.list_dm.add(loaded).then(function() { - self.is_loaded.resolve(); - }); - }, - destroy_content: function() { - this.list_view.destroy(); - this.list_view = undefined; - }, - render_value: function() { - var self = this; - var time; - this.render_value_dm.add(this.is_loaded).then(function() { - clearTimeout(time); - time = setTimeout(function () { - self.list_view.reload_content(); - }, 0); - }); - } -}); - -var Many2ManyDataSet = data.DataSetStatic.extend({ - get_context: function() { - this.context = this.m2m.build_context(); - return this.context; - } -}); - -/** - * @class - * @extends instance.web.ListView - */ -var Many2ManyListView = ListView.extend(/** @lends instance.web.form.Many2ManyListView# */{ - init: function (parent, dataset, view_id, options) { - this._super(parent, dataset, view_id, _.extend(options || {}, { - ListType: Many2ManyList, - })); - }, - do_add_record: function () { - var self = this; - - new common.SelectCreateDialog(this, { - res_model: this.model, - domain: new data.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]), - context: this.m2m_field.build_context(), - title: _t("Add: ") + this.m2m_field.string, - alternative_form_view: this.m2m_field.field.views ? this.m2m_field.field.views.form : undefined, - no_create: this.m2m_field.options.no_create, - on_selected: function(element_ids) { - return self.dataset.o2m.data_link_multi(element_ids); - } - }).open(); - }, - do_activate_record: function(index, id) { - var self = this; - var pop = new common.FormViewDialog(this, { - res_model: this.dataset.model, - res_id: id, - context: this.m2m_field.build_context(), - title: _t("Open: ") + this.m2m_field.string, - alternative_form_view: this.m2m_field.field.views ? this.m2m_field.field.views.form : undefined, - readonly: this.getParent().get("effective_readonly") - }).open(); - pop.on('write_completed', self, function () { - self.dataset.evict_record(id); - self.reload_content(); - }); - }, - do_button_action: function(name, id, callback) { - var self = this; - var _sup = _.bind(this._super, this); - if (! this.m2m_field.options.reload_on_button) { - return _sup(name, id, callback); - } else { - return this.m2m_field.view.save().then(function() { - return _sup(name, id, function() { - self.m2m_field.view.reload(); - }); - }); - } - }, - is_action_enabled: function () { return true; }, -}); -var Many2ManyList = AddAnItemList.extend({ - _add_row_class: 'oe_form_field_many2many_list_row_add', - is_readonly: function () { - return this.view.m2m_field.get('effective_readonly'); - } -}); - -var FieldMany2ManyKanban = AbstractManyField.extend(common.CompletionFieldMixin, { - disable_utility_classes: true, - init: function(field_manager, node) { - this._super(field_manager, node); - common.CompletionFieldMixin.init.call(this); - this.is_loaded = $.Deferred(); - this.initial_is_loaded = this.is_loaded; - }, - start: function() { - this._super.apply(this, arguments); - - var self = this; - - self.load_view(); - self.on("change:effective_readonly", self, function() { - self.is_loaded = self.is_loaded.then(function() { - self.kanban_view.destroy(); - return $.when(self.load_view()).done(function() { - self.render_value(); - }); - }); - }); - }, - load_view: function() { - var self = this; - var KanbanView = core.view_registry.get('kanban'); - this.kanban_view = new KanbanView(this, this.dataset, false, { - 'create_text': _t("Add"), - 'creatable': self.get("effective_readonly") ? false : true, - 'quick_creatable': self.get("effective_readonly") ? false : true, - 'read_only_mode': self.get("effective_readonly") ? true : false, - 'confirm_on_delete': false, - }); - var embedded = (this.field.views || {}).kanban; - if (embedded) { - this.kanban_view.set_embedded_view(embedded); - } - this.kanban_view.m2m = this; - var loaded = $.Deferred(); - this.kanban_view.on("kanban_view_loaded",self,function() { - self.initial_is_loaded.resolve(); - loaded.resolve(); - }); - this.kanban_view.on('switch_mode', this, this.open_popup); - $.async_when().done(function () { - self.kanban_view.appendTo(self.$el); - }); - return loaded; - }, - render_value: function() { - var self = this; - this.dataset.set_ids(this.get("value")); - this.is_loaded = this.is_loaded.then(function() { - return self.kanban_view.do_search(self.build_domain(), self.dataset.get_context(), []); - }); - }, - open_popup: function(type, unused) { - if (type !== "form") - return; - var self = this; - var pop; - if (this.dataset.index === null) { - new common.SelectCreateDialog(this, { - res_model: this.field.relation, - domain: new data.CompoundDomain(this.build_domain(), ["!", ["id", "in", this.dataset.ids]]), - context: this.build_context(), - title: _t("Add: ") + this.string, - on_selected: function(element_ids) { - return self.data_link_multi(element_ids); - } - }).open(); - } else { - var id = self.dataset.ids[self.dataset.index]; - pop = new common.FormViewDialog(this, { - res_model: self.field.relation, - res_id: id, - context: self.build_context(), - title: _t("Open: ") + self.string, - write_function: function(id, data, options) { - return self.data_update(id, data, {}).done(function() { - self.render_value(); - }); - }, - alternative_form_view: self.field.views ? self.field.views.form : undefined, - parent_view: self.view, - child_name: self.name, - readonly: self.get("effective_readonly") - }).open(); - } - }, - add_id: function(id) { - this.quick_create.add_id(id); - }, -}); - -/** * Widget for (many2many field) to upload one or more file in same time and display in list. * The user can delete his files. * Options on attribute ; "blockui" {Boolean} block the UI or not @@ -1780,3 +1632,58 @@ return { }; }); + +odoo.define('web_kanban.Many2ManyKanbanView', function (require) { + "use strict"; + // This code has a dependency on the addon web_kanban. This is a weird dependency issue. To fix it, + // we should either move this code into web_kanban, or move web_kanban into the web client. + + var common = require('web.form_common'); + var core = require('web.core'); + var data = require('web.data'); + var KanbanView = require('web_kanban.KanbanView'); + + var _t = core._t; + + var Many2ManyKanbanView = KanbanView.extend({ + add_record: function() { + var self = this; + new common.SelectCreateDialog(this, { + res_model: this.x2m.field.relation, + domain: new data.CompoundDomain(this.x2m.build_domain(), ["!", ["id", "in", this.dataset.ids]]), + context: this.x2m.build_context(), + title: _t("Add: ") + this.x2m.string, + on_selected: function(element_ids) { + return self.x2m.data_link_multi(element_ids).then(function() { + self.x2m.reload_current_view(); + }); + } + }).open(); + }, + open_record: function(event) { + var self = this; + new common.FormViewDialog(this, { + res_model: this.x2m.field.relation, + res_id: event.data.id, + context: this.x2m.build_context(), + title: _t("Open: ") + this.x2m.string, + write_function: function(id, data) { + return self.x2m.data_update(id, data, {}).done(function() { + self.x2m.reload_current_view(); + }); + }, + alternative_form_view: this.x2m.field.views ? this.x2m.field.views.form : undefined, + parent_view: this.x2m.view, + child_name: this.x2m.name, + read_function: function(ids, fields, options) { + return self.x2m.data_read(ids, fields, options); + }, + form_view_options: {'not_interactible_on_create': true}, + readonly: !this.is_action_enabled('edit') || this.x2m.get("effective_readonly") + }).open(); + }, + }); + + core.view_registry.add('many2many_kanban', Many2ManyKanbanView); + +}); |
