tryton-sao 7.8.10 → 7.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +10 -0
- package/dist/tryton-sao.css +8 -0
- package/dist/tryton-sao.js +109 -30
- package/package.json +1 -1
- package/src/common.js +29 -1
- package/src/rpc.js +5 -7
- package/src/sao.js +1 -1
- package/src/sao.less +8 -0
- package/src/screen.js +3 -0
- package/src/view/form.js +39 -13
- package/src/view/list_form.js +7 -0
- package/src/view/tree.js +8 -1
- package/src/window.js +3 -2
- package/src/wizard.js +14 -5
- package/tests/sao.js +34 -0
package/CHANGELOG
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
|
|
2
|
+
Version 7.8.12 - 2026-06-18
|
|
3
|
+
---------------------------
|
|
4
|
+
* Bug fixes (see mercurial logs for details)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Version 7.8.11 - 2026-06-02
|
|
8
|
+
---------------------------
|
|
9
|
+
* Bug fixes (see mercurial logs for details)
|
|
10
|
+
|
|
11
|
+
|
|
2
12
|
Version 7.8.10 - 2026-05-20
|
|
3
13
|
---------------------------
|
|
4
14
|
* Bug fixes (see mercurial logs for details)
|
package/dist/tryton-sao.css
CHANGED
|
@@ -9534,6 +9534,10 @@ html[theme="default"] .carousel-caption h6 {
|
|
|
9534
9534
|
margin-bottom: -25px;
|
|
9535
9535
|
width: 15px;
|
|
9536
9536
|
}
|
|
9537
|
+
#user-preferences ul.notification-menu {
|
|
9538
|
+
background-color: #fff;
|
|
9539
|
+
color: #333333;
|
|
9540
|
+
}
|
|
9537
9541
|
@media (min-width: 768px) {
|
|
9538
9542
|
#user-preferences ul.notification-menu {
|
|
9539
9543
|
width: 320px;
|
|
@@ -9546,6 +9550,7 @@ html[theme="default"] .carousel-caption h6 {
|
|
|
9546
9550
|
background-color: #bceaeb;
|
|
9547
9551
|
}
|
|
9548
9552
|
#user-preferences ul.notification-menu > li.notification-item > a {
|
|
9553
|
+
color: #333333;
|
|
9549
9554
|
display: flex;
|
|
9550
9555
|
padding: 3px 10px;
|
|
9551
9556
|
}
|
|
@@ -9572,6 +9577,9 @@ html[theme="default"] .carousel-caption h6 {
|
|
|
9572
9577
|
text-align: center;
|
|
9573
9578
|
background-color: #f5f5f5;
|
|
9574
9579
|
}
|
|
9580
|
+
#user-preferences ul.notification-menu > li.divider {
|
|
9581
|
+
background-color: #e5e5e5;
|
|
9582
|
+
}
|
|
9575
9583
|
.attachment-preview {
|
|
9576
9584
|
border-bottom: 1px solid #eeeeee;
|
|
9577
9585
|
display: flex;
|
package/dist/tryton-sao.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
/* eslint-disable no-redeclare */
|
|
5
5
|
var Sao = {
|
|
6
|
-
__version__: '7.8.
|
|
6
|
+
__version__: '7.8.12',
|
|
7
7
|
};
|
|
8
8
|
/* eslint-enable no-redeclare */
|
|
9
9
|
|
|
@@ -1450,11 +1450,6 @@ var Sao = {
|
|
|
1450
1450
|
};
|
|
1451
1451
|
|
|
1452
1452
|
var ajax_error = function(query, status_, error) {
|
|
1453
|
-
if (!process_exception) {
|
|
1454
|
-
console.debug(`RPC error calling ${args}: ${status_}: ${error}.`);
|
|
1455
|
-
dfd.reject();
|
|
1456
|
-
return;
|
|
1457
|
-
}
|
|
1458
1453
|
if (query.status == 503) {
|
|
1459
1454
|
this.retries++;
|
|
1460
1455
|
if (this.retries < 5) {
|
|
@@ -1480,8 +1475,7 @@ var Sao = {
|
|
|
1480
1475
|
}
|
|
1481
1476
|
return;
|
|
1482
1477
|
}
|
|
1483
|
-
}
|
|
1484
|
-
if (query.status == 401) {
|
|
1478
|
+
} else if (query.status == 401) {
|
|
1485
1479
|
//Try to relog
|
|
1486
1480
|
Sao.Session.renew(session).then(function() {
|
|
1487
1481
|
if (async) {
|
|
@@ -1491,6 +1485,10 @@ var Sao = {
|
|
|
1491
1485
|
dfd.resolve();
|
|
1492
1486
|
}
|
|
1493
1487
|
}, dfd.reject);
|
|
1488
|
+
} else if (!process_exception) {
|
|
1489
|
+
console.debug(`RPC error calling ${args}: ${status_}: ${error}.`);
|
|
1490
|
+
dfd.reject();
|
|
1491
|
+
return;
|
|
1494
1492
|
} else {
|
|
1495
1493
|
var err_msg = `[${query.status}] ${error}`;
|
|
1496
1494
|
Sao.common.message.run(
|
|
@@ -4942,7 +4940,9 @@ var Sao = {
|
|
|
4942
4940
|
};
|
|
4943
4941
|
|
|
4944
4942
|
var complete_datetime = function() {
|
|
4945
|
-
return [Sao.Date(), Sao.DateTime(
|
|
4943
|
+
return [Sao.Date(), Sao.DateTime(
|
|
4944
|
+
undefined, undefined, undefined,
|
|
4945
|
+
0, 0, 0, 0, true)];
|
|
4946
4946
|
};
|
|
4947
4947
|
|
|
4948
4948
|
var complete_date = function() {
|
|
@@ -5249,6 +5249,32 @@ var Sao = {
|
|
|
5249
5249
|
]);
|
|
5250
5250
|
return;
|
|
5251
5251
|
}
|
|
5252
|
+
if ((typeof value == 'string') &&
|
|
5253
|
+
['datetime', 'timestamp'].includes(field.type) &&
|
|
5254
|
+
(operator == '=')) {
|
|
5255
|
+
let ctx, format_, parsed_date;
|
|
5256
|
+
if (this.context && Object.keys(this.context).length) {
|
|
5257
|
+
ctx = this.context;
|
|
5258
|
+
} else {
|
|
5259
|
+
ctx = {};
|
|
5260
|
+
}
|
|
5261
|
+
format_ = Sao.common.date_format(ctx.date_format);
|
|
5262
|
+
parsed_date = Sao.common.parse_date(format_, value);
|
|
5263
|
+
if (parsed_date &&
|
|
5264
|
+
(Sao.common.format_date(format_, parsed_date) == value)) {
|
|
5265
|
+
let date = Sao.DateTime.combine(parsed_date, Sao.Time());
|
|
5266
|
+
let next_day = Sao.DateTime(
|
|
5267
|
+
date.year(), date.month(), date.date(),
|
|
5268
|
+
date.hour(), date.minute(), date.second(),
|
|
5269
|
+
date.millisecond())
|
|
5270
|
+
next_day.add(1, 'day');
|
|
5271
|
+
result.push(this._clausify([
|
|
5272
|
+
[field_name, '>=', date],
|
|
5273
|
+
[field_name, '<', next_day]
|
|
5274
|
+
]));
|
|
5275
|
+
return;
|
|
5276
|
+
}
|
|
5277
|
+
}
|
|
5252
5278
|
}
|
|
5253
5279
|
if (['many2one', 'one2many', 'many2many', 'one2one',
|
|
5254
5280
|
'many2many', 'one2one'].includes(field.type) && value) {
|
|
@@ -13966,6 +13992,9 @@ var Sao = {
|
|
|
13966
13992
|
});
|
|
13967
13993
|
},
|
|
13968
13994
|
get current_record() {
|
|
13995
|
+
if (this.__current_record && this.__current_record.destroyed) {
|
|
13996
|
+
this.__current_record = null;
|
|
13997
|
+
}
|
|
13969
13998
|
return this.__current_record;
|
|
13970
13999
|
},
|
|
13971
14000
|
set current_record(record) {
|
|
@@ -15539,11 +15568,12 @@ function eval_pyson(value){
|
|
|
15539
15568
|
});
|
|
15540
15569
|
for (const e of fields) {
|
|
15541
15570
|
const name = e[0];
|
|
15542
|
-
|
|
15571
|
+
if (!record.is_loaded(name)) {
|
|
15572
|
+
promesses.push(record.load(name));
|
|
15573
|
+
}
|
|
15543
15574
|
}
|
|
15544
15575
|
}
|
|
15545
|
-
|
|
15546
|
-
.then(() => {
|
|
15576
|
+
let display = function() {
|
|
15547
15577
|
let promesses = [];
|
|
15548
15578
|
var record = this.record;
|
|
15549
15579
|
for (const name in this.widgets) {
|
|
@@ -15581,7 +15611,13 @@ function eval_pyson(value){
|
|
|
15581
15611
|
container.set_grid_template();
|
|
15582
15612
|
}
|
|
15583
15613
|
});
|
|
15584
|
-
});
|
|
15614
|
+
}.bind(this);
|
|
15615
|
+
if (promesses.length) {
|
|
15616
|
+
return jQuery.when.apply(jQuery, promesses).then(
|
|
15617
|
+
() => display());
|
|
15618
|
+
} else {
|
|
15619
|
+
return display();
|
|
15620
|
+
}
|
|
15585
15621
|
},
|
|
15586
15622
|
set_value: function() {
|
|
15587
15623
|
var record = this.record;
|
|
@@ -18677,7 +18713,11 @@ function eval_pyson(value){
|
|
|
18677
18713
|
},
|
|
18678
18714
|
set_readonly: function(readonly) {
|
|
18679
18715
|
Sao.View.Form.One2Many._super.set_readonly.call(this, readonly);
|
|
18680
|
-
this.prm.
|
|
18716
|
+
if (this.prm.state() == 'pending') {
|
|
18717
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
18718
|
+
} else {
|
|
18719
|
+
this._set_button_sensitive();
|
|
18720
|
+
}
|
|
18681
18721
|
this._set_label_state();
|
|
18682
18722
|
},
|
|
18683
18723
|
set_required: function(required) {
|
|
@@ -18790,7 +18830,7 @@ function eval_pyson(value){
|
|
|
18790
18830
|
display: function() {
|
|
18791
18831
|
Sao.View.Form.One2Many._super.display.call(this);
|
|
18792
18832
|
|
|
18793
|
-
|
|
18833
|
+
let display = function() {
|
|
18794
18834
|
this._set_button_sensitive();
|
|
18795
18835
|
|
|
18796
18836
|
var record = this.record;
|
|
@@ -18837,7 +18877,13 @@ function eval_pyson(value){
|
|
|
18837
18877
|
.css('max-height', this.attributes.height + 'px');
|
|
18838
18878
|
}
|
|
18839
18879
|
return this.screen.display();
|
|
18840
|
-
});
|
|
18880
|
+
}.bind(this);
|
|
18881
|
+
|
|
18882
|
+
if (this.prm.state() == 'pending') {
|
|
18883
|
+
return this.prm.then(() => display());
|
|
18884
|
+
} else {
|
|
18885
|
+
return display();
|
|
18886
|
+
}
|
|
18841
18887
|
},
|
|
18842
18888
|
focus: function() {
|
|
18843
18889
|
if (this.attributes.add_remove) {
|
|
@@ -19114,7 +19160,11 @@ function eval_pyson(value){
|
|
|
19114
19160
|
}
|
|
19115
19161
|
var message = name + ' / ' + Sao.common.humanize(size);
|
|
19116
19162
|
this.label.text(message).attr('title', message);
|
|
19117
|
-
this.prm.
|
|
19163
|
+
if (this.prm.state() == 'pending') {
|
|
19164
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
19165
|
+
} else {
|
|
19166
|
+
this._set_button_sensitive();
|
|
19167
|
+
}
|
|
19118
19168
|
},
|
|
19119
19169
|
validate: function() {
|
|
19120
19170
|
var prm = jQuery.Deferred();
|
|
@@ -19123,9 +19173,8 @@ function eval_pyson(value){
|
|
|
19123
19173
|
if (record) {
|
|
19124
19174
|
var fields = this.screen.current_view.get_fields();
|
|
19125
19175
|
if (!record.validate(fields)) {
|
|
19126
|
-
this.screen.display(true);
|
|
19127
|
-
prm
|
|
19128
|
-
return;
|
|
19176
|
+
this.screen.display(true).always(() => prm.reject());
|
|
19177
|
+
return prm;
|
|
19129
19178
|
}
|
|
19130
19179
|
if (this.screen.pre_validate) {
|
|
19131
19180
|
return record.pre_validate().then(
|
|
@@ -19370,7 +19419,7 @@ function eval_pyson(value){
|
|
|
19370
19419
|
display: function() {
|
|
19371
19420
|
Sao.View.Form.Many2Many._super.display.call(this);
|
|
19372
19421
|
|
|
19373
|
-
|
|
19422
|
+
let display = function() {
|
|
19374
19423
|
var record = this.record;
|
|
19375
19424
|
var field = this.field;
|
|
19376
19425
|
|
|
@@ -19392,7 +19441,13 @@ function eval_pyson(value){
|
|
|
19392
19441
|
.css('max-height', this.attributes.height + 'px');
|
|
19393
19442
|
}
|
|
19394
19443
|
return this.screen.display();
|
|
19395
|
-
});
|
|
19444
|
+
}.bind(this);
|
|
19445
|
+
|
|
19446
|
+
if (this.prm.state() == 'pending') {
|
|
19447
|
+
return this.prm.then(() => display());
|
|
19448
|
+
} else {
|
|
19449
|
+
return display();
|
|
19450
|
+
}
|
|
19396
19451
|
},
|
|
19397
19452
|
focus: function() {
|
|
19398
19453
|
this.entry.focus();
|
|
@@ -22616,6 +22671,13 @@ function eval_pyson(value){
|
|
|
22616
22671
|
this.display_size = this.group.length;
|
|
22617
22672
|
this.display();
|
|
22618
22673
|
}
|
|
22674
|
+
if (reset_view) {
|
|
22675
|
+
let current_path = this.record.get_path(this.group);
|
|
22676
|
+
current_path = current_path.map(function(e) {
|
|
22677
|
+
return e[1];
|
|
22678
|
+
});
|
|
22679
|
+
this.display([current_path]);
|
|
22680
|
+
}
|
|
22619
22681
|
if (path.length > 1) {
|
|
22620
22682
|
prm = this.rows[path[0]].expand_to_path(
|
|
22621
22683
|
path.slice(1),
|
|
@@ -23850,7 +23912,7 @@ function eval_pyson(value){
|
|
|
23850
23912
|
fields, false, false)) {
|
|
23851
23913
|
var value = cell.prop('checked');
|
|
23852
23914
|
this.field.set_client(record, value);
|
|
23853
|
-
if (record !== current_record) {
|
|
23915
|
+
if ((!this.group.parent) & (record !== current_record)) {
|
|
23854
23916
|
// we can not rely on editable tree handler to save the row
|
|
23855
23917
|
record.save();
|
|
23856
23918
|
}
|
|
@@ -25401,6 +25463,7 @@ function eval_pyson(value){
|
|
|
25401
25463
|
},
|
|
25402
25464
|
button_clicked: function(event) {
|
|
25403
25465
|
if (Sao.common.compare(this.screen.selected_records, [this.record])) {
|
|
25466
|
+
event.stopPropagation();
|
|
25404
25467
|
Sao.View.ListGroupViewForm._super.button_clicked.call(this, event);
|
|
25405
25468
|
}
|
|
25406
25469
|
}
|
|
@@ -25503,6 +25566,12 @@ function eval_pyson(value){
|
|
|
25503
25566
|
return this.group.slice();
|
|
25504
25567
|
},
|
|
25505
25568
|
set_cursor: function(new_, reset_view) {
|
|
25569
|
+
if (!this.record) {
|
|
25570
|
+
return;
|
|
25571
|
+
}
|
|
25572
|
+
if (reset_view) {
|
|
25573
|
+
this.display([this.record.id]);
|
|
25574
|
+
}
|
|
25506
25575
|
if (new_) {
|
|
25507
25576
|
this.el.animate({
|
|
25508
25577
|
scrollTop: this.el[0].scrollHeight
|
|
@@ -28519,15 +28588,16 @@ function eval_pyson(value){
|
|
|
28519
28588
|
},
|
|
28520
28589
|
_fill_with: function(template) {
|
|
28521
28590
|
var prm;
|
|
28591
|
+
let context = this.record.get_context();
|
|
28522
28592
|
if (template) {
|
|
28523
28593
|
prm = Sao.rpc({
|
|
28524
28594
|
'method': 'model.ir.email.template.get',
|
|
28525
|
-
'params': [template, this.record.id,
|
|
28595
|
+
'params': [template, this.record.id, context],
|
|
28526
28596
|
}, this.record.model.session);
|
|
28527
28597
|
} else {
|
|
28528
28598
|
prm = Sao.rpc({
|
|
28529
28599
|
'method': 'model.ir.email.template.get_default',
|
|
28530
|
-
'params': [this.record.model.name, this.record.id,
|
|
28600
|
+
'params': [this.record.model.name, this.record.id, context],
|
|
28531
28601
|
}, this.record.model.session);
|
|
28532
28602
|
}
|
|
28533
28603
|
prm.then(values => {
|
|
@@ -28775,6 +28845,7 @@ function eval_pyson(value){
|
|
|
28775
28845
|
if (this.__processing || this.__waiting_response) {
|
|
28776
28846
|
return jQuery.when();
|
|
28777
28847
|
}
|
|
28848
|
+
this.__processing = true;
|
|
28778
28849
|
var process = function() {
|
|
28779
28850
|
if (this.state == this.end_state) {
|
|
28780
28851
|
return this.end();
|
|
@@ -28833,8 +28904,8 @@ function eval_pyson(value){
|
|
|
28833
28904
|
} else {
|
|
28834
28905
|
prms.push(execute_actions());
|
|
28835
28906
|
}
|
|
28836
|
-
|
|
28837
|
-
|
|
28907
|
+
return jQuery.when.apply(jQuery, prms).then(
|
|
28908
|
+
() => this.__processing = false);
|
|
28838
28909
|
}, result => {
|
|
28839
28910
|
if (!result || !this.screen) {
|
|
28840
28911
|
this.state = this.end_state;
|
|
@@ -28957,11 +29028,14 @@ function eval_pyson(value){
|
|
|
28957
29028
|
this.footer.empty();
|
|
28958
29029
|
},
|
|
28959
29030
|
_get_button: function(definition) {
|
|
29031
|
+
let state = this.state;
|
|
28960
29032
|
var button = Sao.Wizard.Form._super._get_button.call(this,
|
|
28961
29033
|
definition);
|
|
28962
29034
|
this.footer.append(button.el);
|
|
28963
29035
|
button.el.click(() => {
|
|
28964
|
-
this.
|
|
29036
|
+
if (this.state === state) {
|
|
29037
|
+
this.response(definition);
|
|
29038
|
+
}
|
|
28965
29039
|
});
|
|
28966
29040
|
return button;
|
|
28967
29041
|
},
|
|
@@ -29009,19 +29083,24 @@ function eval_pyson(value){
|
|
|
29009
29083
|
this.footer.empty();
|
|
29010
29084
|
},
|
|
29011
29085
|
_get_button: function(definition) {
|
|
29086
|
+
let state = this.state;
|
|
29012
29087
|
var button = Sao.Wizard.Dialog._super._get_button.call(this,
|
|
29013
29088
|
definition);
|
|
29014
29089
|
this.footer.append(button.el);
|
|
29015
29090
|
if (definition['default']) {
|
|
29016
29091
|
this.content.unbind('submit');
|
|
29017
29092
|
this.content.submit(e => {
|
|
29018
|
-
this.response(definition);
|
|
29019
29093
|
e.preventDefault();
|
|
29094
|
+
if (this.state === state) {
|
|
29095
|
+
this.response(definition);
|
|
29096
|
+
}
|
|
29020
29097
|
});
|
|
29021
29098
|
button.el.attr('type', 'submit');
|
|
29022
29099
|
} else {
|
|
29023
29100
|
button.el.click(() => {
|
|
29024
|
-
this.
|
|
29101
|
+
if (this.state === state) {
|
|
29102
|
+
this.response(definition);
|
|
29103
|
+
}
|
|
29025
29104
|
});
|
|
29026
29105
|
}
|
|
29027
29106
|
return button;
|
package/package.json
CHANGED
package/src/common.js
CHANGED
|
@@ -1635,7 +1635,9 @@
|
|
|
1635
1635
|
};
|
|
1636
1636
|
|
|
1637
1637
|
var complete_datetime = function() {
|
|
1638
|
-
return [Sao.Date(), Sao.DateTime(
|
|
1638
|
+
return [Sao.Date(), Sao.DateTime(
|
|
1639
|
+
undefined, undefined, undefined,
|
|
1640
|
+
0, 0, 0, 0, true)];
|
|
1639
1641
|
};
|
|
1640
1642
|
|
|
1641
1643
|
var complete_date = function() {
|
|
@@ -1942,6 +1944,32 @@
|
|
|
1942
1944
|
]);
|
|
1943
1945
|
return;
|
|
1944
1946
|
}
|
|
1947
|
+
if ((typeof value == 'string') &&
|
|
1948
|
+
['datetime', 'timestamp'].includes(field.type) &&
|
|
1949
|
+
(operator == '=')) {
|
|
1950
|
+
let ctx, format_, parsed_date;
|
|
1951
|
+
if (this.context && Object.keys(this.context).length) {
|
|
1952
|
+
ctx = this.context;
|
|
1953
|
+
} else {
|
|
1954
|
+
ctx = {};
|
|
1955
|
+
}
|
|
1956
|
+
format_ = Sao.common.date_format(ctx.date_format);
|
|
1957
|
+
parsed_date = Sao.common.parse_date(format_, value);
|
|
1958
|
+
if (parsed_date &&
|
|
1959
|
+
(Sao.common.format_date(format_, parsed_date) == value)) {
|
|
1960
|
+
let date = Sao.DateTime.combine(parsed_date, Sao.Time());
|
|
1961
|
+
let next_day = Sao.DateTime(
|
|
1962
|
+
date.year(), date.month(), date.date(),
|
|
1963
|
+
date.hour(), date.minute(), date.second(),
|
|
1964
|
+
date.millisecond())
|
|
1965
|
+
next_day.add(1, 'day');
|
|
1966
|
+
result.push(this._clausify([
|
|
1967
|
+
[field_name, '>=', date],
|
|
1968
|
+
[field_name, '<', next_day]
|
|
1969
|
+
]));
|
|
1970
|
+
return;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1945
1973
|
}
|
|
1946
1974
|
if (['many2one', 'one2many', 'many2many', 'one2one',
|
|
1947
1975
|
'many2many', 'one2one'].includes(field.type) && value) {
|
package/src/rpc.js
CHANGED
|
@@ -119,11 +119,6 @@
|
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
var ajax_error = function(query, status_, error) {
|
|
122
|
-
if (!process_exception) {
|
|
123
|
-
console.debug(`RPC error calling ${args}: ${status_}: ${error}.`);
|
|
124
|
-
dfd.reject();
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
122
|
if (query.status == 503) {
|
|
128
123
|
this.retries++;
|
|
129
124
|
if (this.retries < 5) {
|
|
@@ -149,8 +144,7 @@
|
|
|
149
144
|
}
|
|
150
145
|
return;
|
|
151
146
|
}
|
|
152
|
-
}
|
|
153
|
-
if (query.status == 401) {
|
|
147
|
+
} else if (query.status == 401) {
|
|
154
148
|
//Try to relog
|
|
155
149
|
Sao.Session.renew(session).then(function() {
|
|
156
150
|
if (async) {
|
|
@@ -160,6 +154,10 @@
|
|
|
160
154
|
dfd.resolve();
|
|
161
155
|
}
|
|
162
156
|
}, dfd.reject);
|
|
157
|
+
} else if (!process_exception) {
|
|
158
|
+
console.debug(`RPC error calling ${args}: ${status_}: ${error}.`);
|
|
159
|
+
dfd.reject();
|
|
160
|
+
return;
|
|
163
161
|
} else {
|
|
164
162
|
var err_msg = `[${query.status}] ${error}`;
|
|
165
163
|
Sao.common.message.run(
|
package/src/sao.js
CHANGED
package/src/sao.less
CHANGED
|
@@ -460,6 +460,9 @@ html[theme="default"] {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
ul.notification-menu {
|
|
463
|
+
background-color: @body-bg;
|
|
464
|
+
color: @text-color;
|
|
465
|
+
|
|
463
466
|
@media (min-width: @grid-float-breakpoint) {
|
|
464
467
|
width: 320px;
|
|
465
468
|
}
|
|
@@ -472,6 +475,7 @@ html[theme="default"] {
|
|
|
472
475
|
}
|
|
473
476
|
|
|
474
477
|
> a {
|
|
478
|
+
color: @text-color;
|
|
475
479
|
display: flex;
|
|
476
480
|
padding: 3px 10px;
|
|
477
481
|
|
|
@@ -508,6 +512,10 @@ html[theme="default"] {
|
|
|
508
512
|
}
|
|
509
513
|
}
|
|
510
514
|
}
|
|
515
|
+
|
|
516
|
+
> li.divider {
|
|
517
|
+
background-color: @dropdown-divider-bg;
|
|
518
|
+
}
|
|
511
519
|
}
|
|
512
520
|
}
|
|
513
521
|
|
package/src/screen.js
CHANGED
package/src/view/form.js
CHANGED
|
@@ -378,11 +378,12 @@ function eval_pyson(value){
|
|
|
378
378
|
});
|
|
379
379
|
for (const e of fields) {
|
|
380
380
|
const name = e[0];
|
|
381
|
-
|
|
381
|
+
if (!record.is_loaded(name)) {
|
|
382
|
+
promesses.push(record.load(name));
|
|
383
|
+
}
|
|
382
384
|
}
|
|
383
385
|
}
|
|
384
|
-
|
|
385
|
-
.then(() => {
|
|
386
|
+
let display = function() {
|
|
386
387
|
let promesses = [];
|
|
387
388
|
var record = this.record;
|
|
388
389
|
for (const name in this.widgets) {
|
|
@@ -420,7 +421,13 @@ function eval_pyson(value){
|
|
|
420
421
|
container.set_grid_template();
|
|
421
422
|
}
|
|
422
423
|
});
|
|
423
|
-
});
|
|
424
|
+
}.bind(this);
|
|
425
|
+
if (promesses.length) {
|
|
426
|
+
return jQuery.when.apply(jQuery, promesses).then(
|
|
427
|
+
() => display());
|
|
428
|
+
} else {
|
|
429
|
+
return display();
|
|
430
|
+
}
|
|
424
431
|
},
|
|
425
432
|
set_value: function() {
|
|
426
433
|
var record = this.record;
|
|
@@ -3516,7 +3523,11 @@ function eval_pyson(value){
|
|
|
3516
3523
|
},
|
|
3517
3524
|
set_readonly: function(readonly) {
|
|
3518
3525
|
Sao.View.Form.One2Many._super.set_readonly.call(this, readonly);
|
|
3519
|
-
this.prm.
|
|
3526
|
+
if (this.prm.state() == 'pending') {
|
|
3527
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
3528
|
+
} else {
|
|
3529
|
+
this._set_button_sensitive();
|
|
3530
|
+
}
|
|
3520
3531
|
this._set_label_state();
|
|
3521
3532
|
},
|
|
3522
3533
|
set_required: function(required) {
|
|
@@ -3629,7 +3640,7 @@ function eval_pyson(value){
|
|
|
3629
3640
|
display: function() {
|
|
3630
3641
|
Sao.View.Form.One2Many._super.display.call(this);
|
|
3631
3642
|
|
|
3632
|
-
|
|
3643
|
+
let display = function() {
|
|
3633
3644
|
this._set_button_sensitive();
|
|
3634
3645
|
|
|
3635
3646
|
var record = this.record;
|
|
@@ -3676,7 +3687,13 @@ function eval_pyson(value){
|
|
|
3676
3687
|
.css('max-height', this.attributes.height + 'px');
|
|
3677
3688
|
}
|
|
3678
3689
|
return this.screen.display();
|
|
3679
|
-
});
|
|
3690
|
+
}.bind(this);
|
|
3691
|
+
|
|
3692
|
+
if (this.prm.state() == 'pending') {
|
|
3693
|
+
return this.prm.then(() => display());
|
|
3694
|
+
} else {
|
|
3695
|
+
return display();
|
|
3696
|
+
}
|
|
3680
3697
|
},
|
|
3681
3698
|
focus: function() {
|
|
3682
3699
|
if (this.attributes.add_remove) {
|
|
@@ -3953,7 +3970,11 @@ function eval_pyson(value){
|
|
|
3953
3970
|
}
|
|
3954
3971
|
var message = name + ' / ' + Sao.common.humanize(size);
|
|
3955
3972
|
this.label.text(message).attr('title', message);
|
|
3956
|
-
this.prm.
|
|
3973
|
+
if (this.prm.state() == 'pending') {
|
|
3974
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
3975
|
+
} else {
|
|
3976
|
+
this._set_button_sensitive();
|
|
3977
|
+
}
|
|
3957
3978
|
},
|
|
3958
3979
|
validate: function() {
|
|
3959
3980
|
var prm = jQuery.Deferred();
|
|
@@ -3962,9 +3983,8 @@ function eval_pyson(value){
|
|
|
3962
3983
|
if (record) {
|
|
3963
3984
|
var fields = this.screen.current_view.get_fields();
|
|
3964
3985
|
if (!record.validate(fields)) {
|
|
3965
|
-
this.screen.display(true);
|
|
3966
|
-
prm
|
|
3967
|
-
return;
|
|
3986
|
+
this.screen.display(true).always(() => prm.reject());
|
|
3987
|
+
return prm;
|
|
3968
3988
|
}
|
|
3969
3989
|
if (this.screen.pre_validate) {
|
|
3970
3990
|
return record.pre_validate().then(
|
|
@@ -4209,7 +4229,7 @@ function eval_pyson(value){
|
|
|
4209
4229
|
display: function() {
|
|
4210
4230
|
Sao.View.Form.Many2Many._super.display.call(this);
|
|
4211
4231
|
|
|
4212
|
-
|
|
4232
|
+
let display = function() {
|
|
4213
4233
|
var record = this.record;
|
|
4214
4234
|
var field = this.field;
|
|
4215
4235
|
|
|
@@ -4231,7 +4251,13 @@ function eval_pyson(value){
|
|
|
4231
4251
|
.css('max-height', this.attributes.height + 'px');
|
|
4232
4252
|
}
|
|
4233
4253
|
return this.screen.display();
|
|
4234
|
-
});
|
|
4254
|
+
}.bind(this);
|
|
4255
|
+
|
|
4256
|
+
if (this.prm.state() == 'pending') {
|
|
4257
|
+
return this.prm.then(() => display());
|
|
4258
|
+
} else {
|
|
4259
|
+
return display();
|
|
4260
|
+
}
|
|
4235
4261
|
},
|
|
4236
4262
|
focus: function() {
|
|
4237
4263
|
this.entry.focus();
|
package/src/view/list_form.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
button_clicked: function(event) {
|
|
14
14
|
if (Sao.common.compare(this.screen.selected_records, [this.record])) {
|
|
15
|
+
event.stopPropagation();
|
|
15
16
|
Sao.View.ListGroupViewForm._super.button_clicked.call(this, event);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
@@ -114,6 +115,12 @@
|
|
|
114
115
|
return this.group.slice();
|
|
115
116
|
},
|
|
116
117
|
set_cursor: function(new_, reset_view) {
|
|
118
|
+
if (!this.record) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (reset_view) {
|
|
122
|
+
this.display([this.record.id]);
|
|
123
|
+
}
|
|
117
124
|
if (new_) {
|
|
118
125
|
this.el.animate({
|
|
119
126
|
scrollTop: this.el[0].scrollHeight
|
package/src/view/tree.js
CHANGED
|
@@ -1528,6 +1528,13 @@
|
|
|
1528
1528
|
this.display_size = this.group.length;
|
|
1529
1529
|
this.display();
|
|
1530
1530
|
}
|
|
1531
|
+
if (reset_view) {
|
|
1532
|
+
let current_path = this.record.get_path(this.group);
|
|
1533
|
+
current_path = current_path.map(function(e) {
|
|
1534
|
+
return e[1];
|
|
1535
|
+
});
|
|
1536
|
+
this.display([current_path]);
|
|
1537
|
+
}
|
|
1531
1538
|
if (path.length > 1) {
|
|
1532
1539
|
prm = this.rows[path[0]].expand_to_path(
|
|
1533
1540
|
path.slice(1),
|
|
@@ -2762,7 +2769,7 @@
|
|
|
2762
2769
|
fields, false, false)) {
|
|
2763
2770
|
var value = cell.prop('checked');
|
|
2764
2771
|
this.field.set_client(record, value);
|
|
2765
|
-
if (record !== current_record) {
|
|
2772
|
+
if ((!this.group.parent) & (record !== current_record)) {
|
|
2766
2773
|
// we can not rely on editable tree handler to save the row
|
|
2767
2774
|
record.save();
|
|
2768
2775
|
}
|
package/src/window.js
CHANGED
|
@@ -2699,15 +2699,16 @@
|
|
|
2699
2699
|
},
|
|
2700
2700
|
_fill_with: function(template) {
|
|
2701
2701
|
var prm;
|
|
2702
|
+
let context = this.record.get_context();
|
|
2702
2703
|
if (template) {
|
|
2703
2704
|
prm = Sao.rpc({
|
|
2704
2705
|
'method': 'model.ir.email.template.get',
|
|
2705
|
-
'params': [template, this.record.id,
|
|
2706
|
+
'params': [template, this.record.id, context],
|
|
2706
2707
|
}, this.record.model.session);
|
|
2707
2708
|
} else {
|
|
2708
2709
|
prm = Sao.rpc({
|
|
2709
2710
|
'method': 'model.ir.email.template.get_default',
|
|
2710
|
-
'params': [this.record.model.name, this.record.id,
|
|
2711
|
+
'params': [this.record.model.name, this.record.id, context],
|
|
2711
2712
|
}, this.record.model.session);
|
|
2712
2713
|
}
|
|
2713
2714
|
prm.then(values => {
|
package/src/wizard.js
CHANGED
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
if (this.__processing || this.__waiting_response) {
|
|
56
56
|
return jQuery.when();
|
|
57
57
|
}
|
|
58
|
+
this.__processing = true;
|
|
58
59
|
var process = function() {
|
|
59
60
|
if (this.state == this.end_state) {
|
|
60
61
|
return this.end();
|
|
@@ -113,8 +114,8 @@
|
|
|
113
114
|
} else {
|
|
114
115
|
prms.push(execute_actions());
|
|
115
116
|
}
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
return jQuery.when.apply(jQuery, prms).then(
|
|
118
|
+
() => this.__processing = false);
|
|
118
119
|
}, result => {
|
|
119
120
|
if (!result || !this.screen) {
|
|
120
121
|
this.state = this.end_state;
|
|
@@ -237,11 +238,14 @@
|
|
|
237
238
|
this.footer.empty();
|
|
238
239
|
},
|
|
239
240
|
_get_button: function(definition) {
|
|
241
|
+
let state = this.state;
|
|
240
242
|
var button = Sao.Wizard.Form._super._get_button.call(this,
|
|
241
243
|
definition);
|
|
242
244
|
this.footer.append(button.el);
|
|
243
245
|
button.el.click(() => {
|
|
244
|
-
this.
|
|
246
|
+
if (this.state === state) {
|
|
247
|
+
this.response(definition);
|
|
248
|
+
}
|
|
245
249
|
});
|
|
246
250
|
return button;
|
|
247
251
|
},
|
|
@@ -289,19 +293,24 @@
|
|
|
289
293
|
this.footer.empty();
|
|
290
294
|
},
|
|
291
295
|
_get_button: function(definition) {
|
|
296
|
+
let state = this.state;
|
|
292
297
|
var button = Sao.Wizard.Dialog._super._get_button.call(this,
|
|
293
298
|
definition);
|
|
294
299
|
this.footer.append(button.el);
|
|
295
300
|
if (definition['default']) {
|
|
296
301
|
this.content.unbind('submit');
|
|
297
302
|
this.content.submit(e => {
|
|
298
|
-
this.response(definition);
|
|
299
303
|
e.preventDefault();
|
|
304
|
+
if (this.state === state) {
|
|
305
|
+
this.response(definition);
|
|
306
|
+
}
|
|
300
307
|
});
|
|
301
308
|
button.el.attr('type', 'submit');
|
|
302
309
|
} else {
|
|
303
310
|
button.el.click(() => {
|
|
304
|
-
this.
|
|
311
|
+
if (this.state === state) {
|
|
312
|
+
this.response(definition);
|
|
313
|
+
}
|
|
305
314
|
});
|
|
306
315
|
}
|
|
307
316
|
return button;
|
package/tests/sao.js
CHANGED
|
@@ -1933,6 +1933,12 @@
|
|
|
1933
1933
|
'name': 'integer',
|
|
1934
1934
|
'type': 'integer'
|
|
1935
1935
|
},
|
|
1936
|
+
'timestamp': {
|
|
1937
|
+
'name': 'timestamp',
|
|
1938
|
+
'string': 'Timestamp',
|
|
1939
|
+
'type': 'timestamp',
|
|
1940
|
+
'format': '"%H:%M:%S"',
|
|
1941
|
+
},
|
|
1936
1942
|
'selection': {
|
|
1937
1943
|
'string': 'Selection',
|
|
1938
1944
|
'name': 'selection',
|
|
@@ -2033,6 +2039,7 @@
|
|
|
2033
2039
|
c(['integer', '>=', 3]),
|
|
2034
2040
|
c(['integer', '<=', 5])
|
|
2035
2041
|
]]],
|
|
2042
|
+
[[c(['Timestamp', null, null])], [c(['timestamp', '=', null])]],
|
|
2036
2043
|
[[c(['Reference', null, 'foo'])],
|
|
2037
2044
|
[c(['reference', 'ilike', '%foo%'])]],
|
|
2038
2045
|
[[c(['Reference', null, 'Spam'])],
|
|
@@ -2073,6 +2080,33 @@
|
|
|
2073
2080
|
QUnit.assert.deepEqual(parser.parse_clause(value), result,
|
|
2074
2081
|
'parse_clause(' + JSON.stringify(value) + ')');
|
|
2075
2082
|
});
|
|
2083
|
+
|
|
2084
|
+
let clause = parser.parse_clause([c(
|
|
2085
|
+
['Timestamp', '=', Sao.common.format_date('%x', Sao.Date(2002, 12, 4))])]);
|
|
2086
|
+
QUnit.assert.strictEqual(clause[0].length, 2);
|
|
2087
|
+
let [ , operator, value] = clause[0][0];
|
|
2088
|
+
QUnit.assert.strictEqual(operator, '>=');
|
|
2089
|
+
QUnit.assert.ok(value.isSame(Sao.Date(2002, 12, 4)));
|
|
2090
|
+
[ , operator, value] = clause[0][1];
|
|
2091
|
+
QUnit.assert.strictEqual(operator, '<');
|
|
2092
|
+
QUnit.assert.ok(value.isSame(Sao.Date(2002, 12, 5)));
|
|
2093
|
+
|
|
2094
|
+
clause = parser.parse_clause([c(
|
|
2095
|
+
['Timestamp', '=',
|
|
2096
|
+
Sao.common.format_datetime('%x %X', Sao.DateTime(2002, 12, 4, 12, 30))])]);
|
|
2097
|
+
[ , operator, value] = clause[0];
|
|
2098
|
+
QUnit.assert.strictEqual(operator, '=');
|
|
2099
|
+
QUnit.assert.ok(value.isSame(Sao.DateTime(2002, 12, 4, 12, 30)));
|
|
2100
|
+
|
|
2101
|
+
clause = parser.parse_clause([c(
|
|
2102
|
+
['Timestamp', null, [
|
|
2103
|
+
`${Sao.common.format_date('%x', Sao.Date(2002, 12, 4))}`,
|
|
2104
|
+
`${Sao.common.format_date('%x', Sao.Date(2002, 12, 5))}`,
|
|
2105
|
+
]])]);
|
|
2106
|
+
[ , operator, value] = clause[0];
|
|
2107
|
+
QUnit.assert.strictEqual(operator, 'in');
|
|
2108
|
+
QUnit.assert.ok(value[0].isSame(Sao.DateTime(2002, 12, 4)));
|
|
2109
|
+
QUnit.assert.ok(value[1].isSame(Sao.DateTime(2002, 12, 5)));
|
|
2076
2110
|
});
|
|
2077
2111
|
|
|
2078
2112
|
QUnit.test('DomainParser.format_value', function() {
|