tryton-sao 7.2.2 → 7.2.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.2.3 - 2024-07-01
3
+ --------------------------
4
+ * Bug fixes (see mercurial logs for details)
5
+
6
+
2
7
  Version 7.2.2 - 2024-06-15
3
8
  --------------------------
4
9
  * Bug fixes (see mercurial logs for details)
@@ -10066,10 +10066,14 @@ img.icon {
10066
10066
  min-height: 150px;
10067
10067
  max-height: 300px;
10068
10068
  }
10069
- .form .form-text textarea,
10070
- .form .form-richtext textarea,
10071
- .form .form-text .richtext,
10072
- .form .form-richtext .richtext {
10069
+ .form .form-text .input-group,
10070
+ .form .form-richtext .input-group {
10071
+ width: 100%;
10072
+ }
10073
+ .form .form-text .input-group textarea,
10074
+ .form .form-richtext .input-group textarea,
10075
+ .form .form-text .input-group .richtext,
10076
+ .form .form-richtext .input-group .richtext {
10073
10077
  height: 100%;
10074
10078
  line-height: 2.5ex;
10075
10079
  min-height: 12.5ex;
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.2.2',
6
+ __version__: '7.2.3',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
@@ -107,6 +107,35 @@ var Sao = {
107
107
  };
108
108
  }
109
109
 
110
+ if (!Set.prototype.intersection) {
111
+ Set.prototype.intersection = function(other) {
112
+ if (this === null) {
113
+ throw new TypeError();
114
+ }
115
+ const result = new Set();
116
+ for (const key of other.keys()) {
117
+ if (this.has(key)) {
118
+ result.add(key)
119
+ }
120
+ }
121
+ return result;
122
+ }
123
+ }
124
+
125
+ if (!Set.prototype.isSubsetOf) {
126
+ Set.prototype.isSubsetOf = function(other) {
127
+ if (this === null) {
128
+ throw new TypeError();
129
+ }
130
+ for (const key of this.keys()) {
131
+ if (!other.has(key)) {
132
+ return false;
133
+ }
134
+ }
135
+ return true;
136
+ }
137
+ }
138
+
110
139
  Sao.setdefault = function(object, key, value) {
111
140
  if (!Object.prototype.hasOwnProperty.call(object, key)) {
112
141
  object[key] = value;
@@ -8290,6 +8319,7 @@ var Sao = {
8290
8319
  views = this.model.fields[name].views;
8291
8320
  }
8292
8321
  var fields = {};
8322
+ var views_operator;
8293
8323
  if (loading == 'eager') {
8294
8324
  for (fname in this.model.fields) {
8295
8325
  field = this.model.fields[fname];
@@ -8297,17 +8327,19 @@ var Sao = {
8297
8327
  fields[fname] = field;
8298
8328
  }
8299
8329
  }
8330
+ views_operator = views.isSubsetOf.bind(views);
8300
8331
  } else {
8301
8332
  fields = this.model.fields;
8333
+ views_operator = function(view) {
8334
+ return Boolean(this.intersection(view).size);
8335
+ }.bind(views);
8302
8336
  }
8303
8337
  var fnames = [];
8304
8338
  for (fname in fields) {
8305
8339
  field = fields[fname];
8306
8340
  if (!(fname in this._loaded) &&
8307
8341
  (!views.size ||
8308
- Sao.common.intersect(
8309
- Array.from(views).sort(),
8310
- Array.from(field.views).sort()))) {
8342
+ views_operator(new Set(field.views)))) {
8311
8343
  fnames.push(fname);
8312
8344
  }
8313
8345
  }
@@ -11861,7 +11893,7 @@ var Sao = {
11861
11893
  this.refresh_resources(true);
11862
11894
  });
11863
11895
  for (const file of files) {
11864
- Sao.common.get_file_data(file, window_.add_data);
11896
+ Sao.common.get_file_data(file, window_.add_data.bind(window_));
11865
11897
  }
11866
11898
  jQuery.when.apply(jQuery, uris).then(function() {
11867
11899
  function empty(value) {
@@ -13115,9 +13147,7 @@ var Sao = {
13115
13147
  this.views = [];
13116
13148
  this.views_preload = attributes.views_preload || {};
13117
13149
  this.exclude_field = attributes.exclude_field;
13118
- this.new_group(attributes.context || {});
13119
13150
  this.current_view = null;
13120
- this.current_record = null;
13121
13151
  this.domain = attributes.domain || [];
13122
13152
  this.context_domain = attributes.context_domain;
13123
13153
  this.size_limit = null;
@@ -13129,11 +13159,14 @@ var Sao = {
13129
13159
  this._current_domain = [];
13130
13160
  this.offset = 0;
13131
13161
  this.order = this.default_order = attributes.order;
13162
+ this.readonly = this.attributes.readonly || false;
13132
13163
  var access = Sao.common.MODELACCESS.get(model_name);
13133
13164
  if (!(access.write || access.create)) {
13134
- this.attributes.readonly = true;
13165
+ this.readonly = true;
13135
13166
  }
13136
13167
  this.search_count = 0;
13168
+ this.new_group(attributes.context || {});
13169
+ this.current_record = null;
13137
13170
  this.screen_container = new Sao.ScreenContainer(
13138
13171
  attributes.tab_domain);
13139
13172
  this.breadcrumb = attributes.breadcrumb || [];
@@ -13176,7 +13209,10 @@ var Sao = {
13176
13209
  var readonly_records = this.selected_records.some(function(r) {
13177
13210
  return r.readonly;
13178
13211
  });
13179
- return this.attributes.readonly || readonly_records;
13212
+ return this.__readonly || readonly_records;
13213
+ },
13214
+ set readonly(value) {
13215
+ this.__readonly = value;
13180
13216
  },
13181
13217
  get deletable() {
13182
13218
  return this.selected_records.every(function(r) {
@@ -13554,7 +13590,7 @@ var Sao = {
13554
13590
  context = this.context;
13555
13591
  }
13556
13592
  var group = new Sao.Group(this.model, context, []);
13557
- group.readonly = this.attributes.readonly;
13593
+ group.readonly = this.__readonly;
13558
13594
  this.set_group(group);
13559
13595
  },
13560
13596
  record_modified: function(display=true) {
@@ -21183,7 +21219,7 @@ function eval_pyson(value){
21183
21219
  },
21184
21220
  display: function(selected, expanded) {
21185
21221
  var current_record = this.record;
21186
- if (jQuery.isEmptyObject(selected)) {
21222
+ if (jQuery.isEmptyObject(selected) && current_record) {
21187
21223
  selected = this.get_selected_paths();
21188
21224
  if (this.selection.prop('checked') &&
21189
21225
  !this.selection.prop('indeterminate')) {
@@ -21192,16 +21228,12 @@ function eval_pyson(value){
21192
21228
  selected.push([record.id]);
21193
21229
  }
21194
21230
  } else {
21195
- if (current_record) {
21196
- var current_path = current_record.get_path(this.group);
21197
- current_path = current_path.map(function(e) {
21198
- return e[1];
21199
- });
21200
- if (!Sao.common.contains(selected, current_path)) {
21201
- selected = [current_path];
21202
- }
21203
- } else if (!current_record) {
21204
- selected = [];
21231
+ var current_path = current_record.get_path(this.group);
21232
+ current_path = current_path.map(function(e) {
21233
+ return e[1];
21234
+ });
21235
+ if (!Sao.common.contains(selected, current_path)) {
21236
+ selected = [current_path];
21205
21237
  }
21206
21238
  }
21207
21239
  }
@@ -21782,7 +21814,7 @@ function eval_pyson(value){
21782
21814
  if (this.editable && new_) {
21783
21815
  td.trigger('click');
21784
21816
  }
21785
- td.find(':input,[tabindex=0]').focus();
21817
+ Sao.common.find_focusable_child(td).focus();
21786
21818
  }
21787
21819
  }
21788
21820
  };
@@ -24400,17 +24432,26 @@ function eval_pyson(value){
24400
24432
  if (!this.start && !this.end) {
24401
24433
  return [['id', '=', -1]];
24402
24434
  }
24403
- var first_datetime = Sao.DateTime(this.start);
24404
- var last_datetime = Sao.DateTime(this.end);
24435
+ var start = Sao.DateTime(this.start);
24436
+ var end = Sao.DateTime(this.end);
24405
24437
  var dtstart = this.attributes.dtstart;
24406
24438
  var dtend = this.attributes.dtend || dtstart;
24407
- return ['OR',
24408
- ['AND', [dtstart, '>=', first_datetime],
24409
- [dtstart, '<', last_datetime]],
24410
- ['AND', [dtend, '>=', first_datetime],
24411
- [dtend, '<', last_datetime]],
24412
- ['AND', [dtstart, '<', first_datetime],
24413
- [dtend, '>', last_datetime]]];
24439
+ var fields = this.screen.model.fields;
24440
+ if (fields[dtstart].description.type == 'date') {
24441
+ start = start.todate();
24442
+ }
24443
+ if (fields[dtend].description.type == 'date') {
24444
+ end = end.todate();
24445
+ }
24446
+ return [
24447
+ [dtstart, '!=', null],
24448
+ [dtend, '!=', null],
24449
+ ['OR',
24450
+ ['AND', [dtstart, '>=', start], [dtstart, '<', end]],
24451
+ ['AND', [dtend, '>=', start], [dtend, '<', end]],
24452
+ ['AND', [dtstart, '<', start], [dtend, '>', end]],
24453
+ ],
24454
+ ];
24414
24455
  },
24415
24456
  get_displayed_period: function(){
24416
24457
  var DatesPeriod = [];
@@ -25045,7 +25086,7 @@ function eval_pyson(value){
25045
25086
  }
25046
25087
  });
25047
25088
 
25048
- var readonly = this.screen.readonly || this.screen.group.readonly;
25089
+ var readonly = this.screen.group.readonly;
25049
25090
 
25050
25091
  this.but_ok = null;
25051
25092
  this.but_new = null;
@@ -25272,7 +25313,7 @@ function eval_pyson(value){
25272
25313
  var name = '_';
25273
25314
  var access = Sao.common.MODELACCESS.get(this.screen.model_name);
25274
25315
  var deletable = this.screen.deletable;
25275
- var readonly = this.screen.readonly || this.screen.group.readonly;
25316
+ var readonly = this.screen.group.readonly;
25276
25317
  if (position >= 1) {
25277
25318
  name = position;
25278
25319
  if (this.domain) {
@@ -25280,10 +25321,12 @@ function eval_pyson(value){
25280
25321
  }
25281
25322
  this.but_next.prop('disabled', position >= size);
25282
25323
  this.but_previous.prop('disabled', position <= 1);
25283
- if (access.delete && !readonly && deletable) {
25284
- this.but_del.prop('disabled', false);
25285
- this.but_undel.prop('disabled', false);
25286
- }
25324
+ this.but_del.prop(
25325
+ 'disabled',
25326
+ readonly ||
25327
+ !access.delete ||
25328
+ !deletable);
25329
+ this.but_undel.prop('disabled', readonly);
25287
25330
  } else {
25288
25331
  this.but_del.prop('disabled', true);
25289
25332
  this.but_undel.prop('disabled', true);
@@ -25356,7 +25399,7 @@ function eval_pyson(value){
25356
25399
  response: function(response_id) {
25357
25400
  var result;
25358
25401
  this.screen.current_view.set_value();
25359
- var readonly = this.screen.readonly || this.screen.group.readonly;
25402
+ var readonly = this.screen.group.readonly;
25360
25403
  if (~['RESPONSE_OK', 'RESPONSE_ACCEPT'].indexOf(response_id) &&
25361
25404
  !readonly &&
25362
25405
  this.screen.current_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.2.2",
5
+ "version": "7.2.3",
6
6
  "homepage": "http://www.tryton.org/",
7
7
  "author": {
8
8
  "name": "Tryton"
package/src/model.js CHANGED
@@ -681,6 +681,7 @@
681
681
  views = this.model.fields[name].views;
682
682
  }
683
683
  var fields = {};
684
+ var views_operator;
684
685
  if (loading == 'eager') {
685
686
  for (fname in this.model.fields) {
686
687
  field = this.model.fields[fname];
@@ -688,17 +689,19 @@
688
689
  fields[fname] = field;
689
690
  }
690
691
  }
692
+ views_operator = views.isSubsetOf.bind(views);
691
693
  } else {
692
694
  fields = this.model.fields;
695
+ views_operator = function(view) {
696
+ return Boolean(this.intersection(view).size);
697
+ }.bind(views);
693
698
  }
694
699
  var fnames = [];
695
700
  for (fname in fields) {
696
701
  field = fields[fname];
697
702
  if (!(fname in this._loaded) &&
698
703
  (!views.size ||
699
- Sao.common.intersect(
700
- Array.from(views).sort(),
701
- Array.from(field.views).sort()))) {
704
+ views_operator(new Set(field.views)))) {
702
705
  fnames.push(fname);
703
706
  }
704
707
  }
package/src/sao.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.2.2',
6
+ __version__: '7.2.3',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
@@ -107,6 +107,35 @@ var Sao = {
107
107
  };
108
108
  }
109
109
 
110
+ if (!Set.prototype.intersection) {
111
+ Set.prototype.intersection = function(other) {
112
+ if (this === null) {
113
+ throw new TypeError();
114
+ }
115
+ const result = new Set();
116
+ for (const key of other.keys()) {
117
+ if (this.has(key)) {
118
+ result.add(key)
119
+ }
120
+ }
121
+ return result;
122
+ }
123
+ }
124
+
125
+ if (!Set.prototype.isSubsetOf) {
126
+ Set.prototype.isSubsetOf = function(other) {
127
+ if (this === null) {
128
+ throw new TypeError();
129
+ }
130
+ for (const key of this.keys()) {
131
+ if (!other.has(key)) {
132
+ return false;
133
+ }
134
+ }
135
+ return true;
136
+ }
137
+ }
138
+
110
139
  Sao.setdefault = function(object, key, value) {
111
140
  if (!Object.prototype.hasOwnProperty.call(object, key)) {
112
141
  object[key] = value;
package/src/sao.less CHANGED
@@ -876,12 +876,16 @@ img.icon {
876
876
  }
877
877
  }
878
878
  .form-text, .form-richtext {
879
- textarea, .richtext {
880
- height: 100%;
881
- line-height: 2.5ex;
882
- min-height: 12.5ex;
883
- overflow: auto;
884
- resize: vertical;
879
+ .input-group {
880
+ width: 100%;
881
+
882
+ textarea, .richtext {
883
+ height: 100%;
884
+ line-height: 2.5ex;
885
+ min-height: 12.5ex;
886
+ overflow: auto;
887
+ resize: vertical;
888
+ }
885
889
  }
886
890
  }
887
891
  .form-richtext {
package/src/screen.js CHANGED
@@ -794,9 +794,7 @@
794
794
  this.views = [];
795
795
  this.views_preload = attributes.views_preload || {};
796
796
  this.exclude_field = attributes.exclude_field;
797
- this.new_group(attributes.context || {});
798
797
  this.current_view = null;
799
- this.current_record = null;
800
798
  this.domain = attributes.domain || [];
801
799
  this.context_domain = attributes.context_domain;
802
800
  this.size_limit = null;
@@ -808,11 +806,14 @@
808
806
  this._current_domain = [];
809
807
  this.offset = 0;
810
808
  this.order = this.default_order = attributes.order;
809
+ this.readonly = this.attributes.readonly || false;
811
810
  var access = Sao.common.MODELACCESS.get(model_name);
812
811
  if (!(access.write || access.create)) {
813
- this.attributes.readonly = true;
812
+ this.readonly = true;
814
813
  }
815
814
  this.search_count = 0;
815
+ this.new_group(attributes.context || {});
816
+ this.current_record = null;
816
817
  this.screen_container = new Sao.ScreenContainer(
817
818
  attributes.tab_domain);
818
819
  this.breadcrumb = attributes.breadcrumb || [];
@@ -855,7 +856,10 @@
855
856
  var readonly_records = this.selected_records.some(function(r) {
856
857
  return r.readonly;
857
858
  });
858
- return this.attributes.readonly || readonly_records;
859
+ return this.__readonly || readonly_records;
860
+ },
861
+ set readonly(value) {
862
+ this.__readonly = value;
859
863
  },
860
864
  get deletable() {
861
865
  return this.selected_records.every(function(r) {
@@ -1233,7 +1237,7 @@
1233
1237
  context = this.context;
1234
1238
  }
1235
1239
  var group = new Sao.Group(this.model, context, []);
1236
- group.readonly = this.attributes.readonly;
1240
+ group.readonly = this.__readonly;
1237
1241
  this.set_group(group);
1238
1242
  },
1239
1243
  record_modified: function(display=true) {
package/src/tab.js CHANGED
@@ -1254,7 +1254,7 @@
1254
1254
  this.refresh_resources(true);
1255
1255
  });
1256
1256
  for (const file of files) {
1257
- Sao.common.get_file_data(file, window_.add_data);
1257
+ Sao.common.get_file_data(file, window_.add_data.bind(window_));
1258
1258
  }
1259
1259
  jQuery.when.apply(jQuery, uris).then(function() {
1260
1260
  function empty(value) {
@@ -346,17 +346,26 @@
346
346
  if (!this.start && !this.end) {
347
347
  return [['id', '=', -1]];
348
348
  }
349
- var first_datetime = Sao.DateTime(this.start);
350
- var last_datetime = Sao.DateTime(this.end);
349
+ var start = Sao.DateTime(this.start);
350
+ var end = Sao.DateTime(this.end);
351
351
  var dtstart = this.attributes.dtstart;
352
352
  var dtend = this.attributes.dtend || dtstart;
353
- return ['OR',
354
- ['AND', [dtstart, '>=', first_datetime],
355
- [dtstart, '<', last_datetime]],
356
- ['AND', [dtend, '>=', first_datetime],
357
- [dtend, '<', last_datetime]],
358
- ['AND', [dtstart, '<', first_datetime],
359
- [dtend, '>', last_datetime]]];
353
+ var fields = this.screen.model.fields;
354
+ if (fields[dtstart].description.type == 'date') {
355
+ start = start.todate();
356
+ }
357
+ if (fields[dtend].description.type == 'date') {
358
+ end = end.todate();
359
+ }
360
+ return [
361
+ [dtstart, '!=', null],
362
+ [dtend, '!=', null],
363
+ ['OR',
364
+ ['AND', [dtstart, '>=', start], [dtstart, '<', end]],
365
+ ['AND', [dtend, '>=', start], [dtend, '<', end]],
366
+ ['AND', [dtstart, '<', start], [dtend, '>', end]],
367
+ ],
368
+ ];
360
369
  },
361
370
  get_displayed_period: function(){
362
371
  var DatesPeriod = [];
package/src/view/tree.js CHANGED
@@ -728,7 +728,7 @@
728
728
  },
729
729
  display: function(selected, expanded) {
730
730
  var current_record = this.record;
731
- if (jQuery.isEmptyObject(selected)) {
731
+ if (jQuery.isEmptyObject(selected) && current_record) {
732
732
  selected = this.get_selected_paths();
733
733
  if (this.selection.prop('checked') &&
734
734
  !this.selection.prop('indeterminate')) {
@@ -737,16 +737,12 @@
737
737
  selected.push([record.id]);
738
738
  }
739
739
  } else {
740
- if (current_record) {
741
- var current_path = current_record.get_path(this.group);
742
- current_path = current_path.map(function(e) {
743
- return e[1];
744
- });
745
- if (!Sao.common.contains(selected, current_path)) {
746
- selected = [current_path];
747
- }
748
- } else if (!current_record) {
749
- selected = [];
740
+ var current_path = current_record.get_path(this.group);
741
+ current_path = current_path.map(function(e) {
742
+ return e[1];
743
+ });
744
+ if (!Sao.common.contains(selected, current_path)) {
745
+ selected = [current_path];
750
746
  }
751
747
  }
752
748
  }
@@ -1327,7 +1323,7 @@
1327
1323
  if (this.editable && new_) {
1328
1324
  td.trigger('click');
1329
1325
  }
1330
- td.find(':input,[tabindex=0]').focus();
1326
+ Sao.common.find_focusable_child(td).focus();
1331
1327
  }
1332
1328
  }
1333
1329
  };
package/src/window.js CHANGED
@@ -179,7 +179,7 @@
179
179
  }
180
180
  });
181
181
 
182
- var readonly = this.screen.readonly || this.screen.group.readonly;
182
+ var readonly = this.screen.group.readonly;
183
183
 
184
184
  this.but_ok = null;
185
185
  this.but_new = null;
@@ -406,7 +406,7 @@
406
406
  var name = '_';
407
407
  var access = Sao.common.MODELACCESS.get(this.screen.model_name);
408
408
  var deletable = this.screen.deletable;
409
- var readonly = this.screen.readonly || this.screen.group.readonly;
409
+ var readonly = this.screen.group.readonly;
410
410
  if (position >= 1) {
411
411
  name = position;
412
412
  if (this.domain) {
@@ -414,10 +414,12 @@
414
414
  }
415
415
  this.but_next.prop('disabled', position >= size);
416
416
  this.but_previous.prop('disabled', position <= 1);
417
- if (access.delete && !readonly && deletable) {
418
- this.but_del.prop('disabled', false);
419
- this.but_undel.prop('disabled', false);
420
- }
417
+ this.but_del.prop(
418
+ 'disabled',
419
+ readonly ||
420
+ !access.delete ||
421
+ !deletable);
422
+ this.but_undel.prop('disabled', readonly);
421
423
  } else {
422
424
  this.but_del.prop('disabled', true);
423
425
  this.but_undel.prop('disabled', true);
@@ -490,7 +492,7 @@
490
492
  response: function(response_id) {
491
493
  var result;
492
494
  this.screen.current_view.set_value();
493
- var readonly = this.screen.readonly || this.screen.group.readonly;
495
+ var readonly = this.screen.group.readonly;
494
496
  if (~['RESPONSE_OK', 'RESPONSE_ACCEPT'].indexOf(response_id) &&
495
497
  !readonly &&
496
498
  this.screen.current_record) {