From 52d855241d74f04147579730eaa30fe266e012fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Tue, 5 Feb 2019 08:56:33 +0100 Subject: [PATCH] work on navbar --- web/static/src/scss/app.scss | 58 +++++++++++++++----- web/static/src/ts/core/base_widget.ts | 8 ++- web/static/src/ts/env.ts | 11 ---- web/static/src/ts/misc/menu_helpers.ts | 10 +++- web/static/src/ts/services/action_manager.ts | 6 +- web/static/src/ts/widgets/Discuss.ts | 2 +- web/static/src/ts/widgets/Navbar.ts | 16 ++++-- web/static/src/ts/widgets/home_menu.ts | 4 +- web/static/src/ts/widgets/notification.ts | 4 +- web/static/src/ts/widgets/root.ts | 5 +- web/static/src/ts/widgets/widget.ts | 20 +++++++ web/static/src/xml/templates.xml | 46 ++++++++++++---- web/static/tests/helpers.ts | 3 +- web/static/tests/widgets/navbar.test.ts | 4 +- 14 files changed, 138 insertions(+), 59 deletions(-) diff --git a/web/static/src/scss/app.scss b/web/static/src/scss/app.scss index 50655d8c..d170be59 100644 --- a/web/static/src/scss/app.scss +++ b/web/static/src/scss/app.scss @@ -1,4 +1,4 @@ -$navbar-height: 40px; +$navbar-height: 46px; $main-color: #875a7b; $o-notification-info-bg-color: #fcfbea; $o-main-text-color: #666666; @@ -12,6 +12,25 @@ body { margin: 0; } +/***** Generic stuff *****/ +.dropdown-toggle.o-no-caret::before, +.dropdown-toggle.o-no-caret::after { + content: normal; +} + +.dropdown-item { + font-size: 13px; + line-height: 20px; + + &:hover { + background-color: #e9ecef; + } + &:active { + color: #212529; + background-color: #dee2e6; + } +} + /***** Web Client *****/ .o_web_client { font-family: sans-serif; @@ -26,17 +45,28 @@ body { color: white; display: flex; line-height: $navbar-height; - font-size: 18px; + font-size: 13px; &.o_in_home { background-color: #bba2a5; } a.o_title { - padding: 10px 16px 16px 20px; - &:hover { - background-color: #68465f; - } + padding: 13px 16px 16px 20px; + color: white; + font-size: 18px; + } + + a.o_title:hover, + a.o_menu_brand:hover { + background-color: darken($main-color, 10); + } + + a.o_menu_brand { + font-size: 20px; + color: white; + text-decoration: none; + padding: 1px 12px; } ul { @@ -46,18 +76,20 @@ body { margin: 0; } - li { + .o_menu_sections > li { margin: 0 4px; - font-size: 20px; &:hover { background-color: darken($main-color, 10); } - } - a { - color: white; - text-decoration: none; - padding: 0 5px; + > a { + display: block; + height: 40px; + font-size: 15px; + color: white; + text-decoration: none; + padding: 0 10px; + } } } diff --git a/web/static/src/ts/core/base_widget.ts b/web/static/src/ts/core/base_widget.ts index aa435110..31143000 100644 --- a/web/static/src/ts/core/base_widget.ts +++ b/web/static/src/ts/core/base_widget.ts @@ -40,7 +40,11 @@ export interface Type extends Function { // Widget //------------------------------------------------------------------------------ -export class BaseWidget extends EventBus { +export class BaseWidget< + T extends WEnv, + Props, + State extends {} +> extends EventBus { __widget__: Meta; template: string = "default"; inlineTemplate: string | null = null; @@ -50,7 +54,7 @@ export class BaseWidget extends EventBus { } env: T; - state: Object = {}; + state: State = {}; props: Props; refs: { [key: string]: BaseWidget | HTMLElement | undefined; diff --git a/web/static/src/ts/env.ts b/web/static/src/ts/env.ts index 3705efb8..7fedb321 100644 --- a/web/static/src/ts/env.ts +++ b/web/static/src/ts/env.ts @@ -36,9 +36,6 @@ export interface Env extends WEnv { // registries actionRegistry: Registry; - // data - menus: Menu[]; - // helpers rpc: IAjax["rpc"]; @@ -72,12 +69,6 @@ export const makeEnvironment = memoize(async function(): Promise { const actionManager = new ActionManager(actionRegistry); const notifications = new NotificationManager(); - // demo data - const menus = [ - { title: "Discuss", actionID: 1 }, - { title: "CRM", actionID: 2 } - ]; - // templates const result = await fetch("templates.xml"); if (!result.ok) { @@ -98,8 +89,6 @@ export const makeEnvironment = memoize(async function(): Promise { actionRegistry, router, - menus, - rpc: ajax.rpc, debug: false, diff --git a/web/static/src/ts/misc/menu_helpers.ts b/web/static/src/ts/misc/menu_helpers.ts index 9a7459ea..6568a0bb 100644 --- a/web/static/src/ts/misc/menu_helpers.ts +++ b/web/static/src/ts/misc/menu_helpers.ts @@ -14,6 +14,7 @@ export interface BaseMenuItem { } export interface MenuItem extends BaseMenuItem { + // root menu id menuId: number; actionId: number; children: MenuItem[]; @@ -28,6 +29,10 @@ export interface MenuInfo { // Helpers //------------------------------------------------------------------------------ +/** + * Generate a valid MenuInfo object from a list of BaseMenuItems. This function + * is supposed to be called once at startup. + */ export function processMenuItems(items: BaseMenuItem[]): MenuInfo { const menuMap: MenuInfo["menuMap"] = {}; const roots: number[] = []; @@ -38,10 +43,11 @@ export function processMenuItems(items: BaseMenuItem[]): MenuInfo { addToMap(root, root.id); } - function addToMap(m: BaseMenuItem, menuId: number) { + function addToMap(m: BaseMenuItem, menuId: number): MenuItem { let item: MenuItem = Object.assign({ menuId, actionId: -1 }, m); menuMap[item.id] = item; - m.children.forEach(c => addToMap(c, menuId)); + item.children = m.children.map(c => addToMap(c, menuId)); + return item; } // add proper actionId to every menuitems diff --git a/web/static/src/ts/services/action_manager.ts b/web/static/src/ts/services/action_manager.ts index 65ccdb1a..d292ce3e 100644 --- a/web/static/src/ts/services/action_manager.ts +++ b/web/static/src/ts/services/action_manager.ts @@ -59,10 +59,12 @@ export class ActionManager extends EventBus implements IActionManager { } doAction(request: ActionRequest) { + console.log("doaction", request); if (typeof request === "number") { // this is an action ID - let name = request === 1 ? "discuss" : "crm"; - let title = request === 1 ? "Discuss" : "CRM"; + let name = request === 131 ? "discuss" : "crm"; + let title = + request === 131 ? "Discuss" : request === 250 ? "Notes" : "CRM"; let Widget = this.registry.get(name); this.stack = [ { diff --git a/web/static/src/ts/widgets/Discuss.ts b/web/static/src/ts/widgets/Discuss.ts index 5cced964..bc34cab9 100644 --- a/web/static/src/ts/widgets/Discuss.ts +++ b/web/static/src/ts/widgets/Discuss.ts @@ -18,7 +18,7 @@ interface State { export class Discuss extends Widget<{}, State> { template = "web.discuss"; widgets = { Clock, Counter, ColorWidget }; - state = { validcounter: true, color: "red" }; + state: State = { validcounter: true, color: "red" }; resetCounter(ev: MouseEvent) { if (this.refs.counter instanceof Counter) { diff --git a/web/static/src/ts/widgets/Navbar.ts b/web/static/src/ts/widgets/Navbar.ts index 4145c0b2..9b34fabf 100644 --- a/web/static/src/ts/widgets/Navbar.ts +++ b/web/static/src/ts/widgets/Navbar.ts @@ -1,6 +1,5 @@ -import { Menu } from "../env"; import { MenuItem } from "../misc/menu_helpers"; -import { Widget } from "./widget"; +import { PureWidget } from "./widget"; //------------------------------------------------------------------------------ // Types @@ -15,16 +14,21 @@ export interface Props { // Navbar //------------------------------------------------------------------------------ -export class Navbar extends Widget { +export class Navbar extends PureWidget { template = "web.navbar"; - getUrl(menu: Menu) { - const action_id = String(menu.actionID); - return this.env.router.formatURL("", { action_id }); + getUrl(menu: MenuItem) { + const action_id = String(menu.actionId); + const menu_id = String(menu.menuId); + return this.env.router.formatURL("", { action_id, menu_id }); } toggleHome(ev: MouseEvent) { ev.preventDefault(); this.trigger("toggle_home_menu"); } + + openMenu(menu: MenuItem) { + this.trigger("open_menu", menu); + } } diff --git a/web/static/src/ts/widgets/home_menu.ts b/web/static/src/ts/widgets/home_menu.ts index 2fc02511..ead08e81 100644 --- a/web/static/src/ts/widgets/home_menu.ts +++ b/web/static/src/ts/widgets/home_menu.ts @@ -21,8 +21,8 @@ export class HomeMenu extends Widget { return info.roots.map(root => info.menuMap[root]!); } - openApp(app: MenuItem, event: MouseEvent) { + openMenu(app: MenuItem, event: MouseEvent) { event.preventDefault(); - this.trigger("app_opened", app); + this.trigger("open_menu", app); } } diff --git a/web/static/src/ts/widgets/notification.ts b/web/static/src/ts/widgets/notification.ts index c4a7a7c5..141709bd 100644 --- a/web/static/src/ts/widgets/notification.ts +++ b/web/static/src/ts/widgets/notification.ts @@ -4,7 +4,9 @@ import { Widget } from "./widget"; export class Notification extends Widget { template = "web.notification"; - close() { + close(ev: MouseEvent) { + // we do not want the url to change + ev.preventDefault(); this.env.notifications.close(this.props.id); } } diff --git a/web/static/src/ts/widgets/root.ts b/web/static/src/ts/widgets/root.ts index b3adbf53..105bd7e3 100644 --- a/web/static/src/ts/widgets/root.ts +++ b/web/static/src/ts/widgets/root.ts @@ -89,7 +89,8 @@ export class Root extends Widget { this.updateState({ inHome: !this.state.inHome }); } - openApp(app: MenuItem) { - this.updateAppState(app, app.actionId); + openMenu(menu: MenuItem) { + const app = this.props.menuInfo.menuMap[menu.menuId]!; + this.updateAppState(app, menu.actionId); } } diff --git a/web/static/src/ts/widgets/widget.ts b/web/static/src/ts/widgets/widget.ts index 6ec33baf..9f66e274 100644 --- a/web/static/src/ts/widgets/widget.ts +++ b/web/static/src/ts/widgets/widget.ts @@ -2,3 +2,23 @@ import { BaseWidget } from "../core/base_widget"; import { Env } from "../env"; export class Widget extends BaseWidget {} + +// TODO: move this to PureComponent in core +export class PureWidget extends Widget { + shouldUpdate(nextProps: Props): boolean { + for (let k in nextProps) { + if (nextProps[k] !== this.props[k]) { + return true; + } + } + return false; + } + async updateState(nextState: Partial) { + for (let k in nextState) { + if (nextState[k] !== this.state[k]) { + return; + } + } + return super.updateState(nextState); + } +} diff --git a/web/static/src/xml/templates.xml b/web/static/src/xml/templates.xml index b11e223e..409b9242 100644 --- a/web/static/src/xml/templates.xml +++ b/web/static/src/xml/templates.xml @@ -2,9 +2,9 @@