tryton-sao 7.4.21 → 7.4.22

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.4.22 - 2025-12-17
3
+ ---------------------------
4
+ * Bug fixes (see mercurial logs for details)
5
+
6
+
2
7
  Version 7.4.21 - 2025-11-21
3
8
  ---------------------------
4
9
  * Bug fixes (see mercurial logs for details)
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.4.21',
6
+ __version__: '7.4.22',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
@@ -4606,11 +4606,12 @@ var Sao = {
4606
4606
  var name = clause[0];
4607
4607
  var operator = clause[1];
4608
4608
  var value = clause[2];
4609
- if (name.endsWith('.rec_name')) {
4609
+ if (name.endsWith('.rec_name')
4610
+ && (value || (clause.length > 3))) {
4610
4611
  name = name.slice(0, -9);
4611
4612
  }
4612
4613
  if (!(name in this.fields)) {
4613
- if (this.is_full_text(value)) {
4614
+ if ((value !== null) && this.is_full_text(value)) {
4614
4615
  value = value.slice(1, -1);
4615
4616
  }
4616
4617
  return this.quote(value);
@@ -5532,7 +5533,7 @@ var Sao = {
5532
5533
  break;
5533
5534
  }
5534
5535
  }
5535
- return target + ',' + value;
5536
+ return target + ',' + (value || '');
5536
5537
  };
5537
5538
 
5538
5539
  var converts = {
@@ -6955,7 +6956,10 @@ var Sao = {
6955
6956
  }).appendTo(dialog.body);
6956
6957
  alert_.append(jQuery('<h4/>')
6957
6958
  .text(title)
6958
- .css('white-space', 'pre-wrap'));
6959
+ .css({
6960
+ 'white-space': 'pre-wrap',
6961
+ 'word-break': 'break-all',
6962
+ }));
6959
6963
  alert_.append(jQuery('<p/>').append(jQuery('<a/>', {
6960
6964
  'class': 'btn btn-default',
6961
6965
  role: 'button',
@@ -8775,7 +8779,7 @@ var Sao = {
8775
8779
  this.on_change(fieldnames);
8776
8780
  this.on_change_with(fieldnames);
8777
8781
  if (validate) {
8778
- return this.validate(null, true);
8782
+ this.validate(null, true);
8779
8783
  }
8780
8784
  if (modified) {
8781
8785
  this.set_modified();
@@ -11157,7 +11161,7 @@ var Sao = {
11157
11161
  if (other.compare(attributes)) {
11158
11162
  Sao.common.scrollIntoViewIfNeeded(
11159
11163
  tablist.find('a[href="#' + other.id + '"]').tab('show'));
11160
- return;
11164
+ return jQuery.when();
11161
11165
  }
11162
11166
  }
11163
11167
  var tab;
@@ -17132,7 +17136,7 @@ function eval_pyson(value){
17132
17136
  },
17133
17137
  get width() {
17134
17138
  var digits = this.digits;
17135
- if (digits) {
17139
+ if (digits && digits.every(d => d !== null)) {
17136
17140
  return digits.reduce(function(acc, cur) {
17137
17141
  return acc + cur;
17138
17142
  });
@@ -17764,15 +17768,21 @@ function eval_pyson(value){
17764
17768
  } else {
17765
17769
  this._popup = true;
17766
17770
  }
17771
+ let view_ids = (this.attributes.view_ids || '').split(',');
17767
17772
  if (this.has_target(value)) {
17768
17773
  var m2o_id =
17769
17774
  this.id_from_value(record.field_get(this.field_name));
17770
17775
  if (evt && (evt.ctrlKey || evt.metaKey)) {
17776
+ if (!jQuery.isEmptyObject(view_ids)) {
17777
+ // Remove the first tree view as mode is form only
17778
+ view_ids.shift();
17779
+ }
17771
17780
  var params = {};
17772
17781
  params.model = this.get_model();
17773
17782
  params.res_id = m2o_id;
17774
17783
  params.mode = ['form'];
17775
17784
  params.name = this.attributes.string;
17785
+ params.view_ids = view_ids;
17776
17786
  params.context = this.field.get_context(this.record);
17777
17787
  Sao.Tab.create(params);
17778
17788
  this._popup = false;
@@ -17821,8 +17831,7 @@ function eval_pyson(value){
17821
17831
  context: context,
17822
17832
  domain: domain,
17823
17833
  order: order,
17824
- view_ids: (this.attributes.view_ids ||
17825
- '').split(','),
17834
+ view_ids: view_ids,
17826
17835
  views_preload: (this.attributes.views || {}),
17827
17836
  new_: this.create_access,
17828
17837
  search_filter: parser.quote(text),
@@ -22818,9 +22827,11 @@ function eval_pyson(value){
22818
22827
  return;
22819
22828
  }
22820
22829
 
22821
- body = listener = jQuery(document.body);
22830
+ body = jQuery(document.body);
22822
22831
  if (body.hasClass('modal-open')) {
22823
22832
  listener = this.tree.el.parents('.modal').last();
22833
+ } else {
22834
+ listener = this.tree.el.parents('.tab-pane').last();
22824
22835
  }
22825
22836
  const handler = event_ => {
22826
22837
  if ((event_.currentTarget == body[0]) &&
@@ -22833,7 +22844,7 @@ function eval_pyson(value){
22833
22844
  event_.stopPropagation();
22834
22845
  return;
22835
22846
  }
22836
- body.off('click.sao.editabletree');
22847
+ listener.off('click.sao.editabletree');
22837
22848
  this.tree.edit_row(null);
22838
22849
  return true;
22839
22850
  };
@@ -22962,7 +22973,10 @@ function eval_pyson(value){
22962
22973
  }
22963
22974
  }
22964
22975
  this._get_column_td(next_column)
22965
- .find(':input,[tabindex=0]').focus();
22976
+ .find(':input,[tabindex=0]')
22977
+ .filter(':visible')
22978
+ .first()
22979
+ .focus();
22966
22980
  } else {
22967
22981
  var prm = jQuery.when();
22968
22982
  if (!this.tree.screen.group.parent) {
@@ -23011,7 +23025,10 @@ function eval_pyson(value){
23011
23025
  this._get_column_td(
23012
23026
  next_column, next_row)
23013
23027
  .trigger('click')
23028
+ .trigger('click')
23014
23029
  .find(':input,[tabindex=0]')
23030
+ .filter(':visible')
23031
+ .first()
23015
23032
  .focus();
23016
23033
  });
23017
23034
  }
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.4.21",
5
+ "version": "7.4.22",
6
6
  "homepage": "https://www.tryton.org/",
7
7
  "author": {
8
8
  "name": "Tryton"
package/src/common.js CHANGED
@@ -1257,11 +1257,12 @@
1257
1257
  var name = clause[0];
1258
1258
  var operator = clause[1];
1259
1259
  var value = clause[2];
1260
- if (name.endsWith('.rec_name')) {
1260
+ if (name.endsWith('.rec_name')
1261
+ && (value || (clause.length > 3))) {
1261
1262
  name = name.slice(0, -9);
1262
1263
  }
1263
1264
  if (!(name in this.fields)) {
1264
- if (this.is_full_text(value)) {
1265
+ if ((value !== null) && this.is_full_text(value)) {
1265
1266
  value = value.slice(1, -1);
1266
1267
  }
1267
1268
  return this.quote(value);
@@ -2183,7 +2184,7 @@
2183
2184
  break;
2184
2185
  }
2185
2186
  }
2186
- return target + ',' + value;
2187
+ return target + ',' + (value || '');
2187
2188
  };
2188
2189
 
2189
2190
  var converts = {
@@ -3606,7 +3607,10 @@
3606
3607
  }).appendTo(dialog.body);
3607
3608
  alert_.append(jQuery('<h4/>')
3608
3609
  .text(title)
3609
- .css('white-space', 'pre-wrap'));
3610
+ .css({
3611
+ 'white-space': 'pre-wrap',
3612
+ 'word-break': 'break-all',
3613
+ }));
3610
3614
  alert_.append(jQuery('<p/>').append(jQuery('<a/>', {
3611
3615
  'class': 'btn btn-default',
3612
3616
  role: 'button',
package/src/model.js CHANGED
@@ -1021,7 +1021,7 @@
1021
1021
  this.on_change(fieldnames);
1022
1022
  this.on_change_with(fieldnames);
1023
1023
  if (validate) {
1024
- return this.validate(null, true);
1024
+ this.validate(null, true);
1025
1025
  }
1026
1026
  if (modified) {
1027
1027
  this.set_modified();
package/src/sao.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.4.21',
6
+ __version__: '7.4.22',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
package/src/tab.js CHANGED
@@ -414,7 +414,7 @@
414
414
  if (other.compare(attributes)) {
415
415
  Sao.common.scrollIntoViewIfNeeded(
416
416
  tablist.find('a[href="#' + other.id + '"]').tab('show'));
417
- return;
417
+ return jQuery.when();
418
418
  }
419
419
  }
420
420
  var tab;
package/src/view/form.js CHANGED
@@ -2170,7 +2170,7 @@ function eval_pyson(value){
2170
2170
  },
2171
2171
  get width() {
2172
2172
  var digits = this.digits;
2173
- if (digits) {
2173
+ if (digits && digits.every(d => d !== null)) {
2174
2174
  return digits.reduce(function(acc, cur) {
2175
2175
  return acc + cur;
2176
2176
  });
@@ -2802,15 +2802,21 @@ function eval_pyson(value){
2802
2802
  } else {
2803
2803
  this._popup = true;
2804
2804
  }
2805
+ let view_ids = (this.attributes.view_ids || '').split(',');
2805
2806
  if (this.has_target(value)) {
2806
2807
  var m2o_id =
2807
2808
  this.id_from_value(record.field_get(this.field_name));
2808
2809
  if (evt && (evt.ctrlKey || evt.metaKey)) {
2810
+ if (!jQuery.isEmptyObject(view_ids)) {
2811
+ // Remove the first tree view as mode is form only
2812
+ view_ids.shift();
2813
+ }
2809
2814
  var params = {};
2810
2815
  params.model = this.get_model();
2811
2816
  params.res_id = m2o_id;
2812
2817
  params.mode = ['form'];
2813
2818
  params.name = this.attributes.string;
2819
+ params.view_ids = view_ids;
2814
2820
  params.context = this.field.get_context(this.record);
2815
2821
  Sao.Tab.create(params);
2816
2822
  this._popup = false;
@@ -2859,8 +2865,7 @@ function eval_pyson(value){
2859
2865
  context: context,
2860
2866
  domain: domain,
2861
2867
  order: order,
2862
- view_ids: (this.attributes.view_ids ||
2863
- '').split(','),
2868
+ view_ids: view_ids,
2864
2869
  views_preload: (this.attributes.views || {}),
2865
2870
  new_: this.create_access,
2866
2871
  search_filter: parser.quote(text),
package/src/view/tree.js CHANGED
@@ -2026,9 +2026,11 @@
2026
2026
  return;
2027
2027
  }
2028
2028
 
2029
- body = listener = jQuery(document.body);
2029
+ body = jQuery(document.body);
2030
2030
  if (body.hasClass('modal-open')) {
2031
2031
  listener = this.tree.el.parents('.modal').last();
2032
+ } else {
2033
+ listener = this.tree.el.parents('.tab-pane').last();
2032
2034
  }
2033
2035
  const handler = event_ => {
2034
2036
  if ((event_.currentTarget == body[0]) &&
@@ -2041,7 +2043,7 @@
2041
2043
  event_.stopPropagation();
2042
2044
  return;
2043
2045
  }
2044
- body.off('click.sao.editabletree');
2046
+ listener.off('click.sao.editabletree');
2045
2047
  this.tree.edit_row(null);
2046
2048
  return true;
2047
2049
  };
@@ -2170,7 +2172,10 @@
2170
2172
  }
2171
2173
  }
2172
2174
  this._get_column_td(next_column)
2173
- .find(':input,[tabindex=0]').focus();
2175
+ .find(':input,[tabindex=0]')
2176
+ .filter(':visible')
2177
+ .first()
2178
+ .focus();
2174
2179
  } else {
2175
2180
  var prm = jQuery.when();
2176
2181
  if (!this.tree.screen.group.parent) {
@@ -2219,7 +2224,10 @@
2219
2224
  this._get_column_td(
2220
2225
  next_column, next_row)
2221
2226
  .trigger('click')
2227
+ .trigger('click')
2222
2228
  .find(':input,[tabindex=0]')
2229
+ .filter(':visible')
2230
+ .first()
2223
2231
  .focus();
2224
2232
  });
2225
2233
  }
package/tests/sao.js CHANGED
@@ -2048,6 +2048,9 @@
2048
2048
  [[c(['Reference', null, 'Spam,bar'])], [
2049
2049
  c(['reference.rec_name', 'ilike', '%bar%', 'spam'])
2050
2050
  ]],
2051
+ [[c(['Reference', null, 'Spam,'])], [
2052
+ c(['reference.rec_name', 'ilike', '%', 'spam'])
2053
+ ]],
2051
2054
  [[c(['Reference', null, ['foo', 'bar']])], [
2052
2055
  c(['reference', 'in', ['foo', 'bar']])
2053
2056
  ]],
@@ -2376,6 +2379,7 @@
2376
2379
  [[['multiselection', 'not in', ['foo', 'bar']]], "MultiSelection: !Foo;Bar"],
2377
2380
  [[['reference', 'ilike', '%foo%']], 'Reference: foo'],
2378
2381
  [[['reference', 'ilike', '%bar%', 'spam']], 'Reference: Spam,bar'],
2382
+ [[['reference.rec_name', '=', null, 'spam']], 'Reference: =Spam,'],
2379
2383
  [[['reference', 'in', ['foo', 'bar']]], 'Reference: foo;bar'],
2380
2384
  [[['many2one', 'ilike', '%John%']], 'Many2One: John'],
2381
2385
  [[['many2one.rec_name', 'in', ['John', 'Jane']]], 'Many2One: John;Jane'],