tryton-sao 7.4.0 → 7.4.2

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.2 - 2024-12-16
3
+ --------------------------
4
+ * Bug fixes (see mercurial logs for details)
5
+
6
+
7
+ Version 7.4.1 - 2024-12-01
8
+ --------------------------
9
+ * Bug fixes (see mercurial logs for details)
10
+
11
+
2
12
  Version 7.4.0 - 2024-11-04
3
13
  --------------------------
4
14
  * Bug fixes (see mercurial logs for details)
@@ -9602,6 +9602,7 @@ html.accesskey select[accesskey] ~ span[data-accesskey] {
9602
9602
  .tab-board .tab-domain > .nav-tabs {
9603
9603
  display: inline-flex;
9604
9604
  white-space: nowrap;
9605
+ width: 1px;
9605
9606
  }
9606
9607
  .tab-form .tab-domain .badge,
9607
9608
  .tab-board .tab-domain .badge {
@@ -9689,7 +9690,8 @@ img.icon {
9689
9690
  [dir="rtl"] img.icon {
9690
9691
  transform: scaleX(-1);
9691
9692
  }
9692
- .screen-container {
9693
+ .screen-container,
9694
+ .board {
9693
9695
  display: flex;
9694
9696
  flex-direction: column;
9695
9697
  flex: 1;
@@ -9974,193 +9976,286 @@ img.icon {
9974
9976
  padding-top: 0;
9975
9977
  padding-bottom: 0;
9976
9978
  }
9977
- .form {
9979
+ .form,
9980
+ .board {
9978
9981
  width: 100%;
9979
9982
  height: 100%;
9980
9983
  }
9981
9984
  .form .form-container,
9985
+ .board .form-container,
9982
9986
  .form .form-hcontainer,
9983
- .form .form-vcontainer {
9987
+ .board .form-hcontainer,
9988
+ .form .form-vcontainer,
9989
+ .board .form-vcontainer {
9984
9990
  display: grid;
9985
9991
  width: 100%;
9986
9992
  height: 100%;
9987
9993
  column-gap: 5px;
9988
9994
  row-gap: 5px;
9989
9995
  }
9990
- .form .form-item {
9996
+ .form .form-item,
9997
+ .board .form-item {
9991
9998
  display: flex;
9992
9999
  }
9993
- .form .form-item > .btn {
10000
+ .form .form-item > .btn,
10001
+ .board .form-item > .btn {
9994
10002
  margin: 5px 0;
9995
10003
  }
9996
- .form .form-notebook {
10004
+ .form .form-notebook,
10005
+ .board .form-notebook {
9997
10006
  border-color: #ddd;
9998
10007
  border-style: solid;
9999
10008
  border-width: 1px;
10000
10009
  }
10001
- .form .form-notebook .nav-tabs {
10010
+ .form .form-notebook .nav-tabs,
10011
+ .board .form-notebook .nav-tabs {
10002
10012
  background: #f8f8f8;
10003
10013
  margin-bottom: 5px;
10004
10014
  }
10005
- .form .form-label {
10015
+ .form .form-label,
10016
+ .board .form-label {
10006
10017
  white-space: pre-wrap;
10007
10018
  width: max-content;
10008
10019
  max-width: 80ch;
10009
10020
  }
10010
10021
  .form .form-char input,
10022
+ .board .form-char input,
10011
10023
  .form .form-password input,
10024
+ .board .form-password input,
10012
10025
  .form .form-integer input,
10026
+ .board .form-integer input,
10013
10027
  .form .form-float input,
10028
+ .board .form-float input,
10014
10029
  .form .form-timedelta input,
10030
+ .board .form-timedelta input,
10015
10031
  .form .form-selection input,
10032
+ .board .form-selection input,
10016
10033
  .form .form-multiselection input,
10034
+ .board .form-multiselection input,
10017
10035
  .form .form-url input,
10036
+ .board .form-url input,
10018
10037
  .form .form-email input,
10038
+ .board .form-email input,
10019
10039
  .form .form-callto input,
10040
+ .board .form-callto input,
10020
10041
  .form .form-sip input,
10042
+ .board .form-sip input,
10021
10043
  .form .form-pyson input,
10044
+ .board .form-pyson input,
10022
10045
  .form .form-char select,
10046
+ .board .form-char select,
10023
10047
  .form .form-password select,
10048
+ .board .form-password select,
10024
10049
  .form .form-integer select,
10050
+ .board .form-integer select,
10025
10051
  .form .form-float select,
10052
+ .board .form-float select,
10026
10053
  .form .form-timedelta select,
10054
+ .board .form-timedelta select,
10027
10055
  .form .form-selection select,
10056
+ .board .form-selection select,
10028
10057
  .form .form-multiselection select,
10058
+ .board .form-multiselection select,
10029
10059
  .form .form-url select,
10060
+ .board .form-url select,
10030
10061
  .form .form-email select,
10062
+ .board .form-email select,
10031
10063
  .form .form-callto select,
10064
+ .board .form-callto select,
10032
10065
  .form .form-sip select,
10033
- .form .form-pyson select {
10066
+ .board .form-sip select,
10067
+ .form .form-pyson select,
10068
+ .board .form-pyson select {
10034
10069
  min-width: 8ch;
10035
10070
  }
10036
- .form .form-date input {
10071
+ .form .form-date input,
10072
+ .board .form-date input {
10037
10073
  width: calc(10ch + 34px);
10038
10074
  }
10039
- .form .form-time input {
10075
+ .form .form-time input,
10076
+ .board .form-time input {
10040
10077
  width: calc(8ch + 34px);
10041
10078
  }
10042
- .form .form-datetime input {
10079
+ .form .form-datetime input,
10080
+ .board .form-datetime input {
10043
10081
  width: calc(19ch + 34px);
10044
10082
  }
10045
10083
  .form .form-many2one select,
10084
+ .board .form-many2one select,
10046
10085
  .form .form-one2one select,
10086
+ .board .form-one2one select,
10047
10087
  .form .form-reference select,
10048
- .form form-binary select {
10088
+ .board .form-reference select,
10089
+ .form form-binary select,
10090
+ .board form-binary select {
10049
10091
  min-width: 8ch;
10050
10092
  }
10051
10093
  .form .form-many2one input,
10094
+ .board .form-many2one input,
10052
10095
  .form .form-one2one input,
10096
+ .board .form-one2one input,
10053
10097
  .form .form-reference input,
10054
- .form form-binary input {
10098
+ .board .form-reference input,
10099
+ .form form-binary input,
10100
+ .board form-binary input {
10055
10101
  min-width: 12ch;
10056
10102
  }
10057
10103
  @media screen and (min-width: 768px) {
10058
10104
  .form .form-reference > .input-sm,
10059
- .form .form-reference > .input-group {
10105
+ .board .form-reference > .input-sm,
10106
+ .form .form-reference > .input-group,
10107
+ .board .form-reference > .input-group {
10060
10108
  width: 50%;
10061
10109
  }
10062
10110
  }
10063
10111
  @media screen and (max-width: 767px) {
10064
10112
  .form .form-reference > .input-sm,
10065
- .form .form-reference > .input-group {
10113
+ .board .form-reference > .input-sm,
10114
+ .form .form-reference > .input-group,
10115
+ .board .form-reference > .input-group {
10066
10116
  width: 100%;
10067
10117
  }
10068
10118
  }
10069
10119
  .form .form-url a > img,
10120
+ .board .form-url a > img,
10070
10121
  .form .form-email a > img,
10122
+ .board .form-email a > img,
10071
10123
  .form .form-callto a > img,
10072
- .form .form-sip a > img {
10124
+ .board .form-callto a > img,
10125
+ .form .form-sip a > img,
10126
+ .board .form-sip a > img {
10073
10127
  width: 1em;
10074
10128
  height: 1em;
10075
10129
  }
10076
- .form .form-many2one > .input-group {
10130
+ .form .form-many2one > .input-group,
10131
+ .board .form-many2one > .input-group {
10077
10132
  width: 100%;
10078
10133
  }
10079
10134
  .form .form-one2many-menu::after,
10080
- .form .form-many2many-menu::after {
10135
+ .board .form-one2many-menu::after,
10136
+ .form .form-many2many-menu::after,
10137
+ .board .form-many2many-menu::after {
10081
10138
  content: "";
10082
10139
  display: table;
10083
10140
  clear: both;
10084
10141
  }
10085
10142
  .form .form-one2many-menu .form-one2many-string,
10143
+ .board .form-one2many-menu .form-one2many-string,
10086
10144
  .form .form-many2many-menu .form-one2many-string,
10145
+ .board .form-many2many-menu .form-one2many-string,
10087
10146
  .form .form-one2many-menu .form-many2many-string,
10088
- .form .form-many2many-menu .form-many2many-string {
10147
+ .board .form-one2many-menu .form-many2many-string,
10148
+ .form .form-many2many-menu .form-many2many-string,
10149
+ .board .form-many2many-menu .form-many2many-string {
10089
10150
  display: inline-table;
10090
10151
  float: left;
10091
10152
  margin: 5px;
10092
10153
  }
10093
10154
  [dir="rtl"] .form .form-one2many-menu .form-one2many-string,
10155
+ [dir="rtl"] .board .form-one2many-menu .form-one2many-string,
10094
10156
  [dir="rtl"] .form .form-many2many-menu .form-one2many-string,
10157
+ [dir="rtl"] .board .form-many2many-menu .form-one2many-string,
10095
10158
  [dir="rtl"] .form .form-one2many-menu .form-many2many-string,
10096
- [dir="rtl"] .form .form-many2many-menu .form-many2many-string {
10159
+ [dir="rtl"] .board .form-one2many-menu .form-many2many-string,
10160
+ [dir="rtl"] .form .form-many2many-menu .form-many2many-string,
10161
+ [dir="rtl"] .board .form-many2many-menu .form-many2many-string {
10097
10162
  float: right;
10098
10163
  }
10099
10164
  .form .form-one2many-menu .form-one2many-toolbar,
10165
+ .board .form-one2many-menu .form-one2many-toolbar,
10100
10166
  .form .form-many2many-menu .form-one2many-toolbar,
10167
+ .board .form-many2many-menu .form-one2many-toolbar,
10101
10168
  .form .form-one2many-menu .form-many2many-toolbar,
10102
- .form .form-many2many-menu .form-many2many-toolbar {
10169
+ .board .form-one2many-menu .form-many2many-toolbar,
10170
+ .form .form-many2many-menu .form-many2many-toolbar,
10171
+ .board .form-many2many-menu .form-many2many-toolbar {
10103
10172
  display: inline-table;
10104
10173
  float: right;
10105
10174
  }
10106
10175
  [dir="rtl"] .form .form-one2many-menu .form-one2many-toolbar,
10176
+ [dir="rtl"] .board .form-one2many-menu .form-one2many-toolbar,
10107
10177
  [dir="rtl"] .form .form-many2many-menu .form-one2many-toolbar,
10178
+ [dir="rtl"] .board .form-many2many-menu .form-one2many-toolbar,
10108
10179
  [dir="rtl"] .form .form-one2many-menu .form-many2many-toolbar,
10109
- [dir="rtl"] .form .form-many2many-menu .form-many2many-toolbar {
10180
+ [dir="rtl"] .board .form-one2many-menu .form-many2many-toolbar,
10181
+ [dir="rtl"] .form .form-many2many-menu .form-many2many-toolbar,
10182
+ [dir="rtl"] .board .form-many2many-menu .form-many2many-toolbar {
10110
10183
  float: left;
10111
10184
  }
10112
10185
  .form .form-one2many-menu .form-one2many-toolbar .badge,
10186
+ .board .form-one2many-menu .form-one2many-toolbar .badge,
10113
10187
  .form .form-many2many-menu .form-one2many-toolbar .badge,
10188
+ .board .form-many2many-menu .form-one2many-toolbar .badge,
10114
10189
  .form .form-one2many-menu .form-many2many-toolbar .badge,
10115
- .form .form-many2many-menu .form-many2many-toolbar .badge {
10190
+ .board .form-one2many-menu .form-many2many-toolbar .badge,
10191
+ .form .form-many2many-menu .form-many2many-toolbar .badge,
10192
+ .board .form-many2many-menu .form-many2many-toolbar .badge {
10116
10193
  max-width: 5em;
10117
10194
  min-width: 5em;
10118
10195
  overflow: hidden;
10119
10196
  text-overflow: ellipsis;
10120
10197
  }
10121
10198
  .form .form-one2many-content,
10122
- .form .form-many2many-content {
10199
+ .board .form-one2many-content,
10200
+ .form .form-many2many-content,
10201
+ .board .form-many2many-content {
10123
10202
  padding: 5px;
10124
10203
  }
10125
10204
  .form .form-one2many-content .treeview,
10205
+ .board .form-one2many-content .treeview,
10126
10206
  .form .form-many2many-content .treeview,
10207
+ .board .form-many2many-content .treeview,
10127
10208
  .form .form-one2many-content .list-form,
10128
- .form .form-many2many-content .list-form {
10209
+ .board .form-one2many-content .list-form,
10210
+ .form .form-many2many-content .list-form,
10211
+ .board .form-many2many-content .list-form {
10129
10212
  height: auto;
10130
10213
  min-height: 150px;
10131
10214
  max-height: 300px;
10132
10215
  }
10133
10216
  .form .form-text .input-group,
10134
- .form .form-richtext .input-group {
10217
+ .board .form-text .input-group,
10218
+ .form .form-richtext .input-group,
10219
+ .board .form-richtext .input-group {
10135
10220
  width: 100%;
10136
10221
  }
10137
10222
  .form .form-text .input-group textarea,
10223
+ .board .form-text .input-group textarea,
10138
10224
  .form .form-richtext .input-group textarea,
10225
+ .board .form-richtext .input-group textarea,
10139
10226
  .form .form-text .input-group .richtext,
10140
- .form .form-richtext .input-group .richtext {
10227
+ .board .form-text .input-group .richtext,
10228
+ .form .form-richtext .input-group .richtext,
10229
+ .board .form-richtext .input-group .richtext {
10141
10230
  height: 100%;
10142
10231
  line-height: 2.5ex;
10143
10232
  min-height: 12.5ex;
10144
10233
  overflow: auto;
10145
10234
  resize: vertical;
10146
10235
  }
10147
- .form .form-richtext > .btn-toolbar {
10236
+ .form .form-richtext > .btn-toolbar,
10237
+ .board .form-richtext > .btn-toolbar {
10148
10238
  min-width: 450px;
10149
10239
  }
10150
- .form .form-separator label {
10240
+ .form .form-separator label,
10241
+ .board .form-separator label {
10151
10242
  margin-top: 10px;
10152
10243
  }
10153
- .form .form-separator hr {
10244
+ .form .form-separator hr,
10245
+ .board .form-separator hr {
10154
10246
  margin-top: 0;
10155
10247
  margin-bottom: 5px;
10156
10248
  }
10157
- .form .form-image {
10249
+ .form .form-image,
10250
+ .board .form-image {
10158
10251
  margin: 2px;
10159
10252
  }
10160
- .form .form-image .caption {
10253
+ .form .form-image .caption,
10254
+ .board .form-image .caption {
10161
10255
  min-width: 120px;
10162
10256
  }
10163
- .form .form-document object {
10257
+ .form .form-document object,
10258
+ .board .form-document object {
10164
10259
  object-fit: scale-down;
10165
10260
  object-position: center top;
10166
10261
  width: 100%;
@@ -10168,70 +10263,91 @@ img.icon {
10168
10263
  height: 100%;
10169
10264
  }
10170
10265
  @media screen and (max-width: 767px) {
10171
- .form .form-document object {
10266
+ .form .form-document object,
10267
+ .board .form-document object {
10172
10268
  min-height: 25vh;
10173
10269
  }
10174
10270
  }
10175
- .form label {
10271
+ .form label,
10272
+ .board label {
10176
10273
  font-weight: normal;
10177
10274
  display: inline;
10178
10275
  padding: 0 5px;
10179
10276
  }
10180
- .form label.required {
10277
+ .form label.required,
10278
+ .board label.required {
10181
10279
  font-weight: bold;
10182
10280
  }
10183
- .form label.editable {
10281
+ .form label.editable,
10282
+ .board label.editable {
10184
10283
  font-style: italic;
10185
10284
  }
10186
- .form .nav-tabs {
10285
+ .form .nav-tabs,
10286
+ .board .nav-tabs {
10187
10287
  margin-bottom: 15px;
10188
10288
  }
10189
- .form .panel-heading {
10289
+ .form .panel-heading,
10290
+ .board .panel-heading {
10190
10291
  padding: 2px 2px;
10191
10292
  }
10192
- .form fieldset.form-group_ {
10293
+ .form fieldset.form-group_,
10294
+ .board fieldset.form-group_ {
10193
10295
  overflow: auto;
10194
10296
  }
10195
- .form fieldset.form-group_ > legend {
10297
+ .form fieldset.form-group_ > legend,
10298
+ .board fieldset.form-group_ > legend {
10196
10299
  font-size: 14px;
10197
10300
  margin-bottom: 5px;
10198
10301
  }
10199
10302
  .form fieldset.form-group_ .form-container,
10303
+ .board fieldset.form-group_ .form-container,
10200
10304
  .form fieldset.form-group_ .form-hcontainer,
10201
- .form fieldset.form-group_ .form-vcontainer {
10305
+ .board fieldset.form-group_ .form-hcontainer,
10306
+ .form fieldset.form-group_ .form-vcontainer,
10307
+ .board fieldset.form-group_ .form-vcontainer {
10202
10308
  vertical-align: middle;
10203
10309
  }
10204
- .form .xexpand {
10310
+ .form .xexpand,
10311
+ .board .xexpand {
10205
10312
  width: 100%;
10206
10313
  }
10207
- .form .xfill {
10314
+ .form .xfill,
10315
+ .board .xfill {
10208
10316
  justify-content: stretch;
10209
10317
  }
10210
- .form .yexpand {
10318
+ .form .yexpand,
10319
+ .board .yexpand {
10211
10320
  height: 100%;
10212
10321
  }
10213
- .form .xalign-start {
10322
+ .form .xalign-start,
10323
+ .board .xalign-start {
10214
10324
  justify-self: start;
10215
10325
  justify-content: start;
10216
10326
  }
10217
- .form .xalign-center {
10327
+ .form .xalign-center,
10328
+ .board .xalign-center {
10218
10329
  justify-self: center;
10219
10330
  justify-content: center;
10220
10331
  }
10221
- .form .xalign-end {
10332
+ .form .xalign-end,
10333
+ .board .xalign-end {
10222
10334
  justify-self: end;
10223
10335
  justify-content: end;
10224
10336
  }
10225
- .form .yalign-start {
10337
+ .form .yalign-start,
10338
+ .board .yalign-start {
10226
10339
  align-items: start;
10227
10340
  }
10228
- .form .yalign-center {
10341
+ .form .yalign-center,
10342
+ .board .yalign-center {
10229
10343
  align-items: center;
10230
10344
  }
10231
- .form .yalign-end {
10345
+ .form .yalign-end,
10346
+ .board .yalign-end {
10232
10347
  align-items: end;
10233
10348
  }
10234
- .form .yfill {
10349
+ .form .yfill,
10350
+ .board .yfill {
10235
10351
  align-self: stretch;
10236
10352
  }
10237
10353
  .form-binary,
@@ -3,7 +3,7 @@
3
3
 
4
4
  /* eslint-disable no-redeclare */
5
5
  var Sao = {
6
- __version__: '7.4.0',
6
+ __version__: '7.4.2',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
@@ -2118,7 +2118,8 @@ var Sao = {
2118
2118
  if ( (!(statement instanceof Sao.PYSON.DateTime ||
2119
2119
  statement instanceof Sao.PYSON.Date ||
2120
2120
  statement instanceof Sao.PYSON.TimeDelta)) &&
2121
- (jQuery(statement.types()).not(['number']).length) ) {
2121
+ (jQuery(statement.types()).not(
2122
+ ['number', 'object']).length) ) {
2122
2123
  throw 'statement must be an integer, float, ' +
2123
2124
  'date, datetime or timedelta';
2124
2125
  }
@@ -6116,7 +6117,9 @@ var Sao = {
6116
6117
  (single_value && operator == 'in' && value.length == 1)) &&
6117
6118
  (!count ||
6118
6119
  ((count === 1) && model.length && name.endsWith('.id')))) {
6119
- value = operator == '=' ? value : value[0];
6120
+ if ((operator == 'in') && single_value) {
6121
+ value = value[0];
6122
+ }
6120
6123
  if (model.length && name.endsWith('.id')) {
6121
6124
  model = model[0];
6122
6125
  value = [model, value];
@@ -9472,7 +9475,7 @@ var Sao = {
9472
9475
  setdefault = false;
9473
9476
  }
9474
9477
  }
9475
- if (setdefault && !pre_validate) {
9478
+ if (setdefault && jQuery.isEmptyObject(pre_validate)) {
9476
9479
  this.set_client(record, value);
9477
9480
  state_attrs.domain_readonly = domain_readonly;
9478
9481
  }
@@ -10326,7 +10329,7 @@ var Sao = {
10326
10329
  }
10327
10330
  for (const record2 of (record._values[this.name] || [])) {
10328
10331
  if (!record2.get_loaded() && (record2.id >= 0) &&
10329
- !pre_validate) {
10332
+ jQuery.isEmptyObject(pre_validate)) {
10330
10333
  continue;
10331
10334
  }
10332
10335
  if (!record2.validate(null, softvalidation, ldomain)) {
@@ -12326,6 +12329,8 @@ var Sao = {
12326
12329
  }
12327
12330
  this.dialogs = [];
12328
12331
  this.board = null;
12332
+ this.create_tabcontent();
12333
+ this.set_name(name);
12329
12334
  UIView = new Sao.Model('ir.ui.view');
12330
12335
  this.view_prm = UIView.execute(
12331
12336
  'view_get', [this.view_id], this.context);
@@ -12342,8 +12347,6 @@ var Sao = {
12342
12347
  });
12343
12348
  this.content.append(this.board.el);
12344
12349
  });
12345
- this.create_tabcontent();
12346
- this.set_name(name);
12347
12350
  },
12348
12351
  compare: function(attributes) {
12349
12352
  if (!attributes) {
@@ -13236,10 +13239,7 @@ var Sao = {
13236
13239
  'class': 'col-md-12'
13237
13240
  }).append(this.context_screen.screen_container.el))
13238
13241
  .prependTo(this.screen_container.filter_box);
13239
- return this.context_screen.new_(false).then(
13240
- // Set manually default to get context_screen_prm
13241
- // resolved when default is set.
13242
- record => record.default_get());
13242
+ return this.context_screen.new_();
13243
13243
  });
13244
13244
  }
13245
13245
 
@@ -13339,7 +13339,7 @@ var Sao = {
13339
13339
  var views = this.views.concat(this.view_to_load)
13340
13340
  var next_view_index = (this.view_index + 1) % views.length;
13341
13341
  var next_view = views[next_view_index];
13342
- if (typeof next_view != 'string') {
13342
+ if (next_view && (typeof next_view != 'string')) {
13343
13343
  next_view = next_view.view_type;
13344
13344
  }
13345
13345
  return next_view;
@@ -14892,6 +14892,10 @@ function eval_pyson(value){
14892
14892
  (function() {
14893
14893
  'use strict';
14894
14894
 
14895
+ function remove_newline(value) {
14896
+ return value.replace(/[\n\r]/gm, '')
14897
+ }
14898
+
14895
14899
  Sao.View.FormXMLViewParser = Sao.class_(Sao.View.XMLViewParser, {
14896
14900
  init: function(view, exclude_field, field_attrs) {
14897
14901
  Sao.View.FormXMLViewParser._super.init.call(
@@ -15110,7 +15114,6 @@ function eval_pyson(value){
15110
15114
  var group = new Sao.View.Form.Container(
15111
15115
  Number(node.getAttribute('col') || 4));
15112
15116
  this.view.containers.push(group);
15113
- this.parse_child(node, group);
15114
15117
 
15115
15118
  if (attributes.xalign === undefined) {
15116
15119
  attributes.xalign = 0.5;
@@ -15135,6 +15138,9 @@ function eval_pyson(value){
15135
15138
 
15136
15139
  this.view.state_widgets.push(widget);
15137
15140
  this.container.add(widget, attributes);
15141
+ // Parse the children at the end to preserve the order of the state
15142
+ // widgets
15143
+ this.parse_child(node, group);
15138
15144
  },
15139
15145
  _parse_hpaned: function(node, attributes) {
15140
15146
  this._parse_paned(node, attributes, 'horizontal');
@@ -17522,7 +17528,7 @@ function eval_pyson(value){
17522
17528
  get_text: function() {
17523
17529
  var record = this.record;
17524
17530
  if (record) {
17525
- return record.field_get_client(this.field_name);
17531
+ return remove_newline(record.field_get_client(this.field_name));
17526
17532
  }
17527
17533
  return '';
17528
17534
  },
@@ -17538,7 +17544,7 @@ function eval_pyson(value){
17538
17544
  set_value: function() {
17539
17545
  var record = this.record;
17540
17546
  var field = this.field;
17541
- if (field.get_client(record) != this.entry.val()) {
17547
+ if (this.get_text() != this.entry.val()) {
17542
17548
  field.set_client(record, this.value_from_id(null, ''));
17543
17549
  this.entry.val('');
17544
17550
  }
@@ -17635,7 +17641,7 @@ function eval_pyson(value){
17635
17641
  get modified() {
17636
17642
  if (this.record && this.field) {
17637
17643
  var value = this.entry.val();
17638
- return this.field.get_client(this.record) != value;
17644
+ return this.get_text() != value;
17639
17645
  }
17640
17646
  return false;
17641
17647
  },
@@ -17963,7 +17969,7 @@ function eval_pyson(value){
17963
17969
  name = '';
17964
17970
  if (value) {
17965
17971
  model = value[0];
17966
- name = value[1];
17972
+ name = remove_newline(value[1]);
17967
17973
  }
17968
17974
  return ((model != this.get_model()) ||
17969
17975
  (name != this.entry.val()));
@@ -17982,7 +17988,8 @@ function eval_pyson(value){
17982
17988
  get_text: function() {
17983
17989
  var record = this.record;
17984
17990
  if (record) {
17985
- return record.field_get_client(this.field_name)[1];
17991
+ return remove_newline(
17992
+ record.field_get_client(this.field_name)[1]);
17986
17993
  }
17987
17994
  return '';
17988
17995
  },
@@ -18036,7 +18043,7 @@ function eval_pyson(value){
18036
18043
  var model, name;
18037
18044
  if (value instanceof Array) {
18038
18045
  model = value[0];
18039
- name = value[1];
18046
+ name = remove_newline(value[1]);
18040
18047
  } else {
18041
18048
  model = '';
18042
18049
  name = '';
@@ -19475,7 +19482,8 @@ function eval_pyson(value){
19475
19482
  set_readonly: function(readonly) {
19476
19483
  Sao.View.Form.Binary._super.set_readonly.call(this, readonly);
19477
19484
  var record = this.record;
19478
- this.but_select.prop('disabled', readonly || !record);
19485
+ this.but_select.toggleClass('disabled', readonly || !record);
19486
+ this.input_select.toggle(!readonly && record);
19479
19487
  this.but_clear.prop('disabled', readonly || !record);
19480
19488
  if (this.text) {
19481
19489
  this.text.prop('readonly', readonly);
@@ -28335,6 +28343,7 @@ function eval_pyson(value){
28335
28343
  _parse_board: function(node, attributes) {
28336
28344
  var container = new Sao.View.Form.Container(
28337
28345
  Number(node.getAttribute('col') || 4));
28346
+ this.view.containers.push(container);
28338
28347
  this.view.el.append(container.el);
28339
28348
  this.parse_child(node, container);
28340
28349
  if (this._containers.length > 0) {
@@ -28378,9 +28387,23 @@ function eval_pyson(value){
28378
28387
  for (i = 0; i < this.actions.length; i++) {
28379
28388
  this.actions[i].display();
28380
28389
  }
28381
- for (i = 0; i < this.state_widgets.length; i++) {
28382
- this.state_widgets[i].set_state(null);
28390
+ var promesses = [];
28391
+ for (let state_widget of this.state_widgets.toReversed()) {
28392
+ var prm = state_widget.set_state(null);
28393
+ if (prm) {
28394
+ promesses.push(prm);
28395
+ }
28396
+ }
28397
+ for (const container of this.containers) {
28398
+ container.set_grid_template();
28383
28399
  }
28400
+ // re-set the grid templates for the StateWidget that are
28401
+ // asynchronous
28402
+ jQuery.when.apply(jQuery, promesses).done(() => {
28403
+ for (const container of this.containers) {
28404
+ container.set_grid_template();
28405
+ }
28406
+ });
28384
28407
  },
28385
28408
  active_changed: function(event_action) {
28386
28409
  for (const action of this.actions) {
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.0",
5
+ "version": "7.4.2",
6
6
  "homepage": "https://www.tryton.org/",
7
7
  "author": {
8
8
  "name": "Tryton"
package/src/board.js CHANGED
@@ -7,6 +7,7 @@
7
7
  _parse_board: function(node, attributes) {
8
8
  var container = new Sao.View.Form.Container(
9
9
  Number(node.getAttribute('col') || 4));
10
+ this.view.containers.push(container);
10
11
  this.view.el.append(container.el);
11
12
  this.parse_child(node, container);
12
13
  if (this._containers.length > 0) {
@@ -50,9 +51,23 @@
50
51
  for (i = 0; i < this.actions.length; i++) {
51
52
  this.actions[i].display();
52
53
  }
53
- for (i = 0; i < this.state_widgets.length; i++) {
54
- this.state_widgets[i].set_state(null);
54
+ var promesses = [];
55
+ for (let state_widget of this.state_widgets.toReversed()) {
56
+ var prm = state_widget.set_state(null);
57
+ if (prm) {
58
+ promesses.push(prm);
59
+ }
60
+ }
61
+ for (const container of this.containers) {
62
+ container.set_grid_template();
55
63
  }
64
+ // re-set the grid templates for the StateWidget that are
65
+ // asynchronous
66
+ jQuery.when.apply(jQuery, promesses).done(() => {
67
+ for (const container of this.containers) {
68
+ container.set_grid_template();
69
+ }
70
+ });
56
71
  },
57
72
  active_changed: function(event_action) {
58
73
  for (const action of this.actions) {
package/src/common.js CHANGED
@@ -2785,7 +2785,9 @@
2785
2785
  (single_value && operator == 'in' && value.length == 1)) &&
2786
2786
  (!count ||
2787
2787
  ((count === 1) && model.length && name.endsWith('.id')))) {
2788
- value = operator == '=' ? value : value[0];
2788
+ if ((operator == 'in') && single_value) {
2789
+ value = value[0];
2790
+ }
2789
2791
  if (model.length && name.endsWith('.id')) {
2790
2792
  model = model[0];
2791
2793
  value = [model, value];
package/src/model.js CHANGED
@@ -1776,7 +1776,7 @@
1776
1776
  setdefault = false;
1777
1777
  }
1778
1778
  }
1779
- if (setdefault && !pre_validate) {
1779
+ if (setdefault && jQuery.isEmptyObject(pre_validate)) {
1780
1780
  this.set_client(record, value);
1781
1781
  state_attrs.domain_readonly = domain_readonly;
1782
1782
  }
@@ -2630,7 +2630,7 @@
2630
2630
  }
2631
2631
  for (const record2 of (record._values[this.name] || [])) {
2632
2632
  if (!record2.get_loaded() && (record2.id >= 0) &&
2633
- !pre_validate) {
2633
+ jQuery.isEmptyObject(pre_validate)) {
2634
2634
  continue;
2635
2635
  }
2636
2636
  if (!record2.validate(null, softvalidation, ldomain)) {
package/src/pyson.js CHANGED
@@ -431,7 +431,8 @@
431
431
  if ( (!(statement instanceof Sao.PYSON.DateTime ||
432
432
  statement instanceof Sao.PYSON.Date ||
433
433
  statement instanceof Sao.PYSON.TimeDelta)) &&
434
- (jQuery(statement.types()).not(['number']).length) ) {
434
+ (jQuery(statement.types()).not(
435
+ ['number', 'object']).length) ) {
435
436
  throw 'statement must be an integer, float, ' +
436
437
  'date, datetime or timedelta';
437
438
  }
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.0',
6
+ __version__: '7.4.2',
7
7
  };
8
8
  /* eslint-enable no-redeclare */
9
9
 
package/src/sao.less CHANGED
@@ -441,6 +441,7 @@ html.accesskey {
441
441
  > .nav-tabs {
442
442
  display: inline-flex;
443
443
  white-space: nowrap;
444
+ width: 1px;
444
445
  }
445
446
  .badge {
446
447
  min-width: 3em;
@@ -548,7 +549,7 @@ img.icon {
548
549
  }
549
550
  }
550
551
 
551
- .screen-container {
552
+ .screen-container, .board {
552
553
  display: flex;
553
554
  flex-direction: column;
554
555
  flex: 1;
@@ -816,7 +817,7 @@ img.icon {
816
817
  }
817
818
  }
818
819
 
819
- .form {
820
+ .form, .board {
820
821
  width: 100%;
821
822
  height: 100%;
822
823
  .form-container, .form-hcontainer, .form-vcontainer {
package/src/screen.js CHANGED
@@ -833,10 +833,7 @@
833
833
  'class': 'col-md-12'
834
834
  }).append(this.context_screen.screen_container.el))
835
835
  .prependTo(this.screen_container.filter_box);
836
- return this.context_screen.new_(false).then(
837
- // Set manually default to get context_screen_prm
838
- // resolved when default is set.
839
- record => record.default_get());
836
+ return this.context_screen.new_();
840
837
  });
841
838
  }
842
839
 
@@ -936,7 +933,7 @@
936
933
  var views = this.views.concat(this.view_to_load)
937
934
  var next_view_index = (this.view_index + 1) % views.length;
938
935
  var next_view = views[next_view_index];
939
- if (typeof next_view != 'string') {
936
+ if (next_view && (typeof next_view != 'string')) {
940
937
  next_view = next_view.view_type;
941
938
  }
942
939
  return next_view;
package/src/tab.js CHANGED
@@ -1650,6 +1650,8 @@
1650
1650
  }
1651
1651
  this.dialogs = [];
1652
1652
  this.board = null;
1653
+ this.create_tabcontent();
1654
+ this.set_name(name);
1653
1655
  UIView = new Sao.Model('ir.ui.view');
1654
1656
  this.view_prm = UIView.execute(
1655
1657
  'view_get', [this.view_id], this.context);
@@ -1666,8 +1668,6 @@
1666
1668
  });
1667
1669
  this.content.append(this.board.el);
1668
1670
  });
1669
- this.create_tabcontent();
1670
- this.set_name(name);
1671
1671
  },
1672
1672
  compare: function(attributes) {
1673
1673
  if (!attributes) {
package/src/view/form.js CHANGED
@@ -14,6 +14,10 @@ function eval_pyson(value){
14
14
  (function() {
15
15
  'use strict';
16
16
 
17
+ function remove_newline(value) {
18
+ return value.replace(/[\n\r]/gm, '')
19
+ }
20
+
17
21
  Sao.View.FormXMLViewParser = Sao.class_(Sao.View.XMLViewParser, {
18
22
  init: function(view, exclude_field, field_attrs) {
19
23
  Sao.View.FormXMLViewParser._super.init.call(
@@ -232,7 +236,6 @@ function eval_pyson(value){
232
236
  var group = new Sao.View.Form.Container(
233
237
  Number(node.getAttribute('col') || 4));
234
238
  this.view.containers.push(group);
235
- this.parse_child(node, group);
236
239
 
237
240
  if (attributes.xalign === undefined) {
238
241
  attributes.xalign = 0.5;
@@ -257,6 +260,9 @@ function eval_pyson(value){
257
260
 
258
261
  this.view.state_widgets.push(widget);
259
262
  this.container.add(widget, attributes);
263
+ // Parse the children at the end to preserve the order of the state
264
+ // widgets
265
+ this.parse_child(node, group);
260
266
  },
261
267
  _parse_hpaned: function(node, attributes) {
262
268
  this._parse_paned(node, attributes, 'horizontal');
@@ -2644,7 +2650,7 @@ function eval_pyson(value){
2644
2650
  get_text: function() {
2645
2651
  var record = this.record;
2646
2652
  if (record) {
2647
- return record.field_get_client(this.field_name);
2653
+ return remove_newline(record.field_get_client(this.field_name));
2648
2654
  }
2649
2655
  return '';
2650
2656
  },
@@ -2660,7 +2666,7 @@ function eval_pyson(value){
2660
2666
  set_value: function() {
2661
2667
  var record = this.record;
2662
2668
  var field = this.field;
2663
- if (field.get_client(record) != this.entry.val()) {
2669
+ if (this.get_text() != this.entry.val()) {
2664
2670
  field.set_client(record, this.value_from_id(null, ''));
2665
2671
  this.entry.val('');
2666
2672
  }
@@ -2757,7 +2763,7 @@ function eval_pyson(value){
2757
2763
  get modified() {
2758
2764
  if (this.record && this.field) {
2759
2765
  var value = this.entry.val();
2760
- return this.field.get_client(this.record) != value;
2766
+ return this.get_text() != value;
2761
2767
  }
2762
2768
  return false;
2763
2769
  },
@@ -3085,7 +3091,7 @@ function eval_pyson(value){
3085
3091
  name = '';
3086
3092
  if (value) {
3087
3093
  model = value[0];
3088
- name = value[1];
3094
+ name = remove_newline(value[1]);
3089
3095
  }
3090
3096
  return ((model != this.get_model()) ||
3091
3097
  (name != this.entry.val()));
@@ -3104,7 +3110,8 @@ function eval_pyson(value){
3104
3110
  get_text: function() {
3105
3111
  var record = this.record;
3106
3112
  if (record) {
3107
- return record.field_get_client(this.field_name)[1];
3113
+ return remove_newline(
3114
+ record.field_get_client(this.field_name)[1]);
3108
3115
  }
3109
3116
  return '';
3110
3117
  },
@@ -3158,7 +3165,7 @@ function eval_pyson(value){
3158
3165
  var model, name;
3159
3166
  if (value instanceof Array) {
3160
3167
  model = value[0];
3161
- name = value[1];
3168
+ name = remove_newline(value[1]);
3162
3169
  } else {
3163
3170
  model = '';
3164
3171
  name = '';
@@ -4597,7 +4604,8 @@ function eval_pyson(value){
4597
4604
  set_readonly: function(readonly) {
4598
4605
  Sao.View.Form.Binary._super.set_readonly.call(this, readonly);
4599
4606
  var record = this.record;
4600
- this.but_select.prop('disabled', readonly || !record);
4607
+ this.but_select.toggleClass('disabled', readonly || !record);
4608
+ this.input_select.toggle(!readonly && record);
4601
4609
  this.but_clear.prop('disabled', readonly || !record);
4602
4610
  if (this.text) {
4603
4611
  this.text.prop('readonly', readonly);
package/tests/sao.js CHANGED
@@ -519,6 +519,20 @@
519
519
  QUnit.strictEqual(new Sao.PYSON.Decoder().decode(eval_), false,
520
520
  'decode(Greater(PYSON.Date(2020, 1, 1), Date(2020, 0, 1)))');
521
521
 
522
+ eval_ = new Sao.PYSON.Encoder().encode(new Sao.PYSON.Greater(
523
+ new Sao.PYSON.Eval('foo', Sao.Date(2020, 0, 1)),
524
+ Sao.Date(2020, 0, 1)));
525
+ QUnit.strictEqual(new Sao.PYSON.Decoder().decode(eval_), false,
526
+ 'decode(Greater(PYSON.Eval("foo", Date(2020, 1, 1)), ' +
527
+ 'Date(2020, 0, 1)))');
528
+
529
+ eval_ = new Sao.PYSON.Encoder().encode(new Sao.PYSON.Greater(
530
+ new Sao.PYSON.Eval('foo', new Sao.PYSON.Date(2020, 1, 1)),
531
+ new Sao.PYSON.Date(2020, 1, 1)));
532
+ QUnit.strictEqual(new Sao.PYSON.Decoder().decode(eval_), false,
533
+ 'decode(Greater(PYSON.Eval("foo", PYSON.Date(2020, 1, 1)), ' +
534
+ 'PYSON.Date(2020, 1, 1)))');
535
+
522
536
  eval_ = new Sao.PYSON.Encoder().encode(new Sao.PYSON.Greater(
523
537
  new Sao.PYSON.Date(2020, 1, 1),
524
538
  new Sao.PYSON.DateTime(2020, 1, 1, 0, 0, 0, 1)));