@eclipse-scout/core 22.0.1 → 22.0.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.
Files changed (77) hide show
  1. package/dist/eclipse-scout-core-c98fb5230e71dcec75ce.min.js +2 -0
  2. package/dist/eclipse-scout-core-c98fb5230e71dcec75ce.min.js.map +1 -0
  3. package/dist/eclipse-scout-core-theme-6b2fef56e9e49231a49c.min.css +1 -0
  4. package/dist/eclipse-scout-core-theme-dark-d2bb274dd42f132bfca0.min.css +1 -0
  5. package/dist/eclipse-scout-core-theme-dark.css +367 -312
  6. package/dist/eclipse-scout-core-theme-dark.css.map +1 -1
  7. package/dist/eclipse-scout-core-theme.css +150 -95
  8. package/dist/eclipse-scout-core-theme.css.map +1 -1
  9. package/dist/eclipse-scout-core.js +371 -204
  10. package/dist/eclipse-scout-core.js.map +1 -1
  11. package/dist/file-list +7 -0
  12. package/dist/locales.json +47126 -0
  13. package/dist/texts.json +1153 -0
  14. package/package.json +2 -2
  15. package/src/action/Button.less +1 -0
  16. package/src/calendar/Calendar.js +40 -58
  17. package/src/calendar/Calendar.less +10 -10
  18. package/src/calendar/CalendarLayout.js +3 -1
  19. package/src/datepicker/DatePicker.less +1 -0
  20. package/src/desktop/desktoptab/DesktopTab.less +5 -2
  21. package/src/desktop/desktoptab/DesktopTabArea.less +7 -3
  22. package/src/desktop/navigation/DesktopNavigation.less +4 -0
  23. package/src/desktop/notification/DesktopNotification.js +11 -4
  24. package/src/desktop/notification/DesktopNotification.less +5 -3
  25. package/src/desktop/outline/Outline.less +4 -4
  26. package/src/desktop/viewbutton/ViewButton.less +13 -9
  27. package/src/desktop/viewbutton/ViewMenuTab.less +3 -2
  28. package/src/filechooser/FileChooser.less +1 -1
  29. package/src/form/Form.less +1 -0
  30. package/src/form/fields/LookupBox.js +2 -1
  31. package/src/form/fields/breadcrumbbarfield/BreadcrumbBarField.less +14 -0
  32. package/src/form/fields/groupbox/GroupBox.js +13 -9
  33. package/src/form/fields/groupbox/GroupBox.less +1 -0
  34. package/src/form/fields/htmlfield/HtmlField.less +0 -1
  35. package/src/form/fields/listbox/ListBox.js +8 -3
  36. package/src/form/fields/tabbox/TabAreaLayout.js +63 -66
  37. package/src/form/fields/tabbox/TabBox.js +4 -7
  38. package/src/form/fields/tabbox/TabBox.less +2 -1
  39. package/src/form/fields/tabbox/TabBoxHeaderLayout.js +5 -5
  40. package/src/glasspane/GlassPane.js +3 -3
  41. package/src/group/Group.less +1 -1
  42. package/src/index.less +1 -0
  43. package/src/jquery/jquery-scout.js +5 -4
  44. package/src/menu/ContextMenuPopup.less +9 -2
  45. package/src/menu/Menu.less +1 -0
  46. package/src/modeselector/Mode.less +15 -37
  47. package/src/modeselector/ModeSelector.js +1 -1
  48. package/src/modeselector/ModeSelector.less +2 -1
  49. package/src/planner/PlannerHeader.less +2 -1
  50. package/src/popup/Popup.js +24 -8
  51. package/src/popup/PopupLayout.js +2 -8
  52. package/src/scrollbar/Scrollbar.less +8 -1
  53. package/src/scrollbar/scrollbars.js +26 -4
  54. package/src/style/colors-dark.less +17 -10
  55. package/src/style/colors.less +11 -3
  56. package/src/style/fonts.less +5 -0
  57. package/src/style/mixins.less +16 -12
  58. package/src/style/sizes-dark.less +4 -1
  59. package/src/style/sizes.less +3 -4
  60. package/src/table/Table.js +37 -29
  61. package/src/table/Table.less +36 -13
  62. package/src/table/TableHeader.js +10 -8
  63. package/src/table/TableHeader.less +1 -0
  64. package/src/table/TableHeaderMenu.js +3 -1
  65. package/src/table/TableHeaderMenu.less +7 -2
  66. package/src/table/columns/BooleanColumn.js +2 -2
  67. package/src/table/columns/Column.js +3 -3
  68. package/src/table/editor/CellEditorPopup.js +8 -1
  69. package/src/tile/TileGrid.js +1 -1
  70. package/src/tile/TileGridLayout.js +2 -2
  71. package/src/tile/accordion/TileAccordion.js +16 -1
  72. package/src/tile/fields/FormFieldTile.less +18 -11
  73. package/src/tree/CompactTree.less +1 -1
  74. package/src/tree/Tree.less +1 -3
  75. package/src/util/arrays.js +24 -2
  76. package/src/util/objects.js +4 -1
  77. package/src/widget/Widget.js +11 -3
@@ -133,7 +133,7 @@
133
133
  transition: box-shadow 250ms;
134
134
  position: absolute;
135
135
  pointer-events: none;
136
- z-index: 1; // ensure shadow layout over elements having a z-index
136
+ z-index: 1; // ensure shadow lays over elements having a z-index
137
137
 
138
138
  #scout.scroll-shadow();
139
139
 
@@ -157,6 +157,13 @@
157
157
  --scroll-shadow-size: @scroll-shadow-size;
158
158
  --scroll-shadow-blur: @scroll-shadow-blur;
159
159
  --scroll-shadow-spread: @scroll-shadow-spread;
160
+
161
+ // Allow a widget to adjust the size of the shadow container
162
+ --scroll-shadow-inset-top: 0;
163
+ --scroll-shadow-inset-right: 0;
164
+ --scroll-shadow-inset-bottom: 0;
165
+ --scroll-shadow-inset-left: 0;
166
+
160
167
  @scroll-shadow-blur-spread-color: var(--scroll-shadow-blur) calc(-1 * var(--scroll-shadow-spread)) var(--scroll-shadow-color);
161
168
  @scroll-shadow-top: inset 0 var(--scroll-shadow-size) @scroll-shadow-blur-spread-color;
162
169
  @scroll-shadow-bottom: inset 0 calc(-1 * var(--scroll-shadow-size)) @scroll-shadow-blur-spread-color;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2010-2021 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
@@ -8,7 +8,7 @@
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
10
10
  */
11
- import {arrays, Device, graphics, HtmlComponent, objects, scout} from '../index';
11
+ import {arrays, Device, graphics, HtmlComponent, Insets, objects, scout} from '../index';
12
12
  import $ from 'jquery';
13
13
 
14
14
  /**
@@ -159,6 +159,17 @@ export function installScrollShadow($container, session, options) {
159
159
  _installMutationObserver(session);
160
160
  _installIntersectionObserver();
161
161
  intersectionObserver.observe($container[0]);
162
+
163
+ // this is required in addition to the intersection observer because the observer events are handled asynchronously later after all the setTimeout calls.
164
+ // Then the shadow might stay visible too long which has an impact on layout updates.
165
+ let containerElement = $container[0];
166
+ let visibleListener = e => {
167
+ if (e.target === containerElement) {
168
+ _onScrollableVisibleChange(containerElement, e.type === 'show');
169
+ }
170
+ };
171
+ $container.data('scroll-shadow-visible-listener', visibleListener);
172
+ $container.on('hide show', visibleListener);
162
173
  }
163
174
 
164
175
  export function uninstallScrollShadow($container, session) {
@@ -177,6 +188,10 @@ export function uninstallScrollShadow($container, session) {
177
188
  if (intersectionObserver) {
178
189
  intersectionObserver.unobserve($container[0]);
179
190
  }
191
+ let visibleListener = $container.data('scroll-shadow-visible-listener');
192
+ if (visibleListener) {
193
+ $container.off('hide show', visibleListener);
194
+ }
180
195
  let $scrollables = _$scrollables[session];
181
196
  if (!$scrollables || !$scrollables.some($scrollable => $scrollable.data('scroll-shadow'))) {
182
197
  _uninstallMutationObserver();
@@ -237,7 +252,7 @@ export function updateScrollShadow($container) {
237
252
  $shadow.toggleClass('bottom', !atBottom && style.indexOf('bottom') > -1);
238
253
  $shadow.toggleClass('left', !atLeft && style.indexOf('left') > -1);
239
254
  $shadow.toggleClass('right', !atRight && style.indexOf('right') > -1);
240
- graphics.setBounds($shadow, graphics.bounds($container, {exact: true}));
255
+ graphics.setBounds($shadow, graphics.bounds($container, {exact: true}).subtract(insets($shadow)));
241
256
  graphics.setMargins($shadow, graphics.margins($container));
242
257
  $shadow.css('border-radius', $container.css('border-radius'));
243
258
 
@@ -253,6 +268,13 @@ export function updateScrollShadow($container) {
253
268
  function atEnd(scrollPos, scrollSize, offsetSize) {
254
269
  return scrollPos + 1 >= scrollSize - offsetSize;
255
270
  }
271
+
272
+ function insets($shadow) {
273
+ return new Insets($shadow.cssPxValue('--scroll-shadow-inset-top'),
274
+ $shadow.cssPxValue('--scroll-shadow-inset-right'),
275
+ $shadow.cssPxValue('--scroll-shadow-inset-bottom'),
276
+ $shadow.cssPxValue('--scroll-shadow-inset-left'));
277
+ }
256
278
  }
257
279
 
258
280
  /**
@@ -726,7 +748,7 @@ export function scrollToBottom($scrollable, options) {
726
748
  /**
727
749
  * @param location object with x and y properties
728
750
  * @param $scrollables one or more scrollables to check against
729
- * @eturns {boolean} true if the location is visible in the current viewport of all the $scrollables, or if $scrollables is null
751
+ * @returns {boolean} true if the location is visible in the current viewport of all the $scrollables, or if $scrollables is null
730
752
  */
731
753
  export function isLocationInView(location, $scrollables) {
732
754
  if (!$scrollables || $scrollables.length === 0) {
@@ -19,13 +19,13 @@
19
19
  @palette-gray-3: #BFC2C3;
20
20
  @palette-gray-4: #A7ACAD;
21
21
  @palette-gray-5: #7E8588;
22
- @palette-gray-5-1: #445155;
23
- @palette-gray-6: #344146;
24
- @palette-gray-6-1: #283438;
25
- @palette-gray-7: #252e31;
26
- @palette-gray-8: #1F272B;
27
- @palette-gray-9: #181C1F;
28
- @palette-gray-10: #0C1013;
22
+ @palette-gray-5-1: #4B595E;
23
+ @palette-gray-6: #3B494F;
24
+ @palette-gray-6-1: #2E3C41;
25
+ @palette-gray-7: #2C363A;
26
+ @palette-gray-8: #252F34;
27
+ @palette-gray-9: #1F2428;
28
+ @palette-gray-10: #0E1316;
29
29
 
30
30
  @fade-white-0: fade(@palette-white, 25%);
31
31
  @fade-white-1: fade(@palette-white, 18%);
@@ -136,9 +136,11 @@
136
136
  @carousel-current-item-color: @palette-gray-1;
137
137
  @check-box-border-color: @palette-gray-5;
138
138
  @mode-color: @text-color;
139
- @mode-alternative-background-color: @palette-gray-10;
139
+ @mode-alternative-background-color: fade(@palette-black, 60%);
140
140
  @mode-alternative-selected-background-color: @palette-gray-7;
141
141
  @mode-alternative-selected-background-disabled-color: @palette-gray-8;
142
+ @mode-alternative-hover-background-color: @palette-gray-9;
143
+ @mode-alternative-active-background-color: @palette-gray-6;
142
144
  @closer-action-color: @text-color;
143
145
  @closer-color: @palette-gray-3;
144
146
  @closer-hover-color: @text-color;
@@ -157,13 +159,15 @@
157
159
  @date-picker-separator-color: @palette-gray-4;
158
160
  @date-picker-day-preselected-background-color: fade(@palette-white, 8%);
159
161
  @dashboard-tile-border-color: @border-color;
160
- @dashboard-tile-alternative-selected-border-color: @dashboard-tile-selected-border-color;
161
- @dashboard-tile-default-selected-border-color: @dashboard-tile-selected-border-color;
162
+ @dashboard-tile-default-inverted-selected-border-color: @item-selection-border-color;
163
+ @dashboard-tile-alternative-selected-border-color: @dashboard-tile-default-selected-border-color;
164
+ @dashboard-tile-alternative-inverted-selected-border-color: @item-selection-border-color;
162
165
  @desktop-bench-drop-shadow-color: fade(@palette-black, 35%);
163
166
  @desktop-header-background-color: @palette-gray-10;
164
167
  @desktop-header-border-color: @palette-gray-8;
165
168
  @desktop-header-color: @title-color;
166
169
  @desktop-logo-background-color: transparent;
170
+ @desktop-tab-border-color: @border-color;
167
171
  @desktop-tab-closer-hover-background-color: @hover-background-color;
168
172
  @desktop-tab-closer-active-background-color: @active-background-color;
169
173
  @desktop-tab-status-color: @save-needer-color;
@@ -186,6 +190,7 @@
186
190
  @planner-large-scale-item-line-color: fade(@palette-white, 20%);
187
191
  @planner-resource-title-color: @text-color;
188
192
  @planner-small-scale-item-line-color: fade(@palette-white, 7%);
193
+ @scroll-shadow-alpha: 0;
189
194
  @scrollbar-thumb-main-color: @palette-white;
190
195
  @scrollbar-thumb-color: fade(@scrollbar-thumb-main-color, 20%);
191
196
  @scrollbar-thumb-hover-color: fade(@scrollbar-thumb-main-color, 30%);
@@ -242,6 +247,8 @@
242
247
  @tile-default-inverted-link-hover-color: @link-hover-color;
243
248
  @tile-default-inverted-status-hover-background-color: @hover-background-color;
244
249
  @tile-default-inverted-status-active-background-color: @active-background-color;
250
+ @tile-default-inverted-error-status-color: @status-error-color;
251
+ @tile-default-inverted-error-status-hover-color: @status-error-hover-color;
245
252
  @tile-default-label-color: @text-color-1;
246
253
  @tile-default-link-active-color: @link-active-color;
247
254
  @tile-table-default-inverted-selection-background-color: @item-selection-background-color;
@@ -227,9 +227,12 @@
227
227
  @context-menu-item-color: @text-color;
228
228
  @context-menu-item-icon-color: @link-color;
229
229
  @dashboard-tile-border-color: darken(@palette-gray-3, 5%);
230
- @dashboard-tile-selected-border-color: @item-selection-border-color;
230
+ @dashboard-tile-default-inverted-background-color: mix(@tile-default-inverted-background-color, @tile-default-inverted-selection-background-color, 65%);
231
+ @dashboard-tile-alternative-inverted-background-color: mix(@tile-alternative-inverted-background-color, @tile-alternative-inverted-selection-background-color, 65%);
232
+ @dashboard-tile-default-selected-border-color: @item-selection-border-color;
233
+ @dashboard-tile-default-inverted-selected-border-color: @dashboard-tile-default-inverted-background-color;
231
234
  @dashboard-tile-alternative-selected-border-color: @tile-alternative-inverted-background-color;
232
- @dashboard-tile-default-selected-border-color: @tile-default-inverted-background-color;
235
+ @dashboard-tile-alternative-inverted-selected-border-color: @dashboard-tile-alternative-inverted-background-color;
233
236
  @date-picker-day-hover-background-color: @hover-background-color;
234
237
  @date-picker-day-selected-color: @selected-color;
235
238
  @date-picker-day-selected-background-color: @selected-background-color;
@@ -266,6 +269,7 @@
266
269
  @desktop-header-background-color: @accent-color-3;
267
270
  @desktop-header-border-color: @border-color;
268
271
  @desktop-tab-background-color: fade(@palette-black, 10%);
272
+ @desktop-tab-border-color: transparent;
269
273
  @desktop-tab-flash-background-color: fade(@palette-black, 40%);
270
274
  @desktop-tab-closer-hover-background-color: fade(@palette-black, 14%);
271
275
  @desktop-tab-closer-active-background-color: fade(@palette-black, 20%);
@@ -298,6 +302,8 @@
298
302
  @mode-alternative-selected-background-color: @palette-white;
299
303
  @mode-alternative-selected-background-disabled-color: @palette-gray-4;
300
304
  @mode-alternative-background-color: rgba(0, 0, 0, 0.08);
305
+ @mode-alternative-hover-background-color: rgba(0, 0, 0, 0.05);
306
+ @mode-alternative-active-background-color: rgba(0, 0, 0, 0.1);
301
307
  @navigate-up-button-border-color: @button-border-color;
302
308
  @navigate-up-button-color: @button-color;
303
309
  @desktop-navigation-background-color: @desktop-header-background-color;
@@ -480,6 +486,8 @@
480
486
  @tile-default-inverted-link-active-color: fade(@tile-default-inverted-color, 75%);
481
487
  @tile-default-inverted-status-hover-background-color: fade(@palette-black, 15%);
482
488
  @tile-default-inverted-status-active-background-color: fade(@palette-black, 20%);
489
+ @tile-default-inverted-error-status-color: @palette-red-3;
490
+ @tile-default-inverted-error-status-hover-color: @tile-default-inverted-error-status-color;
483
491
  @tile-placeholder-background-color: @palette-gray-3;
484
492
  @tile-scrollbar-thumb-inverted-main-color: @palette-gray-4;
485
493
  @tile-scrollbar-thumb-inverted-color: fade(@tile-scrollbar-thumb-inverted-main-color, 30%);
@@ -515,7 +523,7 @@
515
523
  @top-label-disabled-color: @label-disabled-color;
516
524
  @tree-node-active-background-color: @item-active-background-color;
517
525
  @tree-node-control-color: inherit;
518
- @view-tab-selected-color: @active-color;
526
+ @view-tab-selected-color: @outline-title-color;
519
527
  @view-tab-selected-background-color: @desktop-navigation-body-background-color;
520
528
  @view-tab-in-background-selected-background-color: @desktop-navigation-body-in-background-background-color;
521
529
  @view-tab-hover-background-color: fade(@palette-black, 20%);
@@ -38,6 +38,11 @@ Try these to switch between fonts:
38
38
 
39
39
  @letter-spacing: 0.2px;
40
40
 
41
+ // Arial font is hard to vertically align, especially with icons
42
+ // This variable can be used to fix the alignment for specific widgets that can have an icon
43
+ // or are often placed to the side of widgets with icons
44
+ @text-margin-top: 1px;
45
+
41
46
  @icon-font-weight-light: 300;
42
47
 
43
48
  @tooltip-font-weight: @font-weight-normal;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2010-2021 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
@@ -70,26 +70,30 @@
70
70
  padding-bottom: 0;
71
71
  }
72
72
 
73
- .inverted-bottom-round-edge(@border-radius: 12px, @width: 24px, @color: #ffffff) {
73
+ .inverted-bottom-round-edge(@border-radius: 12px, @color: #ffffff) {
74
+ @border-width: 5px;
75
+
74
76
  --color: @color; // Allows to change color only
75
77
  position: absolute;
76
78
  pointer-events: none;
77
79
  background-color: transparent;
78
- bottom: 0;
79
- height: 2 * @width;
80
- width: @width;
81
- box-shadow: 0 @width 0 0 var(--color);
82
- // Cut the leftover on the bottom to only get the edge. Use 110%/-10% because with 100%/0% there are drawing issues, at least with Chrome (a very thin line won't be colored)
83
- clip-path: polygon(-10% 0, 110% 0, 110% 100%, -10% 100%);
80
+ bottom: -@border-width;
81
+ height: @border-radius;
82
+ width: @border-radius;
83
+ box-sizing: content-box;
84
+ border: @border-width solid var(--color);
85
+ border-top: none;
84
86
 
85
87
  &.left {
86
- left: -@width;
87
- border-bottom-right-radius: @border-radius;
88
+ left: -@border-radius;
89
+ border-bottom-right-radius: @border-radius+@border-width;
90
+ border-left: none;
88
91
  }
89
92
 
90
93
  &.right {
91
- right: -@width;
92
- border-bottom-left-radius: @border-radius;
94
+ right: -@border-radius;
95
+ border-bottom-left-radius: @border-radius+@border-width;
96
+ border-right: none;
93
97
  }
94
98
  }
95
99
 
@@ -8,5 +8,8 @@
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
10
10
  */
11
+ @desktop-tab-border-width: 1px;
11
12
  @popup-border-width: 1px;
12
- @tooltip-border-width: 1px;
13
+ @tooltip-border-width: 1px;
14
+ @scroll-shadow-size-large: 14px;
15
+ @scroll-shadow-size: @scroll-shadow-size-large;
@@ -55,7 +55,7 @@
55
55
  @focus-box-shadow-size: 3px;
56
56
  @text-field-padding-x: 10px;
57
57
  @text-field-padding-y: 7px;
58
- @text-field-padding-top-compensation: 1px;
58
+ @text-field-padding-top-compensation: 1px + @text-margin-top;
59
59
  @text-field-alternative-padding-left: 0;
60
60
  @text-field-alternative-padding-right: 0;
61
61
  @text-field-icon-size: 24px;
@@ -162,6 +162,7 @@
162
162
  @desktop-navigation-width: 290px;
163
163
  @desktop-notification-no-icon-padding-y: 16px;
164
164
  @desktop-tab-border-radius: @view-tab-border-radius;
165
+ @desktop-tab-border-width: 0;
165
166
  @desktop-tab-key-box-bottom: @view-tab-key-box-bottom;
166
167
  @desktop-tab-margin-top: @view-tab-margin-top;
167
168
  @desktop-tab-margin-right: 3px;
@@ -223,17 +224,15 @@
223
224
  @mobile-popup-title-margin-top: 10px;
224
225
  @mode-padding-x: 12px;
225
226
  @mode-padding-y: 6px;
226
- @mode-padding-dense: @mode-padding-dense-y @mode-padding-dense-x;
227
227
  @mode-padding-dense-x: 5px;
228
228
  @mode-padding-dense-y: 3px;
229
229
  @mode-border-width: 1px;
230
- @mode-alternative-border-width: 3px;
230
+ @mode-selector-alternative-border-width: 3px;
231
231
  @notification-no-icon-padding-y: 13px;
232
232
  @outline-breadcrumb-node-padding-x: @outline-title-padding-left;
233
233
  @outline-breadcrumb-node-padding-y: 12px;
234
234
  @outline-data-padding-top: 16px;
235
235
  @outline-font-size: @font-size-normal;
236
- @outline-node-control-size: 18px;
237
236
  @outline-node-control-padding-left: @outline-title-padding-left;
238
237
  @outline-node-control-padding-y: @outline-node-padding-y;
239
238
  @outline-node-control-line-height: @tree-node-control-line-height;
@@ -23,6 +23,7 @@ export default class Table extends Widget {
23
23
  this.contextColumn = null;
24
24
  this.checkable = false;
25
25
  this.checkableStyle = Table.CheckableStyle.CHECKBOX;
26
+ this.cellEditorPopup = null;
26
27
  this.compact = false;
27
28
  this.compactHandler = scout.create('TableCompactHandler', {table: this});
28
29
  this.compactColumn = null;
@@ -100,6 +101,7 @@ export default class Table extends Widget {
100
101
  this._popupOpenHandler = this._onDesktopPopupOpen.bind(this);
101
102
  this._rerenderViewPortAfterAttach = false;
102
103
  this._renderViewPortAfterAttach = false;
104
+ this._postAttachActions = [];
103
105
  this._desktopPropertyChangeHandler = this._onDesktopPropertyChange.bind(this);
104
106
  this._addWidgetProperties(['tableControls', 'menus', 'keyStrokes', 'staticMenus', 'tileTableHeader', 'tableTileGridMediator']);
105
107
 
@@ -475,7 +477,6 @@ export default class Table extends Widget {
475
477
  }
476
478
 
477
479
  _removeData() {
478
- this._destroyCellEditorPopup();
479
480
  this._removeAggregateRows();
480
481
  this._uninstallImageListeners();
481
482
  this._uninstallCellTooltipSupport();
@@ -633,11 +634,11 @@ export default class Table extends Widget {
633
634
  // Don't start cell editor or trigger click if row control was clicked (expansion itself is handled by the mouse down handler)
634
635
  return;
635
636
  }
637
+ let row = $row.data('row'); // read row before the $row potentially could be replaced by the column specific logic on mouse up
636
638
  if (mouseButton === 1) {
637
639
  column.onMouseUp(event, $row);
638
640
  $appLink = this._find$AppLink(event);
639
641
  }
640
- let row = $row.data('row');
641
642
  if ($appLink) {
642
643
  this._triggerAppLinkAction(column, row, $appLink.data('ref'), $appLink);
643
644
  } else {
@@ -2068,8 +2069,24 @@ export default class Table extends Widget {
2068
2069
  }
2069
2070
 
2070
2071
  /**
2071
- * This functions starts the cell editor for the given row and column. Prepare must wait until
2072
- * a pending completeCellEdit operation is resolved.
2072
+ * Starts cell editing for the cell at the given column and row, but only if editing is allowed.
2073
+ * @see prepareCellEdit
2074
+ */
2075
+ focusCell(column, row) {
2076
+ let cell = this.cell(column, row);
2077
+ if (this.enabledComputed && row.enabled && cell.editable) {
2078
+ this.prepareCellEdit(column, row);
2079
+ }
2080
+ }
2081
+
2082
+ /**
2083
+ * Creates a cell editor for the cell at the given column and row, ensures the row is selected and passes the editor
2084
+ * to {@link #startCellEdit} which starts the editing by rendering the editor in a {@link CellEditorPopup}.<br>
2085
+ * If the completion of a previous cell edit is still in progress, the preparation is delayed until the completion is finished.
2086
+ *
2087
+ * @param {boolean} [openFieldPopupOnCellEdit] true to instruct the editor to open its control popup when the editor is rendered.
2088
+ * This only has an effect if the editor has a popup (e.g. SmartField or DateField).
2089
+ * @returns Promise the promise will be resolved when the preparation has been finished.
2073
2090
  */
2074
2091
  prepareCellEdit(column, row, openFieldPopupOnCellEdit) {
2075
2092
  let promise = $.resolvedPromise();
@@ -2080,10 +2097,10 @@ export default class Table extends Widget {
2080
2097
  }
2081
2098
 
2082
2099
  /**
2083
- * @param openFieldPopupOnCellEdit when this parameter is set to true, the CellEditorPopup sets an
2100
+ * @param {boolean} [openFieldPopupOnCellEdit] when this parameter is set to true, the CellEditorPopup sets an
2084
2101
  * additional property 'cellEditor' on the editor-field. The field instance may use this property
2085
2102
  * to decide whether or not it should open a popup immediately after it is rendered. This is used
2086
- * for Smart- and DateFields.
2103
+ * for Smart- and DateFields. Default is false.
2087
2104
  */
2088
2105
  prepareCellEditInternal(column, row, openFieldPopupOnCellEdit) {
2089
2106
  let event = new Event({
@@ -3043,10 +3060,18 @@ export default class Table extends Widget {
3043
3060
  }
3044
3061
 
3045
3062
  startCellEdit(column, row, field) {
3046
- if (!this._isDataRendered() || !this.isAttachedAndRendered()) {
3063
+ if (field.destroyed) {
3064
+ // May happen if the action was postponed and the field destroyed in the meantime using endCellEdit.
3065
+ return;
3066
+ }
3067
+ if (!this._isDataRendered()) {
3047
3068
  this._postRenderActions.push(this.startCellEdit.bind(this, column, row, field));
3048
3069
  return;
3049
3070
  }
3071
+ if (!this.$container.isAttached()) {
3072
+ this._postAttachActions.push(this.startCellEdit.bind(this, column, row, field));
3073
+ return;
3074
+ }
3050
3075
 
3051
3076
  this.trigger('startCellEdit', {
3052
3077
  column: column,
@@ -3066,11 +3091,6 @@ export default class Table extends Widget {
3066
3091
  * value is updated by an updateRow event instead.
3067
3092
  */
3068
3093
  endCellEdit(field, saveEditorValue) {
3069
- if (!this._isDataRendered() || !this.isAttachedAndRendered()) {
3070
- this._postRenderActions.push(this.endCellEdit.bind(this, field, saveEditorValue));
3071
- return;
3072
- }
3073
-
3074
3094
  if (!this.cellEditorPopup) {
3075
3095
  // the cellEditorPopup could already be removed by scrolling (out of view range) or be removed by update rows
3076
3096
  field.destroy();
@@ -4656,7 +4676,9 @@ export default class Table extends Widget {
4656
4676
  this.$container.toggleClass('checkable', scout.isOneOf(this.checkableStyle, Table.CheckableStyle.TABLE_ROW, Table.CheckableStyle.CHECKBOX_TABLE_ROW));
4657
4677
  this.$container.toggleClass('table-row-check', this.checkableStyle === Table.CheckableStyle.TABLE_ROW);
4658
4678
  if (this._isDataRendered()) {
4679
+ this._updateRowWidth();
4659
4680
  this._redraw();
4681
+ this.invalidateLayoutTree();
4660
4682
  }
4661
4683
  }
4662
4684
 
@@ -5302,18 +5324,6 @@ export default class Table extends Widget {
5302
5324
  }
5303
5325
  }
5304
5326
 
5305
- focusCell(column, row) {
5306
- if (!this._isDataRendered() || !this.isAttachedAndRendered()) {
5307
- this._postRenderActions.push(this.focusCell.bind(this, column, row));
5308
- return;
5309
- }
5310
-
5311
- let cell = this.cell(column, row);
5312
- if (this.enabledComputed && row.enabled && cell.editable) {
5313
- this.prepareCellEdit(column, row, false);
5314
- }
5315
- }
5316
-
5317
5327
  _attach() {
5318
5328
  this.$parent.append(this.$container);
5319
5329
  super._attach();
@@ -5337,6 +5347,9 @@ export default class Table extends Widget {
5337
5347
  super._renderOnAttach();
5338
5348
  this._rerenderViewportAfterAttach();
5339
5349
  this._renderViewportAfterAttach();
5350
+ let actions = this._postAttachActions;
5351
+ this._postAttachActions = [];
5352
+ actions.forEach(action => action());
5340
5353
  }
5341
5354
 
5342
5355
  _rerenderViewportAfterAttach() {
@@ -5365,11 +5378,6 @@ export default class Table extends Widget {
5365
5378
  super._detach();
5366
5379
  }
5367
5380
 
5368
- _onDetach() {
5369
- super._onDetach();
5370
- this._destroyCellEditorPopup();
5371
- }
5372
-
5373
5381
  /**
5374
5382
  * @param {function} [callback] function to be called right after the popup is destroyed
5375
5383
  */
@@ -49,25 +49,48 @@
49
49
  /* Used for scout.Table.CheckableStyle.TABLE_ROW */
50
50
 
51
51
  &.table-row-check {
52
+ & > .table-data {
53
+ & > .table-row {
54
+ &.selected {
55
+ /* Don't draw selection */
56
+ background-color: transparent;
52
57
 
53
- & > .table-data > .table-row {
58
+ &::after {
59
+ display: none;
60
+ }
61
+ }
54
62
 
55
- &.selected {
56
- /* Don't draw selection */
63
+ &:hover {
64
+ background-color: @hover-background-color;
65
+ }
66
+ }
67
+
68
+ & > .table-row.disabled,
69
+ &.disabled > .table-row {
57
70
  background-color: transparent;
71
+ }
58
72
 
59
- &::after {
60
- display: none;
73
+ & > .table-row {
74
+ &.checked,
75
+ &.checked.selected {
76
+ /* Mark checked rows with a background color */
77
+ background-color: @table-row-checked-background-color;
78
+
79
+ & > .table-cell {
80
+ color: @table-row-checked-color;
81
+ }
82
+
83
+ &:hover {
84
+ background-color: @selected-hover-background-color;
85
+ }
61
86
  }
62
87
  }
63
88
 
64
- &.checked,
65
- &.checked.selected {
66
- /* Mark checked rows with a background color */
67
- background-color: @table-row-checked-background-color;
68
-
69
- & > .table-cell {
70
- color: @table-row-checked-color;
89
+ & > .table-row.disabled,
90
+ &.disabled > .table-row {
91
+ &.checked,
92
+ &.checked.selected {
93
+ background-color: @selected-disabled-background-color;
71
94
  }
72
95
  }
73
96
  }
@@ -622,4 +645,4 @@
622
645
 
623
646
  .organize-columns-behind-scrollbar-column.table-cell.last {
624
647
  padding: 0;
625
- }
648
+ }
@@ -8,7 +8,7 @@
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
10
10
  */
11
- import {arrays, Column, ColumnUserFilter, Device, graphics, GroupBoxMenuItemsOrder, inspector, MenuBar, MenuDestinations, scout, scrollbars, strings, styles, Table, tooltips, Widget} from '../index';
11
+ import {arrays, Column, ColumnUserFilter, Device, graphics, GroupBoxMenuItemsOrder, inspector, MenuBar, MenuDestinations, objects, scout, scrollbars, strings, styles, Table, tooltips, Widget} from '../index';
12
12
  import $ from 'jquery';
13
13
 
14
14
  export default class TableHeader extends Widget {
@@ -459,21 +459,23 @@ export default class TableHeader extends Widget {
459
459
  let filtered = this.table.getFilter(column.id);
460
460
  if (column.sortActive || column.grouped || filtered) {
461
461
  if (column.minWidth < Column.DEFAULT_MIN_WIDTH) {
462
- column.prefMinWidth = column.minWidth;
462
+ column.__minWidthWithoutState = column.minWidth;
463
+ column.__widthWithoutState = column.width;
463
464
  column.minWidth = Column.DEFAULT_MIN_WIDTH;
464
465
  }
465
466
  if (column.width < column.minWidth) {
466
467
  this.table.resizeColumn(column, column.minWidth);
467
468
  }
468
469
  } else {
469
- // Reset to preferred min width if no state is visible
470
- if (column.prefMinWidth !== null) {
471
- column.minWidth = column.prefMinWidth;
472
- column.prefMinWidth = null;
473
- // Resize to old min width, assuming user has not manually changed the size because column is still as width as default_min_width
470
+ // Reset to previous min width if no state is visible
471
+ if (!objects.isNullOrUndefined(column.__minWidthWithoutState)) {
472
+ column.minWidth = column.__minWidthWithoutState;
473
+ // Resize to previous min width, assuming user has not manually changed the size because column is still as width as default_min_width
474
474
  if (column.width === Column.DEFAULT_MIN_WIDTH) {
475
- this.table.resizeColumn(column, column.minWidth);
475
+ this.table.resizeColumn(column, column.__widthWithoutState);
476
476
  }
477
+ column.__minWidthWithoutState = null;
478
+ column.__widthWithoutState = null;
477
479
  }
478
480
  }
479
481
  }
@@ -180,6 +180,7 @@
180
180
 
181
181
  .table-header-item-text {
182
182
  #scout.overflow-ellipsis-nowrap();
183
+ margin-top: @text-margin-top;
183
184
  }
184
185
 
185
186
  .table-header-item-state {
@@ -241,7 +241,9 @@ export default class TableHeaderMenu extends Popup {
241
241
  if (this.filterTable) {
242
242
  this.filterTable.off('rowsChecked', this._filterTableRowsCheckedHandler);
243
243
  }
244
- this.tableHeader.$container.off('scroll', this._tableHeaderScrollHandler);
244
+ if (this.tableHeader.rendered) {
245
+ this.tableHeader.$container.off('scroll', this._tableHeaderScrollHandler);
246
+ }
245
247
  this.$headerItem.select(false);
246
248
  this.table.off('columnMoved', this._onColumnMovedHandler);
247
249
  this.table.off('filterAdded', this._tableFilterHandler);
@@ -33,6 +33,11 @@
33
33
  display: inline-block;
34
34
  vertical-align: top;
35
35
  padding: @table-header-menu-padding;
36
+
37
+ & > .table-header-menu-group > .table-header-menu-group-text {
38
+ // Increase size a little to ensure every text is fully visible, at least for german and english (currently necessary for additional sorting group)
39
+ width: calc(100% + 12px);
40
+ }
36
41
  }
37
42
 
38
43
  .table-header-menu-filters {
@@ -252,11 +257,11 @@
252
257
 
253
258
  & > .table-data {
254
259
  margin-top: 0;
255
- padding: 3px 4px;
260
+ padding: 3px;
256
261
 
257
262
  & > .table-row {
258
263
  border-radius: @border-radius;
259
- margin-bottom: 1px;
264
+ margin-bottom: 2px;
260
265
 
261
266
  &.last {
262
267
  margin-bottom: 0;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2010-2020 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
@@ -21,7 +21,7 @@ export default class BooleanColumn extends Column {
21
21
  this.comparator = comparators.NUMERIC;
22
22
  this.filterType = 'ColumnUserFilter';
23
23
  this.horizontalAlignment = 0;
24
- this.minWidth = Column.NARROW_MIN_WIDTH;
24
+ this.minWidth = Column.SMALL_MIN_WIDTH;
25
25
  this.triStateEnabled = false;
26
26
  this.textBased = false;
27
27
  }