tryton-sao 7.6.2 → 7.6.3

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 CHANGED
@@ -1,4 +1,9 @@
1
1
 
2
+ Version 7.6.3 - 2025-07-01
3
+ --------------------------
4
+ * Bug fixes (see mercurial logs for details)
5
+
6
+
2
7
  Version 7.6.2 - 2025-06-04
3
8
  --------------------------
4
9
  * Bug fixes (see mercurial logs for details)
@@ -8786,6 +8786,11 @@ html[theme="default"] .radio input[type="radio"]:focus,
8786
8786
  html[theme="default"] .radio-inline input[type="radio"]:focus {
8787
8787
  outline: none;
8788
8788
  }
8789
+ html[theme="default"] input[type="radio"]:focus:after,
8790
+ html[theme="default"] .radio input[type="radio"]:focus:after,
8791
+ html[theme="default"] .radio-inline input[type="radio"]:focus:after {
8792
+ border-color: #71bdc1 !important;
8793
+ }
8789
8794
  html[theme="default"] input[type="radio"]:before,
8790
8795
  html[theme="default"] .radio input[type="radio"]:before,
8791
8796
  html[theme="default"] .radio-inline input[type="radio"]:before,
@@ -8886,10 +8891,10 @@ html[theme="default"] .checkbox input[type="checkbox"]:focus,
8886
8891
  html[theme="default"] .checkbox-inline input[type="checkbox"]:focus {
8887
8892
  outline: none;
8888
8893
  }
8889
- html[theme="default"] input[type="checkbox"]:focus:before,
8890
- html[theme="default"] .checkbox input[type="checkbox"]:focus:before,
8891
- html[theme="default"] .checkbox-inline input[type="checkbox"]:focus:before {
8892
- border-color: #267f82;
8894
+ html[theme="default"] input[type="checkbox"]:focus:after,
8895
+ html[theme="default"] .checkbox input[type="checkbox"]:focus:after,
8896
+ html[theme="default"] .checkbox-inline input[type="checkbox"]:focus:after {
8897
+ border-color: #71bdc1 !important;
8893
8898
  }
8894
8899
  html[theme="default"] input[type="checkbox"]:after,
8895
8900
  html[theme="default"] .checkbox input[type="checkbox"]:after,
@@ -9235,7 +9240,8 @@ html[theme="default"] .carousel-caption h6 {
9235
9240
  float: none;
9236
9241
  }
9237
9242
  }
9238
- .btn-primary .icon {
9243
+ .btn-primary .icon,
9244
+ .bg-primary .icon {
9239
9245
  filter: brightness(0) invert(1);
9240
9246
  }
9241
9247
  .panel-heading a {
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.6.2',
6
+ __version__: '7.6.3',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
@@ -1174,20 +1174,26 @@ var Sao = {
1174
1174
  shortcut: 'alt+shift+tab',
1175
1175
  label: Sao.i18n.gettext('Previous tab'),
1176
1176
  callback: function() {
1177
- Sao.Tab.previous_tab();
1177
+ if (!jQuery('body').children('.modal').length) {
1178
+ Sao.Tab.previous_tab();
1179
+ }
1178
1180
  },
1179
1181
  }, {
1180
1182
  shortcut: 'alt+tab',
1181
1183
  label: Sao.i18n.gettext('Next tab'),
1182
1184
  callback: function() {
1183
- Sao.Tab.next_tab();
1185
+ if (!jQuery('body').children('.modal').length) {
1186
+ Sao.Tab.next_tab();
1187
+ }
1184
1188
  },
1185
1189
  }, {
1186
1190
  shortcut: 'ctrl+k',
1187
1191
  label: Sao.i18n.gettext('Global search'),
1188
1192
  callback: function() {
1189
- jQuery('#main_navbar:hidden').collapse('show');
1190
- jQuery('#global-search-entry').focus();
1193
+ if (!jQuery('body').children('.modal').length) {
1194
+ jQuery('#main_navbar:hidden').collapse('show');
1195
+ jQuery('#global-search-entry').focus();
1196
+ }
1191
1197
  },
1192
1198
  }, {
1193
1199
  shortcut: 'f1',
@@ -5371,8 +5377,13 @@ var Sao = {
5371
5377
  }
5372
5378
  let { format } = new Intl.NumberFormat(
5373
5379
  Sao.i18n.BC47(Sao.i18n.getlang()));
5380
+ // use 10000 because some language (ex: es) add thousand
5381
+ // separator only after 9999
5382
+ let [, thousandSeparator] = /^10(.)?000/.exec(format(10000));
5374
5383
  let [, decimalSign] = /^0(.)1$/.exec(format(0.1));
5375
- return Number(string.replace(decimalSign, '.'));
5384
+ return Number(string
5385
+ .replaceAll(thousandSeparator, '')
5386
+ .replace(decimalSign, '.'));
5376
5387
  }
5377
5388
  var convert_selection = function() {
5378
5389
  if (typeof value == 'string') {
@@ -11625,40 +11636,40 @@ var Sao = {
11625
11636
  });
11626
11637
  },
11627
11638
  modified_save: function() {
11628
- this.screen.save_tree_state();
11629
- this.screen.current_view.set_value();
11630
- if (this.screen.modified()) {
11631
- return Sao.common.sur_3b.run(
11632
- Sao.i18n.gettext('This record has been modified\n' +
11633
- 'do you want to save it?'))
11634
- .then(result => {
11635
- switch(result) {
11636
- case 'ok':
11637
- return this.save();
11638
- case 'ko':
11639
- var record_id = null;
11640
- if (this.screen.current_record) {
11641
- record_id = this.screen.current_record.id;
11642
- }
11643
- return this.reload(false).then(() => {
11644
- if (record_id !== null) {
11645
- if (record_id < 0) {
11646
- return jQuery.Deferred().reject(true);
11647
- }
11648
- else if (this.screen.current_record) {
11649
- if (record_id !=
11650
- this.screen.current_record.id) {
11651
- return jQuery.Deferred().reject();
11639
+ return this.screen.save_tree_state().then(() => {
11640
+ this.screen.current_view.set_value();
11641
+ if (this.screen.modified()) {
11642
+ return Sao.common.sur_3b.run(
11643
+ Sao.i18n.gettext('This record has been modified\n' +
11644
+ 'do you want to save it?'))
11645
+ .then(result => {
11646
+ switch(result) {
11647
+ case 'ok':
11648
+ return this.save();
11649
+ case 'ko':
11650
+ var record_id = null;
11651
+ if (this.screen.current_record) {
11652
+ record_id = this.screen.current_record.id;
11653
+ }
11654
+ return this.reload(false).then(() => {
11655
+ if (record_id !== null) {
11656
+ if (record_id < 0) {
11657
+ return jQuery.Deferred().reject(true);
11658
+ }
11659
+ else if (this.screen.current_record) {
11660
+ if (record_id !=
11661
+ this.screen.current_record.id) {
11662
+ return jQuery.Deferred().reject();
11663
+ }
11652
11664
  }
11653
11665
  }
11654
- }
11655
- });
11656
- default:
11657
- return jQuery.Deferred().reject();
11658
- }
11659
- });
11660
- }
11661
- return jQuery.when();
11666
+ });
11667
+ default:
11668
+ return jQuery.Deferred().reject();
11669
+ }
11670
+ });
11671
+ }
11672
+ });
11662
11673
  },
11663
11674
  new_: function() {
11664
11675
  if (!Sao.common.MODELACCESS.get(this.screen.model_name).create) {
@@ -11672,24 +11683,29 @@ var Sao = {
11672
11683
  });
11673
11684
  },
11674
11685
  save: function(tab) {
11686
+ let prm;
11675
11687
  if (tab) {
11676
11688
  // Called from button so we must save the tree state
11677
- this.screen.save_tree_state();
11678
- }
11679
- var access = Sao.common.MODELACCESS.get(this.screen.model_name);
11680
- if (this.screen.readonly || !(access.write || access.create)) {
11681
- return jQuery.Deferred().reject();
11689
+ prm = this.screen.save_tree_state();
11690
+ } else {
11691
+ prm = jQuery.when();
11682
11692
  }
11683
- return this.screen.save_current().then(
11684
- () => {
11685
- this.info_bar.add(
11686
- Sao.i18n.gettext('Record saved.'), 'info');
11687
- this.screen.count_tab_domain(true);
11688
- }, () => {
11689
- this.info_bar.add(
11690
- this.screen.invalid_message(), 'danger');
11693
+ prm.then(() => {
11694
+ var access = Sao.common.MODELACCESS.get(this.screen.model_name);
11695
+ if (this.screen.readonly || !(access.write || access.create)) {
11691
11696
  return jQuery.Deferred().reject();
11692
- });
11697
+ }
11698
+ return this.screen.save_current().then(
11699
+ () => {
11700
+ this.info_bar.add(
11701
+ Sao.i18n.gettext('Record saved.'), 'info');
11702
+ this.screen.count_tab_domain(true);
11703
+ }, () => {
11704
+ this.info_bar.add(
11705
+ this.screen.invalid_message(), 'danger');
11706
+ return jQuery.Deferred().reject();
11707
+ });
11708
+ });
11693
11709
  },
11694
11710
  switch_: function() {
11695
11711
  return this.modified_save().then(() => this.screen.switch_view());
@@ -11728,8 +11744,7 @@ var Sao = {
11728
11744
  if (test_modified) {
11729
11745
  return this.modified_save().then(reload);
11730
11746
  } else {
11731
- this.screen.save_tree_state(false);
11732
- return reload();
11747
+ return this.screen.save_tree_state(false).then(reload);
11733
11748
  }
11734
11749
  },
11735
11750
  copy: function() {
@@ -19046,7 +19061,6 @@ function eval_pyson(value){
19046
19061
  return prm;
19047
19062
  },
19048
19063
  set_value: function() {
19049
- this.screen.save_tree_state();
19050
19064
  if (this.screen.modified()) { // TODO check if required
19051
19065
  this.view.screen.record_modified(false);
19052
19066
  }
@@ -21866,6 +21880,11 @@ function eval_pyson(value){
21866
21880
  this.display_size = Sao.config.display_size;
21867
21881
  }
21868
21882
  }
21883
+ if (!this.display_size &
21884
+ (!jQuery.isEmptyObject(selected) ||
21885
+ !jQuery.isEmptyObject(expanded))) {
21886
+ this.display_size = Sao.config.display_size;
21887
+ }
21869
21888
  let display_size = this.display_size || 0;
21870
21889
  var current_record = this.record;
21871
21890
  if (jQuery.isEmptyObject(selected) && current_record) {
@@ -23000,12 +23019,13 @@ function eval_pyson(value){
23000
23019
  current_record = this.tree.screen.current_record;
23001
23020
  this.tree.select_records(current_record, this.record);
23002
23021
  } else {
23022
+ let selected = this.is_selected();
23003
23023
  if (!(event_.ctrlKey || event_.metaKey) ||
23004
23024
  this.tree.selection_mode ==
23005
23025
  Sao.common.SELECTION_SINGLE) {
23006
23026
  this.tree.select_records(null, null);
23007
23027
  }
23008
- this.set_selection(!this.is_selected());
23028
+ this.set_selection(!selected);
23009
23029
  }
23010
23030
  if (event_.shiftKey || event_.ctrlKey || event_.metaKey) {
23011
23031
  Sao.common.clear_selection();
@@ -23039,6 +23059,9 @@ function eval_pyson(value){
23039
23059
  },
23040
23060
  selection_changed: function() {
23041
23061
  var is_selected = this.is_selected();
23062
+ if (this.tree.selection_mode == Sao.common.SELECTION_SINGLE) {
23063
+ this.tree.select_records(null, null);
23064
+ }
23042
23065
  this.set_selection(is_selected);
23043
23066
  if (is_selected) {
23044
23067
  this.tree.select_changed(this.record);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "tryton-sao",
3
3
  "title": "sao",
4
4
  "description": "Tryton webclient",
5
- "version": "7.6.2",
5
+ "version": "7.6.3",
6
6
  "homepage": "https://www.tryton.org/",
7
7
  "author": {
8
8
  "name": "Tryton"
package/src/common.js CHANGED
@@ -2038,8 +2038,13 @@
2038
2038
  }
2039
2039
  let { format } = new Intl.NumberFormat(
2040
2040
  Sao.i18n.BC47(Sao.i18n.getlang()));
2041
+ // use 10000 because some language (ex: es) add thousand
2042
+ // separator only after 9999
2043
+ let [, thousandSeparator] = /^10(.)?000/.exec(format(10000));
2041
2044
  let [, decimalSign] = /^0(.)1$/.exec(format(0.1));
2042
- return Number(string.replace(decimalSign, '.'));
2045
+ return Number(string
2046
+ .replaceAll(thousandSeparator, '')
2047
+ .replace(decimalSign, '.'));
2043
2048
  }
2044
2049
  var convert_selection = function() {
2045
2050
  if (typeof value == 'string') {
package/src/sao.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.6.2',
6
+ __version__: '7.6.3',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
@@ -1174,20 +1174,26 @@ var Sao = {
1174
1174
  shortcut: 'alt+shift+tab',
1175
1175
  label: Sao.i18n.gettext('Previous tab'),
1176
1176
  callback: function() {
1177
- Sao.Tab.previous_tab();
1177
+ if (!jQuery('body').children('.modal').length) {
1178
+ Sao.Tab.previous_tab();
1179
+ }
1178
1180
  },
1179
1181
  }, {
1180
1182
  shortcut: 'alt+tab',
1181
1183
  label: Sao.i18n.gettext('Next tab'),
1182
1184
  callback: function() {
1183
- Sao.Tab.next_tab();
1185
+ if (!jQuery('body').children('.modal').length) {
1186
+ Sao.Tab.next_tab();
1187
+ }
1184
1188
  },
1185
1189
  }, {
1186
1190
  shortcut: 'ctrl+k',
1187
1191
  label: Sao.i18n.gettext('Global search'),
1188
1192
  callback: function() {
1189
- jQuery('#main_navbar:hidden').collapse('show');
1190
- jQuery('#global-search-entry').focus();
1193
+ if (!jQuery('body').children('.modal').length) {
1194
+ jQuery('#main_navbar:hidden').collapse('show');
1195
+ jQuery('#global-search-entry').focus();
1196
+ }
1191
1197
  },
1192
1198
  }, {
1193
1199
  shortcut: 'f1',
package/src/sao.less CHANGED
@@ -114,7 +114,7 @@ html[theme="default"] {
114
114
  }
115
115
  }
116
116
 
117
- .btn-primary {
117
+ .btn-primary, .bg-primary {
118
118
  .icon {
119
119
  filter: brightness(0) invert(1);
120
120
  }
package/src/tab.js CHANGED
@@ -850,40 +850,40 @@
850
850
  });
851
851
  },
852
852
  modified_save: function() {
853
- this.screen.save_tree_state();
854
- this.screen.current_view.set_value();
855
- if (this.screen.modified()) {
856
- return Sao.common.sur_3b.run(
857
- Sao.i18n.gettext('This record has been modified\n' +
858
- 'do you want to save it?'))
859
- .then(result => {
860
- switch(result) {
861
- case 'ok':
862
- return this.save();
863
- case 'ko':
864
- var record_id = null;
865
- if (this.screen.current_record) {
866
- record_id = this.screen.current_record.id;
867
- }
868
- return this.reload(false).then(() => {
869
- if (record_id !== null) {
870
- if (record_id < 0) {
871
- return jQuery.Deferred().reject(true);
872
- }
873
- else if (this.screen.current_record) {
874
- if (record_id !=
875
- this.screen.current_record.id) {
876
- return jQuery.Deferred().reject();
853
+ return this.screen.save_tree_state().then(() => {
854
+ this.screen.current_view.set_value();
855
+ if (this.screen.modified()) {
856
+ return Sao.common.sur_3b.run(
857
+ Sao.i18n.gettext('This record has been modified\n' +
858
+ 'do you want to save it?'))
859
+ .then(result => {
860
+ switch(result) {
861
+ case 'ok':
862
+ return this.save();
863
+ case 'ko':
864
+ var record_id = null;
865
+ if (this.screen.current_record) {
866
+ record_id = this.screen.current_record.id;
867
+ }
868
+ return this.reload(false).then(() => {
869
+ if (record_id !== null) {
870
+ if (record_id < 0) {
871
+ return jQuery.Deferred().reject(true);
872
+ }
873
+ else if (this.screen.current_record) {
874
+ if (record_id !=
875
+ this.screen.current_record.id) {
876
+ return jQuery.Deferred().reject();
877
+ }
877
878
  }
878
879
  }
879
- }
880
- });
881
- default:
882
- return jQuery.Deferred().reject();
883
- }
884
- });
885
- }
886
- return jQuery.when();
880
+ });
881
+ default:
882
+ return jQuery.Deferred().reject();
883
+ }
884
+ });
885
+ }
886
+ });
887
887
  },
888
888
  new_: function() {
889
889
  if (!Sao.common.MODELACCESS.get(this.screen.model_name).create) {
@@ -897,24 +897,29 @@
897
897
  });
898
898
  },
899
899
  save: function(tab) {
900
+ let prm;
900
901
  if (tab) {
901
902
  // Called from button so we must save the tree state
902
- this.screen.save_tree_state();
903
- }
904
- var access = Sao.common.MODELACCESS.get(this.screen.model_name);
905
- if (this.screen.readonly || !(access.write || access.create)) {
906
- return jQuery.Deferred().reject();
903
+ prm = this.screen.save_tree_state();
904
+ } else {
905
+ prm = jQuery.when();
907
906
  }
908
- return this.screen.save_current().then(
909
- () => {
910
- this.info_bar.add(
911
- Sao.i18n.gettext('Record saved.'), 'info');
912
- this.screen.count_tab_domain(true);
913
- }, () => {
914
- this.info_bar.add(
915
- this.screen.invalid_message(), 'danger');
907
+ prm.then(() => {
908
+ var access = Sao.common.MODELACCESS.get(this.screen.model_name);
909
+ if (this.screen.readonly || !(access.write || access.create)) {
916
910
  return jQuery.Deferred().reject();
917
- });
911
+ }
912
+ return this.screen.save_current().then(
913
+ () => {
914
+ this.info_bar.add(
915
+ Sao.i18n.gettext('Record saved.'), 'info');
916
+ this.screen.count_tab_domain(true);
917
+ }, () => {
918
+ this.info_bar.add(
919
+ this.screen.invalid_message(), 'danger');
920
+ return jQuery.Deferred().reject();
921
+ });
922
+ });
918
923
  },
919
924
  switch_: function() {
920
925
  return this.modified_save().then(() => this.screen.switch_view());
@@ -953,8 +958,7 @@
953
958
  if (test_modified) {
954
959
  return this.modified_save().then(reload);
955
960
  } else {
956
- this.screen.save_tree_state(false);
957
- return reload();
961
+ return this.screen.save_tree_state(false).then(reload);
958
962
  }
959
963
  },
960
964
  copy: function() {
package/src/theme.less CHANGED
@@ -243,6 +243,10 @@ input[type="radio"],
243
243
  outline: none;
244
244
  }
245
245
 
246
+ &:focus:after {
247
+ border-color: @brand-info !important;
248
+ }
249
+
246
250
  &:before,
247
251
  &:after {
248
252
  content: "";
@@ -315,8 +319,8 @@ input[type="checkbox"],
315
319
  outline: none;
316
320
  }
317
321
 
318
- &:focus:before {
319
- border-color: @brand-primary;
322
+ &:focus:after {
323
+ border-color: @brand-info !important;
320
324
  }
321
325
 
322
326
  &:after {
package/src/view/form.js CHANGED
@@ -3963,7 +3963,6 @@ function eval_pyson(value){
3963
3963
  return prm;
3964
3964
  },
3965
3965
  set_value: function() {
3966
- this.screen.save_tree_state();
3967
3966
  if (this.screen.modified()) { // TODO check if required
3968
3967
  this.view.screen.record_modified(false);
3969
3968
  }
package/src/view/tree.js CHANGED
@@ -888,6 +888,11 @@
888
888
  this.display_size = Sao.config.display_size;
889
889
  }
890
890
  }
891
+ if (!this.display_size &
892
+ (!jQuery.isEmptyObject(selected) ||
893
+ !jQuery.isEmptyObject(expanded))) {
894
+ this.display_size = Sao.config.display_size;
895
+ }
891
896
  let display_size = this.display_size || 0;
892
897
  var current_record = this.record;
893
898
  if (jQuery.isEmptyObject(selected) && current_record) {
@@ -2022,12 +2027,13 @@
2022
2027
  current_record = this.tree.screen.current_record;
2023
2028
  this.tree.select_records(current_record, this.record);
2024
2029
  } else {
2030
+ let selected = this.is_selected();
2025
2031
  if (!(event_.ctrlKey || event_.metaKey) ||
2026
2032
  this.tree.selection_mode ==
2027
2033
  Sao.common.SELECTION_SINGLE) {
2028
2034
  this.tree.select_records(null, null);
2029
2035
  }
2030
- this.set_selection(!this.is_selected());
2036
+ this.set_selection(!selected);
2031
2037
  }
2032
2038
  if (event_.shiftKey || event_.ctrlKey || event_.metaKey) {
2033
2039
  Sao.common.clear_selection();
@@ -2061,6 +2067,9 @@
2061
2067
  },
2062
2068
  selection_changed: function() {
2063
2069
  var is_selected = this.is_selected();
2070
+ if (this.tree.selection_mode == Sao.common.SELECTION_SINGLE) {
2071
+ this.tree.select_records(null, null);
2072
+ }
2064
2073
  this.set_selection(is_selected);
2065
2074
  if (is_selected) {
2066
2075
  this.tree.select_changed(this.record);