Files
owl/web/static/src/ts/widgets/root.ts
T

142 lines
4.1 KiB
TypeScript
Raw Normal View History

2019-02-18 15:34:23 +01:00
import { Query } from "../store/router";
import { debounce } from "../core/utils";
2019-02-18 15:34:23 +01:00
import { MenuInfo, MenuItem } from "../loaders/menus";
import { ActionStack } from "../store/action_manager";
import { ActionContainer } from "./action_container";
2019-02-02 16:51:24 +01:00
import { HomeMenu } from "./home_menu";
import { Navbar } from "./navbar";
import { Notification } from "./notification";
2019-02-05 16:08:35 +01:00
import { Env, Widget } from "./widget";
2019-01-31 13:19:30 +01:00
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
2019-02-06 10:42:00 +01:00
export interface Props {
2019-02-05 16:08:35 +01:00
menuInfo: MenuInfo;
}
2019-01-31 10:55:41 +01:00
interface State {
2019-01-31 13:19:30 +01:00
stack: ActionStack;
inHome: boolean;
2019-02-04 13:23:41 +01:00
currentApp: MenuItem | null;
2019-01-31 10:55:41 +01:00
}
2019-01-31 13:19:30 +01:00
//------------------------------------------------------------------------------
// Root Widget
//------------------------------------------------------------------------------
2019-02-04 21:09:17 +01:00
export class Root extends Widget<Props, State> {
template = "web.web_client";
widgets = { Navbar, HomeMenu, ActionContainer };
2019-01-31 10:55:41 +01:00
state: State = {
2019-01-31 13:19:30 +01:00
stack: [],
2019-02-04 13:23:41 +01:00
inHome: false,
currentApp: null
2019-01-31 10:55:41 +01:00
};
notifications: { [id: number]: Notification } = {};
2019-02-04 13:23:41 +01:00
constructor(env: Env, props: Props) {
super(env, props);
const query = this.env.router.getQuery();
2019-02-05 16:08:35 +01:00
let { app, actionId } = this.getAppAndAction(query);
2019-02-04 13:23:41 +01:00
this.state.currentApp = app;
if (!actionId) {
this.state.inHome = true;
}
}
mounted() {
2019-02-04 13:23:41 +01:00
// notifications
this.env.notifications.on("notification_added", this, notif => {
const notification = new Notification(this, notif);
this.notifications[notif.id] = notification;
notification.mount(<any>this.refs.notification_container);
});
this.env.notifications.on("notification_closed", this, id => {
this.notifications[id].destroy();
delete this.notifications[id];
});
2019-02-04 13:23:41 +01:00
2019-02-06 21:20:26 +01:00
// loading indicator
this.env.ajax.on("rpc_status", this, status => {
const method = status === "loading" ? "remove" : "add";
(<any>this.refs.loading_indicator).classList[method]("d-none");
2019-02-06 21:20:26 +01:00
});
2019-02-04 13:23:41 +01:00
// actions
2019-01-31 13:19:30 +01:00
this.env.actionManager.on("action_stack_updated", this, stack =>
2019-02-04 13:23:41 +01:00
this.updateState({ stack, inHome: false })
2019-01-31 13:19:30 +01:00
);
2019-02-04 13:23:41 +01:00
this.env.router.on("query_changed", this, this.updateAction);
this.updateAction(this.env.router.getQuery());
// adding reactiveness to mobile/non mobile
window.addEventListener("resize", <any>debounce(() => {
const isMobile = window.innerWidth <= 768;
if (isMobile !== this.env.isMobile) {
this.env.isMobile = isMobile;
this.render();
}
}, 50));
2019-02-04 13:23:41 +01:00
}
private updateAction(query: Query) {
2019-02-05 16:08:35 +01:00
let { app, actionId } = this.getAppAndAction(query);
2019-02-04 13:23:41 +01:00
this.updateAppState(app, actionId);
}
private updateAppState(app: MenuItem | null, actionId: number | null) {
const newApp = app || this.state.currentApp;
if (actionId) {
const query: Query = { action_id: String(actionId) };
2019-02-05 21:08:06 +01:00
const menuId = newApp ? newApp.app.id : false;
2019-02-04 13:23:41 +01:00
if (menuId) {
query.menu_id = String(menuId);
}
if (app) {
this.updateState({ currentApp: app });
}
this.env.router.navigate(query);
this.env.actionManager.doAction(actionId);
} else {
this.updateState({ inHome: true, currentApp: newApp });
}
2019-01-29 16:13:05 +01:00
}
2019-01-31 10:55:41 +01:00
2019-01-31 13:19:30 +01:00
toggleHome() {
this.updateState({ inHome: !this.state.inHome });
2019-01-31 10:55:41 +01:00
}
2019-02-04 13:23:41 +01:00
2019-02-05 08:56:33 +01:00
openMenu(menu: MenuItem) {
2019-02-05 21:08:06 +01:00
this.updateAppState(menu.app, menu.actionId);
2019-02-04 13:23:41 +01:00
}
2019-02-05 16:08:35 +01:00
private getAppAndAction(
query: Query
): { app: MenuItem | null; actionId: number | null } {
const menuInfo = this.props.menuInfo;
let app: MenuItem | null = null;
let actionId: number | null = null;
if ("action_id" in query) {
actionId = parseInt(query.action_id, 10);
if (menuInfo.actionMap[actionId]) {
2019-02-05 21:08:06 +01:00
const menu = menuInfo.actionMap[actionId]!;
app = menu.app;
2019-02-05 16:08:35 +01:00
}
}
if ("menu_id" in query) {
const menuId = parseInt(query.menu_id, 10);
2019-02-05 21:08:06 +01:00
const menu = menuInfo.menus[menuId];
2019-02-05 16:08:35 +01:00
if (menu) {
2019-02-05 21:08:06 +01:00
app = menu.app;
2019-02-05 16:08:35 +01:00
if (!actionId) {
actionId = menu.actionId;
}
}
}
return { app, actionId };
}
}