tryton-sao 7.8.7 → 7.8.9
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/COPYRIGHT +1 -1
- package/dist/tryton-sao.css +9 -8
- package/dist/tryton-sao.js +75 -45
- package/package.json +1 -1
- package/src/common.js +1 -0
- package/src/model.js +2 -5
- package/src/sao.js +1 -1
- package/src/sao.less +11 -10
- package/src/screen.js +8 -2
- package/src/session.js +4 -0
- package/src/tab.js +30 -18
- package/src/view/form.js +22 -18
- package/src/view/tree.js +7 -1
package/CHANGELOG
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
|
|
2
|
+
Version 7.8.9 - 2026-05-02
|
|
3
|
+
--------------------------
|
|
4
|
+
* Bug fixes (see mercurial logs for details)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Version 7.8.8 - 2026-04-16
|
|
8
|
+
--------------------------
|
|
9
|
+
* Bug fixes (see mercurial logs for details)
|
|
10
|
+
|
|
11
|
+
|
|
2
12
|
Version 7.8.7 - 2026-03-18
|
|
3
13
|
--------------------------
|
|
4
14
|
* Bug fixes (see mercurial logs for details)
|
package/COPYRIGHT
CHANGED
package/dist/tryton-sao.css
CHANGED
|
@@ -9758,12 +9758,10 @@ html.accesskey *[accesskey]:after {
|
|
|
9758
9758
|
padding: 0 2px;
|
|
9759
9759
|
position: absolute;
|
|
9760
9760
|
text-transform: uppercase;
|
|
9761
|
-
|
|
9761
|
+
left: -1em;
|
|
9762
|
+
right: 0;
|
|
9762
9763
|
z-index: 5;
|
|
9763
9764
|
}
|
|
9764
|
-
html.accesskey input[accesskey][type="checkbox"]:after {
|
|
9765
|
-
background-color: initial;
|
|
9766
|
-
}
|
|
9767
9765
|
html.accesskey *[accesskey] ~ span[data-accesskey] {
|
|
9768
9766
|
float: right;
|
|
9769
9767
|
position: relative;
|
|
@@ -9774,10 +9772,13 @@ html.accesskey *[accesskey] ~ span[data-accesskey]:after {
|
|
|
9774
9772
|
html.accesskey *[accesskey]:after {
|
|
9775
9773
|
content: attr(accesskey);
|
|
9776
9774
|
}
|
|
9777
|
-
html.accesskey
|
|
9778
|
-
html.accesskey
|
|
9779
|
-
|
|
9780
|
-
|
|
9775
|
+
html.accesskey[dir="rtl"] *[accesskey] ~ span[data-accesskey]:after,
|
|
9776
|
+
html.accesskey[dir="rtl"] *[accesskey]:after {
|
|
9777
|
+
left: 0;
|
|
9778
|
+
right: -1em;
|
|
9779
|
+
}
|
|
9780
|
+
html.accesskey[dir="rtl"] *[accesskey] ~ span[data-accesskey] {
|
|
9781
|
+
float: left;
|
|
9781
9782
|
}
|
|
9782
9783
|
.tab-form,
|
|
9783
9784
|
.tab-board {
|
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.9',
|
|
7
7
|
};
|
|
8
8
|
/* eslint-enable no-redeclare */
|
|
9
9
|
|
|
@@ -2986,6 +2986,7 @@ var Sao = {
|
|
|
2986
2986
|
if (service_window.closed) {
|
|
2987
2987
|
window.clearInterval(timer);
|
|
2988
2988
|
session.database = database;
|
|
2989
|
+
session.login = null;
|
|
2989
2990
|
session.restore();
|
|
2990
2991
|
if (session.session) {
|
|
2991
2992
|
dfd.resolve(session);
|
|
@@ -3204,6 +3205,9 @@ var Sao = {
|
|
|
3204
3205
|
});
|
|
3205
3206
|
}).prependTo(dialog.footer);
|
|
3206
3207
|
dialog.modal.find('.modal-dialog').removeClass('modal-sm');
|
|
3208
|
+
prm.fail(() => {
|
|
3209
|
+
session.login = null;
|
|
3210
|
+
});
|
|
3207
3211
|
return dialog;
|
|
3208
3212
|
},
|
|
3209
3213
|
});
|
|
@@ -5389,6 +5393,7 @@ var Sao = {
|
|
|
5389
5393
|
let [, thousandSeparator] = /^10(.)?000/.exec(format(10000));
|
|
5390
5394
|
let [, decimalSign] = /^0(.)1$/.exec(format(0.1));
|
|
5391
5395
|
return Number(string
|
|
5396
|
+
.replaceAll(' ', '')
|
|
5392
5397
|
.replaceAll(thousandSeparator, '')
|
|
5393
5398
|
.replace(decimalSign, '.'));
|
|
5394
5399
|
}
|
|
@@ -8791,7 +8796,7 @@ var Sao = {
|
|
|
8791
8796
|
this.group.parent.id;
|
|
8792
8797
|
}
|
|
8793
8798
|
}
|
|
8794
|
-
return this.set_default(values);
|
|
8799
|
+
return this.set_default(values).then(() => values);
|
|
8795
8800
|
});
|
|
8796
8801
|
}
|
|
8797
8802
|
return jQuery.when();
|
|
@@ -10372,10 +10377,7 @@ var Sao = {
|
|
|
10372
10377
|
if (record2) {
|
|
10373
10378
|
let to_update = Object.fromEntries(
|
|
10374
10379
|
Object.entries(vals).filter(
|
|
10375
|
-
([k, v]) =>
|
|
10376
|
-
!Object.prototype.hasOwnProperty.call(
|
|
10377
|
-
vals_to_set, k)
|
|
10378
|
-
}
|
|
10380
|
+
([k, v]) => !Object.hasOwn(vals_to_set, k)
|
|
10379
10381
|
));
|
|
10380
10382
|
record2.set_on_change(to_update);
|
|
10381
10383
|
}
|
|
@@ -10831,6 +10833,7 @@ var Sao = {
|
|
|
10831
10833
|
'class': 'hidden-lg',
|
|
10832
10834
|
}).appendTo(this.name_el);
|
|
10833
10835
|
this.view_prm = jQuery.when();
|
|
10836
|
+
this._action_running = false;
|
|
10834
10837
|
},
|
|
10835
10838
|
menu_def: function() {
|
|
10836
10839
|
return [
|
|
@@ -10954,6 +10957,8 @@ var Sao = {
|
|
|
10954
10957
|
if (this.info_bar) {
|
|
10955
10958
|
this.el.append(this.info_bar.el);
|
|
10956
10959
|
}
|
|
10960
|
+
|
|
10961
|
+
this._chat = null;
|
|
10957
10962
|
},
|
|
10958
10963
|
set_menu: function(menu) {
|
|
10959
10964
|
var previous;
|
|
@@ -10978,8 +10983,13 @@ var Sao = {
|
|
|
10978
10983
|
this.menu_buttons[item.id] = menuitem;
|
|
10979
10984
|
link.click(evt => {
|
|
10980
10985
|
evt.preventDefault();
|
|
10981
|
-
if (!menuitem.hasClass('disabled')
|
|
10982
|
-
this
|
|
10986
|
+
if (!menuitem.hasClass('disabled')
|
|
10987
|
+
&& !this._action_running) {
|
|
10988
|
+
this._action_running = true;
|
|
10989
|
+
(this[item.id]() || jQuery.when())
|
|
10990
|
+
.always(() => {
|
|
10991
|
+
this._action_running = false;
|
|
10992
|
+
});
|
|
10983
10993
|
}
|
|
10984
10994
|
});
|
|
10985
10995
|
} else if (!item && previous) {
|
|
@@ -11083,17 +11093,14 @@ var Sao = {
|
|
|
11083
11093
|
}
|
|
11084
11094
|
this.buttons[item.id].click(item, event => {
|
|
11085
11095
|
var item = event.data;
|
|
11086
|
-
|
|
11087
|
-
// Use data instead of disabled prop because the action may
|
|
11088
|
-
// actually disable the button.
|
|
11089
|
-
if (button.data('disabled')) {
|
|
11096
|
+
if (this._action_running) {
|
|
11090
11097
|
event.preventDefault();
|
|
11091
11098
|
return;
|
|
11092
11099
|
}
|
|
11093
|
-
|
|
11100
|
+
this._action_running = true;
|
|
11094
11101
|
(this[item.id](this) || jQuery.when())
|
|
11095
|
-
.always(
|
|
11096
|
-
|
|
11102
|
+
.always(() => {
|
|
11103
|
+
this._action_running = false;
|
|
11097
11104
|
});
|
|
11098
11105
|
});
|
|
11099
11106
|
};
|
|
@@ -11163,6 +11170,9 @@ var Sao = {
|
|
|
11163
11170
|
tabs.trigger('ready');
|
|
11164
11171
|
if (this._chat) {
|
|
11165
11172
|
this._chat.unregister();
|
|
11173
|
+
let chat = this.sidebar_content.find('.chat');
|
|
11174
|
+
chat.remove();
|
|
11175
|
+
this._chat = null;
|
|
11166
11176
|
}
|
|
11167
11177
|
});
|
|
11168
11178
|
},
|
|
@@ -11717,7 +11727,7 @@ var Sao = {
|
|
|
11717
11727
|
} else {
|
|
11718
11728
|
prm = jQuery.when();
|
|
11719
11729
|
}
|
|
11720
|
-
prm.then(() => {
|
|
11730
|
+
return prm.then(() => {
|
|
11721
11731
|
var access = Sao.common.MODELACCESS.get(this.screen.model_name);
|
|
11722
11732
|
if (this.screen.readonly || !(access.write || access.create)) {
|
|
11723
11733
|
return jQuery.Deferred().reject();
|
|
@@ -11759,6 +11769,8 @@ var Sao = {
|
|
|
11759
11769
|
}
|
|
11760
11770
|
return set_cursor;
|
|
11761
11771
|
});
|
|
11772
|
+
} else {
|
|
11773
|
+
this.refresh_resources(true);
|
|
11762
11774
|
}
|
|
11763
11775
|
return set_cursor;
|
|
11764
11776
|
})
|
|
@@ -11817,18 +11829,18 @@ var Sao = {
|
|
|
11817
11829
|
},
|
|
11818
11830
|
previous: function() {
|
|
11819
11831
|
return this.modified_save().then(() => {
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11832
|
+
return this.screen.display_previous().then(() => {
|
|
11833
|
+
this.info_bar.clear();
|
|
11834
|
+
this.set_buttons_sensitive();
|
|
11835
|
+
});
|
|
11824
11836
|
});
|
|
11825
11837
|
},
|
|
11826
11838
|
next: function() {
|
|
11827
11839
|
return this.modified_save().then(() => {
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
|
|
11831
|
-
|
|
11840
|
+
return this.screen.display_next().then(() => {
|
|
11841
|
+
this.info_bar.clear();
|
|
11842
|
+
this.set_buttons_sensitive();
|
|
11843
|
+
});
|
|
11832
11844
|
});
|
|
11833
11845
|
},
|
|
11834
11846
|
search: function() {
|
|
@@ -12222,6 +12234,8 @@ var Sao = {
|
|
|
12222
12234
|
let chat = this.sidebar_content.find('.chat');
|
|
12223
12235
|
if (chat.length) {
|
|
12224
12236
|
chat.remove();
|
|
12237
|
+
this._chat.unregister()
|
|
12238
|
+
this._chat = null;
|
|
12225
12239
|
} else {
|
|
12226
12240
|
if (this.screen.current_reference) {
|
|
12227
12241
|
this._chat = new Sao.Chat(this.screen.current_reference);
|
|
@@ -13105,8 +13119,14 @@ var Sao = {
|
|
|
13105
13119
|
break;
|
|
13106
13120
|
case 'selection':
|
|
13107
13121
|
case 'multiselection':
|
|
13122
|
+
var selection = jQuery.extend([], field.selection);
|
|
13123
|
+
if (field.sort === undefined || field.sort) {
|
|
13124
|
+
selection.sort(function(a, b) {
|
|
13125
|
+
return a[1].localeCompare(b[1]);
|
|
13126
|
+
});
|
|
13127
|
+
}
|
|
13108
13128
|
entry = new Sao.ScreenContainer.Selection(
|
|
13109
|
-
|
|
13129
|
+
selection, prefix + field.name);
|
|
13110
13130
|
input = entry.el;
|
|
13111
13131
|
input.prop('size', field.selection.length);
|
|
13112
13132
|
break;
|
|
@@ -14736,7 +14756,7 @@ var Sao = {
|
|
|
14736
14756
|
if (this.current_view &&
|
|
14737
14757
|
~['tree', 'graph', 'calendar'].indexOf(this.current_view.view_type) &&
|
|
14738
14758
|
!this.group.parent) {
|
|
14739
|
-
return this.search_filter();
|
|
14759
|
+
return this.search_filter(this.screen_container.get_text());
|
|
14740
14760
|
}
|
|
14741
14761
|
} else if (action == 'reload menu') {
|
|
14742
14762
|
return Sao.Session.current_session.reload_context()
|
|
@@ -15523,7 +15543,8 @@ function eval_pyson(value){
|
|
|
15523
15543
|
}
|
|
15524
15544
|
}
|
|
15525
15545
|
return jQuery.when.apply(jQuery,promesses)
|
|
15526
|
-
.
|
|
15546
|
+
.then(() => {
|
|
15547
|
+
let promesses = [];
|
|
15527
15548
|
var record = this.record;
|
|
15528
15549
|
for (const name in this.widgets) {
|
|
15529
15550
|
var widgets = this.widgets[name];
|
|
@@ -15535,10 +15556,12 @@ function eval_pyson(value){
|
|
|
15535
15556
|
field.set_state(record);
|
|
15536
15557
|
}
|
|
15537
15558
|
for (const widget of widgets) {
|
|
15538
|
-
widget.display();
|
|
15559
|
+
let prm = widget.display();
|
|
15560
|
+
if (prm) {
|
|
15561
|
+
promesses.push(prm);
|
|
15562
|
+
}
|
|
15539
15563
|
}
|
|
15540
15564
|
}
|
|
15541
|
-
var promesses = [];
|
|
15542
15565
|
// We iterate in the reverse order so that the most nested
|
|
15543
15566
|
// widgets are computed first and set_state methods can rely
|
|
15544
15567
|
// on their children having their state set
|
|
@@ -15553,7 +15576,7 @@ function eval_pyson(value){
|
|
|
15553
15576
|
}
|
|
15554
15577
|
// re-set the grid templates for the StateWidget that are
|
|
15555
15578
|
// asynchronous
|
|
15556
|
-
jQuery.when.apply(jQuery, promesses).
|
|
15579
|
+
return jQuery.when.apply(jQuery, promesses).then(() => {
|
|
15557
15580
|
for (const container of this.containers) {
|
|
15558
15581
|
container.set_grid_template();
|
|
15559
15582
|
}
|
|
@@ -17390,11 +17413,13 @@ function eval_pyson(value){
|
|
|
17390
17413
|
this.el = jQuery('<div/>', {
|
|
17391
17414
|
'class': this.class_
|
|
17392
17415
|
});
|
|
17416
|
+
this.group = jQuery('<div/>', {
|
|
17417
|
+
'class': 'input-group input-group-sm'
|
|
17418
|
+
}).css('width', '100%').appendTo(this.el);
|
|
17393
17419
|
this.select = this.labelled = jQuery('<select/>', {
|
|
17394
17420
|
'class': 'form-control input-sm mousetrap',
|
|
17395
17421
|
'name': attributes.name,
|
|
17396
|
-
});
|
|
17397
|
-
this.el.append(this.select);
|
|
17422
|
+
}).appendTo(this.group);
|
|
17398
17423
|
this.select.change(this.focus_out.bind(this));
|
|
17399
17424
|
Sao.common.selection_mixin.init.call(this);
|
|
17400
17425
|
this.init_selection();
|
|
@@ -17495,11 +17520,14 @@ function eval_pyson(value){
|
|
|
17495
17520
|
this.el = jQuery('<div/>', {
|
|
17496
17521
|
'class': this.class_
|
|
17497
17522
|
});
|
|
17523
|
+
this.group = jQuery('<div/>', {
|
|
17524
|
+
'class': 'input-group input-group-sm'
|
|
17525
|
+
}).css('width', '100%').appendTo(this.el);
|
|
17498
17526
|
this.input = this.labelled = jQuery('<input/>', {
|
|
17499
17527
|
'type': 'checkbox',
|
|
17500
17528
|
'class': 'form-control input-sm mousetrap',
|
|
17501
17529
|
'name': attributes.name,
|
|
17502
|
-
}).appendTo(this.
|
|
17530
|
+
}).appendTo(this.group);
|
|
17503
17531
|
this.input.change(this.focus_out.bind(this));
|
|
17504
17532
|
this.input.click(function() {
|
|
17505
17533
|
// Dont trigger click if field is readonly as readonly has no
|
|
@@ -18762,7 +18790,7 @@ function eval_pyson(value){
|
|
|
18762
18790
|
display: function() {
|
|
18763
18791
|
Sao.View.Form.One2Many._super.display.call(this);
|
|
18764
18792
|
|
|
18765
|
-
this.prm.
|
|
18793
|
+
return this.prm.then(() => {
|
|
18766
18794
|
this._set_button_sensitive();
|
|
18767
18795
|
|
|
18768
18796
|
var record = this.record;
|
|
@@ -18772,9 +18800,8 @@ function eval_pyson(value){
|
|
|
18772
18800
|
this.screen.new_group();
|
|
18773
18801
|
this.screen.current_record = null;
|
|
18774
18802
|
this.screen.group.parent = null;
|
|
18775
|
-
this.screen.display();
|
|
18776
18803
|
this.screen.screen_container.hide_filter();
|
|
18777
|
-
return;
|
|
18804
|
+
return this.screen.display();
|
|
18778
18805
|
}
|
|
18779
18806
|
|
|
18780
18807
|
var new_group = record.field_get_client(this.field_name);
|
|
@@ -18803,13 +18830,13 @@ function eval_pyson(value){
|
|
|
18803
18830
|
this.screen.domain = domain;
|
|
18804
18831
|
}
|
|
18805
18832
|
this.screen.size_limit = size_limit;
|
|
18806
|
-
this.screen.display();
|
|
18807
18833
|
if (this.attributes.height !== undefined) {
|
|
18808
18834
|
this.content
|
|
18809
18835
|
.find('.treeview,.list-form').first()
|
|
18810
18836
|
.css('min-height', this.attributes.height + 'px')
|
|
18811
18837
|
.css('max-height', this.attributes.height + 'px');
|
|
18812
18838
|
}
|
|
18839
|
+
return this.screen.display();
|
|
18813
18840
|
});
|
|
18814
18841
|
},
|
|
18815
18842
|
focus: function() {
|
|
@@ -19109,9 +19136,7 @@ function eval_pyson(value){
|
|
|
19109
19136
|
return prm;
|
|
19110
19137
|
},
|
|
19111
19138
|
set_value: function() {
|
|
19112
|
-
|
|
19113
|
-
this.view.screen.record_modified(false);
|
|
19114
|
-
}
|
|
19139
|
+
this.screen.current_view.set_value();
|
|
19115
19140
|
},
|
|
19116
19141
|
_update_completion: function(text) {
|
|
19117
19142
|
if (!this.record) {
|
|
@@ -19345,7 +19370,7 @@ function eval_pyson(value){
|
|
|
19345
19370
|
display: function() {
|
|
19346
19371
|
Sao.View.Form.Many2Many._super.display.call(this);
|
|
19347
19372
|
|
|
19348
|
-
this.prm.
|
|
19373
|
+
return this.prm.then(() => {
|
|
19349
19374
|
var record = this.record;
|
|
19350
19375
|
var field = this.field;
|
|
19351
19376
|
|
|
@@ -19353,21 +19378,20 @@ function eval_pyson(value){
|
|
|
19353
19378
|
this.screen.new_group();
|
|
19354
19379
|
this.screen.current_record = null;
|
|
19355
19380
|
this.screen.group.parent = null;
|
|
19356
|
-
this.screen.display();
|
|
19357
19381
|
this.screen.screen_container.hide_filter();
|
|
19358
|
-
return;
|
|
19382
|
+
return this.screen.display();
|
|
19359
19383
|
}
|
|
19360
19384
|
var new_group = record.field_get_client(this.field_name);
|
|
19361
19385
|
if (new_group != this.screen.group) {
|
|
19362
19386
|
this.screen.set_group(new_group);
|
|
19363
19387
|
}
|
|
19364
|
-
this.screen.display();
|
|
19365
19388
|
if (this.attributes.height !== undefined) {
|
|
19366
19389
|
this.content
|
|
19367
19390
|
.find('.treeview,.list-form').first()
|
|
19368
19391
|
.css('min-height', this.attributes.height + 'px')
|
|
19369
19392
|
.css('max-height', this.attributes.height + 'px');
|
|
19370
19393
|
}
|
|
19394
|
+
return this.screen.display();
|
|
19371
19395
|
});
|
|
19372
19396
|
},
|
|
19373
19397
|
focus: function() {
|
|
@@ -21490,6 +21514,8 @@ function eval_pyson(value){
|
|
|
21490
21514
|
'reset_width',
|
|
21491
21515
|
[this.screen.model_name, window.screen.width],
|
|
21492
21516
|
{});
|
|
21517
|
+
Sao.Session.current_session.cache.clear(
|
|
21518
|
+
`model.${this.screen.model_name}.fields_view_get`);
|
|
21493
21519
|
|
|
21494
21520
|
for (let column of this.columns) {
|
|
21495
21521
|
if (column.col.data('default-width')) {
|
|
@@ -21539,7 +21565,7 @@ function eval_pyson(value){
|
|
|
21539
21565
|
|
|
21540
21566
|
let tree_column_width = (
|
|
21541
21567
|
Sao.Screen.tree_column_width[this.screen.model_name] || {});
|
|
21542
|
-
let width = tree_column_width[name];
|
|
21568
|
+
let width = tree_column_width[column.attributes.name];
|
|
21543
21569
|
if (width || column.attributes.width) {
|
|
21544
21570
|
if (!width) {
|
|
21545
21571
|
width = column.attributes.width;
|
|
@@ -23824,6 +23850,10 @@ function eval_pyson(value){
|
|
|
23824
23850
|
fields, false, false)) {
|
|
23825
23851
|
var value = cell.prop('checked');
|
|
23826
23852
|
this.field.set_client(record, value);
|
|
23853
|
+
if (record !== current_record) {
|
|
23854
|
+
// we can not rely on editable tree handler to save the row
|
|
23855
|
+
record.save();
|
|
23856
|
+
}
|
|
23827
23857
|
} else {
|
|
23828
23858
|
evt.preventDefault();
|
|
23829
23859
|
}
|
package/package.json
CHANGED
package/src/common.js
CHANGED
|
@@ -2086,6 +2086,7 @@
|
|
|
2086
2086
|
let [, thousandSeparator] = /^10(.)?000/.exec(format(10000));
|
|
2087
2087
|
let [, decimalSign] = /^0(.)1$/.exec(format(0.1));
|
|
2088
2088
|
return Number(string
|
|
2089
|
+
.replaceAll(' ', '')
|
|
2089
2090
|
.replaceAll(thousandSeparator, '')
|
|
2090
2091
|
.replace(decimalSign, '.'));
|
|
2091
2092
|
}
|
package/src/model.js
CHANGED
|
@@ -990,7 +990,7 @@
|
|
|
990
990
|
this.group.parent.id;
|
|
991
991
|
}
|
|
992
992
|
}
|
|
993
|
-
return this.set_default(values);
|
|
993
|
+
return this.set_default(values).then(() => values);
|
|
994
994
|
});
|
|
995
995
|
}
|
|
996
996
|
return jQuery.when();
|
|
@@ -2571,10 +2571,7 @@
|
|
|
2571
2571
|
if (record2) {
|
|
2572
2572
|
let to_update = Object.fromEntries(
|
|
2573
2573
|
Object.entries(vals).filter(
|
|
2574
|
-
([k, v]) =>
|
|
2575
|
-
!Object.prototype.hasOwnProperty.call(
|
|
2576
|
-
vals_to_set, k)
|
|
2577
|
-
}
|
|
2574
|
+
([k, v]) => !Object.hasOwn(vals_to_set, k)
|
|
2578
2575
|
));
|
|
2579
2576
|
record2.set_on_change(to_update);
|
|
2580
2577
|
}
|
package/src/sao.js
CHANGED
package/src/sao.less
CHANGED
|
@@ -607,14 +607,11 @@ html.accesskey {
|
|
|
607
607
|
padding: 0 2px;
|
|
608
608
|
position: absolute;
|
|
609
609
|
text-transform: uppercase;
|
|
610
|
-
|
|
610
|
+
left: -1em;
|
|
611
|
+
right: 0;
|
|
611
612
|
z-index: 5;
|
|
612
613
|
}
|
|
613
614
|
|
|
614
|
-
input[accesskey][type="checkbox"]:after {
|
|
615
|
-
background-color: initial;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
615
|
*[accesskey] ~ span[data-accesskey] {
|
|
619
616
|
float: right;
|
|
620
617
|
position: relative;
|
|
@@ -628,11 +625,15 @@ html.accesskey {
|
|
|
628
625
|
content: attr(accesskey);
|
|
629
626
|
}
|
|
630
627
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
628
|
+
&[dir="rtl"] {
|
|
629
|
+
*[accesskey] ~ span[data-accesskey]:after,
|
|
630
|
+
*[accesskey]:after {
|
|
631
|
+
left: 0;
|
|
632
|
+
right: -1em;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
*[accesskey] ~ span[data-accesskey] {
|
|
636
|
+
float: left;
|
|
636
637
|
}
|
|
637
638
|
}
|
|
638
639
|
}
|
package/src/screen.js
CHANGED
|
@@ -501,8 +501,14 @@
|
|
|
501
501
|
break;
|
|
502
502
|
case 'selection':
|
|
503
503
|
case 'multiselection':
|
|
504
|
+
var selection = jQuery.extend([], field.selection);
|
|
505
|
+
if (field.sort === undefined || field.sort) {
|
|
506
|
+
selection.sort(function(a, b) {
|
|
507
|
+
return a[1].localeCompare(b[1]);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
504
510
|
entry = new Sao.ScreenContainer.Selection(
|
|
505
|
-
|
|
511
|
+
selection, prefix + field.name);
|
|
506
512
|
input = entry.el;
|
|
507
513
|
input.prop('size', field.selection.length);
|
|
508
514
|
break;
|
|
@@ -2132,7 +2138,7 @@
|
|
|
2132
2138
|
if (this.current_view &&
|
|
2133
2139
|
~['tree', 'graph', 'calendar'].indexOf(this.current_view.view_type) &&
|
|
2134
2140
|
!this.group.parent) {
|
|
2135
|
-
return this.search_filter();
|
|
2141
|
+
return this.search_filter(this.screen_container.get_text());
|
|
2136
2142
|
}
|
|
2137
2143
|
} else if (action == 'reload menu') {
|
|
2138
2144
|
return Sao.Session.current_session.reload_context()
|
package/src/session.js
CHANGED
|
@@ -346,6 +346,7 @@
|
|
|
346
346
|
if (service_window.closed) {
|
|
347
347
|
window.clearInterval(timer);
|
|
348
348
|
session.database = database;
|
|
349
|
+
session.login = null;
|
|
349
350
|
session.restore();
|
|
350
351
|
if (session.session) {
|
|
351
352
|
dfd.resolve(session);
|
|
@@ -564,6 +565,9 @@
|
|
|
564
565
|
});
|
|
565
566
|
}).prependTo(dialog.footer);
|
|
566
567
|
dialog.modal.find('.modal-dialog').removeClass('modal-sm');
|
|
568
|
+
prm.fail(() => {
|
|
569
|
+
session.login = null;
|
|
570
|
+
});
|
|
567
571
|
return dialog;
|
|
568
572
|
},
|
|
569
573
|
});
|
package/src/tab.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
'class': 'hidden-lg',
|
|
19
19
|
}).appendTo(this.name_el);
|
|
20
20
|
this.view_prm = jQuery.when();
|
|
21
|
+
this._action_running = false;
|
|
21
22
|
},
|
|
22
23
|
menu_def: function() {
|
|
23
24
|
return [
|
|
@@ -141,6 +142,8 @@
|
|
|
141
142
|
if (this.info_bar) {
|
|
142
143
|
this.el.append(this.info_bar.el);
|
|
143
144
|
}
|
|
145
|
+
|
|
146
|
+
this._chat = null;
|
|
144
147
|
},
|
|
145
148
|
set_menu: function(menu) {
|
|
146
149
|
var previous;
|
|
@@ -165,8 +168,13 @@
|
|
|
165
168
|
this.menu_buttons[item.id] = menuitem;
|
|
166
169
|
link.click(evt => {
|
|
167
170
|
evt.preventDefault();
|
|
168
|
-
if (!menuitem.hasClass('disabled')
|
|
169
|
-
this
|
|
171
|
+
if (!menuitem.hasClass('disabled')
|
|
172
|
+
&& !this._action_running) {
|
|
173
|
+
this._action_running = true;
|
|
174
|
+
(this[item.id]() || jQuery.when())
|
|
175
|
+
.always(() => {
|
|
176
|
+
this._action_running = false;
|
|
177
|
+
});
|
|
170
178
|
}
|
|
171
179
|
});
|
|
172
180
|
} else if (!item && previous) {
|
|
@@ -270,17 +278,14 @@
|
|
|
270
278
|
}
|
|
271
279
|
this.buttons[item.id].click(item, event => {
|
|
272
280
|
var item = event.data;
|
|
273
|
-
|
|
274
|
-
// Use data instead of disabled prop because the action may
|
|
275
|
-
// actually disable the button.
|
|
276
|
-
if (button.data('disabled')) {
|
|
281
|
+
if (this._action_running) {
|
|
277
282
|
event.preventDefault();
|
|
278
283
|
return;
|
|
279
284
|
}
|
|
280
|
-
|
|
285
|
+
this._action_running = true;
|
|
281
286
|
(this[item.id](this) || jQuery.when())
|
|
282
|
-
.always(
|
|
283
|
-
|
|
287
|
+
.always(() => {
|
|
288
|
+
this._action_running = false;
|
|
284
289
|
});
|
|
285
290
|
});
|
|
286
291
|
};
|
|
@@ -350,6 +355,9 @@
|
|
|
350
355
|
tabs.trigger('ready');
|
|
351
356
|
if (this._chat) {
|
|
352
357
|
this._chat.unregister();
|
|
358
|
+
let chat = this.sidebar_content.find('.chat');
|
|
359
|
+
chat.remove();
|
|
360
|
+
this._chat = null;
|
|
353
361
|
}
|
|
354
362
|
});
|
|
355
363
|
},
|
|
@@ -904,7 +912,7 @@
|
|
|
904
912
|
} else {
|
|
905
913
|
prm = jQuery.when();
|
|
906
914
|
}
|
|
907
|
-
prm.then(() => {
|
|
915
|
+
return prm.then(() => {
|
|
908
916
|
var access = Sao.common.MODELACCESS.get(this.screen.model_name);
|
|
909
917
|
if (this.screen.readonly || !(access.write || access.create)) {
|
|
910
918
|
return jQuery.Deferred().reject();
|
|
@@ -946,6 +954,8 @@
|
|
|
946
954
|
}
|
|
947
955
|
return set_cursor;
|
|
948
956
|
});
|
|
957
|
+
} else {
|
|
958
|
+
this.refresh_resources(true);
|
|
949
959
|
}
|
|
950
960
|
return set_cursor;
|
|
951
961
|
})
|
|
@@ -1004,18 +1014,18 @@
|
|
|
1004
1014
|
},
|
|
1005
1015
|
previous: function() {
|
|
1006
1016
|
return this.modified_save().then(() => {
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1017
|
+
return this.screen.display_previous().then(() => {
|
|
1018
|
+
this.info_bar.clear();
|
|
1019
|
+
this.set_buttons_sensitive();
|
|
1020
|
+
});
|
|
1011
1021
|
});
|
|
1012
1022
|
},
|
|
1013
1023
|
next: function() {
|
|
1014
1024
|
return this.modified_save().then(() => {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1025
|
+
return this.screen.display_next().then(() => {
|
|
1026
|
+
this.info_bar.clear();
|
|
1027
|
+
this.set_buttons_sensitive();
|
|
1028
|
+
});
|
|
1019
1029
|
});
|
|
1020
1030
|
},
|
|
1021
1031
|
search: function() {
|
|
@@ -1409,6 +1419,8 @@
|
|
|
1409
1419
|
let chat = this.sidebar_content.find('.chat');
|
|
1410
1420
|
if (chat.length) {
|
|
1411
1421
|
chat.remove();
|
|
1422
|
+
this._chat.unregister()
|
|
1423
|
+
this._chat = null;
|
|
1412
1424
|
} else {
|
|
1413
1425
|
if (this.screen.current_reference) {
|
|
1414
1426
|
this._chat = new Sao.Chat(this.screen.current_reference);
|
package/src/view/form.js
CHANGED
|
@@ -382,7 +382,8 @@ function eval_pyson(value){
|
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
384
|
return jQuery.when.apply(jQuery,promesses)
|
|
385
|
-
.
|
|
385
|
+
.then(() => {
|
|
386
|
+
let promesses = [];
|
|
386
387
|
var record = this.record;
|
|
387
388
|
for (const name in this.widgets) {
|
|
388
389
|
var widgets = this.widgets[name];
|
|
@@ -394,10 +395,12 @@ function eval_pyson(value){
|
|
|
394
395
|
field.set_state(record);
|
|
395
396
|
}
|
|
396
397
|
for (const widget of widgets) {
|
|
397
|
-
widget.display();
|
|
398
|
+
let prm = widget.display();
|
|
399
|
+
if (prm) {
|
|
400
|
+
promesses.push(prm);
|
|
401
|
+
}
|
|
398
402
|
}
|
|
399
403
|
}
|
|
400
|
-
var promesses = [];
|
|
401
404
|
// We iterate in the reverse order so that the most nested
|
|
402
405
|
// widgets are computed first and set_state methods can rely
|
|
403
406
|
// on their children having their state set
|
|
@@ -412,7 +415,7 @@ function eval_pyson(value){
|
|
|
412
415
|
}
|
|
413
416
|
// re-set the grid templates for the StateWidget that are
|
|
414
417
|
// asynchronous
|
|
415
|
-
jQuery.when.apply(jQuery, promesses).
|
|
418
|
+
return jQuery.when.apply(jQuery, promesses).then(() => {
|
|
416
419
|
for (const container of this.containers) {
|
|
417
420
|
container.set_grid_template();
|
|
418
421
|
}
|
|
@@ -2249,11 +2252,13 @@ function eval_pyson(value){
|
|
|
2249
2252
|
this.el = jQuery('<div/>', {
|
|
2250
2253
|
'class': this.class_
|
|
2251
2254
|
});
|
|
2255
|
+
this.group = jQuery('<div/>', {
|
|
2256
|
+
'class': 'input-group input-group-sm'
|
|
2257
|
+
}).css('width', '100%').appendTo(this.el);
|
|
2252
2258
|
this.select = this.labelled = jQuery('<select/>', {
|
|
2253
2259
|
'class': 'form-control input-sm mousetrap',
|
|
2254
2260
|
'name': attributes.name,
|
|
2255
|
-
});
|
|
2256
|
-
this.el.append(this.select);
|
|
2261
|
+
}).appendTo(this.group);
|
|
2257
2262
|
this.select.change(this.focus_out.bind(this));
|
|
2258
2263
|
Sao.common.selection_mixin.init.call(this);
|
|
2259
2264
|
this.init_selection();
|
|
@@ -2354,11 +2359,14 @@ function eval_pyson(value){
|
|
|
2354
2359
|
this.el = jQuery('<div/>', {
|
|
2355
2360
|
'class': this.class_
|
|
2356
2361
|
});
|
|
2362
|
+
this.group = jQuery('<div/>', {
|
|
2363
|
+
'class': 'input-group input-group-sm'
|
|
2364
|
+
}).css('width', '100%').appendTo(this.el);
|
|
2357
2365
|
this.input = this.labelled = jQuery('<input/>', {
|
|
2358
2366
|
'type': 'checkbox',
|
|
2359
2367
|
'class': 'form-control input-sm mousetrap',
|
|
2360
2368
|
'name': attributes.name,
|
|
2361
|
-
}).appendTo(this.
|
|
2369
|
+
}).appendTo(this.group);
|
|
2362
2370
|
this.input.change(this.focus_out.bind(this));
|
|
2363
2371
|
this.input.click(function() {
|
|
2364
2372
|
// Dont trigger click if field is readonly as readonly has no
|
|
@@ -3621,7 +3629,7 @@ function eval_pyson(value){
|
|
|
3621
3629
|
display: function() {
|
|
3622
3630
|
Sao.View.Form.One2Many._super.display.call(this);
|
|
3623
3631
|
|
|
3624
|
-
this.prm.
|
|
3632
|
+
return this.prm.then(() => {
|
|
3625
3633
|
this._set_button_sensitive();
|
|
3626
3634
|
|
|
3627
3635
|
var record = this.record;
|
|
@@ -3631,9 +3639,8 @@ function eval_pyson(value){
|
|
|
3631
3639
|
this.screen.new_group();
|
|
3632
3640
|
this.screen.current_record = null;
|
|
3633
3641
|
this.screen.group.parent = null;
|
|
3634
|
-
this.screen.display();
|
|
3635
3642
|
this.screen.screen_container.hide_filter();
|
|
3636
|
-
return;
|
|
3643
|
+
return this.screen.display();
|
|
3637
3644
|
}
|
|
3638
3645
|
|
|
3639
3646
|
var new_group = record.field_get_client(this.field_name);
|
|
@@ -3662,13 +3669,13 @@ function eval_pyson(value){
|
|
|
3662
3669
|
this.screen.domain = domain;
|
|
3663
3670
|
}
|
|
3664
3671
|
this.screen.size_limit = size_limit;
|
|
3665
|
-
this.screen.display();
|
|
3666
3672
|
if (this.attributes.height !== undefined) {
|
|
3667
3673
|
this.content
|
|
3668
3674
|
.find('.treeview,.list-form').first()
|
|
3669
3675
|
.css('min-height', this.attributes.height + 'px')
|
|
3670
3676
|
.css('max-height', this.attributes.height + 'px');
|
|
3671
3677
|
}
|
|
3678
|
+
return this.screen.display();
|
|
3672
3679
|
});
|
|
3673
3680
|
},
|
|
3674
3681
|
focus: function() {
|
|
@@ -3968,9 +3975,7 @@ function eval_pyson(value){
|
|
|
3968
3975
|
return prm;
|
|
3969
3976
|
},
|
|
3970
3977
|
set_value: function() {
|
|
3971
|
-
|
|
3972
|
-
this.view.screen.record_modified(false);
|
|
3973
|
-
}
|
|
3978
|
+
this.screen.current_view.set_value();
|
|
3974
3979
|
},
|
|
3975
3980
|
_update_completion: function(text) {
|
|
3976
3981
|
if (!this.record) {
|
|
@@ -4204,7 +4209,7 @@ function eval_pyson(value){
|
|
|
4204
4209
|
display: function() {
|
|
4205
4210
|
Sao.View.Form.Many2Many._super.display.call(this);
|
|
4206
4211
|
|
|
4207
|
-
this.prm.
|
|
4212
|
+
return this.prm.then(() => {
|
|
4208
4213
|
var record = this.record;
|
|
4209
4214
|
var field = this.field;
|
|
4210
4215
|
|
|
@@ -4212,21 +4217,20 @@ function eval_pyson(value){
|
|
|
4212
4217
|
this.screen.new_group();
|
|
4213
4218
|
this.screen.current_record = null;
|
|
4214
4219
|
this.screen.group.parent = null;
|
|
4215
|
-
this.screen.display();
|
|
4216
4220
|
this.screen.screen_container.hide_filter();
|
|
4217
|
-
return;
|
|
4221
|
+
return this.screen.display();
|
|
4218
4222
|
}
|
|
4219
4223
|
var new_group = record.field_get_client(this.field_name);
|
|
4220
4224
|
if (new_group != this.screen.group) {
|
|
4221
4225
|
this.screen.set_group(new_group);
|
|
4222
4226
|
}
|
|
4223
|
-
this.screen.display();
|
|
4224
4227
|
if (this.attributes.height !== undefined) {
|
|
4225
4228
|
this.content
|
|
4226
4229
|
.find('.treeview,.list-form').first()
|
|
4227
4230
|
.css('min-height', this.attributes.height + 'px')
|
|
4228
4231
|
.css('max-height', this.attributes.height + 'px');
|
|
4229
4232
|
}
|
|
4233
|
+
return this.screen.display();
|
|
4230
4234
|
});
|
|
4231
4235
|
},
|
|
4232
4236
|
focus: function() {
|
package/src/view/tree.js
CHANGED
|
@@ -426,6 +426,8 @@
|
|
|
426
426
|
'reset_width',
|
|
427
427
|
[this.screen.model_name, window.screen.width],
|
|
428
428
|
{});
|
|
429
|
+
Sao.Session.current_session.cache.clear(
|
|
430
|
+
`model.${this.screen.model_name}.fields_view_get`);
|
|
429
431
|
|
|
430
432
|
for (let column of this.columns) {
|
|
431
433
|
if (column.col.data('default-width')) {
|
|
@@ -475,7 +477,7 @@
|
|
|
475
477
|
|
|
476
478
|
let tree_column_width = (
|
|
477
479
|
Sao.Screen.tree_column_width[this.screen.model_name] || {});
|
|
478
|
-
let width = tree_column_width[name];
|
|
480
|
+
let width = tree_column_width[column.attributes.name];
|
|
479
481
|
if (width || column.attributes.width) {
|
|
480
482
|
if (!width) {
|
|
481
483
|
width = column.attributes.width;
|
|
@@ -2760,6 +2762,10 @@
|
|
|
2760
2762
|
fields, false, false)) {
|
|
2761
2763
|
var value = cell.prop('checked');
|
|
2762
2764
|
this.field.set_client(record, value);
|
|
2765
|
+
if (record !== current_record) {
|
|
2766
|
+
// we can not rely on editable tree handler to save the row
|
|
2767
|
+
record.save();
|
|
2768
|
+
}
|
|
2763
2769
|
} else {
|
|
2764
2770
|
evt.preventDefault();
|
|
2765
2771
|
}
|