tryton-sao 7.4.21 → 7.4.23

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,14 @@
1
1
 
2
+ Version 7.4.23 - 2025-12-20
3
+ ---------------------------
4
+ * Bug fixes (see mercurial logs for details)
5
+
6
+
7
+ Version 7.4.22 - 2025-12-17
8
+ ---------------------------
9
+ * Bug fixes (see mercurial logs for details)
10
+
11
+
2
12
  Version 7.4.21 - 2025-11-21
3
13
  ---------------------------
4
14
  * 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.23',
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;
@@ -12258,6 +12262,9 @@ var Sao = {
12258
12262
  const view_type = this.screen.current_view.view_type;
12259
12263
  var next_view_type = this.screen.next_view_type;
12260
12264
  const has_views = this.screen.number_of_views > 1;
12265
+ let sensitive = (
12266
+ record_id >= 0 ? record_id !== null && record_id !== undefined :
12267
+ false);
12261
12268
  var buttons = ['print', 'relate', 'email', 'attach'];
12262
12269
  for (const button_id of buttons) {
12263
12270
  const button = this.buttons[button_id];
@@ -12274,7 +12281,7 @@ var Sao = {
12274
12281
  return keyword == button_id;
12275
12282
  });
12276
12283
  }
12277
- set_sensitive(button_id, position && can_be_sensitive);
12284
+ set_sensitive(button_id, sensitive && can_be_sensitive);
12278
12285
  }
12279
12286
  set_sensitive(
12280
12287
  'switch_',
@@ -17132,7 +17139,7 @@ function eval_pyson(value){
17132
17139
  },
17133
17140
  get width() {
17134
17141
  var digits = this.digits;
17135
- if (digits) {
17142
+ if (digits && digits.every(d => d !== null)) {
17136
17143
  return digits.reduce(function(acc, cur) {
17137
17144
  return acc + cur;
17138
17145
  });
@@ -17764,15 +17771,21 @@ function eval_pyson(value){
17764
17771
  } else {
17765
17772
  this._popup = true;
17766
17773
  }
17774
+ let view_ids = (this.attributes.view_ids || '').split(',');
17767
17775
  if (this.has_target(value)) {
17768
17776
  var m2o_id =
17769
17777
  this.id_from_value(record.field_get(this.field_name));
17770
17778
  if (evt && (evt.ctrlKey || evt.metaKey)) {
17779
+ if (!jQuery.isEmptyObject(view_ids)) {
17780
+ // Remove the first tree view as mode is form only
17781
+ view_ids.shift();
17782
+ }
17771
17783
  var params = {};
17772
17784
  params.model = this.get_model();
17773
17785
  params.res_id = m2o_id;
17774
17786
  params.mode = ['form'];
17775
17787
  params.name = this.attributes.string;
17788
+ params.view_ids = view_ids;
17776
17789
  params.context = this.field.get_context(this.record);
17777
17790
  Sao.Tab.create(params);
17778
17791
  this._popup = false;
@@ -17821,8 +17834,7 @@ function eval_pyson(value){
17821
17834
  context: context,
17822
17835
  domain: domain,
17823
17836
  order: order,
17824
- view_ids: (this.attributes.view_ids ||
17825
- '').split(','),
17837
+ view_ids: view_ids,
17826
17838
  views_preload: (this.attributes.views || {}),
17827
17839
  new_: this.create_access,
17828
17840
  search_filter: parser.quote(text),
@@ -22818,9 +22830,11 @@ function eval_pyson(value){
22818
22830
  return;
22819
22831
  }
22820
22832
 
22821
- body = listener = jQuery(document.body);
22833
+ body = jQuery(document.body);
22822
22834
  if (body.hasClass('modal-open')) {
22823
22835
  listener = this.tree.el.parents('.modal').last();
22836
+ } else {
22837
+ listener = this.tree.el.parents('.tab-pane').last();
22824
22838
  }
22825
22839
  const handler = event_ => {
22826
22840
  if ((event_.currentTarget == body[0]) &&
@@ -22833,7 +22847,7 @@ function eval_pyson(value){
22833
22847
  event_.stopPropagation();
22834
22848
  return;
22835
22849
  }
22836
- body.off('click.sao.editabletree');
22850
+ listener.off('click.sao.editabletree');
22837
22851
  this.tree.edit_row(null);
22838
22852
  return true;
22839
22853
  };
@@ -22962,7 +22976,10 @@ function eval_pyson(value){
22962
22976
  }
22963
22977
  }
22964
22978
  this._get_column_td(next_column)
22965
- .find(':input,[tabindex=0]').focus();
22979
+ .find(':input,[tabindex=0]')
22980
+ .filter(':visible')
22981
+ .first()
22982
+ .focus();
22966
22983
  } else {
22967
22984
  var prm = jQuery.when();
22968
22985
  if (!this.tree.screen.group.parent) {
@@ -23011,7 +23028,10 @@ function eval_pyson(value){
23011
23028
  this._get_column_td(
23012
23029
  next_column, next_row)
23013
23030
  .trigger('click')
23031
+ .trigger('click')
23014
23032
  .find(':input,[tabindex=0]')
23033
+ .filter(':visible')
23034
+ .first()
23015
23035
  .focus();
23016
23036
  });
23017
23037
  }
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.23",
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.23',
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;
@@ -1515,6 +1515,9 @@
1515
1515
  const view_type = this.screen.current_view.view_type;
1516
1516
  var next_view_type = this.screen.next_view_type;
1517
1517
  const has_views = this.screen.number_of_views > 1;
1518
+ let sensitive = (
1519
+ record_id >= 0 ? record_id !== null && record_id !== undefined :
1520
+ false);
1518
1521
  var buttons = ['print', 'relate', 'email', 'attach'];
1519
1522
  for (const button_id of buttons) {
1520
1523
  const button = this.buttons[button_id];
@@ -1531,7 +1534,7 @@
1531
1534
  return keyword == button_id;
1532
1535
  });
1533
1536
  }
1534
- set_sensitive(button_id, position && can_be_sensitive);
1537
+ set_sensitive(button_id, sensitive && can_be_sensitive);
1535
1538
  }
1536
1539
  set_sensitive(
1537
1540
  'switch_',
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'],