From c0ea7644815b5f1785cb5af553d469fc207fa94c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Wed, 6 Mar 2019 14:59:17 +0100 Subject: [PATCH] work on action manager --- web/static/src/ts/registries.ts | 4 +- .../src/ts/store/action_manager_mixin.ts | 87 ++++++++----------- web/static/src/ts/store/store.ts | 10 +-- web/static/src/ts/ui/root.ts | 14 +-- web/static/tests/store/store.test.ts | 4 +- 5 files changed, 54 insertions(+), 65 deletions(-) diff --git a/web/static/src/ts/registries.ts b/web/static/src/ts/registries.ts index f5398b9d..65449d69 100644 --- a/web/static/src/ts/registries.ts +++ b/web/static/src/ts/registries.ts @@ -1,7 +1,7 @@ import { Registry } from "./core/registry"; -import { ActionWidget } from "./store/store"; +import { ControllerWidget } from "./store/store"; import { Discuss } from "./discuss/discuss"; -export const actionRegistry: Registry = new Registry(); +export const actionRegistry: Registry = new Registry(); actionRegistry.add("mail.discuss", Discuss); diff --git a/web/static/src/ts/store/action_manager_mixin.ts b/web/static/src/ts/store/action_manager_mixin.ts index c323a5ba..ddc81a15 100644 --- a/web/static/src/ts/store/action_manager_mixin.ts +++ b/web/static/src/ts/store/action_manager_mixin.ts @@ -7,28 +7,12 @@ import { View } from "../views/view"; // Types //------------------------------------------------------------------------------ -export type Context = { [key: string]: any }; - -export interface CommonActionInfo { - id: number; - context: Context; - title: string; - target: "current" | "new"; - Widget: ActionWidget; -} - +// Miscellaneous export type ActionRequest = number; -export type ActionWidget = Type>; - -export interface ClientActionInfo extends CommonActionInfo { - type: "client"; -} - -export interface ActWindowInfo extends CommonActionInfo { - type: "act_window"; -} +export type ControllerWidget = Type>; +// Action Description interface BaseActionDescription { id: number; target: "current"; @@ -52,13 +36,13 @@ export type ActionDescription = | ClientActionDescription | ActWindowActionDescription; -export type ActionInfo = ClientActionInfo | ActWindowInfo; - -export interface Action { +// Controller +export interface Controller { id: number; + actionId: number; widget?: Widget; - executor(parent: Widget): Promise | null>; - activate(): void; + create(parent: Widget): Promise | null>; + title: string; } //------------------------------------------------------------------------------ @@ -70,8 +54,8 @@ export function actionManagerMixin>( ) { return class extends Base { actionCache: { [key: number]: Promise } = {}; - currentAction?: Action; - lastAction?: Action; + currentController?: Controller; + lastController?: Controller; async doAction(request: ActionRequest) { const self = this; @@ -87,28 +71,21 @@ export function actionManagerMixin>( default: throw new Error("unhandled action"); } - if (executor) { - const action: Action = { - id: this.generateID(), - executor, - activate() { - if (self.currentAction && self.currentAction.widget) { - self.currentAction.widget.destroy(); - } - self.currentAction = action; - self.update({ - inHome: false - }); - document.title = descr.name + " - Odoo"; - } - }; - self.lastAction = action; - this.trigger("update_action", action); - } + const action: Controller = { + id: this.generateID(), + actionId: descr.id, + create: executor, + title: descr.name + }; + self.lastController = action; + this.trigger("update_action", action); } doActWindowAction(descr: ActWindowActionDescription) { - return async function executor(this: Action, parent: Widget) { + return async function executor( + this: Controller, + parent: Widget + ) { const widget = new View(parent, { info: descr.views[0][1] }); const div = document.createElement("div"); await widget.mount(div); @@ -117,9 +94,7 @@ export function actionManagerMixin>( }; } - doClientAction( - descr: ClientActionDescription - ): Action["executor"] | undefined { + doClientAction(descr: ClientActionDescription): Controller["create"] { let key = descr.tag; let ActionWidget = this.actionRegistry.get(key); if (!ActionWidget) { @@ -130,7 +105,10 @@ export function actionManagerMixin>( }); ActionWidget = Widget; } - return async function executor(this: Action, parent: Widget) { + return async function executor( + this: Controller, + parent: Widget + ) { const widget = new ActionWidget!(parent, {}); const div = document.createElement("div"); await widget.mount(div); @@ -150,5 +128,16 @@ export function actionManagerMixin>( } })); } + + activateController(controller: Controller) { + if (this.currentController && this.currentController.widget) { + this.currentController.widget.destroy(); + } + this.currentController = controller; + this.update({ + inHome: false + }); + document.title = controller.title + " - Odoo"; + } }; } diff --git a/web/static/src/ts/store/store.ts b/web/static/src/ts/store/store.ts index fe28abea..23a121f6 100644 --- a/web/static/src/ts/store/store.ts +++ b/web/static/src/ts/store/store.ts @@ -3,7 +3,7 @@ import { Registry } from "../core/registry"; import { idGenerator } from "../core/utils"; import { RPC } from "../services/ajax"; import { IRouter, Query } from "../services/router"; -import { actionManagerMixin, ActionWidget } from "./action_manager_mixin"; +import { actionManagerMixin, ControllerWidget } from "./action_manager_mixin"; import { rpcMixin } from "./rpc_mixin"; import { MenuItem } from "./store"; @@ -11,7 +11,7 @@ import { MenuItem } from "./store"; // Types //------------------------------------------------------------------------------ -export { ActionWidget } from "./action_manager_mixin"; +export { ControllerWidget } from "./action_manager_mixin"; export { RPC } from "./rpc_mixin"; export interface MenuItem { @@ -64,14 +64,14 @@ export class BaseStore extends EventBus { }; menuInfo: MenuInfo; services: Services; - actionRegistry: Registry; + actionRegistry: Registry; currentQuery: Query; generateID = idGenerator(); constructor( services: Services, menuInfo: MenuInfo, - actionRegistry: Registry + actionRegistry: Registry ) { super(); this.services = services; @@ -129,7 +129,7 @@ export class Store extends actionManagerMixin(rpcMixin(BaseStore)) { constructor( services: Services, menuInfo: MenuInfo, - actionRegistry: Registry + actionRegistry: Registry ) { super(services, menuInfo, actionRegistry); const query = this.services.router.getQuery(); diff --git a/web/static/src/ts/ui/root.ts b/web/static/src/ts/ui/root.ts index 61cb2317..edddd3ec 100644 --- a/web/static/src/ts/ui/root.ts +++ b/web/static/src/ts/ui/root.ts @@ -5,7 +5,7 @@ import { HomeMenu } from "./home_menu"; import { Navbar } from "./navbar"; import { Notification } from "./notification"; import { Widget } from "../widget"; -import { Action } from "../store/action_manager_mixin"; +import { Controller } from "../store/action_manager_mixin"; //------------------------------------------------------------------------------ // Root Widget @@ -26,9 +26,9 @@ export class Root extends Widget { mounted() { this.store.on("state_updated", this, this.updateState); this.store.on("rpc_status", this, this.toggleLoadingIndicator); - this.store.on("update_action", this, this.applyAction); - if (this.store.lastAction) { - this.applyAction(this.store.lastAction); + this.store.on("update_action", this, this.applyController); + if (this.store.lastController) { + this.applyController(this.store.lastController); } // adding reactiveness to mobile/non mobile @@ -50,13 +50,13 @@ export class Root extends Widget { (this.refs.loading_indicator).classList[method]("d-none"); } - async applyAction(action: Action) { - const widget = await action.executor(this); + async applyController(controller: Controller) { + const widget = await controller.create(this); if (widget) { // to do: call some public method of widget instead... (this.refs.content).appendChild(widget.el!); widget.__mount(); - action.activate(); + this.store.activateController(controller); } } } diff --git a/web/static/tests/store/store.test.ts b/web/static/tests/store/store.test.ts index 44507b89..d8663e33 100644 --- a/web/static/tests/store/store.test.ts +++ b/web/static/tests/store/store.test.ts @@ -101,7 +101,7 @@ describe("state transitions", () => { expect(store.services.router.getQuery()).toEqual({ home: true }); await promise; - store.lastAction!.activate(); + store.activateController(store.lastController!); expect(store.state.inHome).toBe(false); expect(store.services.router.getQuery()).toEqual({ action_id: "131", @@ -128,7 +128,7 @@ describe("state transitions", () => { const promise = store.activateMenuItem(96); expect(document.title).toBe("Odoo"); await promise; - store.lastAction!.activate(); + store.activateController(store.lastController!); expect(document.title).toBe("Discuss - Odoo");