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.

135 lines
4.4 KiB

  1. /**********************************************************************************
  2. *
  3. * Copyright (c) 2017-2019 MuK IT GmbH.
  4. *
  5. * This file is part of MuK Backend Theme
  6. * (see https://mukit.at).
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. **********************************************************************************/
  22. odoo.define('muk_web_theme.MenuSearchMixin', function (require) {
  23. "use strict";
  24. var core = require('web.core');
  25. var config = require("web.config");
  26. var session = require("web.session");
  27. var _t = core._t;
  28. var QWeb = core.qweb;
  29. var MenuSearchMixin = {
  30. _findNames: function (memo, menu) {
  31. if (menu.action) {
  32. var key = menu.parent_id ? menu.parent_id[1] + "/" : "";
  33. memo[key + menu.name] = menu;
  34. }
  35. if (menu.children.length) {
  36. _.reduce(menu.children, this._findNames.bind(this), memo);
  37. }
  38. return memo;
  39. },
  40. _menuInfo: function (key) {
  41. var original = this._searchableMenus[key];
  42. return _.extend({
  43. action_id: parseInt(original.action.split(',')[1], 10),
  44. }, original);
  45. },
  46. _searchFocus: function () {
  47. if (!config.device.isMobile) {
  48. this.$search_input.focus();
  49. } else {
  50. this.$search_input.blur();
  51. }
  52. },
  53. _searchReset: function () {
  54. this.$search_container.removeClass("has-results");
  55. this.$search_results.empty();
  56. this.$search_input.val("");
  57. },
  58. _searchMenusSchedule: function () {
  59. this._search_def.reject();
  60. this._search_def = $.Deferred();
  61. setTimeout(this._search_def.resolve.bind(this._search_def), 50);
  62. this._search_def.done(this._searchMenus.bind(this));
  63. },
  64. _searchMenus: function () {
  65. var query = this.$search_input.val();
  66. if (query === "") {
  67. this.$search_container.removeClass("has-results");
  68. this.$search_results.empty();
  69. return;
  70. }
  71. var results = fuzzy.filter(query, _.keys(this._searchableMenus), {
  72. pre: "<b>",
  73. post: "</b>",
  74. });
  75. this.$search_container.toggleClass("has-results", Boolean(results.length));
  76. this.$search_results.html(QWeb.render("muk_web_theme.MenuSearchResults", {
  77. results: results,
  78. widget: this,
  79. }));
  80. },
  81. _onSearchResultsNavigate: function (event) {
  82. if (this.$search_results.html().trim() === "") {
  83. this._searchMenusSchedule();
  84. return;
  85. }
  86. var all = this.$search_results.find(".mk_menu_search_result");
  87. var key = event.key || String.fromCharCode(event.which);
  88. var pre_focused = all.filter(".active") || $(all[0]);
  89. var offset = all.index(pre_focused);
  90. if (key === "Tab") {
  91. event.preventDefault();
  92. key = event.shiftKey ? "ArrowUp" : "ArrowDown";
  93. }
  94. switch (key) {
  95. case "Enter":
  96. pre_focused.click();
  97. break;
  98. case "ArrowUp":
  99. offset--;
  100. break;
  101. case "ArrowDown":
  102. offset++;
  103. break;
  104. default:
  105. this._searchMenusSchedule();
  106. return;
  107. }
  108. if (offset < 0) {
  109. offset = all.length + offset;
  110. } else if (offset >= all.length) {
  111. offset -= all.length;
  112. }
  113. var new_focused = $(all[offset]);
  114. pre_focused.removeClass("active");
  115. new_focused.addClass("active");
  116. this.$search_results.scrollTo(new_focused, {
  117. offset: {
  118. top: this.$search_results.height() * -0.5,
  119. },
  120. });
  121. },
  122. _onMenuShown: function(event) {
  123. this._searchFocus();
  124. },
  125. _onMenuHidden: function(event) {
  126. this._searchReset();
  127. },
  128. };
  129. return MenuSearchMixin;
  130. });