mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
add control panel and some more interesting views
This commit is contained in:
@@ -1,7 +1,50 @@
|
||||
// ------------------------------------------------------------------
|
||||
// Variables
|
||||
// ------------------------------------------------------------------
|
||||
$navbar-height: 46px;
|
||||
$main-color: #875a7b;
|
||||
$o-main-text-color: #666666;
|
||||
$o-notification-info-bg-color: #fcfbea;
|
||||
$o-notification-error-bg-color: #f16567;
|
||||
$o-view-background-color: white;
|
||||
$o-control-panel-background-color: $o-view-background-color;
|
||||
$o-horizontal-padding: 16px;
|
||||
$o-cp-breadcrumb-height: 30px;
|
||||
|
||||
// bootstrap overrides
|
||||
// this does not work: $breadcrumb-bg: $o-control-panel-background-color;
|
||||
.breadcrumb {
|
||||
background-color: white;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Mixins
|
||||
// ------------------------------------------------------------------
|
||||
@mixin o-webclient-padding(
|
||||
$top: 0px,
|
||||
$right: $o-horizontal-padding,
|
||||
$bottom: 0px,
|
||||
$left: $o-horizontal-padding
|
||||
) {
|
||||
padding-top: $top;
|
||||
padding-right: $right;
|
||||
padding-bottom: $bottom;
|
||||
padding-left: $left;
|
||||
}
|
||||
|
||||
@mixin o-text-overflow($display: inline-block, $max-width: 100%) {
|
||||
display: $display;
|
||||
max-width: $max-width;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top; // To update display context changed by overflow:hidden
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CSS
|
||||
// ------------------------------------------------------------------
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -138,9 +181,6 @@ body {
|
||||
}
|
||||
|
||||
/***** Notifications *****/
|
||||
$o-notification-info-bg-color: #fcfbea;
|
||||
$o-notification-error-bg-color: #f16567;
|
||||
|
||||
.o_notification_container {
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
@@ -190,9 +230,20 @@ $o-notification-error-bg-color: #f16567;
|
||||
}
|
||||
|
||||
/***** Discuss *****/
|
||||
.o_discuss {
|
||||
padding: 20px;
|
||||
.o_discuss .o_content {
|
||||
font-size: 15px;
|
||||
display: flex;
|
||||
|
||||
.o_discuss_sidebar {
|
||||
background-color: #212529;
|
||||
flex: 0 0 300px;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
}
|
||||
.o_discuss_content {
|
||||
padding: 20px;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 5px;
|
||||
@@ -210,3 +261,81 @@ $o-notification-error-bg-color: #f16567;
|
||||
padding: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/***** Control Panel *****/
|
||||
.o_control_panel {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
border-bottom: 1px solid darken($o-control-panel-background-color, 20%);
|
||||
@include o-webclient-padding($top: 10px, $bottom: 10px);
|
||||
background-color: $o-control-panel-background-color;
|
||||
|
||||
> .breadcrumb {
|
||||
width: 50%;
|
||||
font-size: 18px;
|
||||
|
||||
> li {
|
||||
@include o-text-overflow($max-width: 90%);
|
||||
|
||||
> a {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .o_cp_searchview {
|
||||
width: 50%;
|
||||
min-height: $o-cp-breadcrumb-height;
|
||||
}
|
||||
|
||||
> .o_cp_left {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 50%;
|
||||
margin-top: 5px;
|
||||
|
||||
> .o_cp_sidebar {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
> .o_cp_right {
|
||||
display: flex;
|
||||
width: 50%;
|
||||
margin-top: 5px;
|
||||
|
||||
> .o_cp_pager {
|
||||
margin: auto 0 auto auto;
|
||||
padding-left: 5px;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.o_pager_counter {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***** Action Controller *****/
|
||||
.o_action_controller {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
padding: 0;
|
||||
|
||||
> .o_cp_controller {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
> .o_content {
|
||||
overflow: auto;
|
||||
flex: 1 1 100%;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Clock } from "./clock";
|
||||
import { Counter } from "./counter";
|
||||
import { Widget } from "../widget";
|
||||
|
||||
import { ControlPanel } from "../ui/control_panel";
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -17,7 +17,7 @@ interface State {
|
||||
|
||||
export class Discuss extends Widget<{}, State> {
|
||||
template = "web.discuss";
|
||||
widgets = { Clock, Counter, ColorWidget };
|
||||
widgets = { Clock, Counter, ColorWidget, ControlPanel };
|
||||
state: State = { validcounter: true, color: "red" };
|
||||
|
||||
resetCounter(ev: MouseEvent) {
|
||||
|
||||
@@ -2,7 +2,8 @@ import { WEnv } from "./core/component";
|
||||
import { QWeb } from "./core/qweb_vdom";
|
||||
import { Registry } from "./core/registry";
|
||||
import { idGenerator } from "./core/utils";
|
||||
import { RPC } from "./services/ajax";
|
||||
import { RPC as RPCService } from "./services/ajax";
|
||||
import { RPC } from "./store/store";
|
||||
import { IRouter } from "./services/router";
|
||||
import { ControllerWidget, Store, Notification } from "./store/store";
|
||||
|
||||
@@ -11,7 +12,7 @@ import { ControllerWidget, Store, Notification } from "./store/store";
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export interface Services {
|
||||
rpc: RPC;
|
||||
rpc: RPCService;
|
||||
router: IRouter;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,10 @@ export function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(
|
||||
this: Controller,
|
||||
parent: Widget<any, any>
|
||||
) {
|
||||
const widget = new View!(parent, { info: descr.views[0][1] });
|
||||
const widget = new View!(parent, {
|
||||
info: descr.views[0][1],
|
||||
title: descr.name
|
||||
});
|
||||
const div = document.createElement("div");
|
||||
await widget.mount(div);
|
||||
this.widget = widget;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Widget } from "../widget";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Navbar
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export class ControlPanel extends Widget<Props, {}> {
|
||||
template = "web.control_panel";
|
||||
}
|
||||
@@ -56,6 +56,7 @@ export class Root extends Widget<Store, State> {
|
||||
// to do: call some public method of widget instead...
|
||||
(<HTMLElement>this.refs.content).appendChild(widget.el!);
|
||||
widget.__mount();
|
||||
widget.el!.classList.add("o_action_controller");
|
||||
this.store.activateController(controller);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Widget } from "../widget";
|
||||
import { ControlPanel } from "../ui/control_panel";
|
||||
|
||||
export class BaseView extends Widget<{ info: any }, {}> {
|
||||
template = "web.base_view";
|
||||
widgets = { ControlPanel };
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Widget } from "../widget";
|
||||
import { BaseView } from "./base_view";
|
||||
|
||||
export class FormView extends Widget<{ info: any }, {}> {
|
||||
inlineTemplate = `<div>form view: <span t-esc="props.info"/></div>`;
|
||||
export class FormView extends BaseView {
|
||||
viewType = "form";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Widget } from "../widget";
|
||||
import { BaseView } from "./base_view";
|
||||
|
||||
export class KanbanView extends Widget<{ info: any }, {}> {
|
||||
inlineTemplate = `<div>kanban view: <span t-esc="props.info"/></div>`;
|
||||
export class KanbanView extends BaseView {
|
||||
viewType = "kanban";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Widget } from "../widget";
|
||||
import { BaseView } from "./base_view";
|
||||
|
||||
export class ListView extends Widget<{ info: any }, {}> {
|
||||
inlineTemplate = `<div>list view: <span t-esc="props.info"/></div>`;
|
||||
export class ListView extends BaseView {
|
||||
viewType = "list";
|
||||
}
|
||||
|
||||
@@ -50,6 +50,37 @@
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<div t-name="web.control_panel" class="o_control_panel">
|
||||
<ol class="breadcrumb" role="navigation">
|
||||
<li class="breadcrumb-item active">
|
||||
<t t-esc="props.title"/>
|
||||
</li>
|
||||
</ol>
|
||||
<div class="o_cp_searchview" role="search">
|
||||
<t t-call="web.search_view"/>
|
||||
</div>
|
||||
<div class="o_cp_left">
|
||||
<div class="o_cp_buttons" role="toolbar" aria-label="Control panel toolbar"/>
|
||||
<aside class="o_cp_sidebar"/>
|
||||
</div>
|
||||
<div class="o_cp_right">
|
||||
<div class="btn-group o_search_options" role="search"/>
|
||||
<nav class="o_cp_pager" role="search" aria-label="Pager"/>
|
||||
<nav class="btn-group o_cp_switch_buttons" role="toolbar" aria-label="View switcher"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-name="web.search_view" class="o_searchview" role="search" aria-autocomplete="list">
|
||||
<span class="o_searchview_more fa" title="Advanced Search..." role="img" aria-label="Advanced Search..."/>
|
||||
</div>
|
||||
|
||||
<div t-name="web.base_view" class="o_view_controller">
|
||||
<t t-widget="ControlPanel" t-props="{title: props.title}"/>
|
||||
<div class="o_content">
|
||||
<span t-esc="viewType"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-name="web.home_menu" class="o_home_menu">
|
||||
<div class="o_apps">
|
||||
<a t-foreach="apps" t-as="app" t-att-href="'#menu_id=' + app.id + '&action_id=' + app.actionId" class="o_app" t-on-click="openMenu(app)" t-att-data-menu="app.id">
|
||||
@@ -73,24 +104,31 @@
|
||||
</div>
|
||||
|
||||
<div t-name="web.discuss" class="o_discuss">
|
||||
<span>DISCUSS!!</span>
|
||||
<button t-on-click="resetCounter">Reset first counter</button>
|
||||
<button t-on-click="resetCounterAsync">Reset counter 2 in 3s</button>
|
||||
<button t-on-click="toggle">Toggle Clock/counters</button>
|
||||
<button t-on-click="toggleColor">Toggle Color</button>
|
||||
<button t-on-click="updateState({})">Rerender this widget</button>
|
||||
<input t-ref="textinput"/>
|
||||
<t t-if="state.validcounter">
|
||||
<t t-widget="Counter" t-ref="counter" t-props="{initialState:4}"/>
|
||||
<t t-widget="Counter" t-ref="counter2" t-props="{initialState:400}"/>
|
||||
</t>
|
||||
<t t-else="1">
|
||||
<t t-widget="Clock"/>
|
||||
</t>
|
||||
<t t-widget="ColorWidget" t-props="{color: state.color}"/>
|
||||
<button t-on-click="addNotif(false)">Add notif</button>
|
||||
<button t-on-click="addNotif(true)">Add sticky notif</button>
|
||||
<button t-on-click="addWarning">Add warning</button>
|
||||
<t t-widget="ControlPanel" t-props="{title: 'Discuss'}"/>
|
||||
<div class="o_content">
|
||||
<div class="o_discuss_sidebar">
|
||||
<span>DISCUSS!!</span>
|
||||
</div>
|
||||
<div class="o_discuss_content">
|
||||
<button t-on-click="resetCounter">Reset first counter</button>
|
||||
<button t-on-click="resetCounterAsync">Reset counter 2 in 3s</button>
|
||||
<button t-on-click="toggle">Toggle Clock/counters</button>
|
||||
<button t-on-click="toggleColor">Toggle Color</button>
|
||||
<button t-on-click="updateState({})">Rerender this widget</button>
|
||||
<input t-ref="textinput"/>
|
||||
<t t-if="state.validcounter">
|
||||
<t t-widget="Counter" t-ref="counter" t-props="{initialState:4}"/>
|
||||
<t t-widget="Counter" t-ref="counter2" t-props="{initialState:400}"/>
|
||||
</t>
|
||||
<t t-else="1">
|
||||
<t t-widget="Clock"/>
|
||||
</t>
|
||||
<t t-widget="ColorWidget" t-props="{color: state.color}"/>
|
||||
<button t-on-click="addNotif(false)">Add notif</button>
|
||||
<button t-on-click="addNotif(true)">Add sticky notif</button>
|
||||
<button t-on-click="addWarning">Add warning</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</templates>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export { MockRouter } from "./mock_router";
|
||||
export { MockServer } from "./mock_server";
|
||||
export { TestData, makeTestData, makeMenuInfo } from "./test_data";
|
||||
export { TestEnv, TestInfo, makeTestWEnv, makeTestEnv } from "./test_env";
|
||||
export { makeMenuInfo, makeTestData, TestData } from "./test_data";
|
||||
export { makeTestEnv, makeTestWEnv, TestEnv, TestInfo } from "./test_env";
|
||||
export {
|
||||
makeDeferred,
|
||||
makeTestFixture,
|
||||
nextMicroTick,
|
||||
nextTick,
|
||||
makeTestFixture,
|
||||
normalize,
|
||||
makeDeferred
|
||||
normalize
|
||||
} from "./test_utils";
|
||||
|
||||
@@ -14,7 +14,7 @@ export function makeTestData(): TestData {
|
||||
};
|
||||
}
|
||||
|
||||
function makeMenuInfo(): MenuInfo {
|
||||
export function makeMenuInfo(): MenuInfo {
|
||||
const items: BaseMenuItem[] = [
|
||||
{
|
||||
id: 96,
|
||||
|
||||
@@ -49,7 +49,7 @@ exports[`clicks on client action with invalid key => empty widget is rendered +
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div></div></div>
|
||||
<div class=\\"o_content\\"><div class=\\"o_action_controller\\"></div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
<div class=\\"o_notification o_error\\">
|
||||
@@ -83,33 +83,60 @@ exports[`if url has action_id, will render action and navigate to proper menu_id
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div class=\\"o_discuss\\">
|
||||
<span>DISCUSS!!</span>
|
||||
<button>Reset first counter</button>
|
||||
<button>Reset counter 2 in 3s</button>
|
||||
<button>Toggle Clock/counters</button>
|
||||
<button>Toggle Color</button>
|
||||
<button>Rerender this widget</button>
|
||||
<input>
|
||||
|
||||
<div>
|
||||
<div class=\\"o_content\\"><div class=\\"o_discuss o_action_controller\\">
|
||||
<div class=\\"o_control_panel\\">
|
||||
<ol class=\\"breadcrumb\\" role=\\"navigation\\">
|
||||
<li class=\\"breadcrumb-item active\\">
|
||||
Discuss
|
||||
</li>
|
||||
</ol>
|
||||
<div class=\\"o_cp_searchview\\" role=\\"search\\">
|
||||
<div class=\\"o_searchview\\" role=\\"search\\" aria-autocomplete=\\"list\\">
|
||||
<span class=\\"o_searchview_more fa\\" title=\\"Advanced Search...\\" role=\\"img\\" aria-label=\\"Advanced Search...\\"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_cp_left\\">
|
||||
<div class=\\"o_cp_buttons\\" role=\\"toolbar\\" aria-label=\\"Control panel toolbar\\"></div>
|
||||
<aside class=\\"o_cp_sidebar\\"></aside>
|
||||
</div>
|
||||
<div class=\\"o_cp_right\\">
|
||||
<div class=\\"btn-group o_search_options\\" role=\\"search\\"></div>
|
||||
<nav class=\\"o_cp_pager\\" role=\\"search\\" aria-label=\\"Pager\\"></nav>
|
||||
<nav class=\\"btn-group o_cp_switch_buttons\\" role=\\"toolbar\\" aria-label=\\"View switcher\\"></nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_content\\">
|
||||
<div class=\\"o_discuss_sidebar\\">
|
||||
<span>DISCUSS!!</span>
|
||||
</div>
|
||||
<div class=\\"o_discuss_content\\">
|
||||
<button>Reset first counter</button>
|
||||
<button>Reset counter 2 in 3s</button>
|
||||
<button>Toggle Clock/counters</button>
|
||||
<button>Toggle Color</button>
|
||||
<button>Rerender this widget</button>
|
||||
<input>
|
||||
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 4</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 400</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<div>
|
||||
<span>Current Color: </span>
|
||||
red
|
||||
</div>
|
||||
<button>Add notif</button>
|
||||
<button>Add sticky notif</button>
|
||||
<button>Add warning</button>
|
||||
<button>Add notif</button>
|
||||
<button>Add sticky notif</button>
|
||||
<button>Add warning</button>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
@@ -133,7 +160,7 @@ exports[`open act window action with invalid viewtype => empty widget is rendere
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div></div></div>
|
||||
<div class=\\"o_content\\"><div class=\\"o_action_controller\\"></div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
<div class=\\"o_notification o_error\\">
|
||||
@@ -167,33 +194,60 @@ exports[`start with no action => clicks on client action => discuss is rendered
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div class=\\"o_discuss\\">
|
||||
<span>DISCUSS!!</span>
|
||||
<button>Reset first counter</button>
|
||||
<button>Reset counter 2 in 3s</button>
|
||||
<button>Toggle Clock/counters</button>
|
||||
<button>Toggle Color</button>
|
||||
<button>Rerender this widget</button>
|
||||
<input>
|
||||
|
||||
<div>
|
||||
<div class=\\"o_content\\"><div class=\\"o_discuss o_action_controller\\">
|
||||
<div class=\\"o_control_panel\\">
|
||||
<ol class=\\"breadcrumb\\" role=\\"navigation\\">
|
||||
<li class=\\"breadcrumb-item active\\">
|
||||
Discuss
|
||||
</li>
|
||||
</ol>
|
||||
<div class=\\"o_cp_searchview\\" role=\\"search\\">
|
||||
<div class=\\"o_searchview\\" role=\\"search\\" aria-autocomplete=\\"list\\">
|
||||
<span class=\\"o_searchview_more fa\\" title=\\"Advanced Search...\\" role=\\"img\\" aria-label=\\"Advanced Search...\\"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_cp_left\\">
|
||||
<div class=\\"o_cp_buttons\\" role=\\"toolbar\\" aria-label=\\"Control panel toolbar\\"></div>
|
||||
<aside class=\\"o_cp_sidebar\\"></aside>
|
||||
</div>
|
||||
<div class=\\"o_cp_right\\">
|
||||
<div class=\\"btn-group o_search_options\\" role=\\"search\\"></div>
|
||||
<nav class=\\"o_cp_pager\\" role=\\"search\\" aria-label=\\"Pager\\"></nav>
|
||||
<nav class=\\"btn-group o_cp_switch_buttons\\" role=\\"toolbar\\" aria-label=\\"View switcher\\"></nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_content\\">
|
||||
<div class=\\"o_discuss_sidebar\\">
|
||||
<span>DISCUSS!!</span>
|
||||
</div>
|
||||
<div class=\\"o_discuss_content\\">
|
||||
<button>Reset first counter</button>
|
||||
<button>Reset counter 2 in 3s</button>
|
||||
<button>Toggle Clock/counters</button>
|
||||
<button>Toggle Color</button>
|
||||
<button>Rerender this widget</button>
|
||||
<input>
|
||||
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 4</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 400</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<div>
|
||||
<span>Current Color: </span>
|
||||
red
|
||||
</div>
|
||||
<button>Add notif</button>
|
||||
<button>Add sticky notif</button>
|
||||
<button>Add warning</button>
|
||||
<button>Add notif</button>
|
||||
<button>Add sticky notif</button>
|
||||
<button>Add warning</button>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user