diff --git a/addons/web/static/src/core/utils/arrays.js b/addons/web/static/src/core/utils/arrays.js index 2937135c632..79d1d8a9fed 100644 --- a/addons/web/static/src/core/utils/arrays.js +++ b/addons/web/static/src/core/utils/arrays.js @@ -77,3 +77,18 @@ export function sortBy(array, criterion, order = "asc") { return order === "asc" ? result : -result; }); } + +/** + * Returns an array containing all the elements of arrayA + * that are not in arrayB and vice-versa. + * + * @param {any[]} arrayA + * @param {any[]} arrayB + * @returns an array containing all the elements of arrayA + * that are not in arrayB and vice-versa. + */ +export function symmetricalDifference(arrayA, arrayB) { + return arrayA + .filter((id) => !arrayB.includes(id)) + .concat(arrayB.filter((id) => !arrayA.includes(id))); +} diff --git a/addons/web/static/src/webclient/company_service.js b/addons/web/static/src/webclient/company_service.js index ff940bc4326..5167c65e85f 100644 --- a/addons/web/static/src/webclient/company_service.js +++ b/addons/web/static/src/webclient/company_service.js @@ -2,6 +2,7 @@ import { browser } from "@web/core/browser/browser"; import { registry } from "@web/core/registry"; +import { symmetricalDifference } from "../core/utils/arrays"; function parseCompanyIds(cidsFromHash) { const cids = []; @@ -53,32 +54,29 @@ export const companyService = { get currentCompany() { return availableCompanies[allowedCompanyIds[0]]; }, - setCompanies(mode, companyId) { + setCompanies(mode, ...companyIds) { // compute next company ids - let nextCompanyIds = allowedCompanyIds.slice(); + let nextCompanyIds; if (mode === "toggle") { - if (nextCompanyIds.includes(companyId)) { - nextCompanyIds = nextCompanyIds.filter((id) => id !== companyId); - } else { - nextCompanyIds.push(companyId); - } + nextCompanyIds = symmetricalDifference(allowedCompanyIds, companyIds); } else if (mode === "loginto") { - if (nextCompanyIds.length === 1) { + const companyId = companyIds[0]; + if (allowedCompanyIds.length === 1) { // 1 enabled company: stay in single company mode nextCompanyIds = [companyId]; } else { // multi company mode - if (nextCompanyIds.includes(companyId)) { - nextCompanyIds = nextCompanyIds.filter((id) => id !== companyId); - } - nextCompanyIds.unshift(companyId); + nextCompanyIds = [ + companyId, + ...allowedCompanyIds.filter((id) => id !== companyId), + ]; } } - allowedCompanyIds = nextCompanyIds.length ? nextCompanyIds : [companyId]; + nextCompanyIds = nextCompanyIds.length ? nextCompanyIds : [companyIds[0]]; // apply them - router.pushState({ cids: allowedCompanyIds }, { lock: true }); - cookie.setCookie("cids", allowedCompanyIds); + router.pushState({ cids: nextCompanyIds }, { lock: true }); + cookie.setCookie("cids", nextCompanyIds); browser.setTimeout(() => browser.location.reload()); // history.pushState is a little async }, }; diff --git a/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js b/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js index 62a4f097f2d..4a8ebc5d1f0 100644 --- a/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js +++ b/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js @@ -2,8 +2,13 @@ import { useService } from "../../core/service_hook"; import { registry } from "../../core/registry"; +import { browser } from "../../core/browser/browser"; +import { symmetricalDifference } from "../../core/utils/arrays"; -export class SwitchCompanyMenu extends owl.Component { +const { Component, hooks } = owl; +const { useState } = hooks; + +export class SwitchCompanyMenu extends Component { static isDisplayed(env) { const { availableCompanies } = env.services.company; return Object.keys(availableCompanies).length > 1 && !env.isSmall; @@ -12,16 +17,32 @@ export class SwitchCompanyMenu extends owl.Component { setup() { this.companyService = useService("company"); this.currentCompany = this.companyService.currentCompany; + this.state = useState({ companiesToToggle: [] }); } toggleCompany(companyId) { - this.companyService.setCompanies("toggle", companyId); + this.state.companiesToToggle = symmetricalDifference(this.state.companiesToToggle, [ + companyId, + ]); + browser.clearTimeout(this.toggleTimer); + this.toggleTimer = browser.setTimeout(() => { + this.companyService.setCompanies("toggle", ...this.state.companiesToToggle); + }, this.constructor.toggleDelay); } logIntoCompany(companyId) { + browser.clearTimeout(this.toggleTimer); this.companyService.setCompanies("loginto", companyId); } + + get selectedCompanies() { + return symmetricalDifference( + this.companyService.allowedCompanyIds, + this.state.companiesToToggle + ); + } } SwitchCompanyMenu.template = "web.SwitchCompanyMenu"; +SwitchCompanyMenu.toggleDelay = 1000; registry.category("systray").add("SwitchCompanyMenu", SwitchCompanyMenu, { sequence: 1 }); diff --git a/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.xml b/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.xml index 2a5b08afd1e..d64a8bcf07a 100644 --- a/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.xml +++ b/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.xml @@ -19,7 +19,7 @@
- +