tryton-sao 7.6.14 → 7.6.16

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.6.16 - 2026-02-18
3
+ ---------------------------
4
+ * Bug fixes (see mercurial logs for details)
5
+
6
+
7
+ Version 7.6.15 - 2026-02-01
8
+ ---------------------------
9
+ * Bug fixes (see mercurial logs for details)
10
+
11
+
2
12
  Version 7.6.14 - 2026-01-15
3
13
  ---------------------------
4
14
  * Bug fixes (see mercurial logs for details)
package/COPYRIGHT CHANGED
@@ -1,7 +1,7 @@
1
1
  Copyright (C) 2012-2025 Nicolas Évrard.
2
- Copyright (C) 2012-2025 Cédric Krier.
2
+ Copyright (C) 2012-2026 Cédric Krier.
3
3
  Copyright (C) 2012-2014 Bertrand Chenal.
4
- Copyright (C) 2012-2025 B2CK SPRL.
4
+ Copyright (C) 2012-2026 B2CK SPRL.
5
5
  Copyright (C) 2019 Jitbit.
6
6
  Copyright (C) 2013 Thomas Park
7
7
  Copyright (C) 2020-2021 Maxime Richez
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.6.14',
6
+ __version__: '7.6.16',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
@@ -3428,16 +3428,59 @@ var Sao = {
3428
3428
  };
3429
3429
 
3430
3430
  Sao.common.scrollIntoViewIfNeeded = function(element) {
3431
- element = element[0];
3432
- if (element) {
3433
- var rect = element.getBoundingClientRect();
3434
- if (rect.bottom > window.innerHeight) {
3435
- element.scrollIntoView(false);
3431
+ function isScrollable(el) {
3432
+ let style = getComputedStyle(el);
3433
+ return /(auto|scroll|overlay)/.test(
3434
+ style.overflow + style.overflowY + style.overflowX
3435
+ );
3436
+ }
3437
+
3438
+ function getScrollableAncestors(el) {
3439
+ let ancestors = [];
3440
+ let parent = el.parentElement;
3441
+ while (parent && parent !== document.body) {
3442
+ if (isScrollable(parent)) {
3443
+ ancestors.push(parent);
3444
+ }
3445
+ parent = parent.parentElement;
3436
3446
  }
3437
- if (rect.top < 0) {
3438
- element.scrollIntoView();
3447
+ ancestors.push(window);
3448
+ return ancestors;
3449
+ }
3450
+
3451
+ function scrollIntoViewWithin(el, container) {
3452
+ let rect = el.getBoundingClientRect();
3453
+
3454
+ if (container === window) {
3455
+ if (rect.top < 0 || rect.bottom > window.innerHeight) {
3456
+ el.scrollIntoView({
3457
+ block: 'center',
3458
+ });
3459
+ }
3460
+ } else {
3461
+ let container_rect = container.getBoundingClientRect();
3462
+ let top_ = rect.top - container_rect.top;
3463
+ let bottom = top_ + rect.height;
3464
+
3465
+ let target_top = container.scrollTop;
3466
+
3467
+ if (top_ < 0) {
3468
+ target_top += top_ - container.clientHeight / 2;
3469
+ } else if (bottom > container.clientHeight) {
3470
+ target_top += bottom - container.clientHeight / 2
3471
+ }
3472
+ container.scrollTo({
3473
+ top: Math.max(0, target_top),
3474
+ });
3439
3475
  }
3440
3476
  }
3477
+
3478
+ element.each(function() {
3479
+ let ancestors = getScrollableAncestors(this);
3480
+ for (let ancestor of ancestors) {
3481
+ scrollIntoViewWithin(this, ancestor);
3482
+ }
3483
+ });
3441
3484
  };
3442
3485
 
3443
3486
  // Handle click and Return press event
@@ -8304,11 +8347,14 @@ var Sao = {
8304
8347
  } else {
8305
8348
  cmp = function(a, b) { return a < b; };
8306
8349
  }
8350
+ let max_id = Math.max(0, ...this.map((r) => r.id));
8307
8351
  for (const record of this) {
8308
8352
  if (record.get_loaded([field]) || changed || record.id < 0) {
8353
+ let prev_id = null;
8309
8354
  if (prev) {
8310
8355
  prev.load(field, false);
8311
8356
  index = prev.field_get(field);
8357
+ prev_id = prev.id >= 0 ? prev.id : max_id++;
8312
8358
  } else {
8313
8359
  index = null;
8314
8360
  }
@@ -8319,7 +8365,7 @@ var Sao = {
8319
8365
  update = true;
8320
8366
  } else if (prev) {
8321
8367
  if (record.id >= 0) {
8322
- update = cmp(record.id, prev.id);
8368
+ update = cmp(record.id, prev_id);
8323
8369
  } else if (position === 0) {
8324
8370
  update = true;
8325
8371
  }
@@ -8327,7 +8373,7 @@ var Sao = {
8327
8373
  } else if (value === index) {
8328
8374
  if (prev) {
8329
8375
  if (record.id >= 0) {
8330
- update = cmp(record.id, prev.id);
8376
+ update = cmp(record.id, prev_id);
8331
8377
  } else if (position === 0) {
8332
8378
  update = true;
8333
8379
  }
@@ -10424,11 +10470,6 @@ var Sao = {
10424
10470
  }
10425
10471
  return result;
10426
10472
  },
10427
- get_removed_ids: function(record) {
10428
- return record._values[this.name].record_removed.map(function(r) {
10429
- return r.id;
10430
- });
10431
- },
10432
10473
  get_domain: function(record) {
10433
10474
  var domains = this.get_domains(record);
10434
10475
  var attr_domain = domains[1];
@@ -18812,8 +18853,6 @@ function eval_pyson(value){
18812
18853
  if (existing_ids.length) {
18813
18854
  domain = [domain, ['id', 'not in', existing_ids]];
18814
18855
  }
18815
- var removed_ids = this.field.get_removed_ids(this.record);
18816
- domain = ['OR', domain, ['id', 'in', removed_ids]];
18817
18856
  var text = this.wid_text.val();
18818
18857
 
18819
18858
  if (this._popup) {
@@ -19106,8 +19145,6 @@ function eval_pyson(value){
19106
19145
  if (existing_ids.length) {
19107
19146
  domain = [domain, ['id', 'not in', existing_ids]];
19108
19147
  }
19109
- var removed_ids = this.field.get_removed_ids(this.record);
19110
- domain = ['OR', domain, ['id', 'in', removed_ids]];
19111
19148
  return Sao.common.update_completion(
19112
19149
  this.wid_text, this.record, this.field, model, domain);
19113
19150
  },
@@ -23581,11 +23618,14 @@ function eval_pyson(value){
23581
23618
  cell.text(value);
23582
23619
  }
23583
23620
  };
23621
+ let prm = jQuery.when();
23584
23622
  if (!record.is_loaded(this.attributes.name)) {
23585
- record.load(this.attributes.name, true, false).done(render);
23586
- } else {
23587
- render();
23623
+ prm = prm.then(() => record.load(this.attributes.name, true, false));
23624
+ }
23625
+ if (this.icon && (this.icon in record.model.fields)) {
23626
+ prm = prm.then(() => record.load(this.icon, true, false));
23588
23627
  }
23628
+ prm.done(render);
23589
23629
  return cell;
23590
23630
  },
23591
23631
  clicked: function(event) {
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.14",
5
+ "version": "7.6.16",
6
6
  "homepage": "https://www.tryton.org/",
7
7
  "author": {
8
8
  "name": "Tryton"
package/src/common.js CHANGED
@@ -79,16 +79,59 @@
79
79
  };
80
80
 
81
81
  Sao.common.scrollIntoViewIfNeeded = function(element) {
82
- element = element[0];
83
- if (element) {
84
- var rect = element.getBoundingClientRect();
85
- if (rect.bottom > window.innerHeight) {
86
- element.scrollIntoView(false);
82
+ function isScrollable(el) {
83
+ let style = getComputedStyle(el);
84
+ return /(auto|scroll|overlay)/.test(
85
+ style.overflow + style.overflowY + style.overflowX
86
+ );
87
+ }
88
+
89
+ function getScrollableAncestors(el) {
90
+ let ancestors = [];
91
+ let parent = el.parentElement;
92
+ while (parent && parent !== document.body) {
93
+ if (isScrollable(parent)) {
94
+ ancestors.push(parent);
95
+ }
96
+ parent = parent.parentElement;
87
97
  }
88
- if (rect.top < 0) {
89
- element.scrollIntoView();
98
+ ancestors.push(window);
99
+ return ancestors;
100
+ }
101
+
102
+ function scrollIntoViewWithin(el, container) {
103
+ let rect = el.getBoundingClientRect();
104
+
105
+ if (container === window) {
106
+ if (rect.top < 0 || rect.bottom > window.innerHeight) {
107
+ el.scrollIntoView({
108
+ block: 'center',
109
+ });
110
+ }
111
+ } else {
112
+ let container_rect = container.getBoundingClientRect();
113
+ let top_ = rect.top - container_rect.top;
114
+ let bottom = top_ + rect.height;
115
+
116
+ let target_top = container.scrollTop;
117
+
118
+ if (top_ < 0) {
119
+ target_top += top_ - container.clientHeight / 2;
120
+ } else if (bottom > container.clientHeight) {
121
+ target_top += bottom - container.clientHeight / 2
122
+ }
123
+ container.scrollTo({
124
+ top: Math.max(0, target_top),
125
+ });
90
126
  }
91
127
  }
128
+
129
+ element.each(function() {
130
+ let ancestors = getScrollableAncestors(this);
131
+ for (let ancestor of ancestors) {
132
+ scrollIntoViewWithin(this, ancestor);
133
+ }
134
+ });
92
135
  };
93
136
 
94
137
  // Handle click and Return press event
package/src/model.js CHANGED
@@ -513,11 +513,14 @@
513
513
  } else {
514
514
  cmp = function(a, b) { return a < b; };
515
515
  }
516
+ let max_id = Math.max(0, ...this.map((r) => r.id));
516
517
  for (const record of this) {
517
518
  if (record.get_loaded([field]) || changed || record.id < 0) {
519
+ let prev_id = null;
518
520
  if (prev) {
519
521
  prev.load(field, false);
520
522
  index = prev.field_get(field);
523
+ prev_id = prev.id >= 0 ? prev.id : max_id++;
521
524
  } else {
522
525
  index = null;
523
526
  }
@@ -528,7 +531,7 @@
528
531
  update = true;
529
532
  } else if (prev) {
530
533
  if (record.id >= 0) {
531
- update = cmp(record.id, prev.id);
534
+ update = cmp(record.id, prev_id);
532
535
  } else if (position === 0) {
533
536
  update = true;
534
537
  }
@@ -536,7 +539,7 @@
536
539
  } else if (value === index) {
537
540
  if (prev) {
538
541
  if (record.id >= 0) {
539
- update = cmp(record.id, prev.id);
542
+ update = cmp(record.id, prev_id);
540
543
  } else if (position === 0) {
541
544
  update = true;
542
545
  }
@@ -2633,11 +2636,6 @@
2633
2636
  }
2634
2637
  return result;
2635
2638
  },
2636
- get_removed_ids: function(record) {
2637
- return record._values[this.name].record_removed.map(function(r) {
2638
- return r.id;
2639
- });
2640
- },
2641
2639
  get_domain: function(record) {
2642
2640
  var domains = this.get_domains(record);
2643
2641
  var attr_domain = domains[1];
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.14',
6
+ __version__: '7.6.16',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
package/src/view/form.js CHANGED
@@ -3690,8 +3690,6 @@ function eval_pyson(value){
3690
3690
  if (existing_ids.length) {
3691
3691
  domain = [domain, ['id', 'not in', existing_ids]];
3692
3692
  }
3693
- var removed_ids = this.field.get_removed_ids(this.record);
3694
- domain = ['OR', domain, ['id', 'in', removed_ids]];
3695
3693
  var text = this.wid_text.val();
3696
3694
 
3697
3695
  if (this._popup) {
@@ -3984,8 +3982,6 @@ function eval_pyson(value){
3984
3982
  if (existing_ids.length) {
3985
3983
  domain = [domain, ['id', 'not in', existing_ids]];
3986
3984
  }
3987
- var removed_ids = this.field.get_removed_ids(this.record);
3988
- domain = ['OR', domain, ['id', 'in', removed_ids]];
3989
3985
  return Sao.common.update_completion(
3990
3986
  this.wid_text, this.record, this.field, model, domain);
3991
3987
  },
package/src/view/tree.js CHANGED
@@ -2537,11 +2537,14 @@
2537
2537
  cell.text(value);
2538
2538
  }
2539
2539
  };
2540
+ let prm = jQuery.when();
2540
2541
  if (!record.is_loaded(this.attributes.name)) {
2541
- record.load(this.attributes.name, true, false).done(render);
2542
- } else {
2543
- render();
2542
+ prm = prm.then(() => record.load(this.attributes.name, true, false));
2543
+ }
2544
+ if (this.icon && (this.icon in record.model.fields)) {
2545
+ prm = prm.then(() => record.load(this.icon, true, false));
2544
2546
  }
2547
+ prm.done(render);
2545
2548
  return cell;
2546
2549
  },
2547
2550
  clicked: function(event) {