tryton-sao 8.0.3 → 8.0.5
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 +110 -31
- package/package.json +1 -1
- package/src/common.js +29 -1
- package/src/rpc.js +5 -7
- package/src/sao.js +2 -2
- 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 8.0.5 - 2026-06-18
|
|
3
|
+
--------------------------
|
|
4
|
+
* Bug fixes (see mercurial logs for details)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Version 8.0.4 - 2026-06-02
|
|
8
|
+
--------------------------
|
|
9
|
+
* Bug fixes (see mercurial logs for details)
|
|
10
|
+
|
|
11
|
+
|
|
2
12
|
Version 8.0.3 - 2026-05-20
|
|
3
13
|
--------------------------
|
|
4
14
|
* Bug fixes (see mercurial logs for details)
|
package/dist/tryton-sao.css
CHANGED
|
@@ -9465,6 +9465,10 @@ html[theme="default"] .carousel-caption h6 {
|
|
|
9465
9465
|
margin-bottom: -25px;
|
|
9466
9466
|
width: 15px;
|
|
9467
9467
|
}
|
|
9468
|
+
#user-preferences ul.notification-menu {
|
|
9469
|
+
background-color: #fff;
|
|
9470
|
+
color: #333333;
|
|
9471
|
+
}
|
|
9468
9472
|
@media (min-width: 768px) {
|
|
9469
9473
|
#user-preferences ul.notification-menu {
|
|
9470
9474
|
width: 320px;
|
|
@@ -9477,6 +9481,7 @@ html[theme="default"] .carousel-caption h6 {
|
|
|
9477
9481
|
background-color: #bceaeb;
|
|
9478
9482
|
}
|
|
9479
9483
|
#user-preferences ul.notification-menu > li.notification-item > a {
|
|
9484
|
+
color: #333333;
|
|
9480
9485
|
display: flex;
|
|
9481
9486
|
padding: 3px 10px;
|
|
9482
9487
|
}
|
|
@@ -9503,6 +9508,9 @@ html[theme="default"] .carousel-caption h6 {
|
|
|
9503
9508
|
text-align: center;
|
|
9504
9509
|
background-color: #f5f5f5;
|
|
9505
9510
|
}
|
|
9511
|
+
#user-preferences ul.notification-menu > li.divider {
|
|
9512
|
+
background-color: #e5e5e5;
|
|
9513
|
+
}
|
|
9506
9514
|
.attachment-preview {
|
|
9507
9515
|
border-bottom: 1px solid #eeeeee;
|
|
9508
9516
|
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__: '8.0.
|
|
6
|
+
__version__: '8.0.5',
|
|
7
7
|
};
|
|
8
8
|
/* eslint-enable no-redeclare */
|
|
9
9
|
|
|
@@ -93,7 +93,7 @@ var Sao = {
|
|
|
93
93
|
let display = element.style.display;
|
|
94
94
|
if (show) {
|
|
95
95
|
if (display === 'none') {
|
|
96
|
-
element.style.display = '
|
|
96
|
+
element.style.display = '';
|
|
97
97
|
}
|
|
98
98
|
} else {
|
|
99
99
|
if (display !== 'none') {
|
|
@@ -1490,11 +1490,6 @@ var Sao = {
|
|
|
1490
1490
|
};
|
|
1491
1491
|
|
|
1492
1492
|
var ajax_error = function(query, status_, error) {
|
|
1493
|
-
if (!process_exception) {
|
|
1494
|
-
console.debug(`RPC error calling ${args}: ${status_}: ${error}.`);
|
|
1495
|
-
dfd.reject();
|
|
1496
|
-
return;
|
|
1497
|
-
}
|
|
1498
1493
|
if (query.status == 503) {
|
|
1499
1494
|
this.retries++;
|
|
1500
1495
|
if (this.retries < 5) {
|
|
@@ -1520,8 +1515,7 @@ var Sao = {
|
|
|
1520
1515
|
}
|
|
1521
1516
|
return;
|
|
1522
1517
|
}
|
|
1523
|
-
}
|
|
1524
|
-
if (query.status == 401) {
|
|
1518
|
+
} else if (query.status == 401) {
|
|
1525
1519
|
//Try to relog
|
|
1526
1520
|
Sao.Session.renew(session).then(function() {
|
|
1527
1521
|
if (async) {
|
|
@@ -1531,6 +1525,10 @@ var Sao = {
|
|
|
1531
1525
|
dfd.resolve();
|
|
1532
1526
|
}
|
|
1533
1527
|
}, dfd.reject);
|
|
1528
|
+
} else if (!process_exception) {
|
|
1529
|
+
console.debug(`RPC error calling ${args}: ${status_}: ${error}.`);
|
|
1530
|
+
dfd.reject();
|
|
1531
|
+
return;
|
|
1534
1532
|
} else {
|
|
1535
1533
|
var err_msg = `[${query.status}] ${error}`;
|
|
1536
1534
|
Sao.common.message.run(
|
|
@@ -4965,7 +4963,9 @@ var Sao = {
|
|
|
4965
4963
|
};
|
|
4966
4964
|
|
|
4967
4965
|
var complete_datetime = function() {
|
|
4968
|
-
return [Sao.Date(), Sao.DateTime(
|
|
4966
|
+
return [Sao.Date(), Sao.DateTime(
|
|
4967
|
+
undefined, undefined, undefined,
|
|
4968
|
+
0, 0, 0, 0, true)];
|
|
4969
4969
|
};
|
|
4970
4970
|
|
|
4971
4971
|
var complete_date = function() {
|
|
@@ -5272,6 +5272,32 @@ var Sao = {
|
|
|
5272
5272
|
]);
|
|
5273
5273
|
return;
|
|
5274
5274
|
}
|
|
5275
|
+
if ((typeof value == 'string') &&
|
|
5276
|
+
['datetime', 'timestamp'].includes(field.type) &&
|
|
5277
|
+
(operator == '=')) {
|
|
5278
|
+
let ctx, format_, parsed_date;
|
|
5279
|
+
if (this.context && Object.keys(this.context).length) {
|
|
5280
|
+
ctx = this.context;
|
|
5281
|
+
} else {
|
|
5282
|
+
ctx = {};
|
|
5283
|
+
}
|
|
5284
|
+
format_ = Sao.common.date_format(ctx.date_format);
|
|
5285
|
+
parsed_date = Sao.common.parse_date(format_, value);
|
|
5286
|
+
if (parsed_date &&
|
|
5287
|
+
(Sao.common.format_date(format_, parsed_date) == value)) {
|
|
5288
|
+
let date = Sao.DateTime.combine(parsed_date, Sao.Time());
|
|
5289
|
+
let next_day = Sao.DateTime(
|
|
5290
|
+
date.year(), date.month(), date.date(),
|
|
5291
|
+
date.hour(), date.minute(), date.second(),
|
|
5292
|
+
date.millisecond())
|
|
5293
|
+
next_day.add(1, 'day');
|
|
5294
|
+
result.push(this._clausify([
|
|
5295
|
+
[field_name, '>=', date],
|
|
5296
|
+
[field_name, '<', next_day]
|
|
5297
|
+
]));
|
|
5298
|
+
return;
|
|
5299
|
+
}
|
|
5300
|
+
}
|
|
5275
5301
|
}
|
|
5276
5302
|
if (['many2one', 'one2many', 'many2many', 'one2one',
|
|
5277
5303
|
'many2many', 'one2one'].includes(field.type) && value) {
|
|
@@ -13998,6 +14024,9 @@ var Sao = {
|
|
|
13998
14024
|
});
|
|
13999
14025
|
},
|
|
14000
14026
|
get current_record() {
|
|
14027
|
+
if (this.__current_record && this.__current_record.destroyed) {
|
|
14028
|
+
this.__current_record = null;
|
|
14029
|
+
}
|
|
14001
14030
|
return this.__current_record;
|
|
14002
14031
|
},
|
|
14003
14032
|
set current_record(record) {
|
|
@@ -15577,11 +15606,12 @@ function eval_pyson(value){
|
|
|
15577
15606
|
});
|
|
15578
15607
|
for (const e of fields) {
|
|
15579
15608
|
const name = e[0];
|
|
15580
|
-
|
|
15609
|
+
if (!record.is_loaded(name)) {
|
|
15610
|
+
promesses.push(record.load(name));
|
|
15611
|
+
}
|
|
15581
15612
|
}
|
|
15582
15613
|
}
|
|
15583
|
-
|
|
15584
|
-
.then(() => {
|
|
15614
|
+
let display = function() {
|
|
15585
15615
|
let promesses = [];
|
|
15586
15616
|
var record = this.record;
|
|
15587
15617
|
for (const name in this.widgets) {
|
|
@@ -15619,7 +15649,13 @@ function eval_pyson(value){
|
|
|
15619
15649
|
container.set_grid_template();
|
|
15620
15650
|
}
|
|
15621
15651
|
});
|
|
15622
|
-
});
|
|
15652
|
+
}.bind(this);
|
|
15653
|
+
if (promesses.length) {
|
|
15654
|
+
return jQuery.when.apply(jQuery, promesses).then(
|
|
15655
|
+
() => display());
|
|
15656
|
+
} else {
|
|
15657
|
+
return display();
|
|
15658
|
+
}
|
|
15623
15659
|
},
|
|
15624
15660
|
set_value: function() {
|
|
15625
15661
|
var record = this.record;
|
|
@@ -18721,7 +18757,11 @@ function eval_pyson(value){
|
|
|
18721
18757
|
},
|
|
18722
18758
|
set_readonly: function(readonly) {
|
|
18723
18759
|
Sao.View.Form.One2Many._super.set_readonly.call(this, readonly);
|
|
18724
|
-
this.prm.
|
|
18760
|
+
if (this.prm.state() == 'pending') {
|
|
18761
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
18762
|
+
} else {
|
|
18763
|
+
this._set_button_sensitive();
|
|
18764
|
+
}
|
|
18725
18765
|
},
|
|
18726
18766
|
_set_button_sensitive: function() {
|
|
18727
18767
|
var size_limit, o2m_size;
|
|
@@ -18825,7 +18865,7 @@ function eval_pyson(value){
|
|
|
18825
18865
|
display: function() {
|
|
18826
18866
|
Sao.View.Form.One2Many._super.display.call(this);
|
|
18827
18867
|
|
|
18828
|
-
|
|
18868
|
+
let display = function() {
|
|
18829
18869
|
this._set_button_sensitive();
|
|
18830
18870
|
|
|
18831
18871
|
var record = this.record;
|
|
@@ -18872,7 +18912,13 @@ function eval_pyson(value){
|
|
|
18872
18912
|
.css('max-height', this.attributes.height + 'px');
|
|
18873
18913
|
}
|
|
18874
18914
|
return this.screen.display();
|
|
18875
|
-
});
|
|
18915
|
+
}.bind(this);
|
|
18916
|
+
|
|
18917
|
+
if (this.prm.state() == 'pending') {
|
|
18918
|
+
return this.prm.then(() => display());
|
|
18919
|
+
} else {
|
|
18920
|
+
return display();
|
|
18921
|
+
}
|
|
18876
18922
|
},
|
|
18877
18923
|
focus: function() {
|
|
18878
18924
|
if (this.attributes.add_remove) {
|
|
@@ -19149,7 +19195,11 @@ function eval_pyson(value){
|
|
|
19149
19195
|
}
|
|
19150
19196
|
var message = name + ' / ' + Sao.common.humanize(size);
|
|
19151
19197
|
this.badge.text(message).attr('title', message);
|
|
19152
|
-
this.prm.
|
|
19198
|
+
if (this.prm.state() == 'pending') {
|
|
19199
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
19200
|
+
} else {
|
|
19201
|
+
this._set_button_sensitive();
|
|
19202
|
+
}
|
|
19153
19203
|
},
|
|
19154
19204
|
validate: function() {
|
|
19155
19205
|
var prm = jQuery.Deferred();
|
|
@@ -19158,9 +19208,8 @@ function eval_pyson(value){
|
|
|
19158
19208
|
if (record) {
|
|
19159
19209
|
var fields = this.screen.current_view.get_fields();
|
|
19160
19210
|
if (!record.validate(fields)) {
|
|
19161
|
-
this.screen.display(true);
|
|
19162
|
-
prm
|
|
19163
|
-
return;
|
|
19211
|
+
this.screen.display(true).always(() => prm.reject());
|
|
19212
|
+
return prm;
|
|
19164
19213
|
}
|
|
19165
19214
|
if (this.screen.pre_validate) {
|
|
19166
19215
|
return record.pre_validate().then(
|
|
@@ -19398,7 +19447,7 @@ function eval_pyson(value){
|
|
|
19398
19447
|
display: function() {
|
|
19399
19448
|
Sao.View.Form.Many2Many._super.display.call(this);
|
|
19400
19449
|
|
|
19401
|
-
|
|
19450
|
+
let display = function() {
|
|
19402
19451
|
var record = this.record;
|
|
19403
19452
|
var field = this.field;
|
|
19404
19453
|
|
|
@@ -19420,7 +19469,13 @@ function eval_pyson(value){
|
|
|
19420
19469
|
.css('max-height', this.attributes.height + 'px');
|
|
19421
19470
|
}
|
|
19422
19471
|
return this.screen.display();
|
|
19423
|
-
});
|
|
19472
|
+
}.bind(this);
|
|
19473
|
+
|
|
19474
|
+
if (this.prm.state() == 'pending') {
|
|
19475
|
+
return this.prm.then(() => display());
|
|
19476
|
+
} else {
|
|
19477
|
+
return display();
|
|
19478
|
+
}
|
|
19424
19479
|
},
|
|
19425
19480
|
focus: function() {
|
|
19426
19481
|
this.entry.focus();
|
|
@@ -22670,6 +22725,13 @@ function eval_pyson(value){
|
|
|
22670
22725
|
this.display_size = this.group.length;
|
|
22671
22726
|
this.display();
|
|
22672
22727
|
}
|
|
22728
|
+
if (reset_view) {
|
|
22729
|
+
let current_path = this.record.get_path(this.group);
|
|
22730
|
+
current_path = current_path.map(function(e) {
|
|
22731
|
+
return e[1];
|
|
22732
|
+
});
|
|
22733
|
+
this.display([current_path]);
|
|
22734
|
+
}
|
|
22673
22735
|
if (path.length > 1) {
|
|
22674
22736
|
prm = this.rows[path[0]].expand_to_path(
|
|
22675
22737
|
path.slice(1),
|
|
@@ -23904,7 +23966,7 @@ function eval_pyson(value){
|
|
|
23904
23966
|
fields, false, false)) {
|
|
23905
23967
|
var value = cell.prop('checked');
|
|
23906
23968
|
this.field.set_client(record, value);
|
|
23907
|
-
if (record !== current_record) {
|
|
23969
|
+
if ((!this.group.parent) & (record !== current_record)) {
|
|
23908
23970
|
// we can not rely on editable tree handler to save the row
|
|
23909
23971
|
record.save();
|
|
23910
23972
|
}
|
|
@@ -25455,6 +25517,7 @@ function eval_pyson(value){
|
|
|
25455
25517
|
},
|
|
25456
25518
|
button_clicked: function(event) {
|
|
25457
25519
|
if (Sao.common.compare(this.screen.selected_records, [this.record])) {
|
|
25520
|
+
event.stopPropagation();
|
|
25458
25521
|
Sao.View.ListGroupViewForm._super.button_clicked.call(this, event);
|
|
25459
25522
|
}
|
|
25460
25523
|
}
|
|
@@ -25557,6 +25620,12 @@ function eval_pyson(value){
|
|
|
25557
25620
|
return this.group.slice();
|
|
25558
25621
|
},
|
|
25559
25622
|
set_cursor: function(new_, reset_view) {
|
|
25623
|
+
if (!this.record) {
|
|
25624
|
+
return;
|
|
25625
|
+
}
|
|
25626
|
+
if (reset_view) {
|
|
25627
|
+
this.display([this.record.id]);
|
|
25628
|
+
}
|
|
25560
25629
|
if (new_) {
|
|
25561
25630
|
this.el.animate({
|
|
25562
25631
|
scrollTop: this.el[0].scrollHeight
|
|
@@ -28573,15 +28642,16 @@ function eval_pyson(value){
|
|
|
28573
28642
|
},
|
|
28574
28643
|
_fill_with: function(template) {
|
|
28575
28644
|
var prm;
|
|
28645
|
+
let context = this.record.get_context();
|
|
28576
28646
|
if (template) {
|
|
28577
28647
|
prm = Sao.rpc({
|
|
28578
28648
|
'method': 'model.ir.email.template.get',
|
|
28579
|
-
'params': [template, this.record.id,
|
|
28649
|
+
'params': [template, this.record.id, context],
|
|
28580
28650
|
}, this.record.model.session);
|
|
28581
28651
|
} else {
|
|
28582
28652
|
prm = Sao.rpc({
|
|
28583
28653
|
'method': 'model.ir.email.template.get_default',
|
|
28584
|
-
'params': [this.record.model.name, this.record.id,
|
|
28654
|
+
'params': [this.record.model.name, this.record.id, context],
|
|
28585
28655
|
}, this.record.model.session);
|
|
28586
28656
|
}
|
|
28587
28657
|
prm.then(values => {
|
|
@@ -28829,6 +28899,7 @@ function eval_pyson(value){
|
|
|
28829
28899
|
if (this.__processing || this.__waiting_response) {
|
|
28830
28900
|
return jQuery.when();
|
|
28831
28901
|
}
|
|
28902
|
+
this.__processing = true;
|
|
28832
28903
|
var process = function() {
|
|
28833
28904
|
if (this.state == this.end_state) {
|
|
28834
28905
|
return this.end();
|
|
@@ -28887,8 +28958,8 @@ function eval_pyson(value){
|
|
|
28887
28958
|
} else {
|
|
28888
28959
|
prms.push(execute_actions());
|
|
28889
28960
|
}
|
|
28890
|
-
|
|
28891
|
-
|
|
28961
|
+
return jQuery.when.apply(jQuery, prms).then(
|
|
28962
|
+
() => this.__processing = false);
|
|
28892
28963
|
}, result => {
|
|
28893
28964
|
if (!result || !this.screen) {
|
|
28894
28965
|
this.state = this.end_state;
|
|
@@ -29011,11 +29082,14 @@ function eval_pyson(value){
|
|
|
29011
29082
|
this.footer.empty();
|
|
29012
29083
|
},
|
|
29013
29084
|
_get_button: function(definition) {
|
|
29085
|
+
let state = this.state;
|
|
29014
29086
|
var button = Sao.Wizard.Form._super._get_button.call(this,
|
|
29015
29087
|
definition);
|
|
29016
29088
|
this.footer.append(button.el);
|
|
29017
29089
|
button.el.click(() => {
|
|
29018
|
-
this.
|
|
29090
|
+
if (this.state === state) {
|
|
29091
|
+
this.response(definition);
|
|
29092
|
+
}
|
|
29019
29093
|
});
|
|
29020
29094
|
return button;
|
|
29021
29095
|
},
|
|
@@ -29063,19 +29137,24 @@ function eval_pyson(value){
|
|
|
29063
29137
|
this.footer.empty();
|
|
29064
29138
|
},
|
|
29065
29139
|
_get_button: function(definition) {
|
|
29140
|
+
let state = this.state;
|
|
29066
29141
|
var button = Sao.Wizard.Dialog._super._get_button.call(this,
|
|
29067
29142
|
definition);
|
|
29068
29143
|
this.footer.append(button.el);
|
|
29069
29144
|
if (definition['default']) {
|
|
29070
29145
|
this.content.unbind('submit');
|
|
29071
29146
|
this.content.submit(e => {
|
|
29072
|
-
this.response(definition);
|
|
29073
29147
|
e.preventDefault();
|
|
29148
|
+
if (this.state === state) {
|
|
29149
|
+
this.response(definition);
|
|
29150
|
+
}
|
|
29074
29151
|
});
|
|
29075
29152
|
button.el.attr('type', 'submit');
|
|
29076
29153
|
} else {
|
|
29077
29154
|
button.el.click(() => {
|
|
29078
|
-
this.
|
|
29155
|
+
if (this.state === state) {
|
|
29156
|
+
this.response(definition);
|
|
29157
|
+
}
|
|
29079
29158
|
});
|
|
29080
29159
|
}
|
|
29081
29160
|
return button;
|
package/package.json
CHANGED
package/src/common.js
CHANGED
|
@@ -1644,7 +1644,9 @@
|
|
|
1644
1644
|
};
|
|
1645
1645
|
|
|
1646
1646
|
var complete_datetime = function() {
|
|
1647
|
-
return [Sao.Date(), Sao.DateTime(
|
|
1647
|
+
return [Sao.Date(), Sao.DateTime(
|
|
1648
|
+
undefined, undefined, undefined,
|
|
1649
|
+
0, 0, 0, 0, true)];
|
|
1648
1650
|
};
|
|
1649
1651
|
|
|
1650
1652
|
var complete_date = function() {
|
|
@@ -1951,6 +1953,32 @@
|
|
|
1951
1953
|
]);
|
|
1952
1954
|
return;
|
|
1953
1955
|
}
|
|
1956
|
+
if ((typeof value == 'string') &&
|
|
1957
|
+
['datetime', 'timestamp'].includes(field.type) &&
|
|
1958
|
+
(operator == '=')) {
|
|
1959
|
+
let ctx, format_, parsed_date;
|
|
1960
|
+
if (this.context && Object.keys(this.context).length) {
|
|
1961
|
+
ctx = this.context;
|
|
1962
|
+
} else {
|
|
1963
|
+
ctx = {};
|
|
1964
|
+
}
|
|
1965
|
+
format_ = Sao.common.date_format(ctx.date_format);
|
|
1966
|
+
parsed_date = Sao.common.parse_date(format_, value);
|
|
1967
|
+
if (parsed_date &&
|
|
1968
|
+
(Sao.common.format_date(format_, parsed_date) == value)) {
|
|
1969
|
+
let date = Sao.DateTime.combine(parsed_date, Sao.Time());
|
|
1970
|
+
let next_day = Sao.DateTime(
|
|
1971
|
+
date.year(), date.month(), date.date(),
|
|
1972
|
+
date.hour(), date.minute(), date.second(),
|
|
1973
|
+
date.millisecond())
|
|
1974
|
+
next_day.add(1, 'day');
|
|
1975
|
+
result.push(this._clausify([
|
|
1976
|
+
[field_name, '>=', date],
|
|
1977
|
+
[field_name, '<', next_day]
|
|
1978
|
+
]));
|
|
1979
|
+
return;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1954
1982
|
}
|
|
1955
1983
|
if (['many2one', 'one2many', 'many2many', 'one2one',
|
|
1956
1984
|
'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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
/* eslint-disable no-redeclare */
|
|
5
5
|
var Sao = {
|
|
6
|
-
__version__: '8.0.
|
|
6
|
+
__version__: '8.0.5',
|
|
7
7
|
};
|
|
8
8
|
/* eslint-enable no-redeclare */
|
|
9
9
|
|
|
@@ -93,7 +93,7 @@ var Sao = {
|
|
|
93
93
|
let display = element.style.display;
|
|
94
94
|
if (show) {
|
|
95
95
|
if (display === 'none') {
|
|
96
|
-
element.style.display = '
|
|
96
|
+
element.style.display = '';
|
|
97
97
|
}
|
|
98
98
|
} else {
|
|
99
99
|
if (display !== 'none') {
|
package/src/sao.less
CHANGED
|
@@ -441,6 +441,9 @@ html[theme="default"] {
|
|
|
441
441
|
}
|
|
442
442
|
|
|
443
443
|
ul.notification-menu {
|
|
444
|
+
background-color: @body-bg;
|
|
445
|
+
color: @text-color;
|
|
446
|
+
|
|
444
447
|
@media (min-width: @grid-float-breakpoint) {
|
|
445
448
|
width: 320px;
|
|
446
449
|
}
|
|
@@ -453,6 +456,7 @@ html[theme="default"] {
|
|
|
453
456
|
}
|
|
454
457
|
|
|
455
458
|
> a {
|
|
459
|
+
color: @text-color;
|
|
456
460
|
display: flex;
|
|
457
461
|
padding: 3px 10px;
|
|
458
462
|
|
|
@@ -489,6 +493,10 @@ html[theme="default"] {
|
|
|
489
493
|
}
|
|
490
494
|
}
|
|
491
495
|
}
|
|
496
|
+
|
|
497
|
+
> li.divider {
|
|
498
|
+
background-color: @dropdown-divider-bg;
|
|
499
|
+
}
|
|
492
500
|
}
|
|
493
501
|
}
|
|
494
502
|
|
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;
|
|
@@ -3522,7 +3529,11 @@ function eval_pyson(value){
|
|
|
3522
3529
|
},
|
|
3523
3530
|
set_readonly: function(readonly) {
|
|
3524
3531
|
Sao.View.Form.One2Many._super.set_readonly.call(this, readonly);
|
|
3525
|
-
this.prm.
|
|
3532
|
+
if (this.prm.state() == 'pending') {
|
|
3533
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
3534
|
+
} else {
|
|
3535
|
+
this._set_button_sensitive();
|
|
3536
|
+
}
|
|
3526
3537
|
},
|
|
3527
3538
|
_set_button_sensitive: function() {
|
|
3528
3539
|
var size_limit, o2m_size;
|
|
@@ -3626,7 +3637,7 @@ function eval_pyson(value){
|
|
|
3626
3637
|
display: function() {
|
|
3627
3638
|
Sao.View.Form.One2Many._super.display.call(this);
|
|
3628
3639
|
|
|
3629
|
-
|
|
3640
|
+
let display = function() {
|
|
3630
3641
|
this._set_button_sensitive();
|
|
3631
3642
|
|
|
3632
3643
|
var record = this.record;
|
|
@@ -3673,7 +3684,13 @@ function eval_pyson(value){
|
|
|
3673
3684
|
.css('max-height', this.attributes.height + 'px');
|
|
3674
3685
|
}
|
|
3675
3686
|
return this.screen.display();
|
|
3676
|
-
});
|
|
3687
|
+
}.bind(this);
|
|
3688
|
+
|
|
3689
|
+
if (this.prm.state() == 'pending') {
|
|
3690
|
+
return this.prm.then(() => display());
|
|
3691
|
+
} else {
|
|
3692
|
+
return display();
|
|
3693
|
+
}
|
|
3677
3694
|
},
|
|
3678
3695
|
focus: function() {
|
|
3679
3696
|
if (this.attributes.add_remove) {
|
|
@@ -3950,7 +3967,11 @@ function eval_pyson(value){
|
|
|
3950
3967
|
}
|
|
3951
3968
|
var message = name + ' / ' + Sao.common.humanize(size);
|
|
3952
3969
|
this.badge.text(message).attr('title', message);
|
|
3953
|
-
this.prm.
|
|
3970
|
+
if (this.prm.state() == 'pending') {
|
|
3971
|
+
this.prm.done(() => this._set_button_sensitive());
|
|
3972
|
+
} else {
|
|
3973
|
+
this._set_button_sensitive();
|
|
3974
|
+
}
|
|
3954
3975
|
},
|
|
3955
3976
|
validate: function() {
|
|
3956
3977
|
var prm = jQuery.Deferred();
|
|
@@ -3959,9 +3980,8 @@ function eval_pyson(value){
|
|
|
3959
3980
|
if (record) {
|
|
3960
3981
|
var fields = this.screen.current_view.get_fields();
|
|
3961
3982
|
if (!record.validate(fields)) {
|
|
3962
|
-
this.screen.display(true);
|
|
3963
|
-
prm
|
|
3964
|
-
return;
|
|
3983
|
+
this.screen.display(true).always(() => prm.reject());
|
|
3984
|
+
return prm;
|
|
3965
3985
|
}
|
|
3966
3986
|
if (this.screen.pre_validate) {
|
|
3967
3987
|
return record.pre_validate().then(
|
|
@@ -4199,7 +4219,7 @@ function eval_pyson(value){
|
|
|
4199
4219
|
display: function() {
|
|
4200
4220
|
Sao.View.Form.Many2Many._super.display.call(this);
|
|
4201
4221
|
|
|
4202
|
-
|
|
4222
|
+
let display = function() {
|
|
4203
4223
|
var record = this.record;
|
|
4204
4224
|
var field = this.field;
|
|
4205
4225
|
|
|
@@ -4221,7 +4241,13 @@ function eval_pyson(value){
|
|
|
4221
4241
|
.css('max-height', this.attributes.height + 'px');
|
|
4222
4242
|
}
|
|
4223
4243
|
return this.screen.display();
|
|
4224
|
-
});
|
|
4244
|
+
}.bind(this);
|
|
4245
|
+
|
|
4246
|
+
if (this.prm.state() == 'pending') {
|
|
4247
|
+
return this.prm.then(() => display());
|
|
4248
|
+
} else {
|
|
4249
|
+
return display();
|
|
4250
|
+
}
|
|
4225
4251
|
},
|
|
4226
4252
|
focus: function() {
|
|
4227
4253
|
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
|
@@ -1557,6 +1557,13 @@
|
|
|
1557
1557
|
this.display_size = this.group.length;
|
|
1558
1558
|
this.display();
|
|
1559
1559
|
}
|
|
1560
|
+
if (reset_view) {
|
|
1561
|
+
let current_path = this.record.get_path(this.group);
|
|
1562
|
+
current_path = current_path.map(function(e) {
|
|
1563
|
+
return e[1];
|
|
1564
|
+
});
|
|
1565
|
+
this.display([current_path]);
|
|
1566
|
+
}
|
|
1560
1567
|
if (path.length > 1) {
|
|
1561
1568
|
prm = this.rows[path[0]].expand_to_path(
|
|
1562
1569
|
path.slice(1),
|
|
@@ -2791,7 +2798,7 @@
|
|
|
2791
2798
|
fields, false, false)) {
|
|
2792
2799
|
var value = cell.prop('checked');
|
|
2793
2800
|
this.field.set_client(record, value);
|
|
2794
|
-
if (record !== current_record) {
|
|
2801
|
+
if ((!this.group.parent) & (record !== current_record)) {
|
|
2795
2802
|
// we can not rely on editable tree handler to save the row
|
|
2796
2803
|
record.save();
|
|
2797
2804
|
}
|
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() {
|