diff --git a/addons/web/__init__.py b/addons/web/__init__.py index 343b53d050d..ec702292ce8 100644 --- a/addons/web/__init__.py +++ b/addons/web/__init__.py @@ -1,5 +1,31 @@ import common import controllers +import common.dispatch +import logging + +_logger = logging.getLogger(__name__) + +try: + import openerp.wsgi + import os + import tempfile + _logger.info("embedded mode") + class Options(object): + pass + o = Options() + o.dbfilter = '.*' + o.session_storage = os.path.join(tempfile.gettempdir(), "oe-sessions") + o.addons_path = os.path.dirname(os.path.dirname(__file__)) + o.serve_static = True + o.server_host = '127.0.0.1' + o.server_port = 8069 + + app = common.dispatch.Root(o) + #import openerp.wsgi + openerp.wsgi.register_wsgi_handler(app) + +except ImportError: + _logger.info("standalone mode") # TODO # if we detect that we are imported from the openerp server register common.Root() as a wsgi entry point diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index bf149ff5365..52eee3a8b61 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -1,6 +1,5 @@ { "name" : "web", - "version" : "2.0", "depends" : [], 'active': True, 'js' : [ @@ -48,4 +47,5 @@ "static/src/css/data_export.css", "static/src/css/data_import.css", ], + 'wsgi' : 'app', } diff --git a/webrelease.py b/addons/web/common/release.py similarity index 82% rename from webrelease.py rename to addons/web/common/release.py index 77eb46dd2c3..47570c032bb 100644 --- a/webrelease.py +++ b/addons/web/common/release.py @@ -1,11 +1,10 @@ - -name = 'openerp-web-proto' +name = 'openerp-web' version = '6.1.0 alpha' description = "Web Client of OpenERP, the Enterprise Management Software" long_description = "OpenERP Web is the web client of the OpenERP, a free enterprise management software" -author = "OpenERP S.A." +author = "OpenERP SA" author_email = "info@openerp.com" support_email = 'support@openerp.com' url = "http://www.openerp.com/" download_url = '' -license = "OEPL" +license = "AGPL" diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 81f05fc8dc3..c1642716ea6 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -12,17 +12,18 @@ import textwrap import xmlrpclib import time import zlib -import webrelease from xml.etree import ElementTree from cStringIO import StringIO +from babel.messages.pofile import read_po + import web.common.dispatch as openerpweb import web.common.ast import web.common.nonliterals +import web.common.release openerpweb.ast = web.common.ast openerpweb.nonliterals = web.common.nonliterals -from babel.messages.pofile import read_po # Should move to openerpweb.Xml2Json class Xml2Json: @@ -195,7 +196,7 @@ class WebClient(openerpweb.Controller): @openerpweb.jsonrequest def version_info(self, req): return { - "version": webrelease.version + "version": web.common.release.version } class Database(openerpweb.Controller): @@ -1363,12 +1364,19 @@ class Reports(View): openerpweb.nonliterals.CompoundContext( req.context or {}, action[ "context"])) - report_data = {"id": context["active_id"], "model": context["active_model"]} + report_data = {} + report_ids = context["active_ids"] if 'report_type' in action: report_data['report_type'] = action['report_type'] + if 'datas' in action: + if 'form' in action['datas']: + report_data['form'] = action['datas']['form'] + if 'ids' in action['datas']: + report_ids = action['datas']['ids'] + report_id = report_srv.report( req.session._db, req.session._uid, req.session._password, - action["report_name"], context["active_ids"], + action["report_name"], report_ids, report_data, context) report_struct = None diff --git a/addons/web/static/lib/qweb/qweb2.js b/addons/web/static/lib/qweb/qweb2.js index 473e80d1229..621ea39c74f 100644 --- a/addons/web/static/lib/qweb/qweb2.js +++ b/addons/web/static/lib/qweb/qweb2.js @@ -259,6 +259,9 @@ QWeb2.Engine = (function() { if (req) { // TODO: third parameter is async : https://developer.mozilla.org/en/XMLHttpRequest#open() // do an on_ready in QWeb2{} that could be passed to add_template + if (this.debug) { + s += '?debug=' + (new Date()).getTime(); // TODO fme: do it properly in case there's already url parameters + } req.open('GET', s, false); req.send(null); if (req.responseXML) { @@ -325,13 +328,13 @@ QWeb2.Engine = (function() { render : function(template, dict) { var ndict = QWeb2.tools.extend({}, this.default_dict); QWeb2.tools.extend(ndict, dict); - if (this.debug && window['console'] !== undefined) { + /*if (this.debug && window['console'] !== undefined) { console.time("QWeb render template " + template); - } + }*/ var r = this._render(template, ndict); - if (this.debug && window['console'] !== undefined) { + /*if (this.debug && window['console'] !== undefined) { console.timeEnd("QWeb render template " + template); - } + }*/ return r; }, _render : function(template, dict) { diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 3003f9402ac..f7eca2906a0 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1276,3 +1276,39 @@ label.error { border-left: none; padding-left: 0; } + +ul.oe-arrow-list { + padding-left: 0.5em; + margin: 0; +} +ul.oe-arrow-list li { + display: inline-block; + margin-left: -0.5em; +} +ul.oe-arrow-list li span { + vertical-align: top; + display: inline-block; + border-width:1em; + border-style:solid; + border-color: white; + line-height:0em; +} +ul.oe-arrow-list .oe-arrow-list-before { + border-left-color: rgba(0,0,0,0); + border-right-width:0; +} +ul.oe-arrow-list .oe-arrow-list-after { + border-color: rgba(0,0,0,0); + border-left-color: white; + border-right-width:0; +} +ul.oe-arrow-list li.oe-arrow-list-selected span { + border-color: #CFCCCC; +} +ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-before { + border-left-color: rgba(0,0,0,0); +} +ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after { + border-color: rgba(0,0,0,0); + border-left-color: #CFCCCC; +} diff --git a/addons/web/static/src/img/icons/color-picker.png b/addons/web/static/src/img/icons/color-picker.png new file mode 100644 index 00000000000..765294c6bdd Binary files /dev/null and b/addons/web/static/src/img/icons/color-picker.png differ diff --git a/addons/web/static/src/img/icons/gtk-about.png b/addons/web/static/src/img/icons/gtk-about.png new file mode 100644 index 00000000000..1b430a35758 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-about.png differ diff --git a/addons/web/static/src/img/icons/gtk-bold.png b/addons/web/static/src/img/icons/gtk-bold.png new file mode 100644 index 00000000000..408f25aa20b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-bold.png differ diff --git a/addons/web/static/src/img/icons/gtk-cdrom.png b/addons/web/static/src/img/icons/gtk-cdrom.png new file mode 100644 index 00000000000..27e8edd8a0b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-cdrom.png differ diff --git a/addons/web/static/src/img/icons/gtk-clear.png b/addons/web/static/src/img/icons/gtk-clear.png new file mode 100644 index 00000000000..b2874fb84fa Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-clear.png differ diff --git a/addons/web/static/src/img/icons/gtk-color-picker.png b/addons/web/static/src/img/icons/gtk-color-picker.png new file mode 100644 index 00000000000..232d54f8f3b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-color-picker.png differ diff --git a/addons/web/static/src/img/icons/gtk-connect.png b/addons/web/static/src/img/icons/gtk-connect.png new file mode 100644 index 00000000000..c820b54abcc Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-connect.png differ diff --git a/addons/web/static/src/img/icons/gtk-copy.png b/addons/web/static/src/img/icons/gtk-copy.png new file mode 100644 index 00000000000..3d68da606d2 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-copy.png differ diff --git a/addons/web/static/src/img/icons/gtk-cut.png b/addons/web/static/src/img/icons/gtk-cut.png new file mode 100644 index 00000000000..96681d26968 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-cut.png differ diff --git a/addons/web/static/src/img/icons/gtk-dialog-authentication.png b/addons/web/static/src/img/icons/gtk-dialog-authentication.png new file mode 100644 index 00000000000..eb411112f83 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-dialog-authentication.png differ diff --git a/addons/web/static/src/img/icons/gtk-dialog-error.png b/addons/web/static/src/img/icons/gtk-dialog-error.png new file mode 100644 index 00000000000..e97bc43504b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-dialog-error.png differ diff --git a/addons/web/static/src/img/icons/gtk-dialog-info.png b/addons/web/static/src/img/icons/gtk-dialog-info.png new file mode 100644 index 00000000000..ed46c3ecdb3 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-dialog-info.png differ diff --git a/addons/web/static/src/img/icons/gtk-dialog-question.png b/addons/web/static/src/img/icons/gtk-dialog-question.png new file mode 100644 index 00000000000..ef68f43f43f Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-dialog-question.png differ diff --git a/addons/web/static/src/img/icons/gtk-dialog-warning.png b/addons/web/static/src/img/icons/gtk-dialog-warning.png new file mode 100644 index 00000000000..65a4d2c7220 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-dialog-warning.png differ diff --git a/addons/web/static/src/img/icons/gtk-directory-remote.png b/addons/web/static/src/img/icons/gtk-directory-remote.png new file mode 100644 index 00000000000..34e737d7c07 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-directory-remote.png differ diff --git a/addons/web/static/src/img/icons/gtk-directory.png b/addons/web/static/src/img/icons/gtk-directory.png new file mode 100644 index 00000000000..8e41b7878a9 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-directory.png differ diff --git a/addons/web/static/src/img/icons/gtk-disconnect.png b/addons/web/static/src/img/icons/gtk-disconnect.png new file mode 100644 index 00000000000..fd188701fc2 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-disconnect.png differ diff --git a/addons/web/static/src/img/icons/gtk-dnd-multiple.png b/addons/web/static/src/img/icons/gtk-dnd-multiple.png new file mode 100644 index 00000000000..aa4c65ad5b1 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-dnd-multiple.png differ diff --git a/addons/web/static/src/img/icons/gtk-file.png b/addons/web/static/src/img/icons/gtk-file.png new file mode 100644 index 00000000000..fa157156bcc Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-file.png differ diff --git a/addons/web/static/src/img/icons/gtk-find-and-replace.png b/addons/web/static/src/img/icons/gtk-find-and-replace.png new file mode 100644 index 00000000000..b8d8eeec1b2 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-find-and-replace.png differ diff --git a/addons/web/static/src/img/icons/gtk-floppy.png b/addons/web/static/src/img/icons/gtk-floppy.png new file mode 100644 index 00000000000..7d8209cfb6f Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-floppy.png differ diff --git a/addons/web/static/src/img/icons/gtk-fullscreen.png b/addons/web/static/src/img/icons/gtk-fullscreen.png new file mode 100644 index 00000000000..8ddc31e7481 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-fullscreen.png differ diff --git a/addons/web/static/src/img/icons/gtk-goto-bottom.png b/addons/web/static/src/img/icons/gtk-goto-bottom.png new file mode 100644 index 00000000000..be52840dee1 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-goto-bottom.png differ diff --git a/addons/web/static/src/img/icons/gtk-goto-first.png b/addons/web/static/src/img/icons/gtk-goto-first.png new file mode 100644 index 00000000000..3d00e36d696 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-goto-first.png differ diff --git a/addons/web/static/src/img/icons/gtk-goto-top.png b/addons/web/static/src/img/icons/gtk-goto-top.png new file mode 100644 index 00000000000..227a91e5157 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-goto-top.png differ diff --git a/addons/web/static/src/img/icons/gtk-harddisk.png b/addons/web/static/src/img/icons/gtk-harddisk.png new file mode 100644 index 00000000000..73e5ef0a82e Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-harddisk.png differ diff --git a/addons/web/static/src/img/icons/gtk-help.png b/addons/web/static/src/img/icons/gtk-help.png new file mode 100644 index 00000000000..f8e17009dd6 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-help.png differ diff --git a/addons/web/static/src/img/icons/gtk-home.png b/addons/web/static/src/img/icons/gtk-home.png new file mode 100644 index 00000000000..9d3d50d0fcb Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-home.png differ diff --git a/addons/web/static/src/img/icons/gtk-info.png b/addons/web/static/src/img/icons/gtk-info.png new file mode 100644 index 00000000000..272019f5c99 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-info.png differ diff --git a/addons/web/static/src/img/icons/gtk-italic.png b/addons/web/static/src/img/icons/gtk-italic.png new file mode 100644 index 00000000000..26c57226a31 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-italic.png differ diff --git a/addons/web/static/src/img/icons/gtk-justify-center.png b/addons/web/static/src/img/icons/gtk-justify-center.png new file mode 100644 index 00000000000..d5f514298eb Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-justify-center.png differ diff --git a/addons/web/static/src/img/icons/gtk-justify-left.png b/addons/web/static/src/img/icons/gtk-justify-left.png new file mode 100644 index 00000000000..ecb76b117eb Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-justify-left.png differ diff --git a/addons/web/static/src/img/icons/gtk-justify-right.png b/addons/web/static/src/img/icons/gtk-justify-right.png new file mode 100644 index 00000000000..3cd4d161420 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-justify-right.png differ diff --git a/addons/web/static/src/img/icons/gtk-leave-fullscreen.png b/addons/web/static/src/img/icons/gtk-leave-fullscreen.png new file mode 100644 index 00000000000..15bc8ab7d7b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-leave-fullscreen.png differ diff --git a/addons/web/static/src/img/icons/gtk-media-forward.png b/addons/web/static/src/img/icons/gtk-media-forward.png new file mode 100644 index 00000000000..e5e198fbb79 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-media-forward.png differ diff --git a/addons/web/static/src/img/icons/gtk-media-next.png b/addons/web/static/src/img/icons/gtk-media-next.png new file mode 100644 index 00000000000..e0aa2431cf0 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-media-next.png differ diff --git a/addons/web/static/src/img/icons/gtk-media-previous.png b/addons/web/static/src/img/icons/gtk-media-previous.png new file mode 100644 index 00000000000..756899e0bc1 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-media-previous.png differ diff --git a/addons/web/static/src/img/icons/gtk-media-record.png b/addons/web/static/src/img/icons/gtk-media-record.png new file mode 100644 index 00000000000..904974c81e5 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-media-record.png differ diff --git a/addons/web/static/src/img/icons/gtk-media-rewind.png b/addons/web/static/src/img/icons/gtk-media-rewind.png new file mode 100644 index 00000000000..9c22d9e2778 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-media-rewind.png differ diff --git a/addons/web/static/src/img/icons/gtk-media-stop.png b/addons/web/static/src/img/icons/gtk-media-stop.png new file mode 100644 index 00000000000..128cc2313ec Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-media-stop.png differ diff --git a/addons/web/static/src/img/icons/gtk-missing-image.png b/addons/web/static/src/img/icons/gtk-missing-image.png new file mode 100644 index 00000000000..cc69ed33e4b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-missing-image.png differ diff --git a/addons/web/static/src/img/icons/gtk-paste-v.png b/addons/web/static/src/img/icons/gtk-paste-v.png new file mode 100644 index 00000000000..76ec896f70e Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-paste-v.png differ diff --git a/addons/web/static/src/img/icons/gtk-paste.png b/addons/web/static/src/img/icons/gtk-paste.png new file mode 100644 index 00000000000..840f26c8b38 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-paste.png differ diff --git a/addons/web/static/src/img/icons/gtk-preferences.png b/addons/web/static/src/img/icons/gtk-preferences.png new file mode 100644 index 00000000000..9ba17a0ab20 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-preferences.png differ diff --git a/addons/web/static/src/img/icons/gtk-print-preview.png b/addons/web/static/src/img/icons/gtk-print-preview.png new file mode 100644 index 00000000000..ab15fcbd307 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-print-preview.png differ diff --git a/addons/web/static/src/img/icons/gtk-properties.png b/addons/web/static/src/img/icons/gtk-properties.png new file mode 100644 index 00000000000..894415ec1ce Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-properties.png differ diff --git a/addons/web/static/src/img/icons/gtk-quit.png b/addons/web/static/src/img/icons/gtk-quit.png new file mode 100644 index 00000000000..50b5144660b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-quit.png differ diff --git a/addons/web/static/src/img/icons/gtk-refresh.png b/addons/web/static/src/img/icons/gtk-refresh.png new file mode 100644 index 00000000000..7474728b4c0 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-refresh.png differ diff --git a/addons/web/static/src/img/icons/gtk-revert-to-saved.png b/addons/web/static/src/img/icons/gtk-revert-to-saved.png new file mode 100644 index 00000000000..eaf54584edf Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-revert-to-saved.png differ diff --git a/addons/web/static/src/img/icons/gtk-save-as.png b/addons/web/static/src/img/icons/gtk-save-as.png new file mode 100644 index 00000000000..1831e4e0a4b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-save-as.png differ diff --git a/addons/web/static/src/img/icons/gtk-select-color.png b/addons/web/static/src/img/icons/gtk-select-color.png new file mode 100644 index 00000000000..12b015df107 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-select-color.png differ diff --git a/addons/web/static/src/img/icons/gtk-select-font.png b/addons/web/static/src/img/icons/gtk-select-font.png new file mode 100644 index 00000000000..66e606313a5 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-select-font.png differ diff --git a/addons/web/static/src/img/icons/gtk-sort-ascending.png b/addons/web/static/src/img/icons/gtk-sort-ascending.png new file mode 100644 index 00000000000..a648fa0d359 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-sort-ascending.png differ diff --git a/addons/web/static/src/img/icons/gtk-spell-check.png b/addons/web/static/src/img/icons/gtk-spell-check.png new file mode 100644 index 00000000000..698f7c24a43 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-spell-check.png differ diff --git a/addons/web/static/src/img/icons/gtk-strikethrough.png b/addons/web/static/src/img/icons/gtk-strikethrough.png new file mode 100644 index 00000000000..1c11f214622 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-strikethrough.png differ diff --git a/addons/web/static/src/img/icons/gtk-undelete.png b/addons/web/static/src/img/icons/gtk-undelete.png new file mode 100644 index 00000000000..c44b940c03b Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-undelete.png differ diff --git a/addons/web/static/src/img/icons/gtk-underline.png b/addons/web/static/src/img/icons/gtk-underline.png new file mode 100644 index 00000000000..7dbb5d7e60a Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-underline.png differ diff --git a/addons/web/static/src/img/icons/gtk-unindent.png b/addons/web/static/src/img/icons/gtk-unindent.png new file mode 100644 index 00000000000..8ace914c1bd Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-unindent.png differ diff --git a/addons/web/static/src/img/icons/gtk-zoom-100.png b/addons/web/static/src/img/icons/gtk-zoom-100.png new file mode 100644 index 00000000000..5193406b787 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-zoom-100.png differ diff --git a/addons/web/static/src/img/icons/gtk-zoom-out.png b/addons/web/static/src/img/icons/gtk-zoom-out.png new file mode 100644 index 00000000000..0da5ee7ec13 Binary files /dev/null and b/addons/web/static/src/img/icons/gtk-zoom-out.png differ diff --git a/addons/web/static/src/img/icons/lead-stage-lost.png b/addons/web/static/src/img/icons/lead-stage-lost.png new file mode 100644 index 00000000000..e1f98a26b59 Binary files /dev/null and b/addons/web/static/src/img/icons/lead-stage-lost.png differ diff --git a/addons/web/static/src/img/icons/lead-stage-pending.png b/addons/web/static/src/img/icons/lead-stage-pending.png new file mode 100644 index 00000000000..9e9544ee178 Binary files /dev/null and b/addons/web/static/src/img/icons/lead-stage-pending.png differ diff --git a/addons/web/static/src/img/icons/lead-stage-won.png b/addons/web/static/src/img/icons/lead-stage-won.png new file mode 100644 index 00000000000..02effd5f14c Binary files /dev/null and b/addons/web/static/src/img/icons/lead-stage-won.png differ diff --git a/addons/web/static/src/img/icons/star-off.png b/addons/web/static/src/img/icons/star-off.png new file mode 100644 index 00000000000..7cd0afd4f03 Binary files /dev/null and b/addons/web/static/src/img/icons/star-off.png differ diff --git a/addons/web/static/src/img/icons/star-on.png b/addons/web/static/src/img/icons/star-on.png new file mode 100644 index 00000000000..4f2295e1395 Binary files /dev/null and b/addons/web/static/src/img/icons/star-on.png differ diff --git a/addons/web/static/src/img/icons/stock.png b/addons/web/static/src/img/icons/stock.png new file mode 100644 index 00000000000..ca38181db90 Binary files /dev/null and b/addons/web/static/src/img/icons/stock.png differ diff --git a/addons/web/static/src/img/icons/stock_calendar.png b/addons/web/static/src/img/icons/stock_calendar.png new file mode 100644 index 00000000000..99a1f3f9ef1 Binary files /dev/null and b/addons/web/static/src/img/icons/stock_calendar.png differ diff --git a/addons/web/static/src/img/icons/stock_gantt.png b/addons/web/static/src/img/icons/stock_gantt.png new file mode 100644 index 00000000000..585761b9220 Binary files /dev/null and b/addons/web/static/src/img/icons/stock_gantt.png differ diff --git a/addons/web/static/src/img/icons/stock_graph.png b/addons/web/static/src/img/icons/stock_graph.png new file mode 100644 index 00000000000..4d8310621ea Binary files /dev/null and b/addons/web/static/src/img/icons/stock_graph.png differ diff --git a/addons/web/static/src/img/icons/stock_log.png b/addons/web/static/src/img/icons/stock_log.png new file mode 100644 index 00000000000..32af4dd6901 Binary files /dev/null and b/addons/web/static/src/img/icons/stock_log.png differ diff --git a/addons/web/static/src/img/icons/stock_person.png b/addons/web/static/src/img/icons/stock_person.png new file mode 100644 index 00000000000..202cf0ee6c5 Binary files /dev/null and b/addons/web/static/src/img/icons/stock_person.png differ diff --git a/addons/web/static/src/img/icons/stock_translate.png b/addons/web/static/src/img/icons/stock_translate.png new file mode 100644 index 00000000000..5ab41d49343 Binary files /dev/null and b/addons/web/static/src/img/icons/stock_translate.png differ diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js index 1846a2727ae..10c8de096b2 100644 --- a/addons/web/static/src/js/boot.js +++ b/addons/web/static/src/js/boot.js @@ -5,7 +5,6 @@ /** * @name openerp * @namespace openerp - * @namespace window.openerp */ (function() { if (this.openerp) @@ -48,6 +47,9 @@ * OpenERP Web web module split *---------------------------------------------------------*/ +/** + * @namespace + */ openerp.web = function(instance) { openerp.web.core(instance); if (openerp.web.dates) { diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 4d19287ed33..582ef512f83 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -5,7 +5,14 @@ openerp.web.chrome = function(openerp) { var QWeb = openerp.web.qweb; -openerp.web.Notification = openerp.web.Widget.extend({ +openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Notification# */{ + /** + * @constructs openerp.web.Notification + * @extends openerp.web.Widget + * + * @param parent + * @param element_id + */ init: function(parent, element_id) { this._super(parent, element_id); this.$element.notify({ @@ -27,9 +34,16 @@ openerp.web.Notification = openerp.web.Widget.extend({ } }); -openerp.web.Dialog = openerp.web.OldWidget.extend({ +openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# */{ dialog_title: "", identifier_prefix: 'dialog', + /** + * @constructs openerp.web.Dialog + * @extends openerp.web.OldWidget + * + * @param parent + * @param dialog_options + */ init: function (parent, dialog_options) { var self = this; this._super(parent); @@ -118,8 +132,14 @@ openerp.web.Dialog = openerp.web.OldWidget.extend({ } }); -openerp.web.CrashManager = openerp.web.Dialog.extend({ +openerp.web.CrashManager = openerp.web.Dialog.extend(/** @lends openerp.web.CrashManager# */{ identifier_prefix: 'dialog_crash', + /** + * @constructs opener.web.CrashManager + * @extends openerp.web.Dialog + * + * @param parent + */ init: function(parent) { this._super(parent); this.session.on_rpc_error.add(this.on_rpc_error); @@ -130,7 +150,7 @@ openerp.web.CrashManager = openerp.web.Dialog.extend({ on_rpc_error: function(error) { this.error = error; if (error.data.fault_code) { - var split = error.data.fault_code.split('\n')[0].split(' -- '); + var split = ("" + error.data.fault_code).split('\n')[0].split(' -- '); if (split.length > 1) { error.type = split.shift(); error.data.fault_code = error.data.fault_code.substr(error.type.length + 4); @@ -154,7 +174,14 @@ openerp.web.CrashManager = openerp.web.Dialog.extend({ } }); -openerp.web.Loading = openerp.web.Widget.extend({ +openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{ + /** + * @constructs openerp.web.Loading + * @extends openerp.web.Widget + * + * @param parent + * @param element_id + */ init: function(parent, element_id) { this._super(parent, element_id); this.count = 0; @@ -173,7 +200,15 @@ openerp.web.Loading = openerp.web.Widget.extend({ } }); -openerp.web.Database = openerp.web.Widget.extend({ +openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database# */{ + /** + * @constructs openerp.web.Database + * @extends openerp.web.Widget + * + * @param parent + * @param element_id + * @param option_id + */ init: function(parent, element_id, option_id) { this._super(parent, element_id); this.$option_id = $('#' + option_id); @@ -426,8 +461,15 @@ openerp.web.Database = openerp.web.Widget.extend({ } }); -openerp.web.Login = openerp.web.Widget.extend({ +openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{ remember_creditentials: true, + /** + * @constructs openerp.web.Login + * @extends openerp.web.Widget + * + * @param parent + * @param element_id + */ init: function(parent, element_id) { this._super(parent, element_id); @@ -526,9 +568,15 @@ openerp.web.Login = openerp.web.Widget.extend({ } }); -openerp.web.Header = openerp.web.Widget.extend({ +openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# */{ template: "Header", identifier_prefix: 'oe-app-header-', + /** + * @constructs openerp.web.Header + * @extends openerp.web.Widget + * + * @param parent + */ init: function(parent) { this._super(parent); this.qs = "?" + jQuery.param.querystring(); @@ -539,6 +587,9 @@ openerp.web.Header = openerp.web.Widget.extend({ }, do_update: function () { var self = this; + this.$content.remove(); + if (! this.session.uid) + return; var func = new openerp.web.Model(self.session, "res.users").get_func("read"); func(self.session.uid, ["name", "company_id"]).then(function(res) { self.$content = $(QWeb.render("Header-content", {widget: self, user: res})); @@ -557,9 +608,6 @@ openerp.web.Header = openerp.web.Widget.extend({ modal: true, width: 960, title: "About"}); }); }, - do_reset: function() { - this.$content.remove(); - }, shortcut_load :function(){ var self = this, sc = self.session.shortcuts, @@ -706,11 +754,18 @@ openerp.web.Header = openerp.web.Widget.extend({ }).html(error.error); }, on_logout: function() { - this.$element.find('.oe-shortcuts ul').empty(); } }); -openerp.web.Menu = openerp.web.Widget.extend({ +openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{ + /** + * @constructs openerp.web.Menu + * @extends openerp.web.Widget + * + * @param parent + * @param element_id + * @param secondary_menu_id + */ init: function(parent, element_id, secondary_menu_id) { this._super(parent, element_id); this.secondary_menu_id = secondary_menu_id; @@ -792,13 +847,13 @@ openerp.web.Menu = openerp.web.Widget.extend({ } }); -openerp.web.Homepage = openerp.web.Widget.extend({ -}); - -openerp.web.Preferences = openerp.web.Widget.extend({ -}); - -openerp.web.WebClient = openerp.web.Widget.extend({ +openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClient */{ + /** + * @constructs openerp.web.WebClient + * @extends openerp.web.Widget + * + * @param element_id + */ init: function(element_id) { this._super(null, element_id); openerp.webclient = this; @@ -826,7 +881,7 @@ openerp.web.WebClient = openerp.web.Widget.extend({ this.session.on_session_invalid.add(this.login.do_ask_login); this.session.on_session_valid.add_last(this.header.do_update); - this.session.on_session_invalid.add_last(this.header.do_reset); + this.session.on_session_invalid.add_last(this.header.do_update); this.session.on_session_valid.add_last(this.on_logged); this.menu = new openerp.web.Menu(this, "oe_menu", "oe_secondary_menu"); @@ -837,7 +892,7 @@ openerp.web.WebClient = openerp.web.Widget.extend({ this.session.start(); this.login.start(); this.menu.start(); - this.notification.notify("OpenERP Client", "The openerp client has been initialized."); + console.debug("The openerp client has been initialized."); }, on_logged: function() { if(this.action_manager) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index da2afae3680..77b48820e83 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -4,6 +4,7 @@ openerp.web.core = function(openerp) { openerp.web.qweb = new QWeb2.Engine(); +openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1); /** * John Resig Class with factory improvement */ @@ -12,11 +13,17 @@ openerp.web.qweb = new QWeb2.Engine(); fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; // The web Class implementation (does nothing) /** + * Extended version of John Resig's Class pattern + * * @class */ openerp.web.Class = function(){}; - // Create a new Class that inherits from this class + /** + * Subclass an existing class + * + * @param {Object} prop class-level properties (class attributes and instance methods) to set on the new class + */ openerp.web.Class.extend = function(prop) { var _super = this.prototype; @@ -157,7 +164,7 @@ openerp.web.callback = function(obj, method) { * that does nothing and always return undefined). * * @param {Class} claz - * @param {dict} add Additional functions to override. + * @param {Object} add Additional functions to override. * @return {Class} */ openerp.web.generate_null_object_class = function(claz, add) { @@ -188,7 +195,7 @@ openerp.web.KeyNotFound = openerp.web.NotFound.extend( /** @lends openerp.web.Ke /** * Thrown when a key could not be found in a mapping * - * @constructs + * @constructs openerp.web.KeyNotFound * @extends openerp.web.NotFound * @param {String} key the key which could not be found */ @@ -204,7 +211,7 @@ openerp.web.ObjectNotFound = openerp.web.NotFound.extend( /** @lends openerp.web * Thrown when an object path does not designate a valid class or object * in the openerp hierarchy. * - * @constructs + * @constructs openerp.web.ObjectNotFound * @extends openerp.web.NotFound * @param {String} path the invalid object path */ @@ -228,7 +235,7 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry * object pointed to (e.g. ``"openerp.web.Session"`` for an OpenERP * session object). * - * @constructs + * @constructs openerp.web.Registry * @param {Object} mapping a mapping of keys to object-paths */ init: function (mapping) { @@ -309,7 +316,11 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry } }); -openerp.web.CallbackEnabled = openerp.web.Class.extend({ +openerp.web.CallbackEnabled = openerp.web.Class.extend(/** @lends openerp.web.CallbackEnabled# */{ + /** + * @constructs openerp.web.CallbackEnabled + * @extends openerp.web.Class + */ init: function() { // Transform on_* method into openerp.web.callbacks for (var name in this) { @@ -326,9 +337,11 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend({ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Session# */{ /** - * @constructs - * @param server - * @param port + * @constructs openerp.web.Session + * @extends openerp.web.CallbackEnabled + * + * @param {String} [server] JSON-RPC endpoint hostname + * @param {String} [port] JSON-RPC endpoint port */ init: function(server, port) { this._super(); @@ -576,9 +589,10 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web }); }, do_load_css: function (files) { + var self = this; _.each(files, function (file) { $('head').append($('', { - 'href': file, + 'href': file + (self.debug ? '?debug=' + (new Date().getTime()) : ''), 'rel': 'stylesheet', 'type': 'text/css' })); @@ -590,7 +604,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web var file = files.shift(); var tag = document.createElement('script'); tag.type = 'text/javascript'; - tag.src = file; + tag.src = file + (this.debug ? '?debug=' + (new Date().getTime()) : ''); tag.onload = tag.onreadystatechange = function() { if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done ) return; @@ -708,13 +722,18 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web } }); -/** - * Utility class that any class is allowed to extend to easy common manipulations. - * - * It provides rpc calls, callback on all methods preceded by "on_" or "do_" and a - * logging facility. - */ -openerp.web.SessionAware = openerp.web.CallbackEnabled.extend({ +openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.SessionAware# */{ + /** + * Utility class that any class is allowed to extend to easy common manipulations. + * + * It provides rpc calls, callback on all methods preceded by "on_" or "do_" and a + * logging facility. + * + * @constructs openerp.web.SessionAware + * @extends openerp.web.CallbackEnabled + * + * @param {openerp.web.Session} session + */ init: function(session) { this._super(); this.session = session; @@ -758,15 +777,12 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend({ if(body) { $('
').text(v).appendTo($('body'));
                 }
-                if(notify && this.notification) {
-                    this.notification.notify("Logging:",v);
-                }
             }
         }
     }
 });
 
-openerp.web.Widget = openerp.web.SessionAware.extend({
+openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widget# */{
     /**
      * The name of the QWeb template that will be used for rendering. Must be
      * redefined in subclasses or the default render() method can not be used.
@@ -784,7 +800,9 @@ openerp.web.Widget = openerp.web.SessionAware.extend({
     /**
      * Construct the widget and set its parent if a parent is given.
      *
-     * @constructs
+     * @constructs openerp.web.Widget
+     * @extends openerp.web.SessionAware
+     *
      * @param {openerp.web.Widget} parent Binds the current instance to the given Widget instance.
      * When that widget is destroyed by calling stop(), the current instance will be
      * destroyed too. Can be null.
@@ -860,8 +878,10 @@ openerp.web.Widget = openerp.web.SessionAware.extend({
         if (target instanceof openerp.web.Widget)
             target = target.$element;
         insertion(target);
+        this.on_inserted(this.$element, this);
         return this.start();
     },
+    on_inserted: function(element, widget) {},
     /**
      * Renders the widget using QWeb, `this.template` must be defined.
      * The context given to QWeb contains the "widget" key that references `this`.
@@ -941,17 +961,23 @@ openerp.web.Widget = openerp.web.SessionAware.extend({
 });
 
 /**
+ * @class
+ * @extends openerp.web.Widget
  * @deprecated
  * For retro compatibility only, the only difference with is that render() uses
- * directly `this` instead of context with a "widget" key.
+ * directly ``this`` instead of context with a ``widget`` key.
  */
-openerp.web.OldWidget = openerp.web.Widget.extend({
+openerp.web.OldWidget = openerp.web.Widget.extend(/** @lends openerp.web.OldWidget# */{
     render: function (additional) {
         return openerp.web.qweb.render(this.template, _.extend(_.extend({}, this), additional || {}));
     }
 });
 
-openerp.web.TranslationDataBase = openerp.web.Class.extend({
+openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.web.TranslationDataBase# */{
+    /**
+     * @constructs openerp.web.TranslationDataBase
+     * @extends openerp.web.Class
+     */
     init: function() {
         this.db = {};
         this.parameters = {"direction": 'ltr',
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 4b4523a2723..1eb57241fa6 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -29,7 +29,7 @@ openerp.web.DataGroup =  openerp.web.Widget.extend( /** @lends openerp.web.DataG
      * :js:func:`~openerp.web.DataGroup.list`, which is used to read the
      * content of the current grouping level.
      *
-     * @constructs
+     * @constructs openerp.web.DataGroup
      * @extends openerp.web.Widget
      *
      * @param {openerp.web.Session} session Current OpenERP session
@@ -60,7 +60,7 @@ openerp.web.DataGroup =  openerp.web.Widget.extend( /** @lends openerp.web.DataG
 openerp.web.ContainerDataGroup = openerp.web.DataGroup.extend( /** @lends openerp.web.ContainerDataGroup# */ {
     /**
      *
-     * @constructs
+     * @constructs openerp.web.ContainerDataGroup
      * @extends openerp.web.DataGroup
      *
      * @param session
@@ -197,7 +197,7 @@ openerp.web.ContainerDataGroup = openerp.web.DataGroup.extend( /** @lends opener
 openerp.web.GrouplessDataGroup = openerp.web.DataGroup.extend( /** @lends openerp.web.GrouplessDataGroup# */ {
     /**
      *
-     * @constructs
+     * @constructs openerp.web.GrouplessDataGroup
      * @extends openerp.web.DataGroup
      *
      * @param session
@@ -220,7 +220,7 @@ openerp.web.StaticDataGroup = openerp.web.GrouplessDataGroup.extend( /** @lends
      * A specialization of groupless data groups, relying on a single static
      * dataset as its records provider.
      *
-     * @constructs
+     * @constructs openerp.web.StaticDataGroup
      * @extends openerp.web.GrouplessDataGroup
      * @param {openep.web.DataSetStatic} dataset a static dataset backing the groups
      */
@@ -237,7 +237,7 @@ openerp.web.DataSet =  openerp.web.Widget.extend( /** @lends openerp.web.DataSet
      * DateaManagement interface between views and the collection of selected
      * OpenERP records (represents the view's state?)
      *
-     * @constructs
+     * @constructs openerp.web.DataSet
      * @extends openerp.web.Widget
      *
      * @param {String} model the OpenERP model this dataset will manage
@@ -505,9 +505,10 @@ openerp.web.DataSetStatic =  openerp.web.DataSet.extend({
         this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
     }
 });
-openerp.web.DataSetSearch =  openerp.web.DataSet.extend({
+openerp.web.DataSetSearch =  openerp.web.DataSet.extend(/** @lends openerp.web.DataSetSearch */{
     /**
-     * @constructs
+     * @constructs openerp.web.DataSetSearch
+     * @extends openerp.web.DataSet
      *
      * @param {Object} parent
      * @param {String} model
@@ -612,11 +613,12 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
         var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data};
         this.to_create.push(cached);
         this.cache.push(cached);
+        this.on_change();
         var to_return =  $.Deferred().then(callback);
         to_return.resolve({result: cached.id});
         return to_return.promise();
     },
-    write: function (id, data, callback) {
+    write: function (id, data, options, callback) {
         var self = this;
         var record = _.detect(this.to_create, function(x) {return x.id === id;});
         record = record || _.detect(this.to_write, function(x) {return x.id === id;});
@@ -721,7 +723,7 @@ openerp.web.ReadOnlyDataSetSearch = openerp.web.DataSetSearch.extend({
         return to_return.promise();
     },
     on_create: function(data) {},
-    write: function (id, data, callback) {
+    write: function (id, data, options, callback) {
         this.on_write(id, data);
         var to_return = $.Deferred().then(callback);
         setTimeout(function () {to_return.resolve({"result": true});}, 0);
diff --git a/addons/web/static/src/js/form.js b/addons/web/static/src/js/form.js
index 4f88edb0a53..9858433db32 100644
--- a/addons/web/static/src/js/form.js
+++ b/addons/web/static/src/js/form.js
@@ -12,7 +12,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
     searchable: false,
     template: "FormView",
     /**
-     * @constructs
+     * @constructs openerp.web.FormView
+     * @extends openerp.web.View
+     * 
      * @param {openerp.web.Session} session the current openerp session
      * @param {String} element_id this view's root element id
      * @param {openerp.web.DataSet} dataset the dataset this view will work with
@@ -382,9 +384,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
     },
     on_saved: function(r, success) {
         if (!r.result) {
-            this.notification.warn("Record not saved", "Problem while saving record.");
+            // should not happen in the server, but may happen for internal purpose
         } else {
-            this.notification.notify("Record saved", "The record #" + this.datarecord.id + " has been saved.");
+            console.debug(_.sprintf("The record #%s has been saved.", this.datarecord.id));
             if (success) {
                 success(r);
             }
@@ -406,7 +408,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
      */
     on_created: function(r, success, prepend_on_create) {
         if (!r.result) {
-            this.notification.warn("Record not created", "Problem while creating record.");
+            // should not happen in the server, but may happen for internal purpose
         } else {
             this.datarecord.id = r.result;
             if (!prepend_on_create) {
@@ -420,7 +422,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
             if (this.sidebar) {
                 this.sidebar.attachments.do_update();
             }
-            this.notification.notify("Record created", "The record has been created with id #" + this.datarecord.id);
+            console.debug("The record has been created with id #" + this.datarecord.id);
             if (success) {
                 success(_.extend(r, {created: true}));
             }
@@ -428,13 +430,13 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
         }
     },
     do_search: function (domains, contexts, groupbys) {
-        this.notification.notify("Searching form");
+        console.debug("Searching form");
     },
     on_action: function (action) {
-        this.notification.notify('Executing action ' + action);
+        console.debug('Executing action', action);
     },
     do_cancel: function () {
-        this.notification.notify("Cancelling form");
+        console.debug("Cancelling form");
     },
     reload: function() {
         if (this.dataset.index == null || this.dataset.index < 0) {
@@ -480,7 +482,7 @@ openerp.web.FormDialog = openerp.web.Dialog.extend({
             self.form.on_record_loaded(records[0]);
         });
     },
-    on_form_dialog_saved: function() {
+    on_form_dialog_saved: function(r) {
         this.close();
     }
 });
@@ -599,8 +601,15 @@ openerp.web.form.compute_domain = function(expr, fields) {
     return _.all(stack, _.identity);
 };
 
-openerp.web.form.Widget = openerp.web.Widget.extend({
+openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.Widget# */{
     template: 'Widget',
+    /**
+     * @constructs openerp.web.form.Widget
+     * @extends openerp.web.Widget
+     *
+     * @param view
+     * @param node
+     */
     init: function(view, node) {
         this.view = view;
         this.node = node;
@@ -877,7 +886,14 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
     }
 });
 
-openerp.web.form.Field = openerp.web.form.Widget.extend({
+openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.form.Field# */{
+    /**
+     * @constructs openerp.web.form.Field
+     * @extends openerp.web.form.Widget
+     *
+     * @param view
+     * @param node
+     */
     init: function(view, node) {
         this.name = node.attrs.name;
         this.value = undefined;
@@ -1852,7 +1868,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
             this.viewmanager.views[this.viewmanager.active_view].controller) {
             var view = this.viewmanager.views[this.viewmanager.active_view].controller;
             if (this.viewmanager.active_view === "form") {
-                var res = view.do_save();
+                var res = $.when(view.do_save());
                 if (res === false) {
                     // ignore
                 } else if (res.isRejected()) {
@@ -2004,7 +2020,11 @@ openerp.web.form.Many2ManyDataSet = openerp.web.DataSetStatic.extend({
     }
 });
 
-openerp.web.form.Many2ManyListView = openerp.web.ListView.extend({
+/**
+ * @class
+ * @extends openerp.web.ListView
+ */
+openerp.web.form.Many2ManyListView = openerp.web.ListView.extend(/** @lends openerp.web.form.Many2ManyListView# */{
     do_add_record: function () {
         var pop = new openerp.web.form.SelectCreatePopup(this);
         pop.select_element(this.model, {},
@@ -2031,7 +2051,11 @@ openerp.web.form.Many2ManyListView = openerp.web.ListView.extend({
     }
 });
 
-openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend({
+/**
+ * @class
+ * @extends openerp.web.OldWidget
+ */
+openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends openerp.web.form.SelectCreatePopup# */{
     identifier_prefix: "selectcreatepopup",
     template: "SelectCreatePopup",
     /**
@@ -2200,7 +2224,11 @@ openerp.web.form.SelectCreateListView = openerp.web.ListView.extend({
     }
 });
 
-openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend({
+/**
+ * @class
+ * @extends openerp.web.OldWidget
+ */
+openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp.web.form.FormOpenPopup# */{
     identifier_prefix: "formopenpopup",
     template: "FormOpenPopup",
     /**
@@ -2384,7 +2412,7 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
         if (size === false) {
             this.notification.warn("File Upload", "There was a problem while uploading your file");
             // TODO: use openerp web crashmanager
-            this.log("Error while uploading file : ", name);
+            console.warn("Error while uploading file : ", name);
         } else {
             this.on_file_uploaded_and_valid.apply(this, arguments);
             this.on_ui_change();
@@ -2478,6 +2506,50 @@ openerp.web.form.FieldBinaryImage = openerp.web.form.FieldBinary.extend({
     }
 });
 
+openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
+    template: "FieldStatus",
+    start: function() {
+        this._super();
+        this.selected_value = null;
+        
+        this.render_list();
+    },
+    set_value: function(value) {
+        this._super(value);
+        this.selected_value = value;
+        
+        this.render_list();
+    },
+    render_list: function() {
+        var self = this;
+        var shown = _.map(((this.node.attrs || {}).statusbar_visible || "").split(","),
+            function(x) { return x.trim(); });
+            
+        if (shown.length == 0) {
+            this.to_show = this.field.selection;
+        } else {
+            this.to_show = _.select(this.field.selection, function(x) {
+                return _.indexOf(shown, x[0]) !== -1 || x[0] === self.selected_value;
+            });
+        }
+        
+        var content = openerp.web.qweb.render("FieldStatus.content", {widget: this, _:_});
+        this.$element.html(content);
+        
+        var colors = JSON.parse((this.node.attrs || {}).statusbar_colors || "{}");
+        var color = colors[this.selected_value];
+        if (color) {
+            var elem = this.$element.find("li.oe-arrow-list-selected span");
+            elem.css("border-color", color);
+            elem = this.$element.find("li.oe-arrow-list-selected .oe-arrow-list-before");
+            elem.css("border-left-color", "rgba(0,0,0,0)");
+            elem = this.$element.find("li.oe-arrow-list-selected .oe-arrow-list-after");
+            elem.css("border-color", "rgba(0,0,0,0)");
+            elem.css("border-left-color", color);
+        }
+    }
+});
+
 /**
  * Registry of form widgets, called by :js:`openerp.web.FormView`
  */
@@ -2507,7 +2579,8 @@ openerp.web.form.widgets = new openerp.web.Registry({
     'float_time': 'openerp.web.form.FieldFloat',
     'progressbar': 'openerp.web.form.FieldProgressBar',
     'image': 'openerp.web.form.FieldBinaryImage',
-    'binary': 'openerp.web.form.FieldBinaryFile'
+    'binary': 'openerp.web.form.FieldBinaryFile',
+    'statusbar': 'openerp.web.form.FieldStatus'
 });
 
 };
diff --git a/addons/web/static/src/js/list-editable.js b/addons/web/static/src/js/list-editable.js
index ab78e5e0139..c38c43a4c9c 100644
--- a/addons/web/static/src/js/list-editable.js
+++ b/addons/web/static/src/js/list-editable.js
@@ -1,5 +1,6 @@
 /**
- * @namespace handles editability case for lists, because it depends on form and forms already depends on lists it had to be split out
+ * handles editability case for lists, because it depends on form and forms already depends on lists it had to be split out
+ * @namespace
  */
 openerp.web.list_editable = function (openerp) {
     var KEY_RETURN = 13,
@@ -87,7 +88,7 @@ openerp.web.list_editable = function (openerp) {
         }
     });
 
-    openerp.web.ListView.List.include(/** @lends openerp.web.ListView.List */{
+    openerp.web.ListView.List.include(/** @lends openerp.web.ListView.List# */{
         row_clicked: function (event) {
             if (!this.options.editable) {
                 return this._super(event);
@@ -112,6 +113,7 @@ openerp.web.list_editable = function (openerp) {
                 cancelled.resolve();
             }
             cancelled.then(function () {
+                self.view.unpad_columns();
                 self.edition_form.stop();
                 self.edition_form.$element.remove();
                 delete self.edition_form;
@@ -197,6 +199,16 @@ openerp.web.list_editable = function (openerp) {
                             $new_row.prepend('');
                         }
                     });
+                    // Add columns for the cancel and save buttons, if
+                    // there are none in the list
+                    if (!self.options.selectable) {
+                        self.view.pad_columns(
+                            1, {except: $new_row, position: 'before'});
+                    }
+                    if (!self.options.deletable) {
+                        self.view.pad_columns(
+                            1, {except: $new_row});
+                    }
 
                     self.edition_form.do_show();
                 });
diff --git a/addons/web/static/src/js/list.js b/addons/web/static/src/js/list.js
index 6029b30f866..b9df9e8e2df 100644
--- a/addons/web/static/src/js/list.js
+++ b/addons/web/static/src/js/list.js
@@ -27,7 +27,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
      * See constructor parameters and method documentations for information on
      * the default behaviors and possible options for the list view.
      *
-     * @constructs
+     * @constructs openerp.web.ListView
+     * @extends openerp.web.View
+     *
      * @param parent parent object
      * @param element_id the id of the DOM elements this view should link itself to
      * @param {openerp.web.DataSet} dataset the dataset the view should work with
@@ -49,6 +51,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
         this.dataset = dataset;
         this.model = dataset.model;
         this.view_id = view_id;
+        this.previous_colspan = null;
 
         this.columns = [];
 
@@ -346,7 +349,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
         if (this.sidebar) {
             this.sidebar.$element.show();
         }
-        if (this.hidden) {
+        if (!_(this.dataset.ids).isEmpty()) {
             this.reload_content();
         }
     },
@@ -355,7 +358,6 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
         if (this.sidebar) {
             this.sidebar.$element.hide();
         }
-        this.hidden = true;
     },
     /**
      * Reloads the list view based on the current settings (dataset & al)
@@ -603,6 +605,49 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
     get_selected_ids: function() {
         var ids = this.groups.get_selection().ids;
         return ids;
+    },
+    /**
+     * Adds padding columns at the start or end of all table rows (including
+     * field names row)
+     *
+     * @param {Number} count number of columns to add
+     * @param {Object} options
+     * @param {"before"|"after"} [position="after"] insertion position for the new columns
+     * @param {Object} [except] content row to not pad
+     */
+    pad_columns: function (count, options) {
+        options = options || {};
+        // padding for action/pager header
+        var $first_header = this.$element.find('thead tr:first th');
+        var colspan = $first_header.attr('colspan');
+        if (colspan) {
+            if (!this.previous_colspan) {
+                this.previous_colspan = colspan;
+            }
+            $first_header.attr('colspan', parseInt(colspan, 10) + count);
+        }
+        // Padding for column titles, footer and data rows
+        var $rows = this.$element
+                .find('.oe-listview-header-columns, tr:not(thead tr)')
+                .not(options['except']);
+        var newcols = new Array(count+1).join('');
+        if (options.position === 'before') {
+            $rows.prepend(newcols);
+        } else {
+            $rows.append(newcols);
+        }
+    },
+    /**
+     * Removes all padding columns of the table
+     */
+    unpad_columns: function () {
+        this.$element.find('.oe-listview-padding').remove();
+        if (this.previous_colspan) {
+            this.$element
+                    .find('thead tr:first th')
+                    .attr('colspan', this.previous_colspan);
+            this.previous_colspan = null;
+        }
     }
 });
 openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.ListView.List# */{
@@ -630,7 +675,9 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
      *   Triggered when a row of the table is clicked, provides the index (in
      *   the rows array) and id of the selected record to the handle function.
      *
-     * @constructs
+     * @constructs openerp.web.ListView.List
+     * @extends openerp.web.Class
+     * 
      * @param {Object} opts display options, identical to those of :js:class:`openerp.web.ListView`
      */
     init: function (group, opts) {
@@ -835,7 +882,9 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
      * Provides events similar to those of
      * :js:class:`~openerp.web.ListView.List`
      *
-     * @constructs
+     * @constructs openerp.web.ListView.Groups
+     * @extends openerp.web.Class
+     *
      * @param {openerp.web.ListView} view
      * @param {Object} [options]
      * @param {Collection} [options.records]
@@ -1168,10 +1217,9 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
 });
 
 /**
- * @class
- * @extends openerp.web.Class
+ * @mixin Events
  */
-var Events = {
+var Events = /** @lends Events# */{
     /**
      * @param {String} event event to listen to on the current object, null for all events
      * @param {Function} handler event handler to bind to the relevant event
@@ -1221,10 +1269,10 @@ var Events = {
 };
 var Record = openerp.web.Class.extend(/** @lends Record# */{
     /**
-     * @constructs
+     * @constructs Record
      * @extends openerp.web.Class
-     * @borrows Events#bind as this.bind
-     * @borrows Events#trigger as this.trigger
+     * 
+     * @mixes Events
      * @param {Object} [data]
      */
     init: function (data) {
@@ -1288,10 +1336,10 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
      * Using a "dumb" array of records makes synchronization between the
      * various serious 
      *
-     * @constructs
+     * @constructs Collection
      * @extends openerp.web.Class
-     * @borrows Events#bind as this.bind
-     * @borrows Events#trigger as this.trigger
+     * 
+     * @mixes Events
      * @param {Array} [records] records to initialize the collection with
      * @param {Object} [options]
      */
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 272e96b7d01..21f397c0867 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -1,7 +1,17 @@
 openerp.web.search = function(openerp) {
 var QWeb = openerp.web.qweb;
 
-openerp.web.SearchView = openerp.web.Widget.extend({
+openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.SearchView# */{
+    /**
+     * @constructs openerp.web.SearchView
+     * @extends openerp.web.Widget
+     * 
+     * @param parent
+     * @param element_id
+     * @param dataset
+     * @param view_id
+     * @param defaults
+     */
     init: function(parent, element_id, dataset, view_id, defaults) {
         this._super(parent, element_id);
         this.dataset = dataset;
@@ -380,7 +390,9 @@ openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.se
      * Exception thrown by search widgets when they hold invalid values,
      * which they can not return when asked.
      *
-     * @constructs
+     * @constructs openerp.web.search.Invalid
+     * @extends openerp.web.Class
+     *
      * @param field the name of the field holding an invalid value
      * @param value the invalid value
      * @param message validation failure message
@@ -400,7 +412,7 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
     /**
      * Root class of all search widgets
      *
-     * @constructs
+     * @constructs openerp.web.search.Widget
      * @extends openerp.web.Widget
      *
      * @param view the ancestor view of this widget
@@ -452,8 +464,18 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
         }));
     }
 });
-openerp.web.search.FilterGroup = openerp.web.search.Widget.extend({
+openerp.web.search.FilterGroup = openerp.web.search.Widget.extend(/** @lends openerp.web.search.FilterGroup# */{
     template: 'SearchView.filters',
+    /**
+     * Inclusive group of filters, creates a continuous "button" with clickable
+     * sections (the normal display for filters is to be a self-contained button)
+     *
+     * @constructs openerp.web.search.FilterGroup
+     * @extends openerp.web.search.Widget
+     *
+     * @param {Array} filters elements of the group
+     * @param {openerp.web.SearchView} view view in which the filters are contained
+     */
     init: function (filters, view) {
         this._super(view);
         this.filters = filters;
@@ -494,7 +516,7 @@ openerp.web.search.Group = openerp.web.search.Widget.extend({
 
 openerp.web.search.Input = openerp.web.search.Widget.extend( /** @lends openerp.web.search.Input# */{
     /**
-     * @constructs
+     * @constructs openerp.web.search.Input
      * @extends openerp.web.search.Widget
      *
      * @param view
@@ -512,8 +534,18 @@ openerp.web.search.Input = openerp.web.search.Widget.extend( /** @lends openerp.
             "get_domain not implemented for widget " + this.attrs.type);
     }
 });
-openerp.web.search.Filter = openerp.web.search.Input.extend({
+openerp.web.search.Filter = openerp.web.search.Input.extend(/** @lends openerp.web.search.Filter# */{
     template: 'SearchView.filter',
+    /**
+     * Implementation of the OpenERP filters (button with a context and/or
+     * a domain sent as-is to the search view)
+     *
+     * @constructs openerp.web.search.Filter
+     * @extends openerp.web.search.Input
+     *
+     * @param node
+     * @param view
+     */
     init: function (node, view) {
         this._super(view);
         this.attrs = node.attrs;
@@ -566,7 +598,7 @@ openerp.web.search.Field = openerp.web.search.Input.extend( /** @lends openerp.w
     template: 'SearchView.field',
     default_operator: '=',
     /**
-     * @constructs
+     * @constructs openerp.web.search.Field
      * @extends openerp.web.search.Input
      *
      * @param view_section
@@ -694,7 +726,7 @@ openerp.web.search.SelectionField = openerp.web.search.Field.extend(/** @lends o
 });
 openerp.web.search.BooleanField = openerp.web.search.SelectionField.extend(/** @lends openerp.web.search.BooleanField# */{
     /**
-     * @constructs
+     * @constructs openerp.web.search.BooleanField
      * @extends openerp.web.search.BooleanField
      */
     init: function () {
@@ -729,7 +761,11 @@ openerp.web.search.BooleanField = openerp.web.search.SelectionField.extend(/** @
         }
     }
 });
-openerp.web.search.DateField = openerp.web.search.Field.extend( /** @lends openerp.web.search.DateField# */{
+/**
+ * @class
+ * @extends openerp.web.search.DateField
+ */
+openerp.web.search.DateField = openerp.web.search.Field.extend(/** @lends openerp.web.search.DateField# */{
     /**
      * enables date picker on the HTML widgets
      */
@@ -944,9 +980,16 @@ openerp.web.search.ExtendedSearchGroup = openerp.web.OldWidget.extend({
     }
 });
 
-openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend({
+openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/** @lends openerp.web.search.ExtendedSearchProposition# */{
     template: 'SearchView.extended_search.proposition',
     identifier_prefix: 'extended-search-proposition',
+    /**
+     * @constructs openerp.web.search.ExtendedSearchProposition
+     * @extends openerp.web.OldWidget
+     *
+     * @param parent
+     * @param fields
+     */
     init: function (parent, fields) {
         this._super(parent);
         this.fields = _(fields).chain()
diff --git a/addons/web/static/src/js/view_tree.js b/addons/web/static/src/js/view_tree.js
index a71e4010fcf..2a314f57fa8 100644
--- a/addons/web/static/src/js/view_tree.js
+++ b/addons/web/static/src/js/view_tree.js
@@ -6,16 +6,24 @@ openerp.web.view_tree = function(openerp) {
 var QWeb = openerp.web.qweb;
 
 openerp.web.views.add('tree', 'openerp.web.TreeView');
-/**
- * Genuine tree view (the one displayed as a tree, not the list)
- */
-openerp.web.TreeView = openerp.web.View.extend({
+openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView# */{
     /**
      * Indicates that this view is not searchable, and thus that no search
      * view should be displayed (if there is one active).
      */
     searchable : false,
-
+    /**
+     * Genuine tree view (the one displayed as a tree, not the list)
+     *
+     * @constructs openerp.web.TreeView
+     * @extends openerp.web.View
+     *
+     * @param parent
+     * @param element_id
+     * @param dataset
+     * @param view_id
+     * @param options
+     */
     init: function(parent, element_id, dataset, view_id, options) {
         this._super(parent, element_id);
         this.dataset = dataset;
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 5e211d0b0cd..258ea92ad03 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -115,7 +115,7 @@ openerp.web.ActionManager = openerp.web.Widget.extend({
         var self = this;
         this.rpc('/web/action/run', {
             action_id: action.id,
-            context: {active_id: 66, active_ids: [66], active_model: 'ir.ui.menu'}
+            context: action.context || {}
         }).then(function (action) {
             self.do_action(action, on_closed)
         });
@@ -135,8 +135,17 @@ openerp.web.ActionManager = openerp.web.Widget.extend({
     }
 });
 
-openerp.web.ViewManager =  openerp.web.Widget.extend({
+openerp.web.ViewManager =  openerp.web.Widget.extend(/** @lends openerp.web.ViewManager# */{
     identifier_prefix: "viewmanager",
+    template: "ViewManager",
+    /**
+     * @constructs openerp.web.ViewManager
+     * @extends openerp.web.Widget
+     *
+     * @param parent
+     * @param dataset
+     * @param views
+     */
     init: function(parent, dataset, views) {
         this._super(parent);
         this.model = dataset.model;
@@ -149,7 +158,7 @@ openerp.web.ViewManager =  openerp.web.Widget.extend({
         this.registry = openerp.web.views;
     },
     render: function() {
-        return QWeb.render("ViewManager", {"prefix": this.element_id, views: this.views_src})
+    	return QWeb.render(this.template, {"prefix": this.element_id, views: this.views_src})
     },
     /**
      * @returns {jQuery.Deferred} initial view loading promise
@@ -289,7 +298,8 @@ openerp.web.ViewManager =  openerp.web.Widget.extend({
 });
 
 openerp.web.ViewManagerAction = openerp.web.ViewManager.extend({
-    init: function(parent, action) {
+	template: "ViewManagerAction",
+	init: function(parent, action) {
         this.session = parent.session;
         this.action = action;
         var dataset;
@@ -444,6 +454,7 @@ openerp.web.Sidebar = openerp.web.Widget.extend({
                 if (item.action) {
                     var ids = self.widget_parent.get_selected_ids();
                     if (ids.length == 0) {
+                        //TODO: make prettier warning?
                         $("
").text(_t("You must choose at least one record.")).dialog({ title: _t("Warning"), modal: true @@ -616,7 +627,11 @@ openerp.web.TranslateDialog = openerp.web.Dialog.extend({ } }); -openerp.web.View = openerp.web.Widget.extend({ +/** + * @class + * @extends openerp.web.Widget + */ +openerp.web.View = openerp.web.Widget.extend(/** @lends openerp.web.View# */{ set_default_options: function(options) { this.options = options || {}; _.defaults(this.options, { @@ -656,6 +671,7 @@ openerp.web.View = openerp.web.Widget.extend({ active_ids: [record_id || false], active_model: dataset.model }); + action.context = new openerp.web.CompoundContext(dataset.get_context(), action.context); self.do_action(action, on_closed); } else if (on_closed) { on_closed(action); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 654a4d441e9..ce9f7aad562 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -420,8 +420,6 @@
-
+ + + + + + + + + +
+
+ +
    + + +
  • + +
  • +
    +
+
\ No newline at end of file diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js index 5662a88fc5b..9fe904319f9 100644 --- a/addons/web_dashboard/static/src/js/dashboard.js +++ b/addons/web_dashboard/static/src/js/dashboard.js @@ -282,6 +282,7 @@ openerp.web.client_actions.add( 'board.config.overview', 'openerp.web_dashboard.ConfigOverview' ); if (!openerp.web_dashboard) { + /** @namespace */ openerp.web_dashboard = {}; } openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({ @@ -379,8 +380,9 @@ openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_da * Initializes a "HomeWidget" client widget: handles the display of a given * res.widget objects in an OpenERP view (mainly a dashboard). * - * @constructs + * @constructs openerp.web_dashboard.Widget * @extends openerp.web.View + * * @param {Object} parent * @param {Object} options * @param {Number} options.widget_id diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index e3fac6dbafe..8303c207dbf 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -31,44 +31,65 @@ .openerp .oe_kanban_box_header { background: #EEE; border-bottom: 1px solid #CCC; - padding: 2px; - height: 2em; - white-space: nowrap; } -.openerp .oe_kanban_box_header h4 { +.openerp .oe_kanban_title1 { font-size: 130%; font-weight: bold; - margin: 0; - padding: 0; + padding: 0 4px 0 4px; } -.openerp .oe_kanban_box_header h5 { +.openerp .oe_kanban_title2 { font-size: 120%; font-weight: bold; - margin: 0; - padding: 2px; + padding: 0 4px 0 4px; } -.openerp .oe_kanban_box_header h6 { +.openerp .oe_kanban_title3 { font-size: 110%; font-weight: normal; - margin: 0; - padding: 2px; + padding: 0 4px 0 4px; } .openerp .oe_kanban_small { font-size: 80%; + font-weight: normal; +} +.openerp .oe_kanban_table { + width: 100%; + border: none; + border-collapse: collapse; + margin: 0; + padding: 0; +} +.openerp .oe_kanban_gravatar { + display: block; + border-radius: 2px; } .openerp .oe_kanban_box_content { padding: 4px; } .openerp .oe_kanban_buttons_set { - border-top: 1px dotted #CCC; + border-top: 1px dotted; + white-space: nowrap; + padding-top: 2px; + position: relative; } -.openerp .oe_kanban_buttons_set .oe_kanban_left a { - border-right: 1px dotted #CCC; +.openerp .oe_kanban_buttons_set a { padding: 2px; } -.openerp .oe_kanban_buttons_set .oe_kanban_right a { - border-left: 1px dotted #CCC; - padding: 2px; +.oe_kanban_color_picker { + position: absolute; + top: -10px; + border: 1px solid black; + -moz-box-shadow: 2px 2px 5px #666; + -webkit-box-shadow: 2px 2px 5px #666; + box-shadow: 2px 2px 5px #666; +} +.oe_kanban_color_picker a { + display: block; + width: 30px; + height: 30px; + border: 1px solid black; +} +.oe_kanban_color_picker a:hover { + border-color: white; } .openerp .oe_kanban_left { float: left; @@ -86,17 +107,103 @@ cursor: move; } -/* Custom colors */ -.openerp .oe_kanban_color_1 .oe_kanban_color_bglight, -.openerp .oe_kanban_color_1.oe_kanban_color_bglight { - background: #F5F7C4; +/* Custom colors are also present in kanban.js */ +/* Custom color#1 */ +.openerp .oe_kanban_color_1 .oe_kanban_color_bglight { + background: #FFC7C7; } -.openerp .oe_kanban_color_1 .oe_kanban_color_bgdark, -.openerp .oe_kanban_color_1.oe_kanban_color_bgdark { - background: #EEF093; +.openerp .oe_kanban_color_1 .oe_kanban_color_bgdark { + background: #FF8F8F; } -.openerp .oe_kanban_color_1 .oe_kanban_color_border, -.openerp .oe_kanban_color_1.oe_kanban_color_border { - border-color: #DFE32D; +.openerp .oe_kanban_color_1 .oe_kanban_color_border { + border-color: #D97979; +} + +/* Custom color#2 */ +.openerp .oe_kanban_color_2 .oe_kanban_color_bglight { + background: #FFF1C7; +} +.openerp .oe_kanban_color_2 .oe_kanban_color_bgdark { + background: #FFE38F; +} +.openerp .oe_kanban_color_2 .oe_kanban_color_border { + border-color: #D9C179; +} + +/* Custom color#3 */ +.openerp .oe_kanban_color_3 .oe_kanban_color_bglight { + background: #E3FFC7; +} +.openerp .oe_kanban_color_3 .oe_kanban_color_bgdark { + background: #C7FF8F; +} +.openerp .oe_kanban_color_3 .oe_kanban_color_border { + border-color: #A9D979; +} + +/* Custom color#4 */ +.openerp .oe_kanban_color_4 .oe_kanban_color_bglight { + background: #C7FFD5; +} +.openerp .oe_kanban_color_4 .oe_kanban_color_bgdark { + background: #8FFFAB; +} +.openerp .oe_kanban_color_4 .oe_kanban_color_border { + border-color: #79D991; +} + +/* Custom color#5 */ +.openerp .oe_kanban_color_5 .oe_kanban_color_bglight { + background: #C7FFFF; +} +.openerp .oe_kanban_color_5 .oe_kanban_color_bgdark { + background: #8FFFFF; +} +.openerp .oe_kanban_color_5 .oe_kanban_color_border { + border-color: #79D9D9; +} + +/* Custom color#6 */ +.openerp .oe_kanban_color_6 .oe_kanban_color_bglight { + background: #C7D5FF; +} +.openerp .oe_kanban_color_6 .oe_kanban_color_bgdark { + background: #8FABFF; +} +.openerp .oe_kanban_color_6 .oe_kanban_color_border { + border-color: #8FABFF; +} + +/* Custom color#7 */ +.openerp .oe_kanban_color_7 .oe_kanban_color_bglight { + background: #E3C7FF; +} +.openerp .oe_kanban_color_7 .oe_kanban_color_bgdark { + background: #C78FFF; +} +.openerp .oe_kanban_color_7 .oe_kanban_color_border { + border-color: #A979D9; +} + +/* Custom color#8 */ +.openerp .oe_kanban_color_8 .oe_kanban_color_bglight { + background: #FFC7F1; +} +.openerp .oe_kanban_color_8 .oe_kanban_color_bgdark { + background: #FF8FE3; +} +.openerp .oe_kanban_color_8 .oe_kanban_color_border { + border-color: #D979C1; +} + +/* Alert color */ +.openerp .oe_kanban_color_alert .oe_kanban_color_bglight { + background: #C66; +} +.openerp .oe_kanban_color_alert .oe_kanban_color_bgdark { + background: #E99; +} +.openerp .oe_kanban_color_alert .oe_kanban_color_border { + border-color: #900; } diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index d6aff04e471..52b41e4289e 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -20,6 +20,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ this.qweb = new QWeb2.Engine(); if (this.options.action_views_ids.form) { this.form_dialog = new openerp.web.FormDialog(this, {}, this.options.action_views_ids.form, dataset).start(); + this.form_dialog.on_form_dialog_saved.add_last(this.on_record_saved); } }, start: function() { @@ -30,14 +31,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ this.fields_view = data; this.add_qweb_template(); if (this.qweb.has_template('kanban-box')) { - self.dataset.read_slice(_.keys(self.fields_view.fields), { - context: self.dataset.get_context(), - domain: self.dataset.get_domain() - }, function (records) { - self.all_display_data = [{'records': records, 'value': false, 'header': false, 'ids': self.dataset.ids}]; - self.on_show_data(self.all_display_data); - } - ); + this.do_actual_search(); } }, add_qweb_template: function() { @@ -50,8 +44,8 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ } } }, - do_get_kanban_color: function(variable) { - var number_of_color_schemes = 2, + kanban_color: function(variable) { + var number_of_color_schemes = 8, index = 0; switch (typeof(variable)) { case 'string': @@ -65,25 +59,33 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ default: return ''; } - return 'oe_kanban_color_' + ((index % number_of_color_schemes) + 1); + return 'oe_kanban_color_' + ((index % number_of_color_schemes) || number_of_color_schemes); + }, + kanban_gravatar: function(email, size) { + size = size || 22; + var email_md5 = '2eb60ad22dadcf4dc456b28390a80268'; + return 'http://www.gravatar.com/avatar/' + email_md5 + '.png?s=' + size; }, transform_qweb_template: function(node) { + var qweb_prefix = QWeb.prefix; switch (node.tag) { case 'field': node.tag = 't'; - node.attrs['t-esc'] = node.attrs['name'] + '.value'; + node.attrs['t-esc'] = 'record.' + node.attrs['name'] + '.value'; break case 'button': case 'a': var type = node.attrs.type || ''; - if (_.indexOf('action,object,edit,delete,'.split(','), type) !== -1) { + if (_.indexOf('action,object,edit,delete,color'.split(','), type) !== -1) { _.each(node.attrs, function(v, k) { - node.attrs['data-' + k] = v; - delete(node.attrs[k]); + if (k.substr(0, qweb_prefix.length + 1) !== qweb_prefix + '-') { + node.attrs['data-' + k] = v; + delete(node.attrs[k]); + } }); if (node.attrs['data-states']) { var states = _.map(node.attrs['data-states'].split(','), function(state) { - return "state.value == '" + _.trim(state) + "'"; + return "record.state.value == '" + _.trim(state) + "'"; }); node.attrs['t-if'] = states.join(' or '); } @@ -174,6 +176,33 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ this.notification.warn("Kanban", "No form view defined for this object"); } }, + on_record_saved: function(r) { + var id = this.form_dialog.form.datarecord.id; + // TODO fme: reload record instead of all. need refactoring + this.do_actual_search(); + }, + do_change_color: function(record_id, $e) { + var self = this, + id = record_id, + colors = '#FFC7C7,#FFF1C7,#E3FFC7,#C7FFD5,#C7FFFF,#C7D5FF,#E3C7FF,#FFC7F1'.split(','), + $cpicker = $(QWeb.render('KanbanColorPicker', { colors : colors, columns: 2 })); + $e.after($cpicker); + $cpicker.mouseenter(function() { + clearTimeout($cpicker.data('timeoutId')); + }).mouseleave(function(evt) { + var timeoutId = setTimeout(function() { $cpicker.remove() }, 500); + $cpicker.data('timeoutId', timeoutId); + }); + $cpicker.find('a').click(function() { + var data = {}; + data[$e.data('name')] = $(this).data('color'); + self.dataset.write(id, data, {}, function() { + // TODO fme: reload record instead of all. need refactoring + self.do_actual_search(); + }); + $cpicker.remove(); + }); + }, do_delete: function (id) { var self = this; return $.when(this.dataset.unlink([id])).then(function () { @@ -302,7 +331,11 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ if (data.records.length > 0){ _.each(data.records, function(record) { self.$element.find("#main_" + record.id).children().remove(); - self.$element.find("#main_" + record.id).append(self.qweb.render('kanban-box', self.do_transform_record(record))); + self.$element.find("#main_" + record.id).append(self.qweb.render('kanban-box', { + record: self.do_transform_record(record), + kanban_color: self.kanban_color, + kanban_gravatar: self.kanban_gravatar + })); }); } else { self.$element.find("#column_" + data.value).remove(); @@ -310,8 +343,8 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ } }); this.$element.find('.oe_kanban_action').click(this.on_action_clicked); - this.$element.find('.oe_kanban_record').click(function() { - $(this).find('.oe_kanban_box_show_onclick').removeClass('oe_kanban_box_show_onclick'); + this.$element.find('.oe_kanban_box_show_onclick_trigger').click(function() { + $(this).parent('.oe_kanban_box').find('.oe_kanban_box_show_onclick').toggle(); }); }, on_action_clicked: function(evt) { @@ -322,8 +355,10 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ this.do_delete(record_id); } else if (type == 'edit') { this.do_edit_record(record_id); + } else if (type == 'color') { + this.do_change_color(record_id, $action); } else { - var button_attrs = $(this).data(); + var button_attrs = $action.data(); this.on_button_click(button_attrs, record_id); } }, @@ -336,7 +371,6 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ r.value = openerp.web.format_value(value, r); new_record[name] = r; }); - new_record.__kanban_color = this.do_get_kanban_color; return new_record; }, do_search: function (domains, contexts, group_by) { @@ -353,8 +387,12 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ }); }, do_actual_search : function () { - var self = this; - self.datagroup = new openerp.web.DataGroup(self, self.model, self.domain, self.context, self.group_by || []); + var self = this, + group_by = self.group_by; + if (!group_by.length && this.fields_view.arch.attrs.default_group_by) { + group_by = [this.fields_view.arch.attrs.default_group_by]; + } + self.datagroup = new openerp.web.DataGroup(self, self.model, self.domain, self.context, group_by); self.dataset.context = self.context; self.dataset.domain = self.domain; self.datagroup.list([], diff --git a/addons/web_kanban/static/src/xml/web_kanban.xml b/addons/web_kanban/static/src/xml/web_kanban.xml index 564761c955a..aa7bc73190d 100644 --- a/addons/web_kanban/static/src/xml/web_kanban.xml +++ b/addons/web_kanban/static/src/xml/web_kanban.xml @@ -22,4 +22,16 @@ + + + + + + </tr><tr> + + +
+ +
+
diff --git a/addons/web_mobile/__init__.py b/addons/web_mobile/__init__.py index ee5959455ad..e69de29bb2d 100644 --- a/addons/web_mobile/__init__.py +++ b/addons/web_mobile/__init__.py @@ -1 +0,0 @@ -import controllers diff --git a/addons/web_mobile/controllers/__init__.py b/addons/web_mobile/controllers/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/addons/web_mobile/static/src/js/chrome_mobile.js b/addons/web_mobile/static/src/js/chrome_mobile.js index ff5601d56df..2b9d8600fef 100644 --- a/addons/web_mobile/static/src/js/chrome_mobile.js +++ b/addons/web_mobile/static/src/js/chrome_mobile.js @@ -19,7 +19,7 @@ openerp.web_mobile.MobileWebClient = openerp.web.Widget.extend({ this.$element.html(QWeb.render("WebClient", {})); this.session = new openerp.web.Session("oe_errors"); this.crashmanager = new openerp.web.CrashManager(this); - this.login = new openerp.web_mobile.Login(this, "oe_app"); + this.login = new openerp.web_mobile.Login(this, "oe_login"); // this.session.on_session_invalid.add(this.login.do_ask_login); }, start: function() { @@ -49,6 +49,7 @@ openerp.web_mobile.Login = openerp.web.Widget.extend({ var db = $e.find("div select[name=database]").val(); var login = $e.find("div input[name=login]").val(); var password = $e.find("div input[name=password]").val(); + //$e.hide(); // Should hide then call callback this.session.session_login(db, login, password, function() { @@ -70,8 +71,9 @@ openerp.web_mobile.Login = openerp.web.Widget.extend({ .removeClass("login_invalid") .addClass("login_valid"); //.hide(); - this.homepage = new openerp.web_mobile.HomePage(this, "oe_app"); - this.homepage.start(); + + this.menu = new openerp.web_mobile.Menu(this, "oe_menu", "oe_secondary_menu"); + this.menu.start(); }, do_ask_login: function(continuation) { this.on_login_invalid(); @@ -83,25 +85,6 @@ openerp.web_mobile.Login = openerp.web.Widget.extend({ } }); -openerp.web_mobile.HomePage = openerp.web.Widget.extend({ - init: function(session, element_id) { - this._super(session, element_id); - }, - start: function() { - this.$element.html(QWeb.render("HomePage", {})); - this.header = new openerp.web_mobile.Header(this, "oe_header"); - this.shortcuts = new openerp.web_mobile.Shortcuts(this, "oe_shortcuts"); - this.menu = new openerp.web_mobile.Menu(this, "oe_menu", "oe_secondary_menu"); - this.options = new openerp.web_mobile.Options(this, "oe_options"); - this.header.start(); - this.shortcuts.start(); - this.menu.start(); - this.options.start(); - jQuery("#oe_header").find("h1").html('Home'); - this.$element.find("a").click(this.on_clicked); - } -}); - openerp.web_mobile.Header = openerp.web.Widget.extend({ init: function(session, element_id) { this._super(session, element_id); @@ -109,15 +92,16 @@ openerp.web_mobile.Header = openerp.web.Widget.extend({ start: function() { var self = this; self.$element.html(QWeb.render("Header", this)); - self.$element.find("a").click(this.on_clicked); + } +}); + +openerp.web_mobile.Footer = openerp.web.Widget.extend({ + init: function(session, element_id) { + this._super(session, element_id); }, - on_clicked: function(ev) { - var $opt = $(ev.currentTarget); - var current_id = $opt.attr('id'); - if (current_id == 'home') { - this.homepage = new openerp.web_mobile.HomePage(this, "oe_app"); - this.homepage.start(); - } + start: function() { + var self = this; + self.$element.html(QWeb.render("Footer", this)); } }); @@ -128,17 +112,29 @@ openerp.web_mobile.Shortcuts = openerp.web.Widget.extend({ start: function() { var self = this; this.rpc('/web/session/sc_list',{} ,function(res){ - self.$element.html(QWeb.render("Shortcuts", {'sc' : res})); - self.$element.find("a").click(self.on_clicked); - }) + self.$element.html(QWeb.render("Shortcuts", {'sc' : res})) + self.$element.find('#content').find("a").click(self.on_clicked); + self.$element.find("#footer").find('#preference').click(function(){ + if(!$('#oe_options').html().length){ + this.options = new openerp.web_mobile.Options(self, "oe_options"); + this.options.start(); + } + else{ + self.$element.find("#footer").find('#preference').attr('href','#oe_options'); + } + }); + $.mobile.changePage($("#oe_shortcuts"), "slide", true, true); + }); }, on_clicked: function(ev) { - var $shortcut = $(ev.currentTarget); - var id = $shortcut.data('menu'); - var res_id = $shortcut.data('res'); - jQuery("#oe_header").find("h1").html($shortcut.data('name')); - this.listview = new openerp.web_mobile.ListView(this, "oe_app", res_id); + $shortcut = $(ev.currentTarget); + id = $shortcut.data('menu'); + res_id = $shortcut.data('res'); +// this.header = new openerp.web_mobile.Header(this, "oe_header"); + this.listview = new openerp.web_mobile.ListView(this, "oe_list", res_id); +// this.header.start(); this.listview.start(); + jQuery("#oe_header").find("h1").html($shortcut.data('name')); } }); @@ -153,9 +149,30 @@ openerp.web_mobile.Menu = openerp.web.Widget.extend({ this.rpc("/web/menu/load", {}, this.on_loaded); }, on_loaded: function(data) { + var self = this; this.data = data; this.$element.html(QWeb.render("Menu", this.data)); - this.$element.add(this.$secondary_menu).find("a").click(this.on_menu_click); + + this.$element.find("#footer").find('#shrotcuts').click(function(){ + if(!$('#oe_shortcuts').html().length){ + this.shortcuts = new openerp.web_mobile.Shortcuts(self, "oe_shortcuts"); + this.shortcuts.start(); + } + else{ + self.$element.find("#footer").find('#shrotcuts').attr('href','#oe_shortcuts'); + } + }); + this.$element.find("#footer").find('#preference').click(function(){ + if(!$('#oe_options').html().length){ + this.options = new openerp.web_mobile.Options(self, "oe_options"); + this.options.start(); + } + else{ + self.$element.find("#footer").find('#preference').attr('href','#oe_options'); + } + }); + this.$element.add(this.$secondary_menu).find("#content").find('a').click(this.on_menu_click); + $.mobile.changePage($("#oe_menu"), "slide", true, true); }, on_menu_click: function(ev, id) { var $menu = $(ev.currentTarget); @@ -165,50 +182,80 @@ openerp.web_mobile.Menu = openerp.web.Widget.extend({ this.children = this.data.data.children[i]; } } - jQuery("#oe_header").find("h1").html($menu.data('name')); this.$element .removeClass("login_valid") .addClass("secondary_menu"); //.hide(); - this.secondary = new openerp.web_mobile.Secondary(this, "oe_app", this.children); - this.secondary.start(); + if(!$('#oe_sec_menu').html().length){ + this.secondary = new openerp.web_mobile.Secondary(this, "oe_sec_menu", this.children); + this.secondary.start(); + }else{ + this.$element.find("#content").find('a').attr('href','#oe_sec_menu'); + } + /*if(!$('#oe_sec_menu').html().length){ + this.secondary = new openerp.web_mobile.Secondary(this, "oe_sec_menu", this.children); + this.secondary.start(); + }else{ + // self.$element.find("#content").find('a').attr('href','#oe_sec_menu'); + this.$element.add(this.$secondary_menu).find("#content").find('a').attr('href','#oe_sec_menu'); + }*/ + } }); - openerp.web_mobile.Secondary = openerp.web.Widget.extend({ init: function(session, element_id, secondary_menu_id) { this._super(session, element_id); this.data = secondary_menu_id; }, start: function(ev, id) { + var self = this; + // console.log(this.data,this.$element.html().length); + + /* if(this.$element.html().length){ + self.$element.find('[data-role="listview"]').remove(); + + _.each(self.data.children,function(i){ + var newul = ''; // Create New List Item + self.$element.find('#content').append(newul); + //console.log('in for loop',i.children); + }); + console.log('saaasasaaa',self.$element.find('#content'),self.data); + //self.$element.find('[data-role="listview"]').listview('refresh'); + }else{*/ + var v = { menu : this.data }; this.$element.html(QWeb.render("Menu.secondary", v)); - this.$element.add(this.$secondary_menu).find("a").click(this.on_menu_click); + this.$element.find("#header").find("h1").html(this.data.name); + this.$element.add(this.$secondary_menu).find('#content').find("a").click(this.on_menu_click); + this.$element.find("#footer").find('#shrotcuts').click(function(){ + if(!$('#oe_shortcuts').html().length){ + this.shortcuts = new openerp.web_mobile.Shortcuts(self, "oe_shortcuts"); + this.shortcuts.start(); + } + else{ + self.$element.find("#footer").find('#shrotcuts').attr('href','#oe_shortcuts'); + } + }); + this.$element.find("#footer").find('#preference').click(function(){ + if(!$('#oe_options').html().length){ + this.options = new openerp.web_mobile.Options(self, "oe_options"); + this.options.start(); + } + else{ + self.$element.find("#footer").find('#preference').attr('href','#oe_options'); + } + }); + $.mobile.changePage($("#oe_sec_menu"), "slide", true, true); }, on_menu_click: function(ev, id) { var $menu = $(ev.currentTarget); id = $menu.data('menu'); - for (var i = 0; i < this.data.children.length; i++) { - if (this.data.children[i].id == id) { - this.children = this.data.children[i]; - } + if (id) { + this.listview = new openerp.web_mobile.ListView(this, "oe_list", id); + this.listview.start(); } jQuery("#oe_header").find("h1").html($menu.data('name')); - var child_len = this.children.children.length; - if (child_len > 0) { - this.$element - .removeClass("secondary_menu") - .addClass("content_menu"); - //.hide(); - this.secondary = new openerp.web_mobile.Secondary(this, "oe_app", this.children); - this.secondary.start(); - } - else { - if (id) { - this.listview = new openerp.web_mobile.ListView(this, "oe_app", id); - this.listview.start(); - } - } } }); @@ -216,12 +263,16 @@ openerp.web_mobile.Options = openerp.web.Widget.extend({ start: function() { var self = this; this.$element.html(QWeb.render("Options", this)); - self.$element.find("#logout").click(self.on_logout); - }, - on_logout: function(ev) { - this.session.logout(); -// this.login = new openerp.web_mobile.Login(this, "oe_app"); -// this.login.start(); + this.$element.find("#footer").find('#shrotcuts').click(function(){ + if(!$('#oe_shortcuts').html().length){ + this.shortcuts = new openerp.web_mobile.Shortcuts(self, "oe_shortcuts"); + this.shortcuts.start(); + } + else{ + self.$element.find("#footer").find('#shrotcuts').attr('href','#oe_shortcuts'); + } + }); + $.mobile.changePage($("#oe_options"), "slide", true, true); } }); diff --git a/addons/web_mobile/static/src/js/form_mobile.js b/addons/web_mobile/static/src/js/form_mobile.js index 03291a70bfa..3dc777a2bd6 100644 --- a/addons/web_mobile/static/src/js/form_mobile.js +++ b/addons/web_mobile/static/src/js/form_mobile.js @@ -22,15 +22,16 @@ openerp.web_mobile.FormView = openerp.web.Widget.extend({ var model = this.action.res_model; var view_id = this.action.views[1][0]; this.dataset = new openerp.web.DataSetSearch(this, this.action.res_model, null, null); + var context = new openerp.web.CompoundContext(this.dataset.get_context()); this.dataset.read_slice([],{}, function (result) { for (var i = 0; i < result.length; i++) { if (result[i].id == id) { var data = result[i]; } } - self.rpc("/web/formview/load", {"model": model, "view_id": view_id }, function (result) { - var fields = result.fields_view.fields; - var view_fields = result.fields_view.arch.children; + self.rpc("/web/view/load", {"model": model, "view_id": view_id, "view_type": "form", context: context}, function (result) { + var fields = result.fields; + var view_fields = result.arch.children; var get_fields = self.get_fields(view_fields); var selection = new openerp.web_mobile.Selection(); for (var j = 0; j < view_fields.length; j++) { @@ -38,8 +39,9 @@ openerp.web_mobile.FormView = openerp.web.Widget.extend({ var notebooks = view_fields[j]; } } - $("#oe_header").find("h1").html(result.fields_view.arch.attrs.string); self.$element.html(QWeb.render("FormView", {'get_fields': get_fields, 'notebooks': notebooks || false, 'fields' : fields, 'values' : data })); + + self.$element.find("#header").find('h1').html(self.action.name); self.$element.find('select').change(function(ev){ selection.on_select_option(ev); }); @@ -69,31 +71,50 @@ openerp.web_mobile.FormView = openerp.web.Widget.extend({ if (!next.find('.detail').html().length) { for (var i = 0; i < get_fields.length; i++) { if (fields[get_fields[i].attrs.name].type == 'one2many'){ - var get_fields_test = self.get_fields(fields[get_fields[i].attrs.name].views.form.arch.children); - var fields_test = fields[get_fields[i].attrs.name]['views'].form.fields; - var notebook=fields[get_fields[i].attrs.name].views.form.arch; + if(fields[get_fields[i].attrs.name].views.form){ + var get_fields_test = self.get_fields(fields[get_fields[i].attrs.name].views.form.arch.children); + var fields_test = fields[get_fields[i].attrs.name]['views'].form.fields; + var notebook=fields[get_fields[i].attrs.name].views.form.arch; + } + var relational = get_fields[i].attrs.name; } } if(notebook){ - next.find('.detail').append(QWeb.render("FormView", {'get_fields': get_fields,'fields' : result.fields_view.fields, 'values' : data,'til': notebook.attrs.string })); + next.find('.detail').append(QWeb.render("FormView", {'get_fields': get_fields,'fields' : result.fields, 'values' : data,'til': notebook.attrs.string })); }else{ - next.find('.detail').append(QWeb.render("FormView", {'get_fields': get_fields,'fields' : result.fields_view.fields, 'values' : data })); + next.find('.detail').append(QWeb.render("FormView", {'get_fields': get_fields,'fields' : result.fields, 'values' : data })); } } - next.find('.detail').find('a').click(function(){ - if(next.find('.detail').find('a').next().find('.detail').html().length){ - if (next.find('.detail').find('a').next().hasClass(self.content_collapsed_class)) { - self.collapsed(next.find('.detail').find('a').next(),next.find('.detail').find('a').find('span .ui-icon')); - } - else if (next.find('.detail').find('a').next().hasClass(self.content_expanded_class)) { - self.expanded(next.find('.detail').find('a').next(),next.find('.detail').find('a').find('span .ui-icon')); - } + + //$.mobile.changePage($("#oe_form"), "slide", true, true); + /*next.find('.detail').find('li').click(function(){ + if(data[relational]){ + var dataset = new openerp.web.DataSetStatic(self, result.fields[relational].relation, result.fields[relational].context); + dataset.domain=[['id', 'in', data[relational]]]; + dataset.name_search('', dataset.domain, 'in',false ,function(res){ + for(var i=0;i' + result[i][1] + ''; // Create New List Item + self.$element.find('[data-role="listview"]').append(newli); + } + self.$element.find('[data-role="listview"]').listview('refresh'); + }else{ self.$element.html(QWeb.render("ListView", {'records' : result})); - self.$element.find("#searchid").focus(); - if(request.term){ - self.$element.find("#searchid").val(request.term); - } - self.$element.find("#searchid").autocomplete({ - source: function(req) { self.on_search_data(req); }, - focus: function(e, ui) { - e.preventDefault(); - }, - html: true, - minLength: 0, - delay: 0 + self.$element.find("#header").find('h1').html(self.action.name); + self.$element.find("#footer").find('#shortcuts').click(function(){ + if(!$('#oe_shortcuts').html().length){ + this.shortcut = new openerp.web_mobile.Options(self, "oe_shortcuts"); + this.options.start(); + } + else{ + self.$element.find("#footer").find('#shrotcuts').attr('href','#oe_shortcuts'); + } }); - self.$element.find("#searchid").keyup(self.on_search_data); + self.$element.find("#footer").find('#preference').click(function(){ + if(!$('#oe_options').html().length){ + this.options = new openerp.web_mobile.Options(self, "oe_options"); + this.options.start(); + } + else{ + self.$element.find("#footer").find('#preference').attr('href','#oe_options'); + } + }); + } self.$element.find("a#list-id").click(self.on_list_click); + $.mobile.changePage($("#oe_list"), "slide", true, true); }); }, on_list_click: function(ev) { var $record = $(ev.currentTarget); var self = this; - var id = $record.data('id'); - this.formview = new openerp.web_mobile.FormView(this, "oe_app", id, this.action); + id = $record.data('id'); +// this.header = new openerp.web_mobile.Header(this, "oe_header"); + this.formview = new openerp.web_mobile.FormView(this, "oe_form", id, this.action); +// this.header.start(); this.formview.start(); } }); diff --git a/addons/web_mobile/static/src/web_mobile.html b/addons/web_mobile/static/src/web_mobile.html index 254c4a6ea36..9a17ff49dbb 100755 --- a/addons/web_mobile/static/src/web_mobile.html +++ b/addons/web_mobile/static/src/web_mobile.html @@ -7,19 +7,19 @@ - - - - - + + + + + - - - - - - + + + + + + diff --git a/addons/web_mobile/static/src/xml/web_mobile.xml b/addons/web_mobile/static/src/xml/web_mobile.xml index a3af2e39b90..75d30af55b1 100644 --- a/addons/web_mobile/static/src/xml/web_mobile.xml +++ b/addons/web_mobile/static/src/xml/web_mobile.xml @@ -4,10 +4,14 @@ -
-
-
-
+
+
+
+
+
+
+
+
@@ -38,131 +42,123 @@
- -
-
- -
+ +
+

OpenERP

+
- -