diff options
| author | Géry Debongnie <ged@odoo.com> | 2015-06-15 16:31:27 +0200 |
|---|---|---|
| committer | Géry Debongnie <ged@odoo.com> | 2015-06-15 16:31:27 +0200 |
| commit | 2c7367a8cc8d9e200b1fa2083ce0d80f8f4e4bd3 (patch) | |
| tree | af916cff4d94554b1e9667913e3feb331ec81a13 /addons/web/static | |
| parent | 5cb10d4fc9594f0c6825757c24d66d63664ce026 (diff) | |
| parent | 82186a93bb3f93c36667835df68fa31dcacf97a2 (diff) | |
[MERGE] new kanban view
This branch introduces the new kanban view. It is not completely
compatible with the previous version. Here are a few importants
points to be aware of:
* the kanban view template is rendered directly, not put inside a div.
It means that if a template has more than one root, chaos will ensue
* kanban view has been split into several files, and various js modules
have changed. For example, the KanbanRecord class is now exported by
the 'web_kanban.Record' module. So, require statements need to be
updated
* records do not have access to the view (i.e., record.view.is_action_enabled('edit'))
You can use the 'editable' and 'deletable' key instead
Diffstat (limited to 'addons/web/static')
| -rw-r--r-- | addons/web/static/src/js/framework/core.js | 5 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form_widgets.js | 3 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/pager.js | 111 | ||||
| -rw-r--r-- | addons/web/static/src/less/enterprise_compatibility.less | 195 | ||||
| -rw-r--r-- | addons/web/static/src/less/utils.less | 189 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 23 |
6 files changed, 523 insertions, 3 deletions
diff --git a/addons/web/static/src/js/framework/core.js b/addons/web/static/src/js/framework/core.js index 7bd4800ec98..30138102663 100644 --- a/addons/web/static/src/js/framework/core.js +++ b/addons/web/static/src/js/framework/core.js @@ -186,6 +186,11 @@ return { list_widget_registry: new Registry(), search_widgets_registry: new Registry(), search_filters_registry: new Registry(), + + // necessary to make the kanban view compatible between + // community and enterprise edition + one2many_view_registry: new Registry(), + }; diff --git a/addons/web/static/src/js/views/form_widgets.js b/addons/web/static/src/js/views/form_widgets.js index ee04f8376b4..760ea703d35 100644 --- a/addons/web/static/src/js/views/form_widgets.js +++ b/addons/web/static/src/js/views/form_widgets.js @@ -285,7 +285,7 @@ var Priority = FieldChar.extend({ }, render_value: function() { this.priorities = this.prepare_priority(); - this.$el.html(QWeb.render("Priority", {'widget': this})); + this.$el.html(QWeb.render("FormPriority", {'widget': this})); if (!this.get('readonly')){ this.$el.find('li').on('click', this.set_priority.bind(this)); } @@ -1584,6 +1584,7 @@ var StatInfo = common.AbstractField.extend({ } } this.$el.html(QWeb.render("StatInfo", options)); + this.$el.addClass('o_stat_info'); }, }); diff --git a/addons/web/static/src/js/widgets/pager.js b/addons/web/static/src/js/widgets/pager.js new file mode 100644 index 00000000000..c195aaf530d --- /dev/null +++ b/addons/web/static/src/js/widgets/pager.js @@ -0,0 +1,111 @@ +odoo.define('web.Pager', function (require) { +"use strict"; + +var Widget = require('web.Widget'); + +var direction = { + previous: -1, + next: 1, +}; + +var Pager = Widget.extend({ + template: "Pager", + + events: { + 'click .o-pager-previous': 'previous', + 'click .o-pager-next': 'next', + }, + + // pager goes from 1 to size (included). + // current value is current_min (if limit === 1) + // or the interval [current_min, current_min + limit[ if limit > 1 + init: function (parent, size, current_min, limit, options) { + this.state = { + size: size, + current_min: current_min, + limit: limit, + }; + Object.defineProperty(this.state, 'current_max', { + get: function() { + return Math.min(this.current_min + this.limit - 1, this.size); + } + }); + this.options = options || {}; + this._super(parent); + }, + + start: function () { + this.$content = this.$('.o-pager-value'); + this._render(); + return this._super(); + }, + + set_state: function (options) { + _.extend(this.state, options); + this._render(); + }, + + previous: function(e) { + this._change_selection(direction.previous); + }, + + next: function() { + this._change_selection(direction.next); + }, + + disable: function() { + this.$('button').prop("disabled", true); + }, + + enable: function() { + this.$('button').prop("disabled", false); + }, + + _render: function () { + var state; + var size = this.state.size; + var current_min = this.state.current_min; + var current_max = this.state.current_max; + var single_page = 1 === current_min && current_max === size; + + if (size === 0 || (single_page && this.options.single_page_hidden)) { + this.$el.hide(); + } else { + this.$el.show(); + + if (single_page) { + this.disable(); + } else { + this.enable(); + } + + if (this.state.limit === 1) { + state = "" + current_min + " / " + size; + } else { + state = "" + current_min + "-" + current_max + " / " + size; + } + this.$content.html(state); + } + }, + + _change_selection: function (direction) { + var size = this.state.size; + var current_min = this.state.current_min; + var limit = this.state.limit; + current_min = (current_min + limit*direction); + if (current_min > size) { + current_min = 1; + } else if ((current_min < 1) && (limit === 1)) { + current_min = size; + } else if ((current_min < 1) && (limit > 1)) { + current_min = size - ((size % limit) || limit) + 1; + } + this.state.current_min = current_min; + this.trigger('pager_changed', _.clone(this.state)); + this._render(); + }, +}); + +return Pager; + +});
\ No newline at end of file diff --git a/addons/web/static/src/less/enterprise_compatibility.less b/addons/web/static/src/less/enterprise_compatibility.less new file mode 100644 index 00000000000..1cfd5120c34 --- /dev/null +++ b/addons/web/static/src/less/enterprise_compatibility.less @@ -0,0 +1,195 @@ +// ------------------------------------------------------------------ +// Odoo +// ------------------------------------------------------------------ + +// This file is necessary to make the community edition of the Odoo web +// client compatible with the enterprise edition. + +// The problem is that we have two web clients in parallel, and every +// addons should behave properly with both. + +@odoo-brand-optional-disabled: #6ED0BC; // Specifically used for status bar status arrows +@odoo-brand-primary: #337ab7; +@odoo-brand-optional: @odoo-brand-primary; +@odoo-brand-secondary: #8f8f8f; +@odoo-form-group-cols: 12; +@odoo-horizontal-padding: 16px; +@odoo-list-grey: #e2e2e0; // FIXME: listview thead background color +@odoo-main-color-muted: #a8a8a8; +@odoo-main-text-color: #666666; +@odoo-webclient-background-color: @odoo-brand-secondary; +@odoo-view-background-color: red; +@odoo-shadow-color: #303030; +@brand-primary: @odoo-brand-primary; + +.oe-view-manager { + background-color: #f0eeee !important; +} + +.o_kanban_view { + background-color: #f0eeee; + .o_kanban_header { + color: black !important; + } + + .o_kanban_config i, .o_kanban_quick_add i { + color: #555 !important; + &:hover { + background-color: darken(#f0eeee, 10%) !important; + } + } + + .o_column_folded { + background-color: #f0eeee !important; + border: none !important; + span.o_column_title, span.o_column_unfold { + // color: white !important; + } + } + + .o_column_quick_create { + background-color: #f0eeee !important; + .o_kanban_add_column, .o_kanban_title { + color: black !important; + } + + } +} + +.oe_list { + background-color: white !important; +} + +.btn-icon { + .btn-default; +} + +.openerp .oe_avatar { + float: left; +} + +.openerp .oe_button_box { + float: right; +} + +@grid-gutter-width: 0; + +.oe-control-panel .row { + margin-left: 15px; + margin-right: 15px; +} + +.oe_form_field_one2many { + .oe-view-manager { + background-color: white; + + .o_kanban_view { + background-color: white; + + .o_kanban_record { + box-shadow: none; + } + } + } +} + +// Buttons containing only an icon +.o_icon_button { + background-color: transparent; + border: 0; + padding: 0; + outline: none; +} + +// Stars +.o_priority { + display: inline-block; + padding: 0; + margin: 0; + > a { + display: inline-block; + } + .o_star_on, .o_star_off { + color: @odoo-main-color-muted !important; + &:hover { + text-decoration: none; + } + } + .o_star_on { + color: gold !important; + } +} + +.o_text_overflow { + display: block; + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: top; // To update display context changed by overflow:hidden +} + +.oe-o2m-control-panel { + background-color: white; +} + +.oe_formview { + .oe_button_box { + .oe_stat_button { + + .stat_button_icon { + display: inline-block; + } + + // padding: @odoo-statbutton-vpadding @odoo-statbutton-spacing @odoo-statbutton-vpadding 0px; + text-align: left; + + .o_button_icon { + // margin-left: @odoo-statbutton-spacing; // To create the button padding left (firefox bug) + display: inline-block; + vertical-align: middle; + &:before { + font-size: x-large; + vertical-align: middle; + } + + width: 30%; + } + + // .o_form_field_percent_pie { + // margin-left: @odoo-statbutton-spacing; // To create the button padding left (firefox bug) + // } + + .o_stat_info { // contains the value and text + display: inline-block; + vertical-align: middle; + + max-width: 70%; + // padding-right: @odoo-statbutton-spacing; + line-height: 1.2; + + .o_stat_value { + .o_text_overflow; + font-weight: 700; + color: @odoo-brand-primary; + } + .o_stat_text { + .o_text_overflow; + font-size: small; + + .o_stat_value { + display: inline; + } + } + } + + + // Some buttons only display text and directly use the WidgetButton template instead of StatInfo + > span { + .o_stat_info; // layout + font-size: small; + white-space: normal; // text on several lines if needed + } + } + } +} diff --git a/addons/web/static/src/less/utils.less b/addons/web/static/src/less/utils.less new file mode 100644 index 00000000000..8b8d02898e6 --- /dev/null +++ b/addons/web/static/src/less/utils.less @@ -0,0 +1,189 @@ +// ------------------------------------------------------------------ +// Margin +// ------------------------------------------------------------------ +.utils-margin-loop(@index) when (@index < 256) { + .o-mt@{index} {margin-top: @index px;} + .o-mb@{index} {margin-bottom: @index px;} + .o-mr@{index} {margin-right: @index px;} + .o-ml@{index} {margin-left: @index px;} + + .utils-margin-loop(@index * 2); +} +.utils-margin-loop(2); + +// ------------------------------------------------------------------ +// Padding +// ------------------------------------------------------------------ +.o-webclient-padding(@top: 0px, @right: @odoo-horizontal-padding, @bottom: 0px, @left: @odoo-horizontal-padding) { + padding-top: @top; + padding-right: @right; + padding-bottom: @bottom; + padding-left: @left; +} + +// ------------------------------------------------------------------ +// Caret +// ------------------------------------------------------------------ +.utils-caret-boilerplate() { + content: ""; + display: inline-block; + width: 0; + height: 0; + vertical-align: middle; +} +.o-caret-down(@caret-width: @caret-width-base) { + .utils-caret-boilerplate; + border-bottom: 0; + border-left: @caret-width solid transparent; + border-right: @caret-width solid transparent; + border-top: @caret-width solid; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} +.o-caret-up(@caret-width: @caret-width-base) { + .utils-caret-boilerplate; + border-bottom: @caret-width solid; + border-left: @caret-width solid transparent; + border-right: @caret-width solid transparent; + border-top: 0; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} +.o-caret-left(@caret-width: @caret-width-base) { + .utils-caret-boilerplate; + border-bottom: @caret-width solid transparent; + border-left: 0; + border-right: @caret-width solid; + border-top: @caret-width solid transparent; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} +.o-caret-right(@caret-width: @caret-width-base) { + .utils-caret-boilerplate; + border-bottom: @caret-width solid transparent; + border-left: @caret-width solid; + border-right: 0; + border-top: @caret-width solid transparent; + -moz-transform: scale(0.9999); // Smooth the caret on firefox +} + +// ------------------------------------------------------------------ +// Vendor prefixes +// ------------------------------------------------------------------ +// Flex +.o-flex-display() { + display: -ms-flexbox; + display: -moz-box; + display: -webkit-box; + display: -webkit-flex; + + display: flex; +} +.o-inline-flex-display() { + display: -ms-inline-flexbox; + display: -moz-inline-box; + display: -webkit-inline-box; + display: -webkit-inline-flex; + + display: inline-flex; +} +.o-flex-flow(@direction, @wrap) { + -ms-flex-flow: @direction @wrap; + -moz-flex-flow: @direction @wrap; + -webkit-flex-flow: @direction @wrap; + + flex-flow: @direction @wrap; +} +.o-flex(@grow, @schrink, @basis) { + -ms-flex: @grow @schrink @basis; + -moz-flex: @grow @schrink @basis; + -webkit-box-flex: @grow; + -webkit-flex: @grow @schrink @basis; + + flex: @grow @schrink @basis; +} +.o-justify-content(@justify) { + -moz-justify-content: @justify; + -webkit-justify-content: @justify; + + justify-content: @justify; +} +.o-align-content(@align) { + -webkit-align-content: @align; + + align-content: @align; +} +.o-align-items(@align) { + -webkit-align-items: @align; + + align-items: @align; +} +.o-align-self(@align) { + -webkit-align-self: @align; + + align-self: @align; +} + +// Background-size +// https://css-tricks.com/perfect-full-page-background-image/ +.o-background-size(@size) { + -webkit-background-size: @size; + -moz-background-size: @size; + -o-background-size: @size; + background-size: @size; +} + +// ------------------------------------------------------------------ +// Dropdowns +// ------------------------------------------------------------------ +.o-selected-li() { + li { + position: relative; + > a { + padding: 3px 25px; + color: @odoo-main-text-color; + &:hover { + color: darken(@odoo-main-text-color, 10%); + } + } + &.selected { + > a { + color: darken(@odoo-main-text-color, 10%); + font-weight: bold; + &:before { + font-family: FontAwesome; + position: absolute; + left: 6px; + content: "\f00c"; + } + } + } + } +} + +// ------------------------------------------------------------------ +// Select Appearance +// ------------------------------------------------------------------ +.o-appearance(@value) { + -webkit-appearance: @value; + -moz-appearance: @value; + appearance: @value; +} + +// ------------------------------------------------------------------ +// Transform +// ------------------------------------------------------------------ +.o-transform-origin(@x: 50%, @y: 50%, @z: 0) { + -ms-transform-origin: @x @y @z; + -webkit-transform-origin: @x @y @z; + -moz-transform-origin: @x @y @z; + transform-origin: @x @y @z; +} + +// ------------------------------------------------------------------ +// Position absolute +// ------------------------------------------------------------------ +.o-position-absolute(@top: auto, @right: auto, @bottom: auto, @left: auto) { + position: absolute; + top: @top; + left: @left; + bottom: @bottom; + right: @right; +}
\ No newline at end of file diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 00406837a47..52a7c8130a6 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1104,7 +1104,7 @@ </ul> </div> </t> -<t t-name="Priority"> +<t t-name="FormPriority"> <ul style="list-style: none; padding-left: 2px; display: inline-block;"> <t t-foreach="widget.priorities" t-as="rec" > <li t-att-data-value="rec.click_value" style="display: inline-block;"> @@ -1116,6 +1116,14 @@ </t> </ul> </t> +<t t-name="Priority"> + <div class="o_priority"> + <t t-foreach="widget.priorities" t-as="rec" > + <a t-if="!widget.get('readonly')" href="#" t-att-data-value="rec.click_value" t-att-title="rec.name" t-att-class="widget.get('value') gte rec.value and 'fa fa-star o_star_on' or 'fa fa-star o_star_off'"/> + <span t-if="widget.get('readonly')" t-att-data-value="rec.click_value" t-att-title="rec.name" t-att-class="widget.get('value') gte rec.value and 'fa fa-star o_star_on' or 'fa fa-star o_star_off'"/> + </t> + </div> +</t> <t t-name="FieldEmail"> <span class="oe_form_field oe_form_field_email" t-att-style="widget.node.attrs.style"> <a t-if="widget.get('effective_readonly')" href="#" class="oe_form_uri" target="_blank"/> @@ -1938,14 +1946,25 @@ <a href="javascript:void(0)"><t t-esc="text"/></a> </t> <t t-name="StatInfo"> - <strong><t t-esc="value"/></strong><br/><t t-esc="text"/> + <span class="o_stat_value"><t t-esc="value"/></span> + <span class="o_stat_text"><t t-esc="text"/></span> </t> + <button t-name="toggle_button" type="button" t-att-title="widget.string" style="box-shadow: none; white-space:nowrap;"> <img t-attf-src="#{prefix}/web/static/src/img/icons/#{widget.icon}.png" t-att-alt="widget.string"/> </button> + +<div t-name="Pager"> + <span class="o-pager-value"></span> + <span class="btn-group btn-group-sm"> + <button type="button" class="fa fa-chevron-left btn btn-icon o-pager-previous" accesskey="O"/> + <button type="button" class="fa fa-chevron-right btn btn-icon o-pager-next" accesskey="P"/> + </span> +</div> + <button t-name="FieldToggleBoolean" type="button" t-att-title="widget.string" class="oe_toggle_button"> <img t-attf-src="#{_s}/web/static/src/img/icons/#{widget.icon}" t-att-alt="widget.string"/> |
