[MERGE]Merge with trunk upto revision no 970.
bzr revid: kch@tinyerp.com-20110908103919-0elkj4hdhhgpvx6o
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
.PHONY: all release clean
|
||||
.PHONY: all doc release clean
|
||||
|
||||
HOST = 127.0.0.1
|
||||
PORT = 8080
|
||||
|
||||
|
||||
all: run
|
||||
|
||||
run:
|
||||
@@ -24,6 +23,9 @@ clean:
|
||||
@rm -rf dist
|
||||
@rm -rf *.egg-info
|
||||
|
||||
cloc:
|
||||
cloc openerpweb/*.py addons/*/controllers/*.py addons/*/static/src/*.js addons/*/static/src/js/*.js addons/*/static/src/css/*.css addons/*/static/src/xml/*.xml
|
||||
doc:
|
||||
make -C doc html
|
||||
|
||||
cloc:
|
||||
cloc addons/*/common/*.py addons/*/controllers/*.py addons/*/static/src/*.js addons/*/static/src/js/*.js addons/*/static/src/css/*.css addons/*/static/src/xml/*.xml
|
||||
|
||||
|
||||
+4
-37
@@ -1,42 +1,9 @@
|
||||
Coding style
|
||||
------------
|
||||
|
||||
Javascript
|
||||
http://javascript.crockford.com/code.html with the following amendements:
|
||||
- Line Length should be 160 (132?), dont split at 80, rationale in 2011 we all use 16/9 screens
|
||||
|
||||
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml ?
|
||||
|
||||
Modules Conventions
|
||||
-------------------
|
||||
|
||||
addons/<modulename>/controllers/ python controller
|
||||
addons/<modulename>/controllers/main.py main python controller is there is only one (or should it be <modulename>.py ?)
|
||||
addons/<modulename>/static/ static directory (directly served by the web server)
|
||||
addons/<modulename>/static/<external_library>/ directory containing an external javascrip library respect the directory structure of upstream is this directory
|
||||
addons/<modulename>/static/openerp/ module specfic static files
|
||||
addons/<modulename>/static/openerp/js/ module specific javscript files
|
||||
addons/<modulename>/static/openerp/css/ module specific css files
|
||||
addons/<modulename>/static/openerp/img/ module specific images files
|
||||
addons/<modulename>/static/openerp/ other files
|
||||
addons/<modulename>/__openerp__.py module manifest referencing js and css files
|
||||
|
||||
|
||||
Dependecies
|
||||
OpenERP Web
|
||||
-----------
|
||||
Depends on
|
||||
|
||||
install "CherryPy>=3.1.2" "-d cherrypy"
|
||||
install "simplejson>=2.0.9" "-d simplejson"
|
||||
To build the documentation use:
|
||||
|
||||
Maybe soon on
|
||||
$ make doc
|
||||
|
||||
#install "Babel>=0.9.4" "-d babel"
|
||||
#install "pytz>=2009j" "-d pytz"
|
||||
then look at doc/build/html/index.html
|
||||
|
||||
Probably not anymore on:
|
||||
|
||||
#install "Mako>=0.2.4" "-d mako"
|
||||
#install "formencode>=1.2.2" "-d formencode"
|
||||
#install "pyparsing>=1.5.2" "-f pyparsing.py"
|
||||
#install "xlwt>=0.7" "-d xlwt"
|
||||
|
||||
@@ -4,6 +4,7 @@ from __future__ import with_statement
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
import pprint
|
||||
import sys
|
||||
import traceback
|
||||
import uuid
|
||||
@@ -26,6 +27,8 @@ import backendrpc as backend
|
||||
__all__ = ['Root', 'jsonrequest', 'httprequest', 'Controller',
|
||||
'WebRequest', 'JsonRequest', 'HttpRequest']
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Globals (wont move into a pool)
|
||||
#-----------------------------------------------------------
|
||||
@@ -159,8 +162,8 @@ class JsonRequest(WebRequest):
|
||||
else:
|
||||
self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
|
||||
self.init(self.jsonrequest.get("params", {}))
|
||||
if self.debug or 1:
|
||||
print "--> %s.%s %s" % (controller.__class__.__name__, method.__name__, self.jsonrequest)
|
||||
if _logger.isEnabledFor(logging.DEBUG):
|
||||
_logger.debug("--> %s.%s\n%s", controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest))
|
||||
response['id'] = self.jsonrequest.get('id')
|
||||
response["result"] = method(controller, self, **self.params)
|
||||
except backend.OpenERPUnboundException:
|
||||
@@ -184,7 +187,7 @@ class JsonRequest(WebRequest):
|
||||
}
|
||||
}
|
||||
except Exception:
|
||||
logging.getLogger('openerp.JSONRequest.dispatch').exception\
|
||||
logging.getLogger(__name__ + '.JSONRequest.dispatch').exception\
|
||||
("An error occured while handling a json request")
|
||||
error = {
|
||||
'code': 300,
|
||||
@@ -197,10 +200,8 @@ class JsonRequest(WebRequest):
|
||||
if error:
|
||||
response["error"] = error
|
||||
|
||||
if self.debug or 1:
|
||||
print "<--", response
|
||||
print
|
||||
|
||||
if _logger.isEnabledFor(logging.DEBUG):
|
||||
_logger.debug("<--\n%s", pprint.pformat(response))
|
||||
content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder)
|
||||
return werkzeug.wrappers.Response(
|
||||
content, headers=[('Content-Type', 'application/json'),
|
||||
@@ -237,15 +238,13 @@ class HttpRequest(WebRequest):
|
||||
akw[key] = value
|
||||
else:
|
||||
akw[key] = type(value)
|
||||
if self.debug or 1:
|
||||
print "%s --> %s.%s %r" % (self.httprequest.method, controller.__class__.__name__, method.__name__, akw)
|
||||
_logger.debug("%s --> %s.%s %r", self.httprequest.method, controller.__class__.__name__, method.__name__, akw)
|
||||
r = method(controller, self, **self.params)
|
||||
if self.debug or 1:
|
||||
if isinstance(r, werkzeug.wrappers.BaseResponse):
|
||||
print '<--', r
|
||||
_logger.debug('<-- %s', r)
|
||||
else:
|
||||
print "<--", 'size:', len(r)
|
||||
print
|
||||
_logger.debug("<-- size: %s", len(r))
|
||||
return r
|
||||
|
||||
def make_response(self, data, headers=None, cookies=None):
|
||||
@@ -317,7 +316,7 @@ class Root(object):
|
||||
by the server, will be filtered by this pattern
|
||||
"""
|
||||
def __init__(self, options):
|
||||
self.root = werkzeug.urls.Href('/web/webclient/home')
|
||||
self.root = werkzeug.urls.Href('/web/webclient/home?debug')
|
||||
self.config = options
|
||||
|
||||
self.session_cookie = 'sessionid'
|
||||
@@ -391,7 +390,7 @@ class Root(object):
|
||||
manifest_path = os.path.join(addons_path, module, '__openerp__.py')
|
||||
if os.path.isfile(manifest_path):
|
||||
manifest = ast.literal_eval(open(manifest_path).read())
|
||||
print "Loading", module
|
||||
_logger.info("Loading %s", module)
|
||||
m = __import__(module)
|
||||
addons_module[module] = m
|
||||
addons_manifest[module] = manifest
|
||||
@@ -424,6 +423,6 @@ class Root(object):
|
||||
meth = rest[0]
|
||||
m = getattr(c, meth)
|
||||
if getattr(m, 'exposed', False):
|
||||
print "Dispatching to", ps, c, meth, m
|
||||
_logger.debug("Dispatching to %s %s %s", ps, c, meth)
|
||||
return m
|
||||
return None
|
||||
|
||||
@@ -11,6 +11,7 @@ import simplejson
|
||||
import textwrap
|
||||
import xmlrpclib
|
||||
import time
|
||||
import zlib
|
||||
import webrelease
|
||||
from xml.etree import ElementTree
|
||||
from cStringIO import StringIO
|
||||
@@ -23,8 +24,6 @@ openerpweb.nonliterals = web.common.nonliterals
|
||||
|
||||
from babel.messages.pofile import read_po
|
||||
|
||||
_REPORT_POLLER_DELAY = 0.05
|
||||
|
||||
# Should move to openerpweb.Xml2Json
|
||||
class Xml2Json:
|
||||
# xml2json-direct
|
||||
@@ -104,7 +103,6 @@ home_template = textwrap.dedent("""<!DOCTYPE html>
|
||||
%(javascript)s
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
QWeb = new QWeb2.Engine();
|
||||
var c = new openerp.init();
|
||||
var wc = new c.web.WebClient("oe");
|
||||
wc.start();
|
||||
@@ -144,13 +142,13 @@ class WebClient(openerpweb.Controller):
|
||||
# script tags
|
||||
jslist = ['/web/webclient/js']
|
||||
if req.debug:
|
||||
jslist = manifest_glob(req.config.addons_path, ['web'], 'js')
|
||||
jslist = [i + '?debug=' + str(time.time()) for i in manifest_glob(req.config.addons_path, ['web'], 'js')]
|
||||
js = "\n ".join(['<script type="text/javascript" src="%s"></script>'%i for i in jslist])
|
||||
|
||||
# css tags
|
||||
csslist = ['/web/webclient/css']
|
||||
if req.debug:
|
||||
csslist = manifest_glob(req.config.addons_path, ['web'], 'css')
|
||||
csslist = [i + '?debug=' + str(time.time()) for i in manifest_glob(req.config.addons_path, ['web'], 'css')]
|
||||
css = "\n ".join(['<link rel="stylesheet" href="%s">'%i for i in csslist])
|
||||
r = home_template % {
|
||||
'javascript': js,
|
||||
@@ -453,8 +451,6 @@ def load_actions_from_ir_values(req, key, key2, models, meta):
|
||||
|
||||
def clean_action(req, action):
|
||||
action.setdefault('flags', {})
|
||||
if action['type'] != 'ir.actions.act_window':
|
||||
return action
|
||||
|
||||
context = req.session.eval_context(req.context)
|
||||
eval_ctx = req.session.evaluation_context(context)
|
||||
@@ -466,7 +462,9 @@ def clean_action(req, action):
|
||||
if isinstance(action.get('domain'), basestring):
|
||||
action['domain'] = eval( action['domain'], eval_ctx ) or []
|
||||
|
||||
return fix_view_modes(action)
|
||||
if action['type'] == 'ir.actions.act_window':
|
||||
return fix_view_modes(action)
|
||||
return action
|
||||
|
||||
# I think generate_views,fix_view_modes should go into js ActionManager
|
||||
def generate_views(action):
|
||||
@@ -764,6 +762,8 @@ class View(openerpweb.Controller):
|
||||
fvg = Model.fields_view_get(view_id, view_type, context, toolbar, submenu)
|
||||
# todo fme?: check that we should pass the evaluated context here
|
||||
self.process_view(req.session, fvg, context, transform)
|
||||
if toolbar and transform:
|
||||
self.process_toolbar(req, fvg['toolbar'])
|
||||
return fvg
|
||||
|
||||
def process_view(self, session, fvg, context, transform):
|
||||
@@ -795,6 +795,22 @@ class View(openerpweb.Controller):
|
||||
if field.get('context'):
|
||||
field["context"] = self.parse_context(field["context"], session)
|
||||
|
||||
def process_toolbar(self, req, toolbar):
|
||||
"""
|
||||
The toolbar is a mapping of section_key: [action_descriptor]
|
||||
|
||||
We need to clean all those actions in order to ensure correct
|
||||
round-tripping
|
||||
"""
|
||||
for actions in toolbar.itervalues():
|
||||
for action in actions:
|
||||
if 'context' in action:
|
||||
action['context'] = self.parse_context(
|
||||
action['context'], req.session)
|
||||
if 'domain' in action:
|
||||
action['domain'] = self.parse_domain(
|
||||
action['domain'], req.session)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def add_custom(self, req, view_id, arch):
|
||||
CustomView = req.session.model('ir.ui.view.custom')
|
||||
@@ -884,22 +900,13 @@ class View(openerpweb.Controller):
|
||||
if context_string:
|
||||
elem.set(el, self.parse_context(context_string, session))
|
||||
|
||||
class FormView(View):
|
||||
_cp_path = "/web/formview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id, toolbar=False):
|
||||
fields_view = self.fields_view_get(req, model, view_id, 'form', toolbar=toolbar)
|
||||
return {'fields_view': fields_view}
|
||||
def load(self, req, model, view_id, view_type, toolbar=False):
|
||||
return self.fields_view_get(req, model, view_id, view_type, toolbar=toolbar)
|
||||
|
||||
class ListView(View):
|
||||
_cp_path = "/web/listview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id, toolbar=False):
|
||||
fields_view = self.fields_view_get(req, model, view_id, 'tree', toolbar=toolbar)
|
||||
return {'fields_view': fields_view}
|
||||
|
||||
def process_colors(self, view, row, context):
|
||||
colors = view['arch']['attrs'].get('colors')
|
||||
|
||||
@@ -918,6 +925,15 @@ class ListView(View):
|
||||
return color[0]
|
||||
return 'maroon'
|
||||
|
||||
class TreeView(View):
|
||||
_cp_path = "/web/treeview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def action(self, req, model, id):
|
||||
return load_actions_from_ir_values(
|
||||
req,'action', 'tree_but_open',[(model, id)],
|
||||
False)
|
||||
|
||||
class SearchView(View):
|
||||
_cp_path = "/web/searchview"
|
||||
|
||||
@@ -1062,8 +1078,11 @@ class Action(openerpweb.Controller):
|
||||
context = req.session.eval_context(req.context)
|
||||
action_type = Actions.read([action_id], ['type'], context)
|
||||
if action_type:
|
||||
action = req.session.model(action_type[0]['type']).read([action_id], False,
|
||||
context)
|
||||
ctx = {}
|
||||
if action_type[0]['type'] == 'ir.actions.report.xml':
|
||||
ctx.update({'bin_size': True})
|
||||
ctx.update(context)
|
||||
action = req.session.model(action_type[0]['type']).read([action_id], False, ctx)
|
||||
if action:
|
||||
value = clean_action(req, action[0])
|
||||
return {'result': value}
|
||||
@@ -1073,19 +1092,6 @@ class Action(openerpweb.Controller):
|
||||
return clean_action(req, req.session.model('ir.actions.server').run(
|
||||
[action_id], req.session.eval_context(req.context)))
|
||||
|
||||
class TreeView(View):
|
||||
_cp_path = "/web/treeview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id, toolbar=False):
|
||||
return self.fields_view_get(req, model, view_id, 'tree', toolbar=toolbar)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def action(self, req, model, id):
|
||||
return load_actions_from_ir_values(
|
||||
req,'action', 'tree_but_open',[(model, id)],
|
||||
False)
|
||||
|
||||
class Export(View):
|
||||
_cp_path = "/web/export"
|
||||
|
||||
@@ -1336,29 +1342,56 @@ class ExcelExport(Export):
|
||||
fp.close()
|
||||
return data
|
||||
|
||||
|
||||
class Reports(View):
|
||||
_cp_path = "/web/report"
|
||||
POLLING_DELAY = 0.25
|
||||
TYPES_MAPPING = {
|
||||
'doc': 'application/vnd.ms-word',
|
||||
'html': 'text/html',
|
||||
'odt': 'application/vnd.oasis.opendocument.text',
|
||||
'pdf': 'application/pdf',
|
||||
'sxw': 'application/vnd.sun.xml.writer',
|
||||
'xls': 'application/vnd.ms-excel',
|
||||
}
|
||||
|
||||
@openerpweb.httprequest
|
||||
def index(self, req, action, token):
|
||||
action = simplejson.loads(action)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def get_report(self, req, action):
|
||||
report_srv = req.session.proxy("report")
|
||||
context = req.session.eval_context(openerpweb.nonliterals.CompoundContext(req.context, \
|
||||
action["context"]))
|
||||
context = req.session.eval_context(
|
||||
openerpweb.nonliterals.CompoundContext(
|
||||
req.context or {}, action[ "context"]))
|
||||
|
||||
args = [req.session._db, req.session._uid, req.session._password, action["report_name"], context["active_ids"], {"id": context["active_id"], "model": context["active_model"], "report_type": action["report_type"]}, context]
|
||||
report_id = report_srv.report(*args)
|
||||
report = None
|
||||
report_data = {"id": context["active_id"], "model": context["active_model"]}
|
||||
if 'report_type' in action:
|
||||
report_data['report_type'] = action['report_type']
|
||||
report_id = report_srv.report(
|
||||
req.session._db, req.session._uid, req.session._password,
|
||||
action["report_name"], context["active_ids"],
|
||||
report_data, context)
|
||||
|
||||
report_struct = None
|
||||
while True:
|
||||
args2 = [req.session._db, req.session._uid, req.session._password, report_id]
|
||||
report = report_srv.report_get(*args2)
|
||||
if report["state"]:
|
||||
report_struct = report_srv.report_get(
|
||||
req.session._db, req.session._uid, req.session._password, report_id)
|
||||
if report_struct["state"]:
|
||||
break
|
||||
|
||||
time.sleep(_REPORT_POLLER_DELAY)
|
||||
time.sleep(self.POLLING_DELAY)
|
||||
|
||||
report = base64.b64decode(report_struct['result'])
|
||||
if report_struct.get('code') == 'zlib':
|
||||
report = zlib.decompress(report)
|
||||
report_mimetype = self.TYPES_MAPPING.get(
|
||||
report_struct['format'], 'octet-stream')
|
||||
return req.make_response(report,
|
||||
headers=[
|
||||
('Content-Disposition', 'attachment; filename="%s.%s"' % (action['report_name'], report_struct['format'])),
|
||||
('Content-Type', report_mimetype),
|
||||
('Content-Length', len(report))],
|
||||
cookies={'fileToken': int(token)})
|
||||
|
||||
#TODO: ok now we've got the report, and so what?
|
||||
return False
|
||||
|
||||
class Import(View):
|
||||
_cp_path = "/web/import"
|
||||
@@ -1534,4 +1567,4 @@ class Import(View):
|
||||
d+= ('%s: %s' % (str(key),str(val)))
|
||||
msg = 'Error trying to import this record:%s. ErrorMessage:%s %s' % (d,res[2],res[3])
|
||||
error = {'message':str(msg), 'title':'ImportationError'}
|
||||
return simplejson.dumps({'error':error})
|
||||
return simplejson.dumps({'error':error})
|
||||
@@ -201,7 +201,7 @@ QWeb2.Engine = (function() {
|
||||
this.templates = {};
|
||||
this.compiled_templates = {};
|
||||
this.extend_templates = {};
|
||||
this.dict = {};
|
||||
this.default_dict = {};
|
||||
this.tools = QWeb2.tools;
|
||||
this.jQuery = window.jQuery;
|
||||
this.reserved_words = QWeb2.RESERVED_WORDS.slice(0);
|
||||
@@ -323,10 +323,12 @@ QWeb2.Engine = (function() {
|
||||
" return r.join('');";
|
||||
},
|
||||
render : function(template, dict) {
|
||||
var ndict = QWeb2.tools.extend({}, this.default_dict);
|
||||
QWeb2.tools.extend(ndict, dict);
|
||||
if (this.debug && window['console'] !== undefined) {
|
||||
console.time("QWeb render template " + template);
|
||||
}
|
||||
var r = this._render(template, dict);
|
||||
var r = this._render(template, ndict);
|
||||
if (this.debug && window['console'] !== undefined) {
|
||||
console.timeEnd("QWeb render template " + template);
|
||||
}
|
||||
|
||||
@@ -838,7 +838,8 @@ label.error {
|
||||
.openerp label.oe_label_help {
|
||||
cursor: help;
|
||||
}
|
||||
.openerp .oe_form_field label.oe_label, .openerp .oe_form_field label.oe_label_help {
|
||||
.openerp label.oe_label,
|
||||
.openerp label.oe_label_help {
|
||||
text-align: right;
|
||||
margin: 3px 0 0 10px;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.web.chrome = function(openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
|
||||
openerp.web.Notification = openerp.web.Widget.extend({
|
||||
init: function(parent, element_id) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
openerp.web.core = function(openerp) {
|
||||
openerp.web.qweb = new QWeb2.Engine();
|
||||
/**
|
||||
* John Resig Class with factory improvement
|
||||
*/
|
||||
@@ -374,7 +375,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||
jsonrpc: "2.0",
|
||||
method: "call",
|
||||
params: params,
|
||||
id:null
|
||||
id: _.uniqueId('browser-client-')
|
||||
}).then(function () {deferred.resolve.apply(deferred, arguments);},
|
||||
function(error) {deferred.reject(error, $.Event());});
|
||||
return deferred.fail(function() {
|
||||
@@ -868,7 +869,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend({
|
||||
* @param {Object} additional Additional context arguments to pass to the template.
|
||||
*/
|
||||
render: function (additional) {
|
||||
return QWeb.render(this.template, _.extend({widget: this}, additional || {}));
|
||||
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
|
||||
},
|
||||
/**
|
||||
* Method called after rendering. Mostly used to bind actions, perform asynchronous
|
||||
@@ -946,7 +947,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend({
|
||||
*/
|
||||
openerp.web.OldWidget = openerp.web.Widget.extend({
|
||||
render: function (additional) {
|
||||
return QWeb.render(this.template, _.extend(_.extend({}, this), additional || {}));
|
||||
return openerp.web.qweb.render(this.template, _.extend(_.extend({}, this), additional || {}));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
openerp.web.data_export = function(openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
openerp.web.DataExport = openerp.web.Dialog.extend({
|
||||
template: 'ExportTreeView',
|
||||
dialog_title: 'Export Data',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
openerp.web.form = function (openerp) {
|
||||
|
||||
var _t = openerp.web._t;
|
||||
var QWeb = openerp.web.qweb;
|
||||
|
||||
openerp.web.views.add('form', 'openerp.web.FormView');
|
||||
openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# */{
|
||||
@@ -46,12 +47,17 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
if (this.embedded_view) {
|
||||
var def = $.Deferred().then(this.on_loaded);
|
||||
var self = this;
|
||||
setTimeout(function() {def.resolve({fields_view: self.embedded_view});}, 0);
|
||||
setTimeout(function() {def.resolve(self.embedded_view);}, 0);
|
||||
return def.promise();
|
||||
} else {
|
||||
var context = new openerp.web.CompoundContext(this.dataset.get_context());
|
||||
return this.rpc("/web/formview/load", {"model": this.model, "view_id": this.view_id,
|
||||
toolbar: this.options.sidebar, context: context}, this.on_loaded);
|
||||
return this.rpc("/web/view/load", {
|
||||
"model": this.model,
|
||||
"view_id": this.view_id,
|
||||
"view_type": "form",
|
||||
toolbar: this.options.sidebar,
|
||||
context: context
|
||||
}, this.on_loaded);
|
||||
}
|
||||
},
|
||||
stop: function() {
|
||||
@@ -65,7 +71,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
var self = this;
|
||||
this.fields_view = data.fields_view;
|
||||
this.fields_view = data;
|
||||
var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch);
|
||||
|
||||
this.$element.html(QWeb.render(this.template, { 'frame': frame, 'view': this }));
|
||||
@@ -94,7 +100,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
this.sidebar.start();
|
||||
this.sidebar.do_unfold();
|
||||
this.sidebar.attachments = new openerp.web.form.SidebarAttachments(this.sidebar, this.sidebar.add_section('attachments', "Attachments"), this);
|
||||
this.sidebar.add_toolbar(data.fields_view.toolbar);
|
||||
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
||||
this.set_common_sidebar_sections(this.sidebar);
|
||||
}
|
||||
this.has_been_loaded.resolve();
|
||||
@@ -450,6 +456,34 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
return id ? [id] : [];
|
||||
}
|
||||
});
|
||||
openerp.web.FormDialog = openerp.web.Dialog.extend({
|
||||
init: function(parent, options, view_id, dataset) {
|
||||
this._super(parent, options);
|
||||
this.dataset = dataset;
|
||||
this.view_id = view_id;
|
||||
return this;
|
||||
},
|
||||
start: function() {
|
||||
this._super();
|
||||
this.form = new openerp.web.FormView(this, this.element_id, this.dataset, this.view_id, {
|
||||
sidebar: false,
|
||||
pager: false
|
||||
});
|
||||
this.form.start();
|
||||
this.form.on_created.add_last(this.on_form_dialog_saved);
|
||||
this.form.on_saved.add_last(this.on_form_dialog_saved);
|
||||
return this;
|
||||
},
|
||||
load_id: function(id) {
|
||||
var self = this;
|
||||
return this.dataset.read_ids([id], _.keys(this.form.fields_view.fields), function(records) {
|
||||
self.form.on_record_loaded(records[0]);
|
||||
});
|
||||
},
|
||||
on_form_dialog_saved: function() {
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
|
||||
/** @namespace */
|
||||
openerp.web.form = {};
|
||||
@@ -1217,11 +1251,16 @@ openerp.web.form.FieldTextXml = openerp.web.form.Field.extend({
|
||||
|
||||
openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
|
||||
init: function(view, node) {
|
||||
var self = this;
|
||||
this._super(view, node);
|
||||
this.template = "FieldSelection";
|
||||
this.field_index = _.map(this.field.selection, function(x, index) {
|
||||
return {"ikey": "" + index, "ekey": x[0], "label": x[1]};
|
||||
this.values = this.field.selection;
|
||||
_.each(this.values, function(v, i) {
|
||||
if (v[0] === false && v[1] === '') {
|
||||
self.values.splice(i, 1);
|
||||
}
|
||||
});
|
||||
this.values.unshift([false, '']);
|
||||
},
|
||||
start: function() {
|
||||
// Flag indicating whether we're in an event chain containing a change
|
||||
@@ -1251,13 +1290,14 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
|
||||
value = value === null ? false : value;
|
||||
value = value instanceof Array ? value[0] : value;
|
||||
this._super(value);
|
||||
var option = _.detect(this.field_index, function(x) {return x.ekey === value;});
|
||||
this.$element.find('select').val(option === undefined ? '' : option.ikey);
|
||||
var index = 0;
|
||||
for (var i = 0, ii = this.values.length; i < ii; i++) {
|
||||
if (this.values[i][0] === value) index = i;
|
||||
}
|
||||
this.$element.find('select')[0].selectedIndex = index;
|
||||
},
|
||||
set_value_from_ui: function() {
|
||||
var ikey = this.$element.find('select').val();
|
||||
var option = _.detect(this.field_index, function(x) {return x.ikey === ikey;});
|
||||
this.value = option === undefined ? false : option.ekey;
|
||||
this.value = this.values[this.$element.find('select')[0].selectedIndex][0];
|
||||
this._super();
|
||||
},
|
||||
update_dom: function() {
|
||||
@@ -1265,9 +1305,8 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
|
||||
this.$element.find('select').attr('disabled', this.readonly);
|
||||
},
|
||||
validate: function() {
|
||||
var ikey = this.$element.find('select').val();
|
||||
var option = _.detect(this.field_index, function(x) {return x.ikey === ikey;});
|
||||
this.invalid = this.required && (option === undefined || option.ekey === false);
|
||||
var value = this.values[this.$element.find('select')[0].selectedIndex];
|
||||
this.invalid = !(value && !(this.required && value[0] === false));
|
||||
},
|
||||
focus: function() {
|
||||
this.$element.find('select').focus();
|
||||
|
||||
@@ -74,7 +74,7 @@ openerp.web.list_editable = function (openerp) {
|
||||
},
|
||||
on_loaded: function (data, grouped) {
|
||||
// tree/@editable takes priority on everything else if present.
|
||||
this.options.editable = data.fields_view.arch.attrs.editable || this.options.editable;
|
||||
this.options.editable = data.arch.attrs.editable || this.options.editable;
|
||||
return this._super(data, grouped);
|
||||
}
|
||||
});
|
||||
@@ -183,7 +183,7 @@ openerp.web.list_editable = function (openerp) {
|
||||
template: 'ListView.row.form',
|
||||
registry: openerp.web.list.form.widgets
|
||||
});
|
||||
$.when(self.edition_form.on_loaded({fields_view: self.get_form_fields_view()})).then(function () {
|
||||
$.when(self.edition_form.on_loaded(self.get_form_fields_view())).then(function () {
|
||||
// put in $.when just in case FormView.on_loaded becomes asynchronous
|
||||
$new_row.find('td')
|
||||
.addClass('oe-field-cell')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
openerp.web.list = function (openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
openerp.web.views.add('list', 'openerp.web.ListView');
|
||||
openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# */ {
|
||||
defaults: {
|
||||
@@ -147,7 +148,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||
*/
|
||||
on_loaded: function(data, grouped) {
|
||||
var self = this;
|
||||
this.fields_view = data.fields_view;
|
||||
this.fields_view = data;
|
||||
//this.log(this.fields_view);
|
||||
this.name = "" + this.fields_view.arch.attrs.string;
|
||||
|
||||
@@ -218,7 +219,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||
if (!this.sidebar && this.options.sidebar && this.options.sidebar_id) {
|
||||
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
|
||||
this.sidebar.start();
|
||||
this.sidebar.add_toolbar(data.fields_view.toolbar);
|
||||
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
||||
this.set_common_sidebar_sections(this.sidebar);
|
||||
}
|
||||
},
|
||||
@@ -368,11 +369,12 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||
self.on_loaded(field_view_get, grouped);
|
||||
};
|
||||
if (this.embedded_view) {
|
||||
return $.Deferred().then(callback).resolve({fields_view: this.embedded_view});
|
||||
return $.Deferred().then(callback).resolve(this.embedded_view);
|
||||
} else {
|
||||
return this.rpc('/web/listview/load', {
|
||||
model: this.model,
|
||||
view_id: this.view_id,
|
||||
view_type: "tree",
|
||||
context: this.dataset.get_context(context),
|
||||
toolbar: this.options.sidebar
|
||||
}, callback);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
openerp.web.search = function(openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
|
||||
openerp.web.SearchView = openerp.web.Widget.extend({
|
||||
init: function(parent, element_id, dataset, view_id, defaults) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.web.view_tree = function(openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
|
||||
openerp.web.views.add('tree', 'openerp.web.TreeView');
|
||||
/**
|
||||
@@ -31,6 +32,7 @@ openerp.web.TreeView = openerp.web.View.extend({
|
||||
return this.rpc("/web/treeview/load", {
|
||||
model: this.model,
|
||||
view_id: this.view_id,
|
||||
view_type: "tree",
|
||||
toolbar: this.view_manager ? !!this.view_manager.sidebar : false
|
||||
}, this.on_loaded);
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
openerp.web.views = function(openerp) {
|
||||
|
||||
var _t = openerp.web._t;
|
||||
var QWeb = openerp.web.qweb;
|
||||
|
||||
/**
|
||||
* Registry for all the client actions key: tag value: widget
|
||||
@@ -125,11 +126,11 @@ openerp.web.ActionManager = openerp.web.Widget.extend({
|
||||
(this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
|
||||
},
|
||||
ir_actions_report_xml: function(action) {
|
||||
this.rpc('/web/report/get_report', {
|
||||
action: action,
|
||||
context: {}
|
||||
}).then(function(result) {
|
||||
debugger;
|
||||
$.blockUI();
|
||||
this.session.get_file({
|
||||
url: '/web/report',
|
||||
data: {action: JSON.stringify(action)},
|
||||
complete: $.unblockUI
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -443,7 +444,10 @@ openerp.web.Sidebar = openerp.web.Widget.extend({
|
||||
if (item.action) {
|
||||
var ids = self.widget_parent.get_selected_ids();
|
||||
if (ids.length == 0) {
|
||||
//TODO niv: maybe show a warning?
|
||||
$("<div />").text(_t("You must choose at least one record.")).dialog({
|
||||
title: _t("Warning"),
|
||||
modal: true
|
||||
});
|
||||
return false;
|
||||
}
|
||||
var additional_context = {
|
||||
@@ -453,7 +457,7 @@ openerp.web.Sidebar = openerp.web.Widget.extend({
|
||||
};
|
||||
self.rpc("/web/action/load", {
|
||||
action_id: item.action.id,
|
||||
context: _.extend({"bin_size": true}, additional_context)
|
||||
context: additional_context
|
||||
}, function(result) {
|
||||
result.result.context = _.extend(result.result.context || {},
|
||||
additional_context);
|
||||
|
||||
@@ -799,10 +799,8 @@
|
||||
t-att-id="widget.element_id + '_field'"
|
||||
t-att-class="'field_' + widget.type"
|
||||
style="width: 100%">
|
||||
<t t-foreach="widget.field_index" t-as="options">
|
||||
<option t-att-value="options.ikey">
|
||||
<t t-esc="options.label"/>
|
||||
</option>
|
||||
<t t-foreach="widget.values" t-as="option">
|
||||
<option><t t-esc="option[1]"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</t>
|
||||
@@ -1113,7 +1111,8 @@
|
||||
<div t-att-id="element_id">
|
||||
<select class="searchview_extended_prop_field">
|
||||
<t t-foreach="attrs.fields" t-as="field">
|
||||
<option t-att="{'selected': field === attrs.selected ? 'selected' : null}"
|
||||
<option t-if="typeof field.store === 'undefined' || field.store || field.fnct_search"
|
||||
t-att="{'selected': field === attrs.selected ? 'selected' : null}"
|
||||
t-att-value="field.name">
|
||||
<t t-esc="field.string"/>
|
||||
</option>
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
#!/usr/bin/python
|
||||
import controllers
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
import main
|
||||
@@ -1,11 +0,0 @@
|
||||
import web.common as openerpweb
|
||||
|
||||
from web.controllers.main import View
|
||||
|
||||
class CalendarView(View):
|
||||
_cp_path = "/web_calendar/calendarview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id, toolbar=False):
|
||||
fields_view = self.fields_view_get(req, model, view_id, 'calendar', toolbar=toolbar)
|
||||
return {'fields_view': fields_view}
|
||||
@@ -3,6 +3,7 @@
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.web_calendar = function(openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_calendar/static/src/xml/web_calendar.xml');
|
||||
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
|
||||
openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||
@@ -29,18 +30,18 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||
this.color_map = {};
|
||||
},
|
||||
start: function() {
|
||||
this.rpc("/web_calendar/calendarview/load", {"model": this.model, "view_id": this.view_id, 'toolbar': true}, this.on_loaded);
|
||||
this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type":"calendar", 'toolbar': true}, this.on_loaded);
|
||||
},
|
||||
stop: function() {
|
||||
scheduler.clearAll();
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
this.fields_view = data;
|
||||
this.calendar_fields = {};
|
||||
this.ids = this.dataset.ids;
|
||||
this.color_values = [];
|
||||
this.info_fields = [];
|
||||
|
||||
this.fields_view = data.fields_view;
|
||||
this.name = this.fields_view.name || this.fields_view.arch.attrs.string;
|
||||
this.view_id = this.fields_view.view_id;
|
||||
|
||||
@@ -79,7 +80,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||
this.sidebar.start();
|
||||
this.sidebar.navigator = new openerp.web_calendar.SidebarNavigator(this.sidebar, this.sidebar.add_section('navigator', "Navigator"), this);
|
||||
this.sidebar.responsible = new openerp.web_calendar.SidebarResponsible(this.sidebar, this.sidebar.add_section('responsible', "Responsible"), this);
|
||||
this.sidebar.add_toolbar(data.fields_view.toolbar);
|
||||
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
||||
this.set_common_sidebar_sections(this.sidebar);
|
||||
this.sidebar.do_unfold();
|
||||
this.sidebar.do_fold.add_last(this.refresh_scheduler);
|
||||
|
||||
@@ -3,6 +3,9 @@ import time
|
||||
|
||||
import simplejson
|
||||
import web.common as openerpweb
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
#----------------------------------------------------------
|
||||
# OpenERP Web ajaxim Controllers
|
||||
@@ -195,7 +198,7 @@ class PollServer(openerpweb.Controller):
|
||||
"""
|
||||
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
|
||||
|
||||
print "======== chat status ========",kw
|
||||
_logger.debug("======== chat status ======== %s", kw)
|
||||
# mq.write()
|
||||
return {"action": ""}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
openerp.web_dashboard = function(openerp) {
|
||||
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
|
||||
|
||||
openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
openerp.web_default_home = function (openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_default_home/static/src/xml/web_default_home.xml');
|
||||
|
||||
openerp.web_default_home = {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.web_diagram = function (openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_diagram/static/src/xml/base_diagram.xml');
|
||||
openerp.web.views.add('diagram', 'openerp.web.DiagramView');
|
||||
openerp.web.DiagramView = openerp.web.View.extend({
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
#!/usr/bin/python
|
||||
import controllers
|
||||
@@ -1 +0,0 @@
|
||||
import main
|
||||
@@ -1,11 +0,0 @@
|
||||
import web.common as openerpweb
|
||||
from web.controllers.main import View
|
||||
|
||||
class GanttView(View):
|
||||
_cp_path = "/web_gantt/ganttview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id):
|
||||
fields_view = self.fields_view_get(req, model, view_id, 'gantt')
|
||||
return {'fields_view':fields_view}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* OpenERP web_gantt
|
||||
*---------------------------------------------------------*/
|
||||
openerp.web_gantt = function (openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_gantt/static/src/xml/web_gantt.xml');
|
||||
openerp.web.views.add('gantt', 'openerp.web_gantt.GanttView');
|
||||
openerp.web_gantt.GanttView = openerp.web.View.extend({
|
||||
@@ -31,14 +32,13 @@ init: function(parent, element_id, dataset, view_id) {
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this.rpc("/web_gantt/ganttview/load",
|
||||
{"model": this.model, "view_id": this.view_id}, this.on_loaded);
|
||||
this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "gantt"}, this.on_loaded);
|
||||
},
|
||||
|
||||
on_loaded: function(data) {
|
||||
|
||||
var self = this;
|
||||
this.fields_view = data.fields_view;
|
||||
this.fields_view = data;
|
||||
|
||||
this.name = this.fields_view.arch.attrs.string;
|
||||
this.view_id = this.fields_view.view_id;
|
||||
|
||||
@@ -12,6 +12,7 @@ var COLOR_PALETTE = [
|
||||
'#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f', '#f57900',
|
||||
'#cc0000', '#d400a8'];
|
||||
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_graph/static/src/xml/web_graph.xml');
|
||||
openerp.web.views.add('graph', 'openerp.web_graph.GraphView');
|
||||
openerp.web_graph.GraphView = openerp.web.View.extend({
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
import controllers
|
||||
@@ -1 +0,0 @@
|
||||
import main
|
||||
@@ -1,11 +0,0 @@
|
||||
import web.common as openerpweb
|
||||
|
||||
from web.controllers.main import View
|
||||
|
||||
class KanbanView(View):
|
||||
_cp_path = "/web_kanban/kanbanview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id):
|
||||
fields_view = self.fields_view_get(req, model, view_id, 'kanban')
|
||||
return {'fields_view': fields_view}
|
||||
@@ -1,5 +1,6 @@
|
||||
openerp.web_kanban = function (openerp) {
|
||||
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_kanban/static/src/xml/web_kanban.xml');
|
||||
openerp.web.views.add('kanban', 'openerp.web_kanban.KanbanView');
|
||||
openerp.web_kanban.KanbanView = openerp.web.View.extend({
|
||||
@@ -17,14 +18,16 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
|
||||
this.all_display_data = false;
|
||||
this.groups = [];
|
||||
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();
|
||||
}
|
||||
},
|
||||
start: function() {
|
||||
return this.rpc("/web_kanban/kanbanview/load",
|
||||
{"model": this.model, "view_id": this.view_id}, this.on_loaded);
|
||||
return this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "kanban"}, this.on_loaded);
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
var self = this;
|
||||
this.fields_view = data.fields_view;
|
||||
this.fields_view = data;
|
||||
this.add_qweb_template();
|
||||
if (this.qweb.has_template('kanban-box')) {
|
||||
self.dataset.read_slice(_.keys(self.fields_view.fields), {
|
||||
@@ -42,13 +45,27 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
|
||||
var child = this.fields_view.arch.children[i];
|
||||
if (child.tag === "templates") {
|
||||
this.transform_qweb_template(child);
|
||||
this.qweb.add_template(openerp.web.json_node_to_xml(child, true));
|
||||
this.qweb.add_template(openerp.web.json_node_to_xml(child));
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
do_get_kanban_color: function(variable) {
|
||||
return 'oe_kanban_color_1';
|
||||
var number_of_color_schemes = 2,
|
||||
index = 0;
|
||||
switch (typeof(variable)) {
|
||||
case 'string':
|
||||
for (var i=0, ii=variable.length; i<ii; i++) {
|
||||
index += variable.charCodeAt(i);
|
||||
}
|
||||
break;
|
||||
case 'number':
|
||||
index = Math.round(variable);
|
||||
break;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
return 'oe_kanban_color_' + ((index % number_of_color_schemes) + 1);
|
||||
},
|
||||
transform_qweb_template: function(node) {
|
||||
switch (node.tag) {
|
||||
@@ -143,25 +160,20 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
|
||||
}
|
||||
},
|
||||
on_confirm_click: function (dataset, button_attrs, index, record_id) {
|
||||
if (button_attrs.type == 'edit') {
|
||||
this.do_edit_record(dataset, index);
|
||||
this.on_execute_button_click(dataset, button_attrs, record_id);
|
||||
},
|
||||
do_add_record: function() {
|
||||
this.dataset.index = null;
|
||||
this.do_switch_view('form');
|
||||
},
|
||||
do_edit_record: function(record_id) {
|
||||
if (this.form_dialog) {
|
||||
this.form_dialog.load_id(record_id);
|
||||
this.form_dialog.open();
|
||||
} else {
|
||||
this.on_execute_button_click(dataset, button_attrs, record_id);
|
||||
this.notification.warn("Kanban", "No form view defined for this object");
|
||||
}
|
||||
},
|
||||
do_add_record: function () {
|
||||
this.do_edit_record(this.dataset, null);
|
||||
},
|
||||
do_edit_record: function (dataset, index) {
|
||||
var self = this;
|
||||
_.extend(this.dataset, {
|
||||
domain: dataset.domain,
|
||||
context: dataset.get_context()
|
||||
}).read_slice([], {}, function () {
|
||||
self.dataset.index = index;
|
||||
self.do_switch_view('form');
|
||||
});
|
||||
},
|
||||
do_delete: function (id) {
|
||||
var self = this;
|
||||
return $.when(this.dataset.unlink([id])).then(function () {
|
||||
@@ -297,24 +309,24 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
|
||||
self.all_display_data.splice(index, 1);
|
||||
}
|
||||
});
|
||||
this.$element.find('.oe_kanban_action').click(function() {
|
||||
var record_id = $(this).closest(".oe_kanban_record").attr("id");
|
||||
if (record_id) {
|
||||
record_id = parseInt(record_id.split("_")[1])
|
||||
if (record_id) {
|
||||
if ($(this).data("type") == "delete") {
|
||||
self.do_delete(record_id);
|
||||
} else {
|
||||
var button_attrs = $(this).data()
|
||||
self.on_button_click(button_attrs, record_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
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');
|
||||
});
|
||||
},
|
||||
on_action_clicked: function(evt) {
|
||||
var $action = $(evt.currentTarget),
|
||||
record_id = parseInt($action.closest(".oe_kanban_record").attr("id").split('_')[1]),
|
||||
type = $action.data('type');
|
||||
if (type == 'delete') {
|
||||
this.do_delete(record_id);
|
||||
} else if (type == 'edit') {
|
||||
this.do_edit_record(record_id);
|
||||
} else {
|
||||
var button_attrs = $(this).data();
|
||||
this.on_button_click(button_attrs, record_id);
|
||||
}
|
||||
},
|
||||
do_transform_record: function(record) {
|
||||
var self = this,
|
||||
new_record = {};
|
||||
|
||||
@@ -338,10 +338,10 @@ replace ``addons`` by the directory in which your own addon lives.
|
||||
Python
|
||||
++++++
|
||||
|
||||
.. autoclass:: base.common.backendrpc.OpenERPSession
|
||||
.. autoclass:: web.common.backendrpc.OpenERPSession
|
||||
:members:
|
||||
|
||||
.. autoclass:: base.common.backendrpc.OpenERPModel
|
||||
.. autoclass:: web.common.backendrpc.OpenERPModel
|
||||
:members:
|
||||
|
||||
* Addons lifecycle (loading, execution, events, ...)
|
||||
|
||||
@@ -391,14 +391,14 @@ Python
|
||||
These classes should be moved to other sections of the doc as needed,
|
||||
probably.
|
||||
|
||||
.. automodule:: base.common.dispatch
|
||||
.. automodule:: web.common.dispatch
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
See also: :class:`~base.common.backendrpc.OpenERPSession`,
|
||||
:class:`~base.common.backendrpc.OpenERPModel`
|
||||
See also: :class:`~web.common.backendrpc.OpenERPSession`,
|
||||
:class:`~web.common.backendrpc.OpenERPModel`
|
||||
|
||||
.. automodule:: base.controllers.main
|
||||
.. automodule:: web.controllers.main
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import optparse
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import logging
|
||||
import logging.config
|
||||
|
||||
import werkzeug.serving
|
||||
|
||||
@@ -31,6 +33,10 @@ optparser.add_option('--no-serve-static', dest='serve_static',
|
||||
optparser.add_option('--reloader', dest='reloader',
|
||||
default=False, action='store_true',
|
||||
help="Reload application when python files change")
|
||||
optparser.add_option("--log-level", dest="log_level",
|
||||
default='debug', help="Log level", metavar="LOG_LEVEL")
|
||||
optparser.add_option("--log-config", dest="log_config",
|
||||
default='', help="Log config file", metavar="LOG_CONFIG")
|
||||
|
||||
import web.common.dispatch
|
||||
|
||||
@@ -38,6 +44,12 @@ if __name__ == "__main__":
|
||||
(options, args) = optparser.parse_args(sys.argv[1:])
|
||||
|
||||
os.environ["TZ"] = "UTC"
|
||||
|
||||
if not options.log_config:
|
||||
logging.basicConfig(level=getattr(logging, options.log_level.upper()))
|
||||
else:
|
||||
logging.config.fileConfig(options.log_config)
|
||||
|
||||
app = web.common.dispatch.Root(options)
|
||||
|
||||
werkzeug.serving.run_simple(
|
||||
|
||||
Reference in New Issue
Block a user