diff --git a/odex25_base/advanced_web_domain_widget/__init__.py b/odex25_base/advanced_web_domain_widget/__init__.py old mode 100644 new mode 100755 diff --git a/odex25_base/advanced_web_domain_widget/__manifest__.py b/odex25_base/advanced_web_domain_widget/__manifest__.py old mode 100644 new mode 100755 index ad51a55b4..c7473f241 --- a/odex25_base/advanced_web_domain_widget/__manifest__.py +++ b/odex25_base/advanced_web_domain_widget/__manifest__.py @@ -10,14 +10,12 @@ ################################################################################# { 'name': 'Advanced Web Domain Widget', - 'version': '14.0.2.0.0', + 'version': '14.0.3.0.0', 'summary': 'Set all relational fields domain by selecting its records unsing `in, not in` operator.', 'sequence': 1, 'author': 'Terabits Technolab', - 'category': 'Odex25-base', - 'license': 'OPL-1', - 'website': 'https://www.terabits.xyz', + 'website': 'https://www.terabits.xyz/apps/14.0/advanced_web_domain_widget', 'description':""" """, diff --git a/odex25_base/advanced_web_domain_widget/controllers/__init__.py b/odex25_base/advanced_web_domain_widget/controllers/__init__.py old mode 100644 new mode 100755 diff --git a/odex25_base/advanced_web_domain_widget/models/__init__.py b/odex25_base/advanced_web_domain_widget/models/__init__.py old mode 100644 new mode 100755 index 404d75934..aac9e9b56 --- a/odex25_base/advanced_web_domain_widget/models/__init__.py +++ b/odex25_base/advanced_web_domain_widget/models/__init__.py @@ -1 +1,2 @@ from . import domain_prepare +from . import models \ No newline at end of file diff --git a/odex25_base/advanced_web_domain_widget/models/domain_prepare.py b/odex25_base/advanced_web_domain_widget/models/domain_prepare.py old mode 100644 new mode 100755 diff --git a/odex25_base/advanced_web_domain_widget/models/models.py b/odex25_base/advanced_web_domain_widget/models/models.py old mode 100644 new mode 100755 index b29ce65b3..32d57f3c0 --- a/odex25_base/advanced_web_domain_widget/models/models.py +++ b/odex25_base/advanced_web_domain_widget/models/models.py @@ -5,11 +5,9 @@ class BaseModel(models.AbstractModel): _inherit = 'base' @api.model - def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None, **read_kwargs): - res = super().search_read(domain, fields, offset, limit, order, **read_kwargs) - if self._context.get('web_domain_widget') and hasattr(self, 'company_id'): - for rec in res: - rec.update({'company_name': self.browse(rec.get('id')).company_id.name}) - - return res + def get_widget_name(self, domain=None, fields=None, offset=0, limit=None, order=None, **read_kwargs): + return self.sudo().search_read(domain, ['id', 'display_name'], offset, limit, order) + @api.model + def get_widget_count(self, args): + return self.sudo().search_count(args) \ No newline at end of file diff --git a/odex25_base/advanced_web_domain_widget/security/ir.model.access.csv b/odex25_base/advanced_web_domain_widget/security/ir.model.access.csv old mode 100644 new mode 100755 diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss4.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss4.png index 322dadc1c..996341877 100644 Binary files a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss4.png and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss4.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss5.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss5.png index 6403957ab..0cef7e6a7 100644 Binary files a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss5.png and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss5.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss6.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss6.png index a1a0a2ac2..103827c55 100644 Binary files a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss6.png and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss6.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss7.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss7.png index 9c3825b5b..e89f9e6da 100644 Binary files a/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss7.png and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/date_filter_ss7.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_01.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_01.png new file mode 100644 index 000000000..96c33d419 Binary files /dev/null and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_01.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_02.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_02.png new file mode 100644 index 000000000..27965a9da Binary files /dev/null and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_02.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_03.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_03.png new file mode 100644 index 000000000..c577a1575 Binary files /dev/null and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_bg_img_03.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_header_img.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_header_img.png new file mode 100644 index 000000000..ee1447057 Binary files /dev/null and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/domain_header_img.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/icon_img.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/icon_img.png new file mode 100644 index 000000000..500ffc3bd Binary files /dev/null and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/icon_img.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss1.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss1.png index 8c2f560ec..1c694a15c 100644 Binary files a/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss1.png and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss1.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss2.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss2.png index f0d25a046..3bbfe4d5a 100644 Binary files a/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss2.png and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss2.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss3.png b/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss3.png index b119a9f45..242c622f9 100644 Binary files a/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss3.png and b/odex25_base/advanced_web_domain_widget/static/description/img/screens/ss3.png differ diff --git a/odex25_base/advanced_web_domain_widget/static/description/index.html b/odex25_base/advanced_web_domain_widget/static/description/index.html index 1d135ad3c..8b7a51dc7 100644 --- a/odex25_base/advanced_web_domain_widget/static/description/index.html +++ b/odex25_base/advanced_web_domain_widget/static/description/index.html @@ -1,591 +1,545 @@ - - - - - - - - - - - - - - - - - - - - - -
- - -
-
- - -
-
- -
-
- - - -
-
-
-

- Advanced Web Domain Widget -

- -

- - "Now use the feature of select any models record in domain while using any - relational field." - -

- -

- Odoo base domain widget allows you to only match value or id while user wants to create - domain using any relational fields. So, user confused when model has multiple record's - id and he/she does't remembered. So, we have simplified that by showing models - record to the user. so, he/she can select by finding record and select it. our module - will autometic adds ids of selected records in domain. To select related model's record - and create domain, we allowed additional - two domain operators ('in', 'not in'). - -

- - - - -
-
-
- - - -
-
-

- Highlights -

-
-
-
-
- -
-
-

Select any - models records

-

- Easy to create domain of relational fields by selecting any models record in - domain. We provide additional operators ('in' and 'not in') to create - relational fields domain. -

-
-
-
- -
-
-
- -
-
-

Autometic id add - in domain

-

- When user select models records from popup, there will generate tags of - record's names and add records id in domain. -

-
-
-
-
-
-
- - -
-
-
-
- - -
-
- -
- -
-
-

You just need to change in xml - files to use our advanced domain feature. -

-
-
- -
-
-
  • - Replace name of odoo's 'domain' widget to 'terabits_domain' - widget. - -
  • -
    -
    -
    - Odoo's domain widget -
    -
    - Terabits's domain widget -
    -
    - - -
    -
    -
    -

    Here is odoo's 'domain' widget - for domain creation.

    -
    -
    -
    - Odoo domain widget -
    -
    -
    -

    Here is customized - 'terabits_domain' widget for domain creation.

    -
    -
    -
    - Terabits domain widget -
    -
    - Terabits domain widget -
    -
    -
    -

    Here is customized 'date and - filter' - widget for domain creation.

    -
    -
    -
    - Odoo domain widget -
    -
    -
    -

    Here is how you can select - environment company and user.

    -
    -
    -
    - Odoo domain widget -
    -
    - Odoo domain widget -
    -
    - Odoo domain widget -
    -
    - - -
    -
    -
    - -
    -
    - -
    -
    -

    - This module provides domains with an additional feature - to select any models record while using any relational - field and create a domain after selecting it. for that, - we provide two additional operators ('in' and 'not in') - that allow the user to select - a record of any model. after select any record, its id - automatic adds in domain. -

    -
    -
    -
    -
    - -
    -
    - -
    -
    -

    - User's main benifit is that, he/she does not have to - remember models record id while he/she have to create - domain based on relational fields, because we direct - show all models record so user only have to select its - record. -

    -
    -
    -
    -
    - -
    -
    - -
    -
    -

    - Please drop an email at info@terabits.xyz or raise a - ticket through the Odoo store itself. - -

    -
    -
    -
    -
    -
    -
    - -
    -
    -

    - Yes, I do provide free support for 90 days for any - queries or any bug/issue fixing. - -

    -
    -
    -
    -
    -
    -
    - -
    -
    -

    - In case of if any bug raised in the listed features of - this module, I am committed to providing support free of - cost. You will need to provide me server ssh access or - database access in order to solve the issue. -

    -
    -
    -
    -
    - -
    -
    -
    - - -
    - -
    -
    -

    Changelog(s)

    -
    - -

    - v14.0.1.0.2-December - 10, 2022 -

    -
      -
    • - Minor bug fix. -
    • -
    - -

    - v14.0.0.0.0-November - 23, 2022 -

    -
      -
    • - Initial release for v14 -
    • -
    - -
    -
    - -
    - -
    -
    -
    -
    - - - -
    -
    -
    -
    - -
    -
    -

    - Need a help for this module? -

    -

    - Contact me - info@terabits.xyz - for your queries -

    -
    -
    - - -
    + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    + + + +
    +
    + + +
    +
    +
    + +
    + +
    +

    + Advanced web domian widget +

    +

    + "Now use the feature of select any models record in domain while using any relational field." +

    +

    + Odoo base domain widget allows you to only match value or id while user wants to create
    + domain using any relational fields. So, user confused when model has multiple record's id
    + and he/she does't remembered. So, we have simplified that by showing models record to
    + the user. so, he/she can select by finding record and select it. our module will autometic
    + adds ids of selected records in domain. To select related model's record and create
    + domain, we allowed additional two domain operators ('in', 'not in'). +

    +
    + +
    +
    +
    +
    + + + + + +
    +
    + + +
    +
    +
    +

    + Features +

    +
    + +
    +
    +
    + Select any models records +
    +
    +

    + Easy to create domain of relational fields by
    + selecting any models record in domain. We
    + provide additional operators ('in' and 'not in')
    + to create relational fields domain. +

    +
    +
    + +
    +
    + Autometic id add in domain +
    +
    +

    + When user select models records from popup,
    + there will generate tags of record's names and
    + add records id in domain. +

    +
    +
    + +
    +
    +
    +
    +
    + + + + +
    +
    +
    + +
    + +
    + +
    +
    +

    You just need to change in xml + files to use our advanced domain feature. +

    +
    +
    + +
    +
    +
  • + Replace name of odoo's 'domain' widget to 'terabits_domain' + widget. + +
  • +
    +
    +
    + Odoo's domain widget +
    +
    + Terabits's domain widget +
    +
    + + +
    + + + +
    +
    + + +
    +
    + +
    +
    +
    + +
    +
    +

    + Here is odoo's 'domain' widget for domain creation. +

    +
    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +

    + Here is customized 'terabits_domain' widget for domain creation. +

    +
    +
    + +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +

    + Here is customized 'date and filter' widget for domain creation. +

    +
    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +

    + Here is how you can select environment company and user. +

    +
    +
    + +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    + +
    +
    +

    + This module provides domains with an additional feature + to select any models record while using any relational + field and create a domain after selecting it. for that, + we provide two additional operators ('in' and 'not in') + that allow the user to select + a record of any model. after select any record, its id + automatic adds in domain. +

    +
    +
    +
    +
    + +
    +
    + +
    +
    +

    + User's main benifit is that, he/she does not have to + remember models record id while he/she have to create + domain based on relational fields, because we direct + show all models record so user only have to select its + record. +

    +
    +
    +
    +
    + +
    +
    + +
    +
    +

    + Please drop an email at info@terabits.xyz or raise a + ticket through the Odoo store itself. + +

    +
    +
    +
    +
    +
    +
    + +
    +
    +

    + Yes, I do provide free support for 90 days for any + queries or any bug/issue fixing. + +

    +
    +
    +
    +
    +
    +
    + +
    +
    +

    + In case of if any bug raised in the listed features of + this module, I am committed to providing support free of + cost. You will need to provide me server ssh access or + database access in order to solve the issue. +

    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    +
    +

    Changelog(s)

    +
    + +

    + v14.0.1.0.2 + - + December 10, 2022 +

    +

    + Minor bug fix. +

    + +

    + v14.0.0.0.0 + - + November 23, 2022 +

    +

    + Initial release for v14 +

    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    +

    + Need a help for this module? +

    +

    + Contact me + info@terabits.xyz + for your queries +

    +
    +
    + + +
    \ No newline at end of file diff --git a/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_fields.js b/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_fields.js old mode 100644 new mode 100755 index 878644296..77cffb97f --- a/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_fields.js +++ b/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_fields.js @@ -12,7 +12,7 @@ var config = require('web.config'); var core = require('web.core'); var Domain = require('web.Domain'); var DomainSelector = require('advanced_web_domain_widget.TerabitsDomainSelector'); -var DomainSelectorDialog = require('advanced_web_domain_widget.DomainSelectorDialog'); +var {DomainSelectorDialog, DomainSelectorDialog2} = require('advanced_web_domain_widget.DomainSelectorDialog'); var view_dialogs = require('web.view_dialogs'); require("web.zoomodoo"); @@ -439,8 +439,61 @@ var TerabitsFieldDomain = AbstractField.extend({ }, }); +var TerabitsFieldDomain2 = TerabitsFieldDomain.extend({ + _replaceContent: function () { + if (this._$content) { + this._$content.remove(); + } + this._$content = $(qweb.render("TerabitsFieldDomain.content2", { + hasModel: !!this._domainModel, + isValid: !!this._isValidForModel, + nbRecords: this.record.specialData[this.name].nbRecords || 0, + inDialogEdit: this.inDialog && this.mode === "edit", + isDateFilter: this.value[0] && this.value[0]?.length>0? this.value[0][1] == "date_filter": false + })); + this._$content.appendTo(this.$el); + }, + + _render: function () { + // If there is no model, only change the non-domain-selector content + if (!this._domainModel) { + this._replaceContent(); + return Promise.resolve(); + } + + // Convert char value to array value + var value = this.value || "[]"; + + // Create the domain selector or change the value of the current one... + var def; + + if (!this.domainSelector) { + this.domainSelector = new DomainSelector.TerabitsDomainSelector2(this, this._domainModel, value, { + readonly: this.mode === "readonly" || this.inDialog, + filters: this.fsFilters, + debugMode: config.isDebug(), + }); + def = this.domainSelector.prependTo(this.$el); + } else { + def = this.domainSelector.setDomain(value); + } + // ... then replace the other content (matched records, etc) + return def.then(this._replaceContent.bind(this)); + }, + + _onDialogEditButtonClick: function (e) { + e.preventDefault(); + new DomainSelectorDialog2(this, this._domainModel, this.value || "[]", { + readonly: this.mode === "readonly", + filters: this.fsFilters, + debugMode: config.isDebug(), + }).open(); + }, +}) + return { TerabitsFieldDomain: TerabitsFieldDomain, + TerabitsFieldDomain2: TerabitsFieldDomain2 }; }); diff --git a/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_model.js b/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_model.js old mode 100644 new mode 100755 index 281dc23ec..ce3728411 --- a/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_model.js +++ b/odex25_base/advanced_web_domain_widget/static/src/js/fields/basic_model.js @@ -239,7 +239,7 @@ BasicModel.include({ }); self._rpc({ model: domainModel, - method: 'search_count', + method: 'get_widget_count', args: [newDomain], context: context }) diff --git a/odex25_base/advanced_web_domain_widget/static/src/js/fields/terabits_fields_registry.js b/odex25_base/advanced_web_domain_widget/static/src/js/fields/terabits_fields_registry.js old mode 100644 new mode 100755 index 2a401ab34..75eb94b79 --- a/odex25_base/advanced_web_domain_widget/static/src/js/fields/terabits_fields_registry.js +++ b/odex25_base/advanced_web_domain_widget/static/src/js/fields/terabits_fields_registry.js @@ -6,6 +6,7 @@ odoo.define('advanced_web_domain_widget._terabits_field_registry', function (req // Basic fields fieldRegistry.add('terabits_domain', basic_fields.TerabitsFieldDomain); + fieldRegistry.add('terabits_field_domain', basic_fields.TerabitsFieldDomain2); }); diff --git a/odex25_base/advanced_web_domain_widget/static/src/js/widget/TerabitsDomainSelector.js b/odex25_base/advanced_web_domain_widget/static/src/js/widget/TerabitsDomainSelector.js old mode 100644 new mode 100755 index 04cbaa594..24f0b16f2 --- a/odex25_base/advanced_web_domain_widget/static/src/js/widget/TerabitsDomainSelector.js +++ b/odex25_base/advanced_web_domain_widget/static/src/js/widget/TerabitsDomainSelector.js @@ -5,7 +5,7 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi var datepicker = require("web.datepicker"); var Domain = require("web.Domain"); var field_utils = require("web.field_utils"); - var ModelFieldSelector = require("advanced_web_domain_widget.ModelFieldSelector"); + var {ModelFieldSelector, ModelFieldSelector2} = require("advanced_web_domain_widget.ModelFieldSelector"); var ModelRecordSelector = require("advanced_web_domain_widget.ModelRecordSelector"); var Widget = require("web.Widget"); var _t = core._t; @@ -451,6 +451,33 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi }, }); + var TerabitsDomainTree2 = TerabitsDomainTree.extend({ + _addChild: function (domain, afterNode) { + var i = afterNode ? _.indexOf(this.children, afterNode) : this.children.length; + if (i < 0) return false; + + this.children.splice(i + 1, 0, instantiateNode2(this, this.model, domain, this.options)); + this.trigger_up("domain_changed", { child: this }); + return true; + }, + + _addFlattenedChildren: function (domain) { + var node = instantiateNode2(this, this.model, domain, this.options); + if (node === null) { + return; + } + if (!node.children || node.operator !== this.operator) { + this.children.push(node); + return; + } + _.each(node.children, (function (child) { + child.setParent(this); + this.children.push(child); + }).bind(this)); + node.destroy(); + }, + }) + /** * The TerabitsDomainSelector widget can be used to build prefix char domain. It is the * TerabitsDomainTree specialization to use to have a fully working widget. @@ -611,6 +638,154 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi }, }); + var TerabitsDomainSelector2 = TerabitsDomainTree2.extend({ + template: "TerabitsDomainSelector", + events: _.extend({}, TerabitsDomainTree.prototype.events, { + "click .o_domain_add_first_node_button": "_onAddFirstButtonClick", + "change .o_domain_debug_input": "_onDebugInputChange", + }), + custom_events: _.extend({}, TerabitsDomainTree.prototype.custom_events, { + domain_changed: "_onDomainChange", + }), + + start: function () { + var self = this; + return this._super.apply(this, arguments).then(function () { + if (self.invalidDomain) { + var msg = _t("This domain is not supported."); + self.$el.html(msg); + } + }); + }, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * Changes the internal domain value and forces a reparsing and rerendering. + * If the internal domain value was already equal to the given one, this + * does nothing. + * + * @param {string} domain + * @returns {Promise} resolved when the rerendering is finished + */ + setDomain: function (domain) { + if (domain === Domain.prototype.arrayToString(this.getDomain())) { + return Promise.resolve(); + } + var parsedDomain = this._parseDomain(domain); + if (parsedDomain) { + return this._redraw(parsedDomain); + } + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @see TerabitsDomainTree._initialize + */ + _initialize: function (domain) { + // Check if the domain starts with implicit "&" operators and make them + // explicit. As the TerabitsDomainSelector is a specialization of a TerabitsDomainTree, + // it is waiting for a tree and not a leaf. So [] and [A] will be made + // explicit with ["&"], ["&", A] so that tree parsing is made correctly. + // Note: the domain is considered to be a valid one + if (domain.length > 1) { + Domain.prototype.normalizeArray(domain); + } else { + domain = ["&"].concat(domain); + } + return this._super(domain); + }, + /** + * @see TerabitsDomainTree._postRender + * Warns the user if the domain is not valid after rendering. + */ + _postRender: function () { + this._super.apply(this, arguments); + + // Display technical domain if in debug mode + this.$debugInput = this.$(".o_domain_debug_input"); + if (this.$debugInput.length) { + this.$debugInput.val(Domain.prototype.arrayToString(this.getDomain())); + } + + // Warn the user if the domain is not valid after rendering + if (!this._isValid) { + this.do_warn(false, _t("Domain not supported")); + } + }, + /** + * This method is ugly but achieves the right behavior without flickering. + * + * @param {Array|string} domain + * @returns {Promise} + */ + _redraw: function (domain) { + var oldChildren = this.children.slice(); + this._initialize(domain || this.getDomain()); + return this._renderChildrenTo($("
    ")).then((function () { + _.each(oldChildren, function (child) { child.destroy(); }); + this.renderElement(); + this._postRender(); + _.each(this.children, (function (child) { + if(child.$el){ + child.$el.appendTo(this.$childrenContainer); + } + }).bind(this)); + }).bind(this)); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Called when the "add a filter" button is clicked -> adds a first domain + * node + */ + _onAddFirstButtonClick: function () { + this._addChild(this.options.default || [["id", "=", 1]]); + }, + /** + * Called when the debug input value is changed -> constructs the tree + * representation if valid or warn the user if invalid. + * + * @param {Event} e + */ + _onDebugInputChange: function (e) { + // When the debug input changes, the string prefix domain is read. If it + // is syntax-valid the widget is re-rendered and notifies the parents. + // If not, a warning is shown to the user and the input is ignored. + var domain; + try { + domain = Domain.prototype.stringToArray($(e.currentTarget).val()); + } catch (err) { // If there is a syntax error, just ignore the change + this.do_warn(_t("Syntax error"), _t("Domain not properly formed")); + return; + } + this._redraw(domain).then((function () { + this.trigger_up("domain_changed", { child: this, alreadyRedrawn: true }); + }).bind(this)); + }, + /** + * Called when a (child's) domain has changed -> redraw the entire tree + * representation if necessary + * + * @param {OdooEvent} e + */ + _onDomainChange: function (e) { + // If a subdomain notifies that it underwent some modifications, the + // TerabitsDomainSelector catches the message and performs a full re-rendering. + if (!e.data.alreadyRedrawn) { + this._redraw(); + } + }, + }); + /** * TerabitsDomainNode which handles a domain which cannot be split in another * subdomains, i.e. composed of a field chain, an operator and a value. @@ -711,13 +886,21 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi const ids = (this.value) ? this.value : []; wDefs.push(this._rpc({ model: model_rel, - method: 'search_read', + method: 'get_widget_name', kwargs: { domain: [['id', 'in', ids]], fields: ['id', 'display_name'], }, }).then(function (data) { self.value = []; + if(model_rel == 'res.users' && _.contains(ids,0)){ + self.tagsvalues.push([0, 'Environment User']); + self.value.push(0); + } + if(model_rel == 'res.company' && _.contains(ids,0)){ + self.tagsvalues.push([0, 'Environment Company']); + self.value.push(0); + } _.each(data, function (rec, index) { self.tagsvalues.push([rec.id, rec.display_name]); // to remove invalid id which is not in records @@ -1065,6 +1248,126 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi }, }); + var TerabitsDomainLeaf2 = TerabitsDomainLeaf.extend({ + willStart: function () { + var defs = [this._super.apply(this, arguments)]; + + // In edit mode, instantiate a field selector. This is done here in + // willStart and prepared by appending it to a dummy element because the + // TerabitsDomainLeaf rendering need some information which cannot be computed + // before the ModelFieldSelector is fully rendered (TODO). + + this.fieldSelector = new ModelFieldSelector2( + this, + this.model, + this.chain !== undefined ? this.chain.toString().split(".") : [], + this.options + ); + defs.push(this.fieldSelector.appendTo($("
    ")).then((function () { + var wDefs = []; + var selectedField = this.fieldSelector.getSelectedField() || {}; + if ((this.operator == 'in' && _.contains(['many2one', 'many2many', 'one2many'], selectedField.type) || selectedField.name == "id") && typeof (this.currentDomain[0][2][0]) == 'string') { + this.value = []; + } else { + this.value = this.currentDomain[0][2]; + } + this.title = selectedField.string; + this.recordReader = new ModelRecordSelector( + this, + selectedField.relation, + this.chain !== undefined ? this.chain.toString().split(".") : [], + this.options, + this.title + ); + if (!this.readonly) { + // Set list of operators according to field type + this.displayValue = this.value; + this.operators = this._getOperatorsFromType(selectedField.type, selectedField.name); + if (_.contains(["child_of", "parent_of", "like", "not like", "=like", "=ilike"], this.operator)) { + // In case user entered manually or from demo data + this.operators[this.operator] = operator_mapping[this.operator]; + } else if (!this.operators[this.operator]) { + // In case the domain uses an unsupported operator for the + // field type + this.operators[this.operator] = "?"; + } + // Set list of values according to field type + + this.selectionChoices = null; + if (selectedField.type === "boolean") { + this.selectionChoices = [["1", _t("set (true)")], ["0", _t("not set (false)")]]; + } else if (selectedField.type === "selection") { + this.selectionChoices = selectedField.selection; + } + else if ((_.contains(['many2one', 'many2many', 'one2many'], selectedField.type) || selectedField.name == "id") && (_.contains(['in', 'not in'], this.operator))) { + var model_rel = selectedField.name == "id"? selectedField.model: selectedField.relation + // var def = this.get_rec(model_rel) + // var model_rel = selectedField.relation + this.selectionChoices = null + // this.recordReader.appendTo($("
    ")) + var self = this; + const ids = (this.value) ? this.value : []; + wDefs.push(this._rpc({ + model: model_rel, + method: 'get_widget_name', + kwargs: { + domain: [['id', 'in', ids]], + fields: ['id', 'display_name'], + }, + }).then(function (data) { + self.value = []; + if(model_rel == 'res.users' && _.contains(ids,0)){ + self.tagsvalues.push([0, 'Environment User']); + self.value.push(0); + } + if(model_rel == 'res.company' && _.contains(ids,0)){ + self.tagsvalues.push([0, 'Environment Company']); + self.value.push(0); + } + _.each(data, function (rec, index) { + self.tagsvalues.push([rec.id, rec.display_name]); + // to remove invalid id which is not in records + self.value.push(rec.id); + + }) + })); + + wDefs.push(this.recordReader.appendTo($('
    ')).then((function () { + this.displayValue = []; + // this.value = []; + }).bind(this))); + } + // Adapt display value and operator for rendering + + try { + if (selectedField && !selectedField.relation && !_.isArray(this.value)) { + this.displayValue = field_utils.format[selectedField.type](this.value, selectedField); + } + } catch (err) {/**/ } + this.displayOperator = this.operator; + if (selectedField.type === "boolean") { + this.displayValue = this.value ? "1" : "0"; + } else if ((this.operator === "!=" || this.operator === "=") && this.value === false) { + this.displayOperator = this.operator === "!=" ? "set" : "not set"; + } + // TODO the value could be a m2o input, etc... + if (_.contains(["date", "datetime"], selectedField.type)) { + this.valueWidget = new (selectedField.type === "datetime" ? datepicker.DateTimeWidget : datepicker.DateWidget)(this); + wDefs.push(this.valueWidget.appendTo("
    ").then((function () { + this.valueWidget.$el.addClass("o_domain_leaf_value_input"); + this.valueWidget.setValue(moment(this.value)); + this.valueWidget.on("datetime_changed", this, function () { + this._changeValue(this.valueWidget.getValue()); + }); + }).bind(this))); + } + return Promise.all(wDefs); + } + }).bind(this))); + + return Promise.all(defs); + }, + }) /** @@ -1086,8 +1389,19 @@ odoo.define("advanced_web_domain_widget.TerabitsDomainSelector", function (requi return null } + function instantiateNode2(parent, model, domain, options) { + if (domain.length > 1) { + return new TerabitsDomainTree2(parent, model, domain, options); + } else if (domain.length === 1) { + return new TerabitsDomainLeaf2(parent, model, domain, options); + } + return null + } + return { TerabitsDomainSelector:TerabitsDomainSelector, - TerabitsDomainLeaf:TerabitsDomainLeaf + TerabitsDomainSelector2:TerabitsDomainSelector2, + TerabitsDomainLeaf:TerabitsDomainLeaf, + TerabitsDomainLeaf2:TerabitsDomainLeaf2, }; }); diff --git a/odex25_base/advanced_web_domain_widget/static/src/js/widget/domain_selector_dialog.js b/odex25_base/advanced_web_domain_widget/static/src/js/widget/domain_selector_dialog.js old mode 100644 new mode 100755 index 50f801a99..1092863c2 --- a/odex25_base/advanced_web_domain_widget/static/src/js/widget/domain_selector_dialog.js +++ b/odex25_base/advanced_web_domain_widget/static/src/js/widget/domain_selector_dialog.js @@ -10,7 +10,7 @@ odoo.define("advanced_web_domain_widget.DomainSelectorDialog", function (require /** * @class DomainSelectorDialog */ - return Dialog.extend({ + var DomainSelectorDialog = Dialog.extend({ init: function (parent, model, domain, options) { this.model = model; this.options = _.extend({ @@ -51,5 +51,40 @@ odoo.define("advanced_web_domain_widget.DomainSelectorDialog", function (require ]); }, }); + + var DomainSelectorDialog2 = DomainSelectorDialog.extend({ + init: function (parent, model, domain, options) { + this.model = model; + this.options = _.extend({ + readonly: true, + debugMode: false, + }, options || {}); + + var buttons; + if (this.options.readonly) { + buttons = [ + {text: _t("Close"), close: true}, + ]; + } else { + buttons = [ + {text: _t("Save"), classes: "btn-primary", close: true, click: function () { + this.trigger_up("domain_selected", {domain: this.domainSelector.getDomain()}); + }}, + {text: _t("Discard"), close: true}, + ]; + } + + this._super(parent, _.extend({}, { + title: _t("Domain"), + buttons: buttons, + }, options || {})); + + this.domainSelector = new DomainSelector.TerabitsDomainSelector2(this, model, domain, options); + }, + }) + return { + DomainSelectorDialog: DomainSelectorDialog, + DomainSelectorDialog2: DomainSelectorDialog2 + } }); \ No newline at end of file diff --git a/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_field_selector.js b/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_field_selector.js old mode 100644 new mode 100755 index 4d86e73f4..a0d40f550 --- a/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_field_selector.js +++ b/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_field_selector.js @@ -586,7 +586,66 @@ var TerabitsModelFieldSelector = Widget.extend({ } }); -return TerabitsModelFieldSelector; +var TerabitsModelFieldSelector2 = TerabitsModelFieldSelector.extend({ + _render: function () { + + // Render the chain value + this.$value.html(core.qweb.render(this.template + ".value", { + chain: this.chain, + pages: this.pages, + })); + + // Toggle the warning message + this.$valid.toggleClass('d-none', !!this.isValid()); + + // Adapt the popover content + var page = _.last(this.pages); + var title = ""; + if (this.pages.length > 1) { + var prevField = _.findWhere(this.pages[this.pages.length - 2], { + name: (this.chain.length === this.pages.length) ? this.chain[this.chain.length - 2] : _.last(this.chain), + }); + if (prevField) title = prevField.string; + } + this.$(".o_field_selector_popover_header .o_field_selector_title").text(title); + + var lines = _.filter(page, this.options.filter); + if (this.searchValue) { + var matches = fuzzy.filter(this.searchValue, _.pluck(lines, 'string')); + lines = _.map(_.pluck(matches, 'index'), function (i) { + return lines[i]; + }); + } + + this.$(".o_field_selector_page").replaceWith(core.qweb.render(this.template + ".page2", { + lines: lines, + followRelations: this.options.followRelations, + debug: this.options.debugMode, + })); + this.$input.val(this.chain.join(".")); + }, + + + _pushPageData: function (model) { + var def; + if (this.model === model && this.options.fields) { + def = Promise.resolve(sortFields(this.options.fields, model, this.options.order)); + } else { + def = this._getModelFieldsFromCache(model, this.options.filters); + } + return def.then((function (fields) { + if(this.pages.length <= 0) + this.pages.push(fields); + }).bind(this)); + }, + + + _onPrevPageClick: function () { + // this._goToPrevPage(); + }, +}) +return {ModelFieldSelector: TerabitsModelFieldSelector, + ModelFieldSelector2: TerabitsModelFieldSelector2}; /** * Allows to transform a mapping field name -> field info in an array of the diff --git a/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_record_selector.js b/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_record_selector.js old mode 100644 new mode 100755 index 8564f0853..049dc64c2 --- a/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_record_selector.js +++ b/odex25_base/advanced_web_domain_widget/static/src/js/widget/model_record_selector.js @@ -104,7 +104,7 @@ odoo.define("advanced_web_domain_widget.ModelRecordSelector", function (require) ; var def = this._rpc({ model: model, - method: 'search_read', + method: 'get_widget_name', kwargs: { domain: [], fields: ['id', 'display_name'], @@ -113,6 +113,12 @@ odoo.define("advanced_web_domain_widget.ModelRecordSelector", function (require) if (data) { this.records = data } + if(model == 'res.users'){ + this.records.push({'id': 0, 'display_name': 'Environment User'}) + } + if(model == 'res.company'){ + this.records.push({'id': 0, 'display_name': 'Environment Company'}) + } // if(model == 'res.users'){ // this.records.push({'id':0,'display_name':'Environment User'}) // } diff --git a/odex25_base/advanced_web_domain_widget/static/src/scss/style.scss b/odex25_base/advanced_web_domain_widget/static/src/scss/style.scss old mode 100644 new mode 100755 diff --git a/odex25_base/advanced_web_domain_widget/static/src/xml/domain_base.xml b/odex25_base/advanced_web_domain_widget/static/src/xml/domain_base.xml old mode 100644 new mode 100755 index 9f884cf3e..f804e4ecf --- a/odex25_base/advanced_web_domain_widget/static/src/xml/domain_base.xml +++ b/odex25_base/advanced_web_domain_widget/static/src/xml/domain_base.xml @@ -16,6 +16,22 @@
    Select a model to add a filter.
    + + +
    + + + Invalid domain + + + +
    +
    Select a model to add a filter.
    +