[REF] web: introduces search bar toggler component

Part-of: odoo/odoo#116641
This commit is contained in:
Romeo Fragomeli
2023-05-12 22:59:22 +02:00
committed by Pierre Paridans
parent eef262abf4
commit 475aa6ca49
19 changed files with 114 additions and 38 deletions
@@ -68,6 +68,7 @@
</t>
</nav>
</t>
<t t-slot="control-panel-navigation-additional"/>
</div>
</div>
</div>
@@ -9,18 +9,8 @@ import { DomainSelectorDialog } from "@web/core/domain_selector_dialog/domain_se
import { fuzzyTest } from "@web/core/utils/search";
import { _t } from "@web/core/l10n/translation";
import { SearchBarMenu } from "../search_bar_menu/search_bar_menu";
import { useDebounced } from "@web/core/utils/timing";
import { browser } from "@web/core/browser/browser";
import { SIZES } from "@web/core/ui/ui_service";
import {
Component,
onMounted,
onWillUnmount,
useExternalListener,
useRef,
useState,
} from "@odoo/owl";
import { Component, useExternalListener, useRef, useState } from "@odoo/owl";
const parsers = registry.category("parsers");
const CHAR_FIELDS = ["char", "html", "many2many", "many2one", "one2many", "text", "properties"];
@@ -41,7 +31,6 @@ export class SearchBar extends Component {
expanded: [],
focusedIndex: 0,
query: "",
showSearchBar: this.ui.size > SIZES.SM,
});
// derived state
@@ -64,10 +53,6 @@ export class SearchBar extends Component {
useExternalListener(window, "click", this.onWindowClick);
useExternalListener(window, "keydown", this.onWindowKeydown);
this.onResize = useDebounced(this.onResize, 200);
onMounted(() => browser.addEventListener("resize", this.onResize));
onWillUnmount(() => browser.removeEventListener("resize", this.onResize));
}
/**
@@ -443,10 +428,6 @@ export class SearchBar extends Component {
this.inputRef.el.focus();
}
onResize() {
this.state.showSearchBar = this.ui.size > SIZES.SM;
}
/**
* @param {KeyboardEvent} ev
*/
@@ -80,7 +80,7 @@
</t>
<t t-name="web.SearchBar" owl="1">
<div t-if="state.showSearchBar" class="o_cp_searchview d-flex input-group" role="search" t-ref="root">
<div class="o_cp_searchview d-flex input-group" role="search" t-ref="root">
<div class="o_searchview form-control d-print-contents d-flex align-items-center py-1 border-end-0" role="search" aria-autocomplete="list">
<i class="o_searchview_icon d-print-none oi oi-search me-2"
role="img"
@@ -97,11 +97,6 @@
</div>
<SearchBarMenu/>
</div>
<t t-portal="'.o_control_panel_navigation,.o_searchview'">
<button t-attf-class="btn btn-secondary {{state.showSearchBar?'d-md-none active':''}}" t-on-click="onToggleSearchBar">
<i class="fa fa-fw fa-search"/>
</button>
</t>
</t>
</templates>
@@ -0,0 +1,55 @@
/** @odoo-module **/
import { Component, useEffect, useState } from "@odoo/owl";
import { browser } from "@web/core/browser/browser";
import { useService } from "@web/core/utils/hooks";
import { useDebounced } from "@web/core/utils/timing";
export class SearchBarToggler extends Component {}
SearchBarToggler.template = "web.SearchBar.Toggler";
SearchBarToggler.props = {
isSmall: Boolean,
showSearchBar: Boolean,
toggleSearchBar: Function,
};
export function useSearchBarToggler() {
const ui = useService("ui");
let isToggled = false;
const state = useState({
isSmall: ui.isSmall,
showSearchBar: false,
});
const updateState = () => {
state.isSmall = ui.isSmall;
state.showSearchBar = !ui.isSmall || isToggled;
};
updateState();
function toggleSearchBar() {
isToggled = !isToggled;
updateState();
}
const onResize = useDebounced(updateState, 200);
useEffect(
() => {
browser.addEventListener("resize", onResize);
return () => browser.removeEventListener("resize", onResize);
},
() => []
);
return {
state,
component: SearchBarToggler,
get props() {
return {
isSmall: state.isSmall,
showSearchBar: state.showSearchBar,
toggleSearchBar,
};
},
};
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="web.SearchBar.Toggler" owl="1">
<button t-if="props.isSmall" t-attf-class="btn btn-secondary {{ props.showSearchBar ? 'active' : '' }}" t-on-click="props.toggleSearchBar">
<i class="fa fa-fw fa-search"/>
</button>
</t>
</templates>
@@ -13,6 +13,7 @@ import { CalendarFilterPanel } from "./filter_panel/calendar_filter_panel";
import { CalendarMobileFilterPanel } from "./mobile_filter_panel/calendar_mobile_filter_panel";
import { CalendarQuickCreate } from "./quick_create/calendar_quick_create";
import { SearchBar } from "@web/search/search_bar/search_bar";
import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler";
import { ViewScaleSelector } from "@web/views/view_components/view_scale_selector";
import { CogMenu } from "@web/search/cog_menu/cog_menu";
@@ -57,6 +58,8 @@ export class CalendarController extends Component {
this.state = useState({
showSideBar: !this.env.isSmall,
});
this.searchBarToggler = useSearchBarToggler();
}
get rendererProps() {
@@ -11,7 +11,10 @@
<t t-call="{{ props.buttonTemplate }}"/>
</t>
<t t-set-slot="layout-actions">
<SearchBar/>
<SearchBar t-if="searchBarToggler.state.showSearchBar"/>
</t>
<t t-set-slot="control-panel-navigation-additional">
<t t-component="searchBarToggler.component" t-props="searchBarToggler.props"/>
</t>
<div class="o_calendar_container">
<MobileFilterPanel t-if="env.isSmall" t-props="mobileFilterPanelProps" />
@@ -6,6 +6,7 @@ import { useModel } from "@web/views/model";
import { standardViewProps } from "@web/views/standard_view_props";
import { useSetupView } from "@web/views/view_hook";
import { SearchBar } from "@web/search/search_bar/search_bar";
import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler";
import { CogMenu } from "@web/search/cog_menu/cog_menu";
import { Component, useRef } from "@odoo/owl";
@@ -21,6 +22,7 @@ export class GraphController extends Component {
},
getContext: () => this.getContext(),
});
this.searchBarToggler = useSearchBarToggler();
}
/**
@@ -57,7 +57,10 @@
<CogMenu/>
</t>
<t t-set-slot="layout-actions">
<SearchBar/>
<SearchBar t-if="searchBarToggler.state.showSearchBar"/>
</t>
<t t-set-slot="control-panel-navigation-additional">
<t t-component="searchBarToggler.component" t-props="searchBarToggler.props"/>
</t>
<t t-if="model.data">
<t t-if="model.useSampleModel and props.info.noContentHelp" t-call="web.ActionHelper">
@@ -10,6 +10,7 @@ import { useViewButtons } from "@web/views/view_button/view_button_hook";
import { useSetupView } from "@web/views/view_hook";
import { KanbanRenderer } from "./kanban_renderer";
import { SearchBar } from "@web/search/search_bar/search_bar";
import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler";
import { CogMenu } from "@web/search/cog_menu/cog_menu";
import { Component, reactive, useRef } from "@odoo/owl";
@@ -78,6 +79,7 @@ export class KanbanController extends Component {
};
}
});
this.searchBarToggler = useSearchBarToggler();
}
get modelParams() {
@@ -33,7 +33,10 @@
<CogMenu/>
</t>
<t t-set-slot="layout-actions">
<SearchBar/>
<SearchBar t-if="searchBarToggler.state.showSearchBar"/>
</t>
<t t-set-slot="control-panel-navigation-additional">
<t t-component="searchBarToggler.component" t-props="searchBarToggler.props"/>
</t>
<t t-component="props.Renderer"
list="model.root"
@@ -21,6 +21,7 @@ import { ExportDataDialog } from "@web/views/view_dialogs/export_data_dialog";
import { useSetupView } from "@web/views/view_hook";
import { ListConfirmationDialog } from "./list_confirmation_dialog";
import { SearchBar } from "@web/search/search_bar/search_bar";
import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler";
import { Dropdown } from "@web/core/dropdown/dropdown";
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
import { CogMenu } from "@web/search/cog_menu/cog_menu";
@@ -144,6 +145,7 @@ export class ListController extends Component {
},
() => [this.model.root.selection.length]
);
this.searchBarToggler = useSearchBarToggler();
}
get modelParams() {
@@ -594,7 +596,17 @@ export class ListController extends Component {
}
ListController.template = `web.ListView`;
ListController.components = { ActionMenus, Layout, ViewButton, MultiRecordViewButton, SearchBar, Dropdown, DropdownItem, CogMenu, ActionMenusItems };
ListController.components = {
ActionMenus,
Layout,
ViewButton,
MultiRecordViewButton,
SearchBar,
Dropdown,
DropdownItem,
CogMenu,
ActionMenusItems,
};
ListController.props = {
...standardViewProps,
allowSelectors: { type: Boolean, optional: true },
@@ -32,7 +32,10 @@
</t>
<t t-set-slot="layout-actions">
<SearchBar/>
<SearchBar t-if="searchBarToggler.state.showSearchBar"/>
</t>
<t t-set-slot="control-panel-navigation-additional">
<t t-component="searchBarToggler.component" t-props="searchBarToggler.props"/>
</t>
<t t-set-slot="control-panel-additional-actions">
@@ -5,6 +5,7 @@ import { useModel } from "@web/views/model";
import { standardViewProps } from "@web/views/standard_view_props";
import { useSetupView } from "@web/views/view_hook";
import { SearchBar } from "@web/search/search_bar/search_bar";
import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler";
import { CogMenu } from "@web/search/cog_menu/cog_menu";
import { Component, useRef } from "@odoo/owl";
@@ -21,6 +22,7 @@ export class PivotController extends Component {
},
getContext: () => this.getContext(),
});
this.searchBarToggler = useSearchBarToggler();
}
/**
* @returns {Object}
@@ -25,7 +25,10 @@
<CogMenu/>
</t>
<t t-set-slot="layout-actions">
<SearchBar/>
<SearchBar t-if="searchBarToggler.state.showSearchBar"/>
</t>
<t t-set-slot="control-panel-navigation-additional">
<t t-component="searchBarToggler.component" t-props="searchBarToggler.props"/>
</t>
<t t-set="displayNoContent" t-value="
props.info.noContentHelp !== false and (
@@ -67,7 +67,7 @@ QUnit.module("Mobile Views", ({ beforeEach }) => {
await triggerEvents(fixture, ".o_data_row:nth-child(1)", ["touchstart", "touchend"]);
assert.containsOnce(fixture, ".o_list_selection_box");
assert.containsNone(fixture, ".o_list_selection_box .o_list_select_domain");
assert.containsNone(fixture, ".o_control_panel .fa-search");
assert.containsNone(fixture, ".o_control_panel .o_cp_searchview");
assert.ok(
fixture.querySelector(".o_list_selection_box").textContent.includes("1 selected")
);
@@ -739,6 +739,7 @@ QUnit.module("ViewDialogs", (hooks) => {
activateElement: () => {},
deactivateElement: () => {},
size: 4,
isSmall: true,
};
const fakeUIService = {
start(env) {
@@ -419,7 +419,7 @@ stepUtils.autoExpandMoreButtons('.o_form_saved'),
content: _t('Save'),
position: 'right',
}, {
trigger: '.o_form_button_save',
trigger: '.o_form_status_indicator .o_form_button_save',
content: _t("Save this product and the modifications you've made to it."),
position: 'bottom',
}, {
@@ -1,8 +1,6 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
import odoo.tests
import unittest
class BaseTestUi(odoo.tests.HttpCase):
@@ -81,5 +79,4 @@ class TestUiMobile(BaseTestUi):
touch_enabled = True
def test_01_main_flow_tour_mobile(self):
raise unittest.SkipTest("Skip Milk")
# self.main_flow_tour()
self.main_flow_tour()