mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
reorganize store code
This commit is contained in:
@@ -22,7 +22,7 @@ export interface Subscription {
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export class EventBus {
|
||||
private subscriptions: { [eventType: string]: Subscription[] } = {};
|
||||
subscriptions: { [eventType: string]: Subscription[] } = {};
|
||||
|
||||
/**
|
||||
* Add a listener for the 'eventType' events.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { WEnv } from "./core/component";
|
||||
import { QWeb } from "./core/qweb_vdom";
|
||||
import { idGenerator } from "./core/utils";
|
||||
import { INotification, RPC, Services, Store } from "./store";
|
||||
import { INotification, RPC, Services, Store } from "./store/store";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { findInTree } from "./core/utils";
|
||||
import { MenuInfo, MenuItem } from "./store";
|
||||
import { MenuInfo, MenuItem } from "./store/store";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Templates
|
||||
|
||||
@@ -5,7 +5,7 @@ import { loadMenus, loadTemplates } from "./loaders";
|
||||
import { actionRegistry } from "./registries";
|
||||
import { rpc } from "./services/ajax";
|
||||
import { Router } from "./services/router";
|
||||
import { Store } from "./store";
|
||||
import { Store } from "./store/store";
|
||||
import { Root } from "./widgets/root";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Registry } from "./core/registry";
|
||||
import { ActionWidget } from "./store";
|
||||
import { ActionWidget } from "./store/store";
|
||||
import { CRM } from "./widgets/crm";
|
||||
import { Discuss } from "./widgets/discuss";
|
||||
|
||||
|
||||
@@ -1,336 +0,0 @@
|
||||
import { Type } from "./core/component";
|
||||
import { EventBus } from "./core/event_bus";
|
||||
import { Registry } from "./core/registry";
|
||||
import { RPC } from "./services/ajax";
|
||||
import { IRouter, Query } from "./services/router";
|
||||
import { Widget } from "./widgets/widget";
|
||||
import { idGenerator } from "./core/utils";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export interface MenuItem {
|
||||
id: number;
|
||||
name: string;
|
||||
parentId: number | false;
|
||||
action: string | false;
|
||||
icon: string | false;
|
||||
|
||||
// root menu id
|
||||
app: MenuItem;
|
||||
actionId: number;
|
||||
children: MenuItem[];
|
||||
}
|
||||
|
||||
export interface MenuInfo {
|
||||
menus: { [key: number]: MenuItem | undefined };
|
||||
|
||||
actionMap: { [id: number]: MenuItem | undefined };
|
||||
roots: number[];
|
||||
}
|
||||
|
||||
export interface State {
|
||||
stack: ActionStack;
|
||||
inHome: boolean;
|
||||
currentApp: MenuItem | null;
|
||||
}
|
||||
|
||||
export interface Services {
|
||||
rpc: RPC;
|
||||
router: IRouter;
|
||||
}
|
||||
|
||||
export type Context = { [key: string]: any };
|
||||
|
||||
export interface CommonActionInfo {
|
||||
id: number;
|
||||
context: Context;
|
||||
title: string;
|
||||
target: "current" | "new";
|
||||
}
|
||||
|
||||
export type ActionRequest = string | number;
|
||||
|
||||
export type ActionWidget = Type<Widget<{}, {}>>;
|
||||
|
||||
export interface ClientActionInfo extends CommonActionInfo {
|
||||
type: "client";
|
||||
name: string;
|
||||
Widget: ActionWidget;
|
||||
}
|
||||
|
||||
export interface ActWindowInfo extends CommonActionInfo {
|
||||
type: "act_window";
|
||||
view: string;
|
||||
}
|
||||
|
||||
export interface ActionDescription {
|
||||
id: number;
|
||||
type: "ir.actions.act_window" | "ir.actions.client";
|
||||
target: "current";
|
||||
}
|
||||
|
||||
export type ActionInfo = ClientActionInfo | ActWindowInfo;
|
||||
export type ActionStack = ActionInfo[];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Store
|
||||
//------------------------------------------------------------------------------
|
||||
class BaseStore extends EventBus {
|
||||
state: State = {
|
||||
stack: [],
|
||||
inHome: false,
|
||||
currentApp: null
|
||||
};
|
||||
menuInfo: MenuInfo;
|
||||
services: Services;
|
||||
actionRegistry: Registry<ActionWidget>;
|
||||
|
||||
constructor(
|
||||
services: Services,
|
||||
menuInfo: MenuInfo,
|
||||
actionRegistry: Registry<ActionWidget>
|
||||
) {
|
||||
super();
|
||||
this.services = services;
|
||||
this.menuInfo = menuInfo;
|
||||
this.actionRegistry = actionRegistry;
|
||||
}
|
||||
|
||||
update(nextState: Partial<State>) {
|
||||
Object.assign(this.state, nextState);
|
||||
this.trigger("state_updated", this.state);
|
||||
}
|
||||
|
||||
toggleHomeMenu() {
|
||||
if (this.state.inHome && !this.state.currentApp) {
|
||||
return;
|
||||
}
|
||||
this.update({ inHome: !this.state.inHome });
|
||||
}
|
||||
}
|
||||
|
||||
export class Store extends actionManagerMixin(
|
||||
rpcMixin(notificationMixin(BaseStore))
|
||||
) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RPC Mixin
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export interface RPCModelQuery {
|
||||
model: string;
|
||||
method: string;
|
||||
args?: any[];
|
||||
kwargs?: { [key: string]: any };
|
||||
context?: { [key: string]: any };
|
||||
}
|
||||
|
||||
export interface RPCControllerQuery {
|
||||
route: string;
|
||||
params: { [key: string]: any };
|
||||
}
|
||||
|
||||
export type RPCQuery = RPCModelQuery | RPCControllerQuery;
|
||||
|
||||
export type RPC = (rpc: RPCQuery) => Promise<any>;
|
||||
|
||||
interface RequestParameters {
|
||||
route: string;
|
||||
params: { [key: string]: any };
|
||||
}
|
||||
|
||||
function rpcMixin<T extends Type<BaseStore>>(Base: T) {
|
||||
return class extends Base {
|
||||
counter: number = 0;
|
||||
|
||||
async rpc(rpc: RPCQuery): Promise<any> {
|
||||
const request = this.prepareRequest(rpc);
|
||||
if (this.counter === 0) {
|
||||
this.trigger("rpc_status", "loading");
|
||||
}
|
||||
this.counter++;
|
||||
const result = await this.services.rpc(request.route, request.params);
|
||||
this.counter--;
|
||||
if (this.counter === 0) {
|
||||
this.trigger("rpc_status", "notloading");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private prepareRequest(query: RPCQuery): RequestParameters {
|
||||
let route: string;
|
||||
let params = "params" in query ? query.params : {};
|
||||
if ("route" in query) {
|
||||
route = query.route;
|
||||
} else if ("model" in query && "method" in query) {
|
||||
route = `/web/dataset/call_kw/${query.model}/${query.method}`;
|
||||
params.args = query.args || [];
|
||||
params.model = query.model;
|
||||
params.method = query.method;
|
||||
params.kwargs = Object.assign(params.kwargs || {}, query.kwargs);
|
||||
params.kwargs.context =
|
||||
query.context || params.context || params.kwargs.context;
|
||||
} else {
|
||||
throw new Error("Invalid Query");
|
||||
}
|
||||
|
||||
// doing this remove empty keys, and undefined stuff
|
||||
const sanitizedParams = JSON.parse(JSON.stringify(params));
|
||||
return { route, params: sanitizedParams };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Notifications Mixin
|
||||
//------------------------------------------------------------------------------
|
||||
export interface INotification {
|
||||
id: number;
|
||||
title: string;
|
||||
message: string;
|
||||
type: "notification" | "warning";
|
||||
sticky: boolean;
|
||||
}
|
||||
|
||||
function notificationMixin<T extends Type<BaseStore>>(Base: T) {
|
||||
return class extends Base {
|
||||
private generateID = idGenerator();
|
||||
|
||||
addNotification(notif: Partial<INotification>): number {
|
||||
const id = this.generateID();
|
||||
const defaultVals = {
|
||||
title: "",
|
||||
message: "",
|
||||
type: "notification",
|
||||
sticky: false
|
||||
};
|
||||
const notification = Object.assign(defaultVals, notif, { id });
|
||||
this.trigger("notification_added", notification);
|
||||
if (!notification.sticky) {
|
||||
setTimeout(() => this.closeNotification(id), 2500);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
closeNotification(id: number) {
|
||||
this.trigger("notification_closed", id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Action Manager Mixin
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(Base: T) {
|
||||
return class extends Base {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
const query = this.services.router.getQuery();
|
||||
let { app, actionId } = this.getAppAndAction(query);
|
||||
this.state.currentApp = app;
|
||||
if (!actionId) {
|
||||
this.state.inHome = true;
|
||||
}
|
||||
|
||||
this.services.router.on("query_changed", this, this.updateAction);
|
||||
this.updateAction(this.services.router.getQuery());
|
||||
}
|
||||
|
||||
private updateAction(query: Query) {
|
||||
let { app, actionId } = this.getAppAndAction(query);
|
||||
this.updateAppState(app, actionId);
|
||||
}
|
||||
|
||||
activateMenuItem(menuId: number) {
|
||||
const menu = this.menuInfo.menus[menuId];
|
||||
if (!menu) {
|
||||
throw new Error("Invalid menu id");
|
||||
}
|
||||
return this.updateAppState(menu.app, menu.actionId);
|
||||
}
|
||||
|
||||
private async updateAppState(
|
||||
app: MenuItem | null,
|
||||
actionId: number | null
|
||||
) {
|
||||
const newApp = app || this.state.currentApp;
|
||||
if (actionId) {
|
||||
const query: Query = { action_id: String(actionId) };
|
||||
const menuId = newApp ? newApp.app.id : false;
|
||||
if (menuId) {
|
||||
query.menu_id = String(menuId);
|
||||
}
|
||||
if (app) {
|
||||
this.update({ currentApp: app });
|
||||
}
|
||||
this.services.router.navigate(query);
|
||||
return this.doAction(actionId);
|
||||
} else {
|
||||
this.update({ inHome: true, currentApp: newApp });
|
||||
}
|
||||
}
|
||||
|
||||
private getAppAndAction(
|
||||
query: Query
|
||||
): { app: MenuItem | null; actionId: number | null } {
|
||||
const menuInfo = this.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]) {
|
||||
const menu = menuInfo.actionMap[actionId]!;
|
||||
app = menu.app;
|
||||
}
|
||||
}
|
||||
if ("menu_id" in query) {
|
||||
const menuId = parseInt(query.menu_id, 10);
|
||||
const menu = menuInfo.menus[menuId];
|
||||
if (menu) {
|
||||
app = menu.app;
|
||||
if (!actionId) {
|
||||
actionId = menu.actionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { app, actionId };
|
||||
}
|
||||
|
||||
async doAction(request: ActionRequest) {
|
||||
if (typeof request === "number") {
|
||||
await this.loadAction(request);
|
||||
// this is an action ID
|
||||
let name = request === 131 ? "discuss" : "crm";
|
||||
let title =
|
||||
request === 131 ? "Discuss" : request === 250 ? "Notes" : "CRM";
|
||||
let Widget = this.actionRegistry.get(name);
|
||||
this.update({
|
||||
inHome: false,
|
||||
stack: [
|
||||
{
|
||||
id: 1,
|
||||
context: {},
|
||||
target: "current",
|
||||
type: "client",
|
||||
name,
|
||||
title,
|
||||
Widget: Widget
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private loadAction(id: number) {
|
||||
return this.rpc({
|
||||
route: "web/action/load",
|
||||
params: {
|
||||
action_id: id
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { Type } from "../core/component";
|
||||
import { rpcMixin } from "./rpc_mixin";
|
||||
import { Widget } from "../widgets/widget";
|
||||
|
||||
export type Context = { [key: string]: any };
|
||||
|
||||
export interface CommonActionInfo {
|
||||
id: number;
|
||||
context: Context;
|
||||
title: string;
|
||||
target: "current" | "new";
|
||||
}
|
||||
|
||||
export type ActionRequest = string | number;
|
||||
|
||||
export type ActionWidget = Type<Widget<{}, {}>>;
|
||||
|
||||
export interface ClientActionInfo extends CommonActionInfo {
|
||||
type: "client";
|
||||
name: string;
|
||||
Widget: ActionWidget;
|
||||
}
|
||||
|
||||
export interface ActWindowInfo extends CommonActionInfo {
|
||||
type: "act_window";
|
||||
view: string;
|
||||
}
|
||||
|
||||
export interface ActionDescription {
|
||||
id: number;
|
||||
type: "ir.actions.act_window" | "ir.actions.client";
|
||||
target: "current";
|
||||
}
|
||||
|
||||
export type ActionInfo = ClientActionInfo | ActWindowInfo;
|
||||
export type ActionStack = ActionInfo[];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Action Manager Mixin
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(
|
||||
Base: T
|
||||
) {
|
||||
return class extends Base {
|
||||
async doAction(request: ActionRequest) {
|
||||
if (typeof request === "number") {
|
||||
await this.loadAction(request);
|
||||
// this is an action ID
|
||||
let name = request === 131 ? "discuss" : "crm";
|
||||
let title =
|
||||
request === 131 ? "Discuss" : request === 250 ? "Notes" : "CRM";
|
||||
let Widget = this.actionRegistry.get(name);
|
||||
this.update({
|
||||
inHome: false,
|
||||
stack: [
|
||||
{
|
||||
id: 1,
|
||||
context: {},
|
||||
target: "current",
|
||||
type: "client",
|
||||
name,
|
||||
title,
|
||||
Widget: Widget
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
loadAction(id: number) {
|
||||
return this.rpc({
|
||||
route: "web/action/load",
|
||||
params: {
|
||||
action_id: id
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Type } from "../core/component";
|
||||
import { BaseStore } from "./store";
|
||||
import { idGenerator } from "../core/utils";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Notifications Mixin
|
||||
//------------------------------------------------------------------------------
|
||||
export interface INotification {
|
||||
id: number;
|
||||
title: string;
|
||||
message: string;
|
||||
type: "notification" | "warning";
|
||||
sticky: boolean;
|
||||
}
|
||||
|
||||
export function notificationMixin<T extends Type<BaseStore>>(Base: T) {
|
||||
return class extends Base {
|
||||
generateID = idGenerator();
|
||||
|
||||
addNotification(notif: Partial<INotification>): number {
|
||||
const id = this.generateID();
|
||||
const defaultVals = {
|
||||
title: "",
|
||||
message: "",
|
||||
type: "notification",
|
||||
sticky: false
|
||||
};
|
||||
const notification = Object.assign(defaultVals, notif, { id });
|
||||
this.trigger("notification_added", notification);
|
||||
if (!notification.sticky) {
|
||||
setTimeout(() => this.closeNotification(id), 2500);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
closeNotification(id: number) {
|
||||
this.trigger("notification_closed", id);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Type } from "../core/component";
|
||||
import { BaseStore } from "./store";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export interface RPCModelQuery {
|
||||
model: string;
|
||||
method: string;
|
||||
args?: any[];
|
||||
kwargs?: { [key: string]: any };
|
||||
context?: { [key: string]: any };
|
||||
}
|
||||
|
||||
export interface RPCControllerQuery {
|
||||
route: string;
|
||||
params: { [key: string]: any };
|
||||
}
|
||||
|
||||
export type RPCQuery = RPCModelQuery | RPCControllerQuery;
|
||||
|
||||
export type RPC = (rpc: RPCQuery) => Promise<any>;
|
||||
|
||||
export interface RequestParameters {
|
||||
route: string;
|
||||
params: { [key: string]: any };
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// rpc Mixin
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export function rpcMixin<T extends Type<BaseStore>>(Base: T) {
|
||||
return class extends Base {
|
||||
counter: number = 0;
|
||||
|
||||
async rpc(rpc: RPCQuery): Promise<any> {
|
||||
const request = this.prepareRequest(rpc);
|
||||
if (this.counter === 0) {
|
||||
this.trigger("rpc_status", "loading");
|
||||
}
|
||||
this.counter++;
|
||||
const result = await this.services.rpc(request.route, request.params);
|
||||
this.counter--;
|
||||
if (this.counter === 0) {
|
||||
this.trigger("rpc_status", "notloading");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
prepareRequest(query: RPCQuery): RequestParameters {
|
||||
let route: string;
|
||||
let params = "params" in query ? query.params : {};
|
||||
if ("route" in query) {
|
||||
route = query.route;
|
||||
} else if ("model" in query && "method" in query) {
|
||||
route = `/web/dataset/call_kw/${query.model}/${query.method}`;
|
||||
params.args = query.args || [];
|
||||
params.model = query.model;
|
||||
params.method = query.method;
|
||||
params.kwargs = Object.assign(params.kwargs || {}, query.kwargs);
|
||||
params.kwargs.context =
|
||||
query.context || params.context || params.kwargs.context;
|
||||
} else {
|
||||
throw new Error("Invalid Query");
|
||||
}
|
||||
|
||||
// doing this remove empty keys, and undefined stuff
|
||||
const sanitizedParams = JSON.parse(JSON.stringify(params));
|
||||
return { route, params: sanitizedParams };
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
import { EventBus } from "../core/event_bus";
|
||||
import { Registry } from "../core/registry";
|
||||
import { RPC } from "../services/ajax";
|
||||
import { IRouter, Query } from "../services/router";
|
||||
import {
|
||||
actionManagerMixin,
|
||||
ActionStack,
|
||||
ActionWidget
|
||||
} from "./action_manager_mixin";
|
||||
import { notificationMixin } from "./notification_mixin";
|
||||
import { rpcMixin } from "./rpc_mixin";
|
||||
import { MenuItem } from "./store";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export { ActionStack, ActionWidget } from "./action_manager_mixin";
|
||||
export { INotification } from "./notification_mixin";
|
||||
export { RPC } from "./rpc_mixin";
|
||||
|
||||
export interface MenuItem {
|
||||
id: number;
|
||||
name: string;
|
||||
parentId: number | false;
|
||||
action: string | false;
|
||||
icon: string | false;
|
||||
|
||||
// root menu id
|
||||
app: MenuItem;
|
||||
actionId: number;
|
||||
children: MenuItem[];
|
||||
}
|
||||
|
||||
export interface MenuInfo {
|
||||
menus: { [key: number]: MenuItem | undefined };
|
||||
|
||||
actionMap: { [id: number]: MenuItem | undefined };
|
||||
roots: number[];
|
||||
}
|
||||
|
||||
export interface State {
|
||||
stack: ActionStack;
|
||||
inHome: boolean;
|
||||
currentApp: MenuItem | null;
|
||||
}
|
||||
|
||||
export interface Services {
|
||||
rpc: RPC;
|
||||
router: IRouter;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Store
|
||||
//------------------------------------------------------------------------------
|
||||
export class BaseStore extends EventBus {
|
||||
state: State = {
|
||||
stack: [],
|
||||
inHome: false,
|
||||
currentApp: null
|
||||
};
|
||||
menuInfo: MenuInfo;
|
||||
services: Services;
|
||||
actionRegistry: Registry<ActionWidget>;
|
||||
|
||||
constructor(
|
||||
services: Services,
|
||||
menuInfo: MenuInfo,
|
||||
actionRegistry: Registry<ActionWidget>
|
||||
) {
|
||||
super();
|
||||
this.services = services;
|
||||
this.menuInfo = menuInfo;
|
||||
this.actionRegistry = actionRegistry;
|
||||
}
|
||||
|
||||
update(nextState: Partial<State>) {
|
||||
Object.assign(this.state, nextState);
|
||||
this.trigger("state_updated", this.state);
|
||||
}
|
||||
|
||||
toggleHomeMenu() {
|
||||
if (this.state.inHome && !this.state.currentApp) {
|
||||
return;
|
||||
}
|
||||
this.update({ inHome: !this.state.inHome });
|
||||
}
|
||||
}
|
||||
|
||||
export class Store extends actionManagerMixin(
|
||||
rpcMixin(notificationMixin(BaseStore))
|
||||
) {
|
||||
constructor(
|
||||
services: Services,
|
||||
menuInfo: MenuInfo,
|
||||
actionRegistry: Registry<ActionWidget>
|
||||
) {
|
||||
super(services, menuInfo, actionRegistry);
|
||||
const query = this.services.router.getQuery();
|
||||
let { app, actionId } = this.getAppAndAction(query);
|
||||
this.state.currentApp = app;
|
||||
if (!actionId) {
|
||||
this.state.inHome = true;
|
||||
}
|
||||
|
||||
this.services.router.on("query_changed", this, this.updateAction);
|
||||
this.updateAction(this.services.router.getQuery());
|
||||
}
|
||||
|
||||
private updateAction(query: Query) {
|
||||
let { app, actionId } = this.getAppAndAction(query);
|
||||
this.updateAppState(app, actionId);
|
||||
}
|
||||
|
||||
activateMenuItem(menuId: number) {
|
||||
const menu = this.menuInfo.menus[menuId];
|
||||
if (!menu) {
|
||||
throw new Error("Invalid menu id");
|
||||
}
|
||||
return this.updateAppState(menu.app, menu.actionId);
|
||||
}
|
||||
|
||||
private async updateAppState(app: MenuItem | null, actionId: number | null) {
|
||||
const newApp = app || this.state.currentApp;
|
||||
if (actionId) {
|
||||
const query: Query = { action_id: String(actionId) };
|
||||
const menuId = newApp ? newApp.app.id : false;
|
||||
if (menuId) {
|
||||
query.menu_id = String(menuId);
|
||||
}
|
||||
if (app) {
|
||||
this.update({ currentApp: app });
|
||||
}
|
||||
this.services.router.navigate(query);
|
||||
return this.doAction(actionId);
|
||||
} else {
|
||||
this.update({ inHome: true, currentApp: newApp });
|
||||
}
|
||||
}
|
||||
|
||||
getAppAndAction(
|
||||
query: Query
|
||||
): { app: MenuItem | null; actionId: number | null } {
|
||||
const menuInfo = this.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]) {
|
||||
const menu = menuInfo.actionMap[actionId]!;
|
||||
app = menu.app;
|
||||
}
|
||||
}
|
||||
if ("menu_id" in query) {
|
||||
const menuId = parseInt(query.menu_id, 10);
|
||||
const menu = menuInfo.menus[menuId];
|
||||
if (menu) {
|
||||
app = menu.app;
|
||||
if (!actionId) {
|
||||
actionId = menu.actionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { app, actionId };
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MenuItem } from "../store";
|
||||
import { MenuItem } from "../store/store";
|
||||
import { PureWidget } from "./widget";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ActionStack } from "../store";
|
||||
import { ActionStack } from "../store/store";
|
||||
import { Widget } from "./widget";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MenuInfo, MenuItem } from "../store";
|
||||
import { MenuInfo, MenuItem } from "../store/store";
|
||||
import { Widget } from "./widget";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { INotification } from "../store";
|
||||
import { INotification } from "../store/store";
|
||||
import { Widget } from "./widget";
|
||||
|
||||
export class Notification extends Widget<INotification, {}> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { debounce } from "../core/utils";
|
||||
import { Env } from "../env";
|
||||
import { State, Store } from "../store";
|
||||
import { State, Store } from "../store/store";
|
||||
import { ActionContainer } from "./action_container";
|
||||
import { HomeMenu } from "./home_menu";
|
||||
import { Navbar } from "./navbar";
|
||||
|
||||
@@ -6,7 +6,7 @@ import { idGenerator } from "../src/ts/core/utils";
|
||||
import { getMenuInfo } from "../src/ts/loaders";
|
||||
import { actionRegistry } from "../src/ts/registries";
|
||||
import { IRouter, Query, RouterEvent } from "../src/ts/services/router";
|
||||
import { MenuInfo, Services, Store } from "../src/ts/store";
|
||||
import { MenuInfo, Services, Store } from "../src/ts/store/store";
|
||||
|
||||
export function makeTestFixture() {
|
||||
let fixture = document.createElement("div");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Env, makeEnv } from "../../src/ts/env";
|
||||
import { ActionStack, Store } from "../../src/ts/store";
|
||||
import { ActionStack, Store } from "../../src/ts/store/store";
|
||||
import { ActionContainer, Props } from "../../src/ts/widgets/action_container";
|
||||
import { Widget } from "../../src/ts/widgets/widget";
|
||||
import * as helpers from "../helpers";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Env, makeEnv } from "../../src/ts/env";
|
||||
import { Store } from "../../src/ts/store";
|
||||
import { Store } from "../../src/ts/store/store";
|
||||
import { HomeMenu, Props } from "../../src/ts/widgets/home_menu";
|
||||
import * as helpers from "../helpers";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Env, makeEnv } from "../../src/ts/env";
|
||||
import { MenuInfo, Store } from "../../src/ts/store";
|
||||
import { MenuInfo, Store } from "../../src/ts/store/store";
|
||||
import { Navbar, Props } from "../../src/ts/widgets/navbar";
|
||||
import * as helpers from "../helpers";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Env, makeEnv } from "../../src/ts/env";
|
||||
import { INotification, Store } from "../../src/ts/store";
|
||||
import { INotification, Store } from "../../src/ts/store/store";
|
||||
import { Notification } from "../../src/ts/widgets/notification";
|
||||
import * as helpers from "../helpers";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Env, makeEnv } from "../../src/ts/env";
|
||||
import { Store } from "../../src/ts/store";
|
||||
import { Store } from "../../src/ts/store/store";
|
||||
import { Root } from "../../src/ts/widgets/root";
|
||||
import * as helpers from "../helpers";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user