add control panel and some more interesting views

This commit is contained in:
Géry Debongnie
2019-03-08 11:59:02 +01:00
parent c3c060a028
commit 98fe440a84
14 changed files with 327 additions and 77 deletions
+134 -5
View File
@@ -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;
}
}
+2 -2
View File
@@ -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) {
+3 -2
View File
@@ -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;
+17
View File
@@ -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";
}
+1
View File
@@ -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);
}
}
+7
View File
@@ -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 };
}
+3 -3
View File
@@ -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";
}
+3 -3
View File
@@ -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";
}
+3 -3
View File
@@ -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";
}
+56 -18
View File
@@ -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 + '&amp;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>
+5 -5
View File
@@ -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";
+1 -1
View File
@@ -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\\">