mirror of
https://github.com/OCA/web.git
synced 2025-02-22 13:21:25 +02:00
@@ -180,6 +180,15 @@ Other example for 'purchase.order.line' fields:
|
||||
Usage
|
||||
=====
|
||||
|
||||
When you change the value of a field and switch to edit another record, the
|
||||
changes will be applied to the previous record without having to click on
|
||||
accept changes.
|
||||
|
||||
Parts of the widget:
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_widget_one2many_product_picker/static/img/product_picker_anat.png
|
||||
|
||||
Preview:
|
||||
~~~~~~~~
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
When you change the value of a field and switch to edit another record, the
|
||||
changes will be applied to the previous record without having to click on
|
||||
accept changes.
|
||||
|
||||
Parts of the widget:
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: ../static/img/product_picker_anat.png
|
||||
|
||||
Preview:
|
||||
~~~~~~~~
|
||||
|
||||
|
||||
@@ -380,15 +380,16 @@ ul.auto-toc {
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#usage" id="id6">Usage</a><ul>
|
||||
<li><a class="reference internal" href="#preview" id="id7">Preview:</a></li>
|
||||
<li><a class="reference internal" href="#parts-of-the-widget" id="id7">Parts of the widget:</a></li>
|
||||
<li><a class="reference internal" href="#preview" id="id8">Preview:</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#known-issues-roadmap" id="id8">Known issues / Roadmap</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="id9">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="id10">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="id11">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="id12">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="id13">Maintainers</a></li>
|
||||
<li><a class="reference internal" href="#known-issues-roadmap" id="id9">Known issues / Roadmap</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="id10">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="id11">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="id12">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="id13">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="id14">Maintainers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -564,22 +565,31 @@ options="{'search': [{'name': _('Starts With'), 'domain': [('name', '=like'
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h1><a class="toc-backref" href="#id6">Usage</a></h1>
|
||||
<p>When you change the value of a field and switch to edit another record, the
|
||||
changes will be applied to the previous record without having to click on
|
||||
accept changes.</p>
|
||||
<div class="section" id="parts-of-the-widget">
|
||||
<h2><a class="toc-backref" href="#id7">Parts of the widget:</a></h2>
|
||||
<blockquote>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/web/12.0/web_widget_one2many_product_picker/static/img/product_picker_anat.png" src="https://raw.githubusercontent.com/OCA/web/12.0/web_widget_one2many_product_picker/static/img/product_picker_anat.png" />
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="preview">
|
||||
<h2><a class="toc-backref" href="#id7">Preview:</a></h2>
|
||||
<h2><a class="toc-backref" href="#id8">Preview:</a></h2>
|
||||
<blockquote>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/web/12.0/web_widget_one2many_product_picker/static/img/product_picker.gif" src="https://raw.githubusercontent.com/OCA/web/12.0/web_widget_one2many_product_picker/static/img/product_picker.gif" />
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="known-issues-roadmap">
|
||||
<h1><a class="toc-backref" href="#id8">Known issues / Roadmap</a></h1>
|
||||
<h1><a class="toc-backref" href="#id9">Known issues / Roadmap</a></h1>
|
||||
<ul class="simple">
|
||||
<li>Translations in the xml ‘options’ attribute of the field that use the widget can’t be exported automatically to be translated</li>
|
||||
<li>The product card animations can be improved. Currently the card is recreated, so we lost some elements to apply correct effects.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="bug-tracker">
|
||||
<h1><a class="toc-backref" href="#id9">Bug Tracker</a></h1>
|
||||
<h1><a class="toc-backref" href="#id10">Bug Tracker</a></h1>
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us smashing it by providing a detailed and welcomed
|
||||
@@ -587,15 +597,15 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
|
||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
<h1><a class="toc-backref" href="#id10">Credits</a></h1>
|
||||
<h1><a class="toc-backref" href="#id11">Credits</a></h1>
|
||||
<div class="section" id="authors">
|
||||
<h2><a class="toc-backref" href="#id11">Authors</a></h2>
|
||||
<h2><a class="toc-backref" href="#id12">Authors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>Tecnativa</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributors">
|
||||
<h2><a class="toc-backref" href="#id12">Contributors</a></h2>
|
||||
<h2><a class="toc-backref" href="#id13">Contributors</a></h2>
|
||||
<ul>
|
||||
<li><p class="first"><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:</p>
|
||||
<blockquote>
|
||||
@@ -609,7 +619,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="maintainers">
|
||||
<h2><a class="toc-backref" href="#id13">Maintainers</a></h2>
|
||||
<h2><a class="toc-backref" href="#id14">Maintainers</a></h2>
|
||||
<p>This module is maintained by the OCA.</p>
|
||||
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
|
||||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 MiB After Width: | Height: | Size: 5.1 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 138 KiB |
@@ -89,9 +89,9 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateForm", f
|
||||
model: this.basicFieldParams.model,
|
||||
mainRecordData: this.getParent().getParent().state,
|
||||
});
|
||||
if (this.id) {
|
||||
this.basicFieldParams.model.save(this.id, {savePoint: true});
|
||||
}
|
||||
// if (this.id) {
|
||||
// this.basicFieldParams.model.save(this.id, {savePoint: true});
|
||||
// }
|
||||
var def2 = this.formView.getController(this).then(function (controller) {
|
||||
self.controller = controller;
|
||||
self.$el.empty();
|
||||
|
||||
@@ -18,6 +18,8 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
|
||||
BasicModel.include({
|
||||
_applyOnChange: function (values, record, viewType) {
|
||||
var vt = viewType || record.viewType;
|
||||
// Ignore changes by record context 'ignore_onchanges' fields
|
||||
if ('ignore_onchanges' in record.context) {
|
||||
var ignore_changes = record.context.ignore_onchanges;
|
||||
for (var index in ignore_changes) {
|
||||
@@ -64,11 +66,28 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates buttons depending on record status
|
||||
*
|
||||
* @private
|
||||
* Create or accept changes
|
||||
*/
|
||||
_updateButtons: function () {
|
||||
auto: function () {
|
||||
var record = this.model.get(this.handle);
|
||||
if (record.context.has_changes_confirmed || typeof record.context.has_changes_confirmed === "undefined") {
|
||||
return;
|
||||
}
|
||||
var state = this._getRecordState();
|
||||
if (state === "new") {
|
||||
this._add();
|
||||
} else if (state === "dirty") {
|
||||
this._change();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Know the real state of the record
|
||||
* - record: Normal
|
||||
* - new: Is a new record
|
||||
* - dirty: Has changes
|
||||
*/
|
||||
_getRecordState: function () {
|
||||
var record = this.model.get(this.handle);
|
||||
var state = "record";
|
||||
if (this.model.isNew(record.id)) {
|
||||
@@ -89,25 +108,41 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates buttons depending on record status
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_updateButtons: function () {
|
||||
this.$el.find(
|
||||
".oe_one2many_product_picker_form_buttons").remove();
|
||||
this.$el.find(".o_form_view").append(
|
||||
qweb.render(
|
||||
"One2ManyProductPicker.QuickCreate.FormButtons", {
|
||||
state: state,
|
||||
state: this._getRecordState(),
|
||||
})
|
||||
);
|
||||
|
||||
if (this._disabled) {
|
||||
this._disableQuickCreate();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_disableQuickCreate: function () {
|
||||
|
||||
if (!this.$el) {
|
||||
return;
|
||||
}
|
||||
// Ensures that the record won't be created twice
|
||||
this._disabled = true;
|
||||
this.$el.addClass("o_disabled");
|
||||
this.$("input:not(:disabled)")
|
||||
this.$("input:not(:disabled),button:not(:disabled)")
|
||||
.addClass("o_temporarily_disabled")
|
||||
.attr("disabled", "disabled");
|
||||
},
|
||||
@@ -120,7 +155,7 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
// Allows to create again
|
||||
this._disabled = false;
|
||||
this.$el.removeClass("o_disabled");
|
||||
this.$("input.o_temporarily_disabled")
|
||||
this.$("input.o_temporarily_disabled,button.o_temporarily_disabled")
|
||||
.removeClass("o_temporarily_disabled")
|
||||
.attr("disabled", false);
|
||||
},
|
||||
@@ -208,6 +243,9 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
// Don't do anything if we are already creating a record
|
||||
return $.Deferred();
|
||||
}
|
||||
this.model.updateRecordContext(this.handle, {
|
||||
has_changes_confirmed: true,
|
||||
});
|
||||
var self = this;
|
||||
this._disableQuickCreate();
|
||||
return this.saveRecord(this.handle, {
|
||||
@@ -216,64 +254,70 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
savePoint: true,
|
||||
viewType: "form",
|
||||
}).then(function () {
|
||||
self._enableQuickCreate();
|
||||
var record = self.model.get(self.handle);
|
||||
self.trigger_up("create_quick_record", {
|
||||
id: record.id,
|
||||
self.trigger_up("restore_flip_card", {
|
||||
success_callback: function () {
|
||||
self.trigger_up("create_quick_record", {
|
||||
id: record.id,
|
||||
});
|
||||
self.model.unsetDirty(self.handle);
|
||||
//self._updateButtons();
|
||||
self._enableQuickCreate();
|
||||
},
|
||||
block: true,
|
||||
});
|
||||
self.model.unsetDirty(self.handle);
|
||||
self._updateButtons();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickAdd: function (ev) {
|
||||
ev.stopPropagation();
|
||||
this.model.updateRecordContext(this.handle, {
|
||||
has_changes_confirmed: true,
|
||||
});
|
||||
this._add();
|
||||
},
|
||||
_remove: function () {
|
||||
if (this._disabled) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickRemove: function (ev) {
|
||||
ev.stopPropagation();
|
||||
// Don't do anything if we are already creating a record
|
||||
return $.Deferred();
|
||||
}
|
||||
|
||||
this._disableQuickCreate();
|
||||
this.trigger_up("restore_flip_card", {block: true});
|
||||
var record = this.model.get(this.handle);
|
||||
this.trigger_up("list_record_remove", {
|
||||
id: this.renderer.state.id,
|
||||
id: record.id,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickChange: function (ev) {
|
||||
ev.stopPropagation();
|
||||
_change: function () {
|
||||
var self = this;
|
||||
if (this._disabled) {
|
||||
|
||||
// Don't do anything if we are already creating a record
|
||||
return $.Deferred();
|
||||
}
|
||||
this._disableQuickCreate();
|
||||
this.model.updateRecordContext(this.handle, {
|
||||
has_changes_confirmed: true,
|
||||
});
|
||||
var record = this.model.get(this.handle);
|
||||
this.trigger_up("update_quick_record", {
|
||||
id: record.id,
|
||||
|
||||
this.trigger_up("restore_flip_card", {
|
||||
success_callback: function () {
|
||||
self.trigger_up("update_quick_record", {
|
||||
id: record.id,
|
||||
});
|
||||
self.model.unsetDirty(self.handle);
|
||||
//self._updateButtons();
|
||||
self._enableQuickCreate();
|
||||
},
|
||||
block: true,
|
||||
});
|
||||
this.trigger_up("restore_flip_card");
|
||||
this.model.unsetDirty(this.handle);
|
||||
this._updateButtons();
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickDiscard: function (ev) {
|
||||
_discard: function () {
|
||||
var self = this;
|
||||
ev.stopPropagation();
|
||||
if (this._disabled) {
|
||||
|
||||
// Don't do anything if we are already creating a record
|
||||
return $.Deferred();
|
||||
}
|
||||
this._disableQuickCreate();
|
||||
var record = this.model.get(this.handle);
|
||||
this.model.discardChanges(this.handle, {
|
||||
rollback: true,
|
||||
@@ -285,14 +329,52 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
this.update({}, {reload: false});
|
||||
this.trigger_up("restore_flip_card");
|
||||
this._updateButtons();
|
||||
this._enableQuickCreate();
|
||||
} else {
|
||||
this.update({}, {reload: false}).then(function () {
|
||||
self.model.unsetDirty(self.handle);
|
||||
self.trigger_up("restore_flip_card");
|
||||
self._updateButtons();
|
||||
self._enableQuickCreate();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickAdd: function (ev) {
|
||||
ev.stopPropagation();
|
||||
this._add();
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickRemove: function (ev) {
|
||||
ev.stopPropagation();
|
||||
this._remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickChange: function (ev) {
|
||||
ev.stopPropagation();
|
||||
this._change();
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickDiscard: function (ev) {
|
||||
ev.stopPropagation();
|
||||
this._discard();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -302,6 +384,9 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView
|
||||
Controller: ProductPickerQuickCreateFormController,
|
||||
}),
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function (viewInfo, params) {
|
||||
this._super.apply(this, arguments);
|
||||
this.controllerParams.compareKey = params.compareKey;
|
||||
|
||||
@@ -13,6 +13,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
var tools = require("web_widget_one2many_product_picker.tools");
|
||||
var ProductPickerQuickModifPriceForm = require(
|
||||
"web_widget_one2many_product_picker.ProductPickerQuickModifPriceForm");
|
||||
var FieldManagerMixin = require('web.FieldManagerMixin');
|
||||
|
||||
var qweb = core.qweb;
|
||||
var _t = core._t;
|
||||
@@ -38,7 +39,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
this.subWidgets = {};
|
||||
this._clickFlipCardCount = 0;
|
||||
this._setState(state, options.searchRecord);
|
||||
this.widgets = [];
|
||||
this.widgets = {
|
||||
front: [],
|
||||
back: [],
|
||||
};
|
||||
|
||||
this._lazyUpdateRecord = _.debounce(this._updateRecord.bind(this), 450);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -71,6 +77,14 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
_.invoke(this.subWidgets, "on_detach_callback");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
destroy: function () {
|
||||
this.$card.off("")
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -94,6 +108,13 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
if (state) {
|
||||
this._setState(state);
|
||||
}
|
||||
this.$card.removeClass("blocked");
|
||||
// Avoid recreate active record
|
||||
if (this.$card.hasClass("active")) {
|
||||
this._processDynamicFields();
|
||||
return $.when();
|
||||
}
|
||||
|
||||
this.on_detach_callback();
|
||||
return this._render();
|
||||
},
|
||||
@@ -160,6 +181,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
this.fields = this.getParent().state.fields;
|
||||
this.fieldsInfo = this.getParent().state.fieldsInfo.form;
|
||||
this.state = viewState;
|
||||
|
||||
if (recordSearch) {
|
||||
this.recordSearch = recordSearch;
|
||||
}
|
||||
@@ -176,6 +198,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
// Using directly the 'model record' instead of the state because
|
||||
// the state it's a parsed version of this record that doesn't
|
||||
// contains the '_virtual' attribute.
|
||||
var model = this.options.basicFieldParams.model;
|
||||
var record = model.get(this.state.id);
|
||||
return {
|
||||
record_search: this.recordSearch,
|
||||
user_context: this.getSession() && this.getSession().user_context || {},
|
||||
@@ -187,6 +211,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
monetary: this._getMonetaryFieldValue.bind(this),
|
||||
show_discount: this.options.showDiscount,
|
||||
is_virtual: this.is_virtual,
|
||||
modified: record && record.context.product_picker_modified,
|
||||
active_model: '',
|
||||
};
|
||||
},
|
||||
@@ -230,6 +255,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
var model = this.options.basicFieldParams.model;
|
||||
var scontext = _.extend(
|
||||
{}, this._getInternalVirtualRecordContext(), context);
|
||||
// Force qty to 1.0 to launch correct onchanges
|
||||
scontext[`default_${this.options.fieldMap.product_uom_qty}`] = 1.0;
|
||||
var sdata = _.extend({}, this._getInternalVirtualRecordData(), data);
|
||||
return model.createVirtualRecord(
|
||||
this.options.basicFieldParams.value.id, {
|
||||
@@ -238,10 +265,20 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
});
|
||||
},
|
||||
|
||||
_detachAllWidgets: function () {
|
||||
_.invoke(this.widgets.front, "on_detach_callback");
|
||||
_.invoke(this.widgets.back, "on_detach_callback");
|
||||
this.widgets = {
|
||||
front: [],
|
||||
back: [],
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_render: function () {
|
||||
this._detachAllWidgets();
|
||||
this.defs = [];
|
||||
this._replaceElement(
|
||||
qweb.render(
|
||||
@@ -249,11 +286,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
this._getQWebContext()
|
||||
)
|
||||
);
|
||||
this.$el.data("renderer_widget_index", this.options.renderer_widget_index);
|
||||
this.$card = this.$(".oe_flip_card");
|
||||
this.$front = this.$(".oe_flip_card_front");
|
||||
this.$back = this.$(".oe_flip_card_back");
|
||||
this._processWidgetFields(this.$front);
|
||||
this._processWidgets(this.$front);
|
||||
this._processWidgets(this.$front, 'front');
|
||||
this._processDynamicFields();
|
||||
return $.when.apply(this, this.defs);
|
||||
},
|
||||
@@ -265,7 +303,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
* @private
|
||||
* @param {jQueryElement} $container
|
||||
*/
|
||||
_processWidgetFields: function ($container) {
|
||||
_processWidgetFields: function ($container, widget_list) {
|
||||
var self = this;
|
||||
$container.find("field").each(function () {
|
||||
var $field = $(this);
|
||||
@@ -357,7 +395,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
* @private
|
||||
* @param {jQueryElement} $container
|
||||
*/
|
||||
_processWidgets: function ($container) {
|
||||
_processWidgets: function ($container, widget_zone) {
|
||||
var self = this;
|
||||
$container.find("widget").each(function () {
|
||||
var $field = $(this);
|
||||
@@ -375,7 +413,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
data: self.state && self.state.data,
|
||||
});
|
||||
|
||||
self.widgets.push(widget);
|
||||
self.widgets[widget_zone].push(widget);
|
||||
|
||||
var def = widget
|
||||
._widgetRenderAndInsert(function () {
|
||||
@@ -469,6 +507,91 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_saveRecord: function () {
|
||||
var self = this;
|
||||
var model = this.options.basicFieldParams.model;
|
||||
var record = model.get(this.state.id);
|
||||
return model.save(record.id, {
|
||||
savePoint: true,
|
||||
}).then(function () {
|
||||
var record = model.get(self.state.id);
|
||||
self.trigger_up("create_quick_record", {
|
||||
id: record.id,
|
||||
});
|
||||
model.unsetDirty(self.state.id);
|
||||
self.$card.find('.o_catch_attention').removeClass('o_catch_attention');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_updateRecord: function (changes) {
|
||||
var model = this.options.basicFieldParams.model;
|
||||
var record = model.get(this.state.id);
|
||||
this.trigger_up("update_quick_record", {
|
||||
id: record.id,
|
||||
});
|
||||
model.unsetDirty(this.state.id);
|
||||
this.$card.find('.o_catch_attention').removeClass('o_catch_attention');
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_addProduct: function () {
|
||||
var self = this;
|
||||
var changes = {};
|
||||
if (this.state.data[this.options.fieldMap.product_uom_qty] === 0) {
|
||||
changes[this.options.fieldMap.product_uom_qty] = 1;
|
||||
}
|
||||
var model = this.options.basicFieldParams.model;
|
||||
this.$card.addClass("blocked");
|
||||
return model.notifyChanges(this.state.id, changes).then(function () {
|
||||
self._saveRecord();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Number} amount
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_incProductQty: function (amount) {
|
||||
var self = this;
|
||||
this.state.data[this.options.fieldMap.product_uom_qty] += amount;
|
||||
var model = this.options.basicFieldParams.model;
|
||||
var record = model.get(this.state.id);
|
||||
var state_data = record.data;
|
||||
state_data[this.options.fieldMap.product_uom_qty] += amount;
|
||||
var changes = _.pick(state_data, this.options.fieldMap.product_uom_qty);
|
||||
|
||||
return model.notifyChanges(record.id, changes).then(function () {
|
||||
self._processDynamicFields();
|
||||
self._lazyUpdateRecord();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_doInteractAnim: function (target, currentTarget) {
|
||||
var $target = $(target);
|
||||
var $currentTarget = $(currentTarget);
|
||||
var $img = $currentTarget.find(".oe_flip_card_front img");
|
||||
$target.addClass('o_catch_attention');
|
||||
$img.addClass('oe_product_picker_catch_attention');
|
||||
$img.on('animationend', function () {
|
||||
$img.removeClass('oe_product_picker_catch_attention');
|
||||
$img.off('animationend');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -503,11 +626,31 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
* @param {ClickEvent} evt
|
||||
*/
|
||||
_onClickFlipCard: function (evt) {
|
||||
|
||||
// Avoid clicks on form elements
|
||||
if (['INPUT', 'BUTTON', 'A'].indexOf(evt.target.tagName) !== -1) {
|
||||
if (['INPUT', 'BUTTON', 'A'].indexOf(evt.target.tagName) !== -1 || this.$card.hasClass('blocked')) {
|
||||
return;
|
||||
}
|
||||
var $target = $(evt.target);
|
||||
if (!this.options.readOnlyMode) {
|
||||
if (
|
||||
$target.hasClass('add_product') ||
|
||||
$target.parents('.add_product').length
|
||||
) {
|
||||
if (!this.is_adding_product) {
|
||||
this.is_adding_product = true;
|
||||
this._addProduct();
|
||||
this._doInteractAnim(evt.target, evt.currentTarget);
|
||||
}
|
||||
return;
|
||||
} else if (
|
||||
$target.hasClass('product_qty') ||
|
||||
$target.parents('.product_qty').length
|
||||
) {
|
||||
this._incProductQty(1);
|
||||
this._doInteractAnim(evt.target, evt.currentTarget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!this._clickFlipCardDelayed) {
|
||||
this._clickFlipCardDelayed = setTimeout(
|
||||
this._onClickDelayedFlipCard.bind(this, evt),
|
||||
@@ -534,21 +677,28 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
}
|
||||
if (this.$card.hasClass("active")) {
|
||||
this.$card.removeClass("active");
|
||||
this.$card.find('.oe_flip_card_front').removeClass("d-none");
|
||||
this.$front.removeClass("d-none");
|
||||
} else {
|
||||
var self = this;
|
||||
this.defs = [];
|
||||
this._processWidgetFields(this.$back);
|
||||
this._processWidgets(this.$back);
|
||||
if (!this.widgets.back.length) {
|
||||
this._processWidgetFields(this.$back);
|
||||
this._processWidgets(this.$back, 'back');
|
||||
}
|
||||
this._processDynamicFields();
|
||||
$.when(this.defs).then(function () {
|
||||
var $actived_card = self.$el.parent().find(".active");
|
||||
$actived_card.removeClass("active");
|
||||
$actived_card.find('.oe_flip_card_front').removeClass("d-none");
|
||||
self.$card.addClass("active");
|
||||
setTimeout(function () {
|
||||
self.$('.oe_flip_card_front').addClass("d-none");
|
||||
}, 200);
|
||||
self.$card.on('transitionend', function () {
|
||||
self.$front.addClass("d-none");
|
||||
self.$card.off('transitionend');
|
||||
});
|
||||
self.trigger_up("record_flip", {
|
||||
widget_index: self.$el.data("renderer_widget_index"),
|
||||
prev_widget_index: $actived_card.parent().data("renderer_widget_index"),
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -609,9 +759,33 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onRestoreFlipCard: function () {
|
||||
this.$(".oe_flip_card").removeClass("active");
|
||||
this.$('.oe_flip_card_front').removeClass("d-none");
|
||||
_onRestoreFlipCard: function (evt) {
|
||||
var self = this;
|
||||
this.$card.removeClass("active");
|
||||
this.$front.removeClass("d-none");
|
||||
if (this.$card.hasClass('oe_flip_card_maximized')) {
|
||||
this.$card.removeClass('oe_flip_card_maximized');
|
||||
this.$card.on('transitionend', function () {
|
||||
self.$card.css({
|
||||
position: "",
|
||||
top: "",
|
||||
left: "",
|
||||
width: "",
|
||||
height: "",
|
||||
zIndex: "",
|
||||
});
|
||||
self.$card.off('transitionend');
|
||||
if (evt.data.success_callback) {
|
||||
evt.data.success_callback();
|
||||
}
|
||||
});
|
||||
} else if (evt.data.success_callback) {
|
||||
evt.data.success_callback();
|
||||
}
|
||||
|
||||
if (evt.data.block) {
|
||||
this.$card.addClass("blocked");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
var BasicRenderer = require("web.BasicRenderer");
|
||||
var One2ManyProductPickerRecord = require(
|
||||
"web_widget_one2many_product_picker.One2ManyProductPickerRecord");
|
||||
var ProductPickerQuickCreateForm = require(
|
||||
"web_widget_one2many_product_picker.ProductPickerQuickCreateForm");
|
||||
|
||||
var qweb = core.qweb;
|
||||
|
||||
@@ -19,6 +21,9 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
events: {
|
||||
'click #productPickerLoadMore': '_onClickLoadMore',
|
||||
},
|
||||
custom_events: {
|
||||
'record_flip': '_onRecordFlip',
|
||||
},
|
||||
|
||||
DELAY_GET_RECORDS: 150,
|
||||
MIN_PERC_GET_RECORDS: 0.9,
|
||||
@@ -62,8 +67,9 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
* @param {Object} widget
|
||||
*/
|
||||
removeWidget: function (widget) {
|
||||
this.widgets.splice(this.widgets.indexOf(widget), 1);
|
||||
var index = this.widgets.indexOf(widget);
|
||||
widget.destroy();
|
||||
delete this.widgets[index];
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -98,14 +104,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
*/
|
||||
updateState: function (state, params) {
|
||||
var self = this;
|
||||
var sparams = _.extend({}, params, {noRender: true});
|
||||
if (_.isEqual(this.state.data, state.data)) {
|
||||
return this._super.apply(this, arguments);
|
||||
return this._super(state, sparams);
|
||||
}
|
||||
var old_state = _.clone(this.state.data);
|
||||
return this._super(
|
||||
state,
|
||||
_.extend({}, params, {noRender: true})
|
||||
).then(function () {
|
||||
return this._super(state, sparams).then(function () {
|
||||
self._updateStateRecords(old_state);
|
||||
});
|
||||
},
|
||||
@@ -115,7 +119,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
* @param {Array[Object]} states
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
_removeRecords: function (states) {
|
||||
_removeRecords: function (states, new_states) {
|
||||
var defs = [];
|
||||
var to_destroy = [];
|
||||
for (var index_state in states) {
|
||||
@@ -128,7 +132,6 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
}
|
||||
}
|
||||
}
|
||||
this.widgets = _.compact(this.widgets);
|
||||
|
||||
if (this.search_group.name === "main_lines") {
|
||||
_.invoke(to_destroy, "destroy");
|
||||
@@ -142,18 +145,33 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
var widget_product_id = widget_destroyed.state
|
||||
.data[this.options.field_map.product].data.id;
|
||||
var found = false;
|
||||
// If already exists a widget for the product don't try create a new one
|
||||
for (var eb = this.widgets.length-1; eb>=0; --eb) {
|
||||
var widget = this.widgets[eb];
|
||||
if (
|
||||
widget &&
|
||||
widget.state &&
|
||||
widget.state.data[this.options.field_map.product].data.id === widget_product_id
|
||||
) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// Get the new state ID if exists to link it with the new record
|
||||
var new_state_id = undefined;
|
||||
for (var eb = new_states.length-1; eb>=0; --eb) {
|
||||
var state = new_states[eb];
|
||||
if (
|
||||
state.data[this.options.field_map.product].data.id === widget_product_id
|
||||
) {
|
||||
new_state_id = state.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var search_record = _.find(this.search_data, {id: widget_product_id});
|
||||
var new_search_record = _.extend({}, search_record, {__id: state.id});
|
||||
var new_search_record = _.extend({}, search_record, {__id: new_state_id});
|
||||
var search_record_index = widget_destroyed.$el.index();
|
||||
defs.push(
|
||||
this.appendSearchRecords(
|
||||
@@ -188,7 +206,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
var found = false;
|
||||
for (var e in this.state.data) {
|
||||
var current_state = this.state.data[e];
|
||||
if (current_state.id === old_state.id) {
|
||||
if (current_state.id === old_state.id || (typeof current_state.data.id !== 'undefined' && current_state.data.id === old_state.data.id)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -197,7 +215,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
states_to_destroy.push(old_state);
|
||||
}
|
||||
}
|
||||
this._removeRecords(states_to_destroy);
|
||||
this._removeRecords(states_to_destroy, this.state.data);
|
||||
|
||||
// Records to Update or Create
|
||||
var defs = [];
|
||||
@@ -209,12 +227,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
var search_record = false;
|
||||
for (var e = this.widgets.length-1; e>=0; --e) {
|
||||
var widget = this.widgets[e];
|
||||
if (!widget) {
|
||||
if (!widget || !widget.state) {
|
||||
|
||||
// Already processed widget (deleted)
|
||||
continue;
|
||||
}
|
||||
if (widget.state.id === state.id) {
|
||||
if (widget.state.id === state.id || (typeof state.data.id !== 'undefined' && widget.state.data.id === state.data.id)) {
|
||||
widget.recreate(state);
|
||||
exists = true;
|
||||
break;
|
||||
@@ -243,7 +261,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
defs.push(this.appendSearchRecords([new_search_record], false, true, search_record_index)[0]);
|
||||
}
|
||||
}
|
||||
this.widgets = _.compact(this.widgets);
|
||||
|
||||
_.invoke(to_destroy, "destroy");
|
||||
return $.when(defs);
|
||||
},
|
||||
@@ -253,7 +271,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
*/
|
||||
_renderView: function () {
|
||||
var self = this;
|
||||
var oldWidgets = this.widgets;
|
||||
var oldWidgets = _.compact(this.widgets);
|
||||
this.widgets = [];
|
||||
this.$recordsContainer = $("<DIV/>", {
|
||||
class: "w-100 row",
|
||||
@@ -277,7 +295,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
},
|
||||
|
||||
/**
|
||||
* Compare search results with current lines
|
||||
* Compare search results with current lines.
|
||||
* Link a current state with the 'search record'.
|
||||
*
|
||||
* @private
|
||||
* @param {Array[Object]} results
|
||||
@@ -360,10 +379,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
no_process_records?search_records:this._processSearchRecords(search_records);
|
||||
_.each(processed_records, function (search_record) {
|
||||
var state_data = self._getRecordDataById(search_record.__id);
|
||||
var widget_options = self._getRecordOptions(search_record);
|
||||
widget_options.renderer_widget_index = self.widgets.length;
|
||||
var ProductPickerRecord = new One2ManyProductPickerRecord(
|
||||
self,
|
||||
state_data,
|
||||
self._getRecordOptions(search_record)
|
||||
widget_options
|
||||
);
|
||||
self.widgets.push(ProductPickerRecord);
|
||||
|
||||
@@ -380,12 +401,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
// the search data. Using search data instead of waiting for
|
||||
// simulated state gives a low FCP time.
|
||||
var def = ProductPickerRecord.appendTo(self.$recordsContainer)
|
||||
.then(function () {
|
||||
if (typeof position !== "undefined") {
|
||||
var $elm = self.$el.find("> div > div:nth("+position+")");
|
||||
ProductPickerRecord.$el.insertAfter($elm);
|
||||
.then(function (widget, widget_position) {
|
||||
if (typeof widget_position !== "undefined") {
|
||||
var $elm = this.$el.find("> div > div:nth("+widget_position+")");
|
||||
widget.$el.insertAfter($elm);
|
||||
}
|
||||
});
|
||||
}.bind(self, ProductPickerRecord, position));
|
||||
if (def.state() === "pending") {
|
||||
self.defs.push(def);
|
||||
}
|
||||
@@ -441,6 +462,53 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||
this._loadMoreWorking = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Do card flip
|
||||
*
|
||||
* @param {Integer} index
|
||||
*/
|
||||
doWidgetFlip: function (index) {
|
||||
var widget = this.widgets[index];
|
||||
var $actived_card = this.$el.find(".active");
|
||||
if (widget.$card.hasClass("active")) {
|
||||
widget.$card.removeClass("active");
|
||||
widget.$card.find('.oe_flip_card_front').removeClass("d-none");
|
||||
} else {
|
||||
var self = widget;
|
||||
widget.defs = [];
|
||||
widget._processWidgetFields(widget.$back);
|
||||
widget._processWidgets(widget.$back);
|
||||
widget._processDynamicFields();
|
||||
$.when(widget.defs).then(function () {
|
||||
$actived_card.removeClass("active");
|
||||
$actived_card.find('.oe_flip_card_front').removeClass("d-none");
|
||||
self.$card.addClass("active");
|
||||
setTimeout(function () {
|
||||
self.$('.oe_flip_card_front').addClass("d-none");
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle card flip.
|
||||
* Used to create/update the record
|
||||
*
|
||||
* @param {CustomEvent} evt
|
||||
*/
|
||||
_onRecordFlip: function (evt) {
|
||||
var prev_widget_index = evt.data.prev_widget_index;
|
||||
if (typeof prev_widget_index !== "undefined") {
|
||||
// Only check 'back' widgets so there is where the form was created
|
||||
for (var index in this.widgets[prev_widget_index].widgets.back) {
|
||||
var widget = this.widgets[prev_widget_index].widgets.back[index];
|
||||
if (widget instanceof ProductPickerQuickCreateForm) {
|
||||
widget.controller.auto();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return One2ManyProductPickerRenderer;
|
||||
|
||||
@@ -580,11 +580,20 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
|
||||
* @param {CustomEvent} evt
|
||||
*/
|
||||
_onCreateQuickRecord: function (evt) {
|
||||
var self = this;
|
||||
this.parent_controller.model.setPureVirtual(evt.data.id, false);
|
||||
this._setValue({operation: "ADD", id: evt.data.id});
|
||||
if (this.options.auto_save) {
|
||||
this.parent_controller.saveRecord(undefined, {stayInEdit: true});
|
||||
if (!self.options.auto_save) {
|
||||
self.parent_controller.model.updateRecordContext(evt.data.id, {
|
||||
product_picker_modified: true,
|
||||
});
|
||||
}
|
||||
this._setValue({operation: "ADD", id: evt.data.id}).then(function () {
|
||||
if (self.options.auto_save) {
|
||||
self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function () {
|
||||
self.renderer.updateState(self.value);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -594,10 +603,19 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
|
||||
* @param {CustomEevent} evt
|
||||
*/
|
||||
_onUpdateQuickRecord: function (evt) {
|
||||
this._setValue({operation: "UPDATE", id: evt.data.id, data: evt.data.data});
|
||||
if (this.options.auto_save) {
|
||||
this.parent_controller.saveRecord(undefined, {stayInEdit: true});
|
||||
var self = this;
|
||||
if (!self.options.auto_save) {
|
||||
self.parent_controller.model.updateRecordContext(evt.data.id, {
|
||||
product_picker_modified: true,
|
||||
});
|
||||
}
|
||||
this._setValue({operation: "UPDATE", id: evt.data.id, data: evt.data.data}).then(function () {
|
||||
if (self.options.auto_save) {
|
||||
self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function () {
|
||||
self.renderer.updateState(self.value);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
$one2many-product-picker-max-height: 500px;
|
||||
$one2many-product-picker-card-min-height: 150px;
|
||||
$one2many-product-picker-card-max-height: 150px;
|
||||
$one2many-product-picker-transition-3d-time: 0.3s;
|
||||
$one2many-product-picker-transition-3d-time: 0.15s;
|
||||
$one2many-product-picker-card-form-padding: 0em;
|
||||
$one2many-product-picker-quick-modif-price-max-width: 400px;
|
||||
$one2many-product-picker-zoom-scale: 1.4;
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
transition: top $one2many-product-picker-transition-3d-time, left $one2many-product-picker-transition-3d-time, width $one2many-product-picker-transition-3d-time, height $one2many-product-picker-transition-3d-time;
|
||||
height: $one2many-product-picker-card-min-height;
|
||||
|
||||
&.blocked {
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.5;
|
||||
@@ -211,6 +215,9 @@
|
||||
font-size: 0.95rem;
|
||||
z-index: 0;
|
||||
}
|
||||
.add_product, .product_qty, .price_unit {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,3 +237,20 @@
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.oe_product_picker_catch_attention {
|
||||
position: relative;
|
||||
animation: productPickerCatchAttention 200ms normal forwards;
|
||||
}
|
||||
|
||||
@keyframes productPickerCatchAttention {
|
||||
0% {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
@@ -72,11 +72,16 @@
|
||||
<div class="oe_flip_container p-1 col-4 col-sm-4 col-md-2 col-lg-2 col-xl-1">
|
||||
<div t-attf-class="oe_flip_card {{!state && 'disabled' || ''}}">
|
||||
<div class="oe_flip_card_inner text-center">
|
||||
<div t-attf-class="oe_flip_card_front p-0 {{state && !is_virtual && 'border-primary' || ''}}">
|
||||
<div t-attf-class="oe_flip_card_front p-0 {{(modified && 'border-warning') || (state && !is_virtual && 'border-success') || ''}}">
|
||||
<t t-if="state">
|
||||
<t t-if="!is_virtual">
|
||||
<div class="position-absolute m-0 text-left">
|
||||
<span t-att-data-field="field_map.product_uom_qty" t-attf-data-esc="str({{field_map.product_uom_qty}}) + ' x ' + {{field_map.product_uom}}.data.display_name" class="badge badge-primary font-weight-bold rounded-0 mt-1 p-2" />
|
||||
<span t-att-data-field="field_map.product_uom_qty" t-attf-data-esc="str({{field_map.product_uom_qty}}) + ' x ' + {{field_map.product_uom}}.data.display_name" t-attf-class="badge {{modified && 'badge-warning' || 'badge-success'}} font-weight-bold rounded-0 mt-1 p-2 product_qty" />
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="position-absolute m-0 text-left">
|
||||
<span class="badge badge-primary font-weight-bold rounded-0 mt-1 p-2 add_product"><i class="fa fa-plus"></i> Add 1 <t t-esc="state.data[field_map.product_uom].data.display_name"/></span>
|
||||
</div>
|
||||
</t>
|
||||
<div class="position-absolute m-0 text-left badge_price">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<t t-name="One2ManyProductPicker.QuickCreate.FormButtons">
|
||||
<div class="oe_one2many_product_picker_form_buttons">
|
||||
<t t-if="state == 'new'">
|
||||
<button class="btn btn-primary oe_record_add">Add</button>
|
||||
<button t-attf-class="btn btn-primary oe_record_add">Add</button>
|
||||
</t>
|
||||
<t t-elif="state == 'dirty'">
|
||||
<button class="btn btn-success oe_record_change mr-2"><i class="fa fa-check" /></button>
|
||||
|
||||
@@ -26,8 +26,6 @@ odoo.define('web_widget_one2many_product_picker.widget_tests', function (require
|
||||
'</form>';
|
||||
};
|
||||
|
||||
console.log(getArch());
|
||||
|
||||
QUnit.module('Web Widget One2Many Product Picker', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
|
||||
Reference in New Issue
Block a user