mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
work on action manager
This commit is contained in:
@@ -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<ActionWidget> = new Registry();
|
||||
export const actionRegistry: Registry<ControllerWidget> = new Registry();
|
||||
|
||||
actionRegistry.add("mail.discuss", Discuss);
|
||||
|
||||
@@ -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<Widget<{}, {}>>;
|
||||
|
||||
export interface ClientActionInfo extends CommonActionInfo {
|
||||
type: "client";
|
||||
}
|
||||
|
||||
export interface ActWindowInfo extends CommonActionInfo {
|
||||
type: "act_window";
|
||||
}
|
||||
export type ControllerWidget = Type<Widget<{}, {}>>;
|
||||
|
||||
// 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<any, any>;
|
||||
executor(parent: Widget<any, any>): Promise<Widget<any, any> | null>;
|
||||
activate(): void;
|
||||
create(parent: Widget<any, any>): Promise<Widget<any, any> | null>;
|
||||
title: string;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -70,8 +54,8 @@ export function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(
|
||||
) {
|
||||
return class extends Base {
|
||||
actionCache: { [key: number]: Promise<ActionDescription> } = {};
|
||||
currentAction?: Action;
|
||||
lastAction?: Action;
|
||||
currentController?: Controller;
|
||||
lastController?: Controller;
|
||||
|
||||
async doAction(request: ActionRequest) {
|
||||
const self = this;
|
||||
@@ -87,28 +71,21 @@ export function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(
|
||||
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<any, any>) {
|
||||
return async function executor(
|
||||
this: Controller,
|
||||
parent: Widget<any, any>
|
||||
) {
|
||||
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<T extends ReturnType<typeof rpcMixin>>(
|
||||
};
|
||||
}
|
||||
|
||||
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<T extends ReturnType<typeof rpcMixin>>(
|
||||
});
|
||||
ActionWidget = Widget;
|
||||
}
|
||||
return async function executor(this: Action, parent: Widget<any, any>) {
|
||||
return async function executor(
|
||||
this: Controller,
|
||||
parent: Widget<any, any>
|
||||
) {
|
||||
const widget = new ActionWidget!(parent, {});
|
||||
const div = document.createElement("div");
|
||||
await widget.mount(div);
|
||||
@@ -150,5 +128,16 @@ export function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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<ActionWidget>;
|
||||
actionRegistry: Registry<ControllerWidget>;
|
||||
currentQuery: Query;
|
||||
generateID = idGenerator();
|
||||
|
||||
constructor(
|
||||
services: Services,
|
||||
menuInfo: MenuInfo,
|
||||
actionRegistry: Registry<ActionWidget>
|
||||
actionRegistry: Registry<ControllerWidget>
|
||||
) {
|
||||
super();
|
||||
this.services = services;
|
||||
@@ -129,7 +129,7 @@ export class Store extends actionManagerMixin(rpcMixin(BaseStore)) {
|
||||
constructor(
|
||||
services: Services,
|
||||
menuInfo: MenuInfo,
|
||||
actionRegistry: Registry<ActionWidget>
|
||||
actionRegistry: Registry<ControllerWidget>
|
||||
) {
|
||||
super(services, menuInfo, actionRegistry);
|
||||
const query = this.services.router.getQuery();
|
||||
|
||||
@@ -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<Store, State> {
|
||||
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<Store, State> {
|
||||
(<any>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...
|
||||
(<HTMLElement>this.refs.content).appendChild(widget.el!);
|
||||
widget.__mount();
|
||||
action.activate();
|
||||
this.store.activateController(controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user