Reviewers: ,
Please review this at http://codereview.tryton.org/777004/
Affected files:
M Gruntfile.js
M src/common.js
M src/model.js
M src/screen.js
M src/view.js
A src/window.js
Index: Gruntfile.js
===================================================================
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -15,7 +15,8 @@
'src/screen.js',
'src/view.js',
'src/action.js',
- 'src/common.js'
+ 'src/common.js',
+ 'src/window.js'
],
dest: 'dist/<%= pkg.name %>.js'
}
Index: src/common.js
===================================================================
--- a/src/common.js
+++ b/src/common.js
@@ -1,5 +1,15 @@
/* This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. */
+
+var FLOAT_TIME_CONV = {
+ 'Y': 8760,
+ 'M': 672,
+ 'w': 168,
+ 'd': 24,
+ 'h': 1,
+ 'm': 1.0 / 60
+};
+
(function() {
'use strict';
@@ -53,6 +63,50 @@
return text;
};
+ Sao.common.float_time_to_text = function(val, conv) {
+ var value = "";
+ if (val === null) return value;
+
+ if (conv) {
+ var tmp_conv = jQuery.extend({}, FLOAT_TIME_CONV);
+ jQuery.extend(tmp_conv, conv);
+ conv = tmp_conv;
+ } else {
+ conv = FLOAT_TIME_CONV;
+ }
+
+ if (val < 0) value += "-";
+ val = Math.abs(val);
+ var years = Math.floor(val / conv.Y);
+ val -= years * conv.Y;
+ var months = Math.floor(val / conv.M);
+ val -= months * conv.M;
+ var weeks = Math.floor(val / conv.w);
+ val -= weeks * conv.w;
+ var days = Math.floor(val / conv.d);
+ val -= days * conv.d;
+ var hours = Math.floor(val);
+ val -= hours;
+ var mins = Math.floor((val % 1 + 0.01) / conv.m);
+ //TODO Localization
+ if (years)
+ value += " " + years + "Y";
+ if (months)
+ value += " " + months + "M";
+ if (weeks)
+ value += " " + weeks + "w";
+ if (days)
+ value += " " + days + "d";
+ if (hours || mins || !value) {
+ mins = mins.toFixed();
+ value += (" " +
+ hours.toString().length < 2 ? "0" + hours.toString() :
hours.toString() +
+ ":" +
+ mins.toString().length < 2 ? "0" + mins.toString() :
mins.toString());
+ }
+ return jQuery.trim(value);
+ };
+
Sao.common.EvalEnvironment = function(parent_, eval_type) {
if (eval_type === undefined)
eval_type = 'eval';
Index: src/model.js
===================================================================
--- a/src/model.js
+++ b/src/model.js
@@ -875,7 +875,7 @@
},
get_client: function(record) {
var rec_name = record._values[this.name + '.rec_name'];
- if (rec_name === undefined) {
+ if (!rec_name) {
this.set(record, this.get(record));
rec_name = record._values[this.name + '.rec_name'] || '';
}
@@ -886,20 +886,24 @@
// TODO force parent
var store_rec_name = function(rec_name) {
record._values[this.name + '.rec_name'] = rec_name[0].rec_name;
+ return rec_name[0].rec_name;
};
+ var prm;
if (!rec_name && (value >= 0) && (value !== null)) {
var model_name = record.model.fields[this.name].description
.relation;
- var prm = Sao.rpc({
+ prm = Sao.rpc({
'method': 'model.' + model_name + '.' + 'read',
'params': [[value], ['rec_name'], record.get_context()]
}, record.model.session);
prm.done(store_rec_name.bind(this));
} else {
store_rec_name.call(this, [{'rec_name': rec_name}]);
+ prm = jQuery.when(rec_name);
}
record._values[this.name] = value;
// TODO force parent
+ return prm;
},
set_client: function(record, value) {
var rec_name;
Index: src/screen.js
===================================================================
--- a/src/screen.js
+++ b/src/screen.js
@@ -66,10 +66,6 @@
this.content_box.append(widget);
}
});
-}());
-
-(function() {
- 'use strict';
Sao.Screen = Sao.class_(Object, {
init: function(model_name, attributes) {
@@ -95,6 +91,10 @@
} else {
this.row_activate = attributes.row_activate;
}
+ //if (!jQuery.isEmptyObject(this.view_ids) ||
+ //!jQuery.isEmptyObject(this.view_to_load)) {
+ //this.switch_view();
+ //}
},
load_next_view: function() {
if (this.view_to_load) {
@@ -200,9 +200,18 @@
}
group.screens.push(this);
this.group = group;
+ if (jQuery.isEmptyObject(group)) {
+ this.current_record = null;
+ } else {
+ this.current_record = group[0];
+ }
},
- new_group: function() {
- this.set_group(new Sao.Group(this.model, this.context, []));
+ new_group: function(ids) {
+ var group = new Sao.Group(this.model, this.context, []);
+ if (ids) {
+ group.load(ids);
+ }
+ this.set_group(group);
},
display: function() {
if (this.views) {
Index: src/view.js
===================================================================
--- a/src/view.js
+++ b/src/view.js
@@ -850,6 +850,8 @@
return Sao.View.Form.Boolean;
case 'text':
return Sao.View.Form.Text;
+ case 'many2one':
+ return Sao.View.Form.Many2One;
}
};
@@ -1097,4 +1099,122 @@
}
});
+ Sao.View.Form.Many2One = Sao.class_(Sao.View.Form.Widget, {
+ class_: 'form-many2one',
+ init: function(field_name, model, attributes) {
+ Sao.View.Form.Many2One._super.init.call(this, field_name, model,
+ attributes);
+ this.el = jQuery('<div/>', {
+ 'class': this.class_
+ });
+ this.entry = jQuery('<input/>', {
+ 'type': 'input'
+ });
+ this.el.append(this.entry);
+ this.but_open = jQuery('<button/>').button({
+ 'icons': {
+ 'primary': "ui-icon-search"
+ },
+ 'text': false
+ });
+ this.but_open.click(this.sig_edit.bind(this));
+ this.el.append(this.but_open);
+ this.but_new = jQuery('<button/>').button({
+ 'icons': {
+ 'primary': "ui-icon-document"
+ },
+ 'text': false
+ });
+ this.but_new.click(this.sig_new.bind(this));
+ this.el.append(this.but_new);
+ this.model = attributes.relation;
+ // TODO autocompletion
+ },
+ get_screen: function() {
+ var domain = this.field().get_domain(this.record());
+ var context = this.field().get_context(this.record());
+ return new Sao.Screen(this.model, {
+ 'context': context,
+ 'domain': domain,
+ 'mode': ['form'],
+ 'view_ids': (this.attributes.view_ids || "").split(','),
+ 'views_preload': this.attributes.views
+ });
+ },
+ display: function(record, field) {
+ // TODO set_button_sensitive
+ var text_value, value;
+ Sao.View.Form.Many2One._super.display.call(this, record, field);
+ if (record) {
+ text_value = record.field_get_client(this.field_name);
+ value = record.field_get(this.field_name);
+ } else {
+ text_value = "";
+ value = null;
+ }
+ this.entry.val(text_value || '');
+ if ((value !== undefined) && (value !== null)) {
+ this.but_open.button({
+ 'icons': {
+ 'primary': "ui-icon-folder-open"
+ }});
+ } else {
+ this.but_open.button({
+ 'icons': {
+ 'primary': "ui-icon-search"
+ }});
+ }
+ },
+ id_from_value: function (value) {
+ return value;
+ },
+ get_model: function (value) {
+ return this.attributes.relation;
+ },
+ sig_edit: function(evt) {
+ // TODO Model Access
+ var win;
+ var value = this.record().field_get(this.field_name);
+ if (this.get_model() && (value !== undefined) && (value !== null))
{
+ var screen = this.get_screen();
+ var m2o_id =
this.id_from_value(this.record().field_get(this.field_name));
+ screen.new_group([m2o_id]);
+ var callback = function (evt, ui) {
+ this.record().field_set_client(this.field_name, value);
+ }.bind(this);
+ win = new Sao.WinForm(callback, screen); // TODO add
save_current
+ } else if (this.get_model()) {
+ var dom;
+ var domain = this.field().get_domain(this.record());
+ var context = this.field().get_context(this.record());
+ var text = this.entry.val();
+ if (text) {
+ dom = [["rec_name", "ilike", "%" + text + "%"]];
+ } else {
+ dom = domain;
+ }
+ var model = new Sao.Model(this.get_model());
+ var ids_prm = model.execute('search',
+ [dom, 0, Sao.config.limit, null], context);
+ ids_prm.done(function (ids) {
+ if (ids.length == 1) {
+ this.record().field_set_client(this.field_name,
+ this.id_from_value(ids[0]));
+ return;
+ }
+ var callback = function (evt, ui) {
+ this.record().field_set_client(this.field_name, value);
+ }.bind(this);
+ win = new Sao.WinSearch(callback, this.model, false, ids,
context,
+ domain, (this.attributes.view_ids || "").split(','),
+ (this.attributes.views || {}),
+ false); // TODO compute from but_new status
+ }.bind(this));
+ }
+ },
+ sig_new: function(evt) {
+ console.log('sig_new');
+ }
+ });
+
}());
Index: src/window.js
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/window.js
@@ -0,0 +1,80 @@
+/* This file is part of Tryton. The COPYRIGHT file at the top level of
+ this repository contains the full copyright notices and license terms. */
+(function() {
+ 'use strict';
+
+ Sao.WinForm = Sao.class_(Object, {
+ init: function(callback, screen, view_type, new_obj, many, domain,
+ context, save_current) {
+ this.screen = screen;
+ if (!view_type) {
+ view_type = 'form';
+ }
+ var screen_views = [];
+ for (var i=0,len=this.screen.views; i<len; i++) {
+ screen_views.push(this.screen.views[i].view_type);
+ }
+ if (screen_views.indexOf(view_type) == -1 &&
+ this.screen.view_to_load.indexOf(view_type) == -1) {
+ this.screen.add_view_id(null, view_type);
+ }
+ var switch_prm = this.screen.switch_view(view_type);
+ this.many = many || 0;
+ this.domain = domain || null;
+ this.context = context || null;
+ this.save_current = save_current;
+ this.prev_view = screen.current_view;
+ this.el = jQuery('<div/>');
+
+ if (view_type == "tree") {
+ // TODO
+ }
+
+ switch_prm.done(function () {
+ this.el.dialog({
+ autoOpen: false,
+ buttons: [],
+ title: '' // this.screen.current_view
+ });
+ this.el.bind('dialogclose', callback);
+ this.el.append(this.screen.screen_container.content_box);
+ this.el.dialog('open');
+ this.screen.display();
+ }.bind(this));
+
+ }
+ });
+
+ Sao.WinSearch = Sao.class_(Object, {
+ init: function(callback, model, sel_multi, ids, context, domain,
view_ids,
+ views_preload, new_) {
+ views_preload = views_preload || {};
+ this.domain = domain || [];
+ this.context = context || {};
+ this.sel_multi = sel_multi;
+
+ this.el = jQuery('<div/>');
+ this.el.dialog({
+ autoOpen: false,
+ buttons: []
+ });
+ this.screen = new Sao.Screen(model, {
+ mode: ['tree'],
+ context: context,
+ view_ids: view_ids
+ });
+ this.el.bind('dialogclose', callback);
+ if (!jQuery.isEmptyObject(ids)) {
+ this.screen.new_group(ids);
+ }
+ this.screen.load_next_view().done(function() {
+ this.screen.switch_view().done(function () {
+ this.el.append(this.screen.screen_container.el);
+ this.el.dialog('open');
+ this.screen.display();
+ }.bind(this));
+ }.bind(this));
+ }
+ });
+
+}());