diff --git a/web/static/src/ts/env.ts b/web/static/src/ts/env.ts
index 41eb94ce..e952c00b 100644
--- a/web/static/src/ts/env.ts
+++ b/web/static/src/ts/env.ts
@@ -1,6 +1,7 @@
import { QWeb } from "./core/qweb_vdom";
import { idGenerator, memoize } from "./core/utils";
import { WEnv } from "./core/widget";
+import { registry } from "./registry";
import { ActionManager, IActionManager } from "./services/action_manager";
import { Ajax, IAjax } from "./services/ajax";
import { IRouter, Router } from "./services/router";
@@ -46,7 +47,7 @@ export const makeEnvironment = memoize(function(): Env {
const qweb = new QWeb();
const router = new Router();
const ajax = new Ajax();
- const actionManager = new ActionManager(router);
+ const actionManager = new ActionManager(router, registry);
const menus = [
{ title: "Discuss", actionID: 1 },
{ title: "CRM", actionID: 2 }
diff --git a/web/static/src/ts/main.ts b/web/static/src/ts/main.ts
index a9a2699b..ad8e9bdf 100644
--- a/web/static/src/ts/main.ts
+++ b/web/static/src/ts/main.ts
@@ -1,8 +1,18 @@
///
-import { RootWidget } from "./widgets/root_widget";
import { makeEnvironment } from "./env";
+import { registry } from "./registry";
+import { Discuss } from "./widgets/discuss";
+import { RootWidget } from "./widgets/root_widget";
+//------------------------------------------------------------------------------
+// Prepare application registry
+//------------------------------------------------------------------------------
+registry.addAction("discuss", Discuss);
+
+//------------------------------------------------------------------------------
+// Application bootstrapping
+//------------------------------------------------------------------------------
document.addEventListener("DOMContentLoaded", async function() {
const env = makeEnvironment();
const rootWidget = new RootWidget(env);
diff --git a/web/static/src/ts/registry.ts b/web/static/src/ts/registry.ts
new file mode 100644
index 00000000..a81a2ea4
--- /dev/null
+++ b/web/static/src/ts/registry.ts
@@ -0,0 +1,36 @@
+import { Widget } from "./core/widget";
+import { Env } from "./env";
+
+//------------------------------------------------------------------------------
+// Types
+//------------------------------------------------------------------------------
+interface Type extends Function {
+ new (...args: any[]): T;
+}
+
+type ActionWidget = Type>;
+
+//------------------------------------------------------------------------------
+// Registry code
+//------------------------------------------------------------------------------
+export class Registry {
+ actions: { [key: string]: ActionWidget } = {};
+
+ addAction(name: string, action: ActionWidget): Registry {
+ return this.addToRegistry(this.actions, name, action);
+ }
+
+ private addToRegistry(
+ map: { [k: string]: T },
+ name: string,
+ elem: T
+ ): Registry {
+ if (name in map) {
+ throw new Error(`Key ${name} already exists!`);
+ }
+ map[name] = elem;
+ return this;
+ }
+}
+
+export const registry = new Registry();
diff --git a/web/static/src/ts/services/action_manager.ts b/web/static/src/ts/services/action_manager.ts
index 71971906..dbe5d86e 100644
--- a/web/static/src/ts/services/action_manager.ts
+++ b/web/static/src/ts/services/action_manager.ts
@@ -1,6 +1,7 @@
import { EventBus, Callback } from "../core/event_bus";
import { Widget } from "../core/widget";
import { Env } from "../env";
+import { Registry } from "../registry";
import { CRM } from "../widgets/crm";
import { Discuss } from "../widgets/discuss";
import { Query, IRouter } from "./router";
@@ -50,11 +51,13 @@ const actions: any[] = [
export class ActionManager extends EventBus implements IActionManager {
router: IRouter;
+ registry: Registry;
currentAction: ActionWidget | null = null;
- constructor(router: IRouter) {
+ constructor(router: IRouter, registry: Registry) {
super();
this.router = router;
+ this.registry = registry;
const query = this.router.getQuery();
this.update(query);
this.router.on("query_changed", this, this.update);