5 changed files with 119 additions and 68 deletions
@ -1,34 +1,109 @@ |
|||||
/** @odoo-module **/ |
/** @odoo-module **/ |
||||
|
|
||||
import { NavBar } from "@web/webclient/navbar/navbar"; |
import { NavBar } from "@web/webclient/navbar/navbar"; |
||||
|
const { fuzzyLookup } = require('@web/core/utils/search'); |
||||
|
import { computeAppsAndMenuItems } from "@web/webclient/menus/menu_helpers"; |
||||
|
const { onMounted, useState, useRef } = owl; |
||||
import { patch } from "@web/core/utils/patch"; |
import { patch } from "@web/core/utils/patch"; |
||||
import { useRef, onMounted } from "@odoo/owl"; |
|
||||
|
|
||||
patch(NavBar.prototype, { |
patch(NavBar.prototype, { |
||||
setup() { |
setup() { |
||||
super.setup(); |
super.setup(); |
||||
|
|
||||
// Attach a ref for the root element
|
// Attach a ref for the root element
|
||||
this.sideRoot = useRef("side_root"); |
this.searchState = useState({ |
||||
|
searchResults: [], |
||||
|
hasResults: false, |
||||
|
showResults: false, |
||||
|
query: "" |
||||
|
}); |
||||
|
this.searchInputRef = useRef("searchInput"); |
||||
|
this._searchTimeout = null; |
||||
|
let { apps, menuItems } = computeAppsAndMenuItems(this.menuService.getMenuAsTree("root")); |
||||
|
this._apps = apps; |
||||
|
this._searchableMenus = menuItems; |
||||
|
}, |
||||
|
|
||||
// Ensure that DOM manipulation happens after mounting
|
openSidebar(ev) { |
||||
onMounted(this.handleMounted.bind(this)); |
const sidebarPanel = ev.target.closest('header').querySelector('#sidebar_panel'); |
||||
|
const actionManager = document.body.querySelector('.o_action_manager'); |
||||
|
if (!ev.target.classList.contains('opened')) { |
||||
|
sidebarPanel.style.display = 'block'; |
||||
|
ev.target.classList.toggle('opened'); |
||||
|
actionManager.style.marginLeft = '320px'; |
||||
|
actionManager.style.transition = 'all .1s linear'; |
||||
|
} else { |
||||
|
sidebarPanel.style.display = 'none'; |
||||
|
ev.target.classList.toggle('opened'); |
||||
|
actionManager.style.marginLeft = '0px'; |
||||
|
} |
||||
|
}, |
||||
|
clickSidebar(ev) { |
||||
|
this.searchState.query = ""; |
||||
|
this.searchInputRef.el.value = ""; |
||||
|
this.searchState.searchResults = []; |
||||
|
this.searchState.hasResults = false; |
||||
|
this.searchState.showResults = false; |
||||
|
const sidebarPanel = ev.target.closest('header').querySelector('#sidebar_panel'); |
||||
|
const actionManager = document.body.querySelector('.o_action_manager'); |
||||
|
sidebarPanel.style.display = 'none'; |
||||
|
actionManager.style.marginLeft = '0px'; |
||||
}, |
}, |
||||
|
|
||||
handleMounted() { |
_searchMenusSchedule(ev) { |
||||
// Access the DOM element for the sidebar panel
|
const query = ev.target.value; |
||||
if (!this.sideRoot.el) { |
this.searchState.query = query; |
||||
console.error("sideRoot.el is not defined. Check the template structure."); |
|
||||
return; |
// Clear previous timeout
|
||||
|
if (this._searchTimeout) { |
||||
|
clearTimeout(this._searchTimeout); |
||||
} |
} |
||||
|
|
||||
this.$searchContainer = this.sideRoot.el.querySelector(".search-container"); |
// Debounce search
|
||||
this.$searchInput = this.sideRoot.el.querySelector(".search-input"); |
this._searchTimeout = setTimeout(() => { |
||||
this.$searchResults = this.sideRoot.el.querySelector(".search-results"); |
this._searchMenus(query); |
||||
this.$appMenu = this.sideRoot.el.querySelector(".app-menu"); |
}, 50); |
||||
|
}, |
||||
|
|
||||
if (!this.$searchContainer || !this.$searchInput) { |
_searchMenus(query) { |
||||
console.error("Required elements not found in the DOM."); |
if (query === "") { |
||||
|
this.searchState.searchResults = []; |
||||
|
this.searchState.hasResults = false; |
||||
|
this.searchState.showResults = false; |
||||
|
return; |
||||
} |
} |
||||
|
|
||||
|
this.searchState.showResults = true; |
||||
|
var results = []; |
||||
|
|
||||
|
// Search for all apps
|
||||
|
fuzzyLookup(query, this._apps, (menu) => menu.label) |
||||
|
.forEach((menu) => { |
||||
|
results.push({ |
||||
|
category: "apps", |
||||
|
name: menu.label, |
||||
|
actionID: menu.actionID, |
||||
|
id: menu.id, |
||||
|
webIconData: menu.webIconData, |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
// Search for all content
|
||||
|
fuzzyLookup(query, this._searchableMenus, (menu) => |
||||
|
(menu.parents + " / " + menu.label).split("/").reverse().join("/") |
||||
|
).forEach((menu) => { |
||||
|
results.push({ |
||||
|
category: "menu_items", |
||||
|
name: menu.parents + " / " + menu.label, |
||||
|
actionID: menu.actionID, |
||||
|
id: menu.id, |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
this.searchState.searchResults = results; |
||||
|
this.searchState.hasResults = results.length > 0; |
||||
|
}, |
||||
|
|
||||
|
getMenuUrl(actionID, menuId) { |
||||
|
return `/web#action=${actionID}&menu_id=${menuId}`; |
||||
}, |
}, |
||||
}); |
}); |
||||
|
@ -1,33 +0,0 @@ |
|||||
/** @odoo-module **/ |
|
||||
import { NavBar } from "@web/webclient/navbar/navbar"; |
|
||||
import { patch } from "@web/core/utils/patch"; |
|
||||
|
|
||||
// Patch NavBar for adding new sidebar functionality
|
|
||||
patch(NavBar.prototype, { |
|
||||
setup() { |
|
||||
super.setup(); |
|
||||
}, |
|
||||
|
|
||||
// Toggle sidebar on click
|
|
||||
openSidebar(ev) { |
|
||||
const sidebarPanel = ev.target.closest('header').querySelector('#sidebar_panel'); |
|
||||
const actionManager = document.body.querySelector('.o_action_manager'); |
|
||||
|
|
||||
if (!ev.target.classList.contains('opened')) { |
|
||||
sidebarPanel.style.display = 'block'; |
|
||||
ev.target.classList.toggle('opened'); |
|
||||
actionManager.style.marginLeft = '320px'; |
|
||||
actionManager.style.transition = 'all .1s linear'; |
|
||||
} else { |
|
||||
sidebarPanel.style.display = 'none'; |
|
||||
ev.target.classList.toggle('opened'); |
|
||||
actionManager.style.marginLeft = '0px'; |
|
||||
} |
|
||||
}, |
|
||||
clickSidebar(ev) { |
|
||||
const sidebarPanel = ev.target.closest('header').querySelector('#sidebar_panel'); |
|
||||
const actionManager = document.body.querySelector('.o_action_manager'); |
|
||||
sidebarPanel.style.display = 'none'; |
|
||||
actionManager.style.marginLeft = '0px'; |
|
||||
}, |
|
||||
}); |
|
Loading…
Reference in new issue