You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

242 lines
7.8 KiB

  1. /* Copyright 2019 Onestein
  2. * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
  3. odoo.define('web_edit_user_filter', function (require) {
  4. "use strict";
  5. var FavoriteMenu = require('web.FavoriteMenu'),
  6. core = require('web.core'),
  7. SearchView = require('web.SearchView');
  8. var qweb = core.qweb;
  9. var _t = core._t;
  10. FavoriteMenu.include({
  11. /**
  12. * Adds the facets data to the filter.
  13. *
  14. * @override
  15. * @private
  16. */
  17. _createFilter: function (filter) {
  18. var facets = [];
  19. this.query.each(function (facet) {
  20. var json_facet = facet.attributes;
  21. json_facet.values = facet.get('values');
  22. _.each(json_facet.values, function (value, i) {
  23. if (typeof value.value === 'object' &&
  24. 'attrs' in value.value) {
  25. json_facet.values[i] = {
  26. attrs: value.value.attrs,
  27. };
  28. }
  29. });
  30. if ('field' in json_facet) {
  31. json_facet.field = {
  32. attrs: json_facet.field.attrs,
  33. };
  34. }
  35. facets.push(json_facet);
  36. });
  37. filter.facet = JSON.stringify(facets);
  38. return this._super(filter);
  39. },
  40. /**
  41. * Adds the edit button to the favourite filter menu item.
  42. *
  43. * @override
  44. * @private
  45. */
  46. append_filter: function (filter) {
  47. var self = this;
  48. var res = this._super(filter);
  49. var key = this.key_for(filter);
  50. this.$filters[key].append($('<span>', {
  51. class: 'fa fa-pencil o-edit-user-filter',
  52. on: {
  53. click: function (event) {
  54. event.stopImmediatePropagation();
  55. self._unpackFilter(filter);
  56. },
  57. },
  58. }));
  59. return res;
  60. },
  61. /**
  62. * Unpacks a saved filter and updates the search view's facets.
  63. *
  64. * @private
  65. */
  66. _unpackFilter: function (filter) {
  67. var self = this;
  68. var facets = JSON.parse(filter.facet);
  69. var new_facets = [];
  70. this.query.reset([]);
  71. _.each(facets, function (segment) {
  72. if (segment.cat === 'groupByCategory') {
  73. _.each(segment.values, function (value) {
  74. var groupBy = _.find(
  75. self.searchview.groupbysMapping,
  76. function (mapping) {
  77. return mapping.groupby.attrs.context === value.attrs.context;
  78. }
  79. );
  80. var eventData = {
  81. category: 'groupByCategory',
  82. itemId: groupBy.groupbyId,
  83. isActive: true,
  84. groupId: groupBy.groupId,
  85. };
  86. self.trigger_up('menu_item_toggled', eventData);
  87. });
  88. } else if (segment.cat === 'filterCategory') {
  89. _.each(segment.values, function (value) {
  90. var filterDomain = _.find(
  91. self.searchview.filtersMapping,
  92. function (mapping) {
  93. return mapping.filter.attrs.domain === value.attrs.domain;
  94. }
  95. );
  96. var eventData = {
  97. category: 'filterCategory',
  98. itemId: filterDomain.filterId,
  99. isActive: true,
  100. groupId: filterDomain.groupId,
  101. };
  102. self.trigger_up('menu_item_toggled', eventData);
  103. });
  104. } else {
  105. var search_widget = _.find(
  106. self.searchview.search_fields, function (f) {
  107. return f.attrs.name === segment.field.attrs.name;
  108. }
  109. );
  110. new_facets.push({
  111. category: segment.category,
  112. field: search_widget,
  113. values: segment.values,
  114. });
  115. }
  116. });
  117. this.query.add(new_facets);
  118. },
  119. });
  120. SearchView.include({
  121. /**
  122. * Removes a value from a facet.
  123. *
  124. * @private
  125. * @param {Backbone.Model} model
  126. * @param {Integer|Object} value The value to remove
  127. */
  128. _removeValue: function (model, value) {
  129. var toRemove = model.values.filter(function (v) {
  130. if (typeof v.attributes.value === 'object') {
  131. return v.attributes.value.attrs.name === value;
  132. }
  133. return v.attributes.value.toString() === value;
  134. });
  135. model.values.remove(toRemove);
  136. },
  137. /**
  138. * Renders a popover for a facet.
  139. *
  140. * @private
  141. * @param {jQuery} $facet Element of the facet
  142. * @param {Backbone.Model} model
  143. */
  144. _renderPopover: function ($facet, model) {
  145. var self = this;
  146. var $content = $(qweb.render('web_edit_user_filter.Popover', {
  147. values: model.get('values'),
  148. }));
  149. // Cannot use Widget.events here because renderFacets is
  150. // triggered apart from renderElement
  151. $content.find('.list-group-item').click(function () {
  152. self._removeValue(model, $(this).attr('data-value'));
  153. });
  154. $facet.popover({
  155. title: _t('Edit Facet'),
  156. template: qweb.render('web_edit_user_filter.PopoverTemplate'),
  157. content: $content,
  158. container: this.$el,
  159. html: true,
  160. trigger: 'manual',
  161. placement: 'bottom',
  162. animation: false,
  163. });
  164. },
  165. /**
  166. * Hides all popovers.
  167. *
  168. * @private
  169. */
  170. _hidePopovers: function () {
  171. this.$el.find('.popover').popover('hide');
  172. },
  173. /**
  174. * @override
  175. */
  176. renderFacets: function () {
  177. var self = this;
  178. var res = this._super.apply(this, arguments);
  179. this.$el.find('.o-edit-user-filter-popover').remove();
  180. _.each(this.input_subviews, function (input_subview) {
  181. if (!input_subview.model ||
  182. input_subview.model.attributes.is_custom_filter) {
  183. return;
  184. }
  185. input_subview.$el.addClass('o-edit-user-filter-editable');
  186. self._renderPopover(input_subview.$el, input_subview.model);
  187. input_subview.$el.click(function () {
  188. self._hidePopovers();
  189. input_subview.$el.popover('show');
  190. });
  191. });
  192. return res;
  193. },
  194. /**
  195. * @override
  196. */
  197. start: function () {
  198. var self = this;
  199. var res = this._super.apply(this, arguments);
  200. this._proxyHidePopovers = this.proxy('_hidePopovers');
  201. $(document).click(this._proxyHidePopovers);
  202. return res;
  203. },
  204. /**
  205. * @override
  206. */
  207. destroy: function () {
  208. var res = this._super.apply(this, arguments);
  209. $(document).unbind('click', this._proxyHidePopovers);
  210. return res;
  211. }
  212. });
  213. });