@eclipse-scout/core 22.0.11 → 22.0.19
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/dist/eclipse-scout-core-d110a434bcc809661ce5.min.js +2 -0
- package/dist/eclipse-scout-core-d110a434bcc809661ce5.min.js.map +1 -0
- package/dist/eclipse-scout-core-theme-dark-fd0e080c10f65e67b68b.min.css +1 -0
- package/dist/eclipse-scout-core-theme-dark.css +20 -5
- package/dist/eclipse-scout-core-theme-dark.css.map +1 -1
- package/dist/eclipse-scout-core-theme-f3a61fbc12acf8e27fcc.min.css +1 -0
- package/dist/eclipse-scout-core-theme.css +20 -5
- package/dist/eclipse-scout-core-theme.css.map +1 -1
- package/dist/eclipse-scout-core.js +184 -105
- package/dist/eclipse-scout-core.js.map +1 -1
- package/dist/file-list +4 -4
- package/package.json +2 -2
- package/src/App.js +1 -0
- package/src/desktop/DesktopDense.less +24 -6
- package/src/desktop/OpenUriHandler.js +5 -5
- package/src/form/fields/FormField.js +1 -1
- package/src/form/fields/datefield/DateField.js +2 -0
- package/src/form/fields/sequencebox/SequenceBox.js +20 -3
- package/src/form/fields/stringfield/StringField.js +9 -1
- package/src/session/Session.js +21 -18
- package/src/table/Table.js +2 -3
- package/src/table/columns/ColumnOptimalWidthMeasurer.js +1 -1
- package/src/testing/JasmineScoutUtil.js +127 -0
- package/src/testing/index.js +7 -3
- package/src/tile/TileGrid.js +5 -15
- package/src/tile/TileGridLayout.js +21 -11
- package/src/tile/accordion/TileAccordion.js +4 -23
- package/src/tile/accordion/TileAccordionLayout.js +39 -2
- package/src/tree/Tree.js +4 -0
- package/src/util/arrays.js +4 -0
- package/src/util/objects.js +4 -1
- package/src/widget/FilterSupport.js +19 -8
- package/dist/eclipse-scout-core-e5e8740e3649f5b9f279.min.js +0 -2
- package/dist/eclipse-scout-core-e5e8740e3649f5b9f279.min.js.map +0 -1
- package/dist/eclipse-scout-core-theme-74b63e0d57bed407a729.min.css +0 -1
- package/dist/eclipse-scout-core-theme-dark-b82aea152f416e38ce7f.min.css +0 -1
package/dist/file-list
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
eclipse-scout-core-
|
|
2
|
-
eclipse-scout-core-
|
|
3
|
-
eclipse-scout-core-theme-
|
|
4
|
-
eclipse-scout-core-theme-dark-b82aea152f416e38ce7f.min.css
|
|
1
|
+
eclipse-scout-core-d110a434bcc809661ce5.min.js
|
|
2
|
+
eclipse-scout-core-d110a434bcc809661ce5.min.js.map
|
|
3
|
+
eclipse-scout-core-theme-dark-fd0e080c10f65e67b68b.min.css
|
|
5
4
|
eclipse-scout-core-theme-dark.css
|
|
6
5
|
eclipse-scout-core-theme-dark.css.map
|
|
6
|
+
eclipse-scout-core-theme-f3a61fbc12acf8e27fcc.min.css
|
|
7
7
|
eclipse-scout-core-theme.css
|
|
8
8
|
eclipse-scout-core-theme.css.map
|
|
9
9
|
eclipse-scout-core.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eclipse-scout/core",
|
|
3
|
-
"version": "22.0.
|
|
3
|
+
"version": "22.0.19",
|
|
4
4
|
"description": "Eclipse Scout runtime",
|
|
5
5
|
"author": "BSI Business Systems Integration AG",
|
|
6
6
|
"homepage": "https://www.eclipse.org/scout",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"src"
|
|
27
27
|
],
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@eclipse-scout/cli": "22.0.
|
|
29
|
+
"@eclipse-scout/cli": "22.0.19",
|
|
30
30
|
"@eclipse-scout/releng": "^22.0.0",
|
|
31
31
|
"jasmine-core": "3.10.1",
|
|
32
32
|
"jasmine-ajax": "4.0.0",
|
package/src/App.js
CHANGED
|
@@ -62,6 +62,7 @@ export default class App {
|
|
|
62
62
|
* @param {string|string[]} [options.bootstrap.textsUrl] URL or multiple URLs pointing to a json resource containing texts that will be available through texts.js.
|
|
63
63
|
* @param {string} [options.bootstrap.localesUrl] URL pointing to a json resource containing locale information processed by locales.js
|
|
64
64
|
* @param {string} [options.bootstrap.codesUrl] URL pointing to a json resources containing codes that will be available through codes.js
|
|
65
|
+
* @param {object} [options.session] Object to configure the session, see {@link Session.init} for the available options.
|
|
65
66
|
*/
|
|
66
67
|
init(options) {
|
|
67
68
|
options = options || {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2010-
|
|
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
|
|
6
|
-
*
|
|
6
|
+
* https://www.eclipse.org/legal/epl-v10.html
|
|
7
7
|
*
|
|
8
8
|
* Contributors:
|
|
9
9
|
* BSI Business Systems Integration AG - initial API and implementation
|
|
@@ -50,7 +50,8 @@
|
|
|
50
50
|
|
|
51
51
|
.menubar:not(.main-menubar) {
|
|
52
52
|
& > .menubar-box {
|
|
53
|
-
& > .menu-item
|
|
53
|
+
& > .menu-item,
|
|
54
|
+
& > .combo-menu > .menu-item {
|
|
54
55
|
padding-top: 3px; /* @menubar-item-padding-y; */
|
|
55
56
|
padding-bottom: 3px; /* @menubar-item-padding-y; */
|
|
56
57
|
|
|
@@ -58,10 +59,22 @@
|
|
|
58
59
|
min-height: @logical-grid-row-height-dense; /* @logical-grid-row-height; */
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
& > .menu-button
|
|
62
|
+
& > .menu-button,
|
|
63
|
+
& > .combo-menu > .menu-button {
|
|
62
64
|
padding-top: 2px;
|
|
63
65
|
padding-bottom: 2px;
|
|
64
66
|
}
|
|
67
|
+
|
|
68
|
+
& > .combo-menu {
|
|
69
|
+
padding: 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
& > .form-field-menu {
|
|
73
|
+
padding-top: 0;
|
|
74
|
+
padding-bottom: 0;
|
|
75
|
+
margin-top: 0;
|
|
76
|
+
margin-bottom: 0;
|
|
77
|
+
}
|
|
65
78
|
}
|
|
66
79
|
}
|
|
67
80
|
|
|
@@ -155,14 +168,18 @@
|
|
|
155
168
|
}
|
|
156
169
|
}
|
|
157
170
|
|
|
158
|
-
|
|
159
171
|
/* ContextMenuPopup.less */
|
|
160
172
|
|
|
161
173
|
.context-menu {
|
|
162
|
-
& > .menu-item
|
|
174
|
+
& > .menu-item,
|
|
175
|
+
& > .combo-menu > .menu-item {
|
|
163
176
|
padding-top: 6px; /* padding: 11px 15px; */
|
|
164
177
|
padding-bottom: 6px;
|
|
165
178
|
}
|
|
179
|
+
|
|
180
|
+
& > .combo-menu {
|
|
181
|
+
padding: 0;
|
|
182
|
+
}
|
|
166
183
|
}
|
|
167
184
|
|
|
168
185
|
/* CheckBoxField.less */
|
|
@@ -279,6 +296,7 @@
|
|
|
279
296
|
}
|
|
280
297
|
|
|
281
298
|
/* BreadcrumbItem.less */
|
|
299
|
+
|
|
282
300
|
.breadcrumb-item {
|
|
283
301
|
font-size: @font-size-normal;
|
|
284
302
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
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
|
|
6
|
-
*
|
|
6
|
+
* https://www.eclipse.org/legal/epl-v10.html
|
|
7
7
|
*
|
|
8
8
|
* Contributors:
|
|
9
9
|
* BSI Business Systems Integration AG - initial API and implementation
|
|
@@ -50,7 +50,7 @@ export default class OpenUriHandler {
|
|
|
50
50
|
} else {
|
|
51
51
|
this.openUriAsNewWindow(uri);
|
|
52
52
|
}
|
|
53
|
-
} else if (Device.get().browser === Device.Browser.CHROME) {
|
|
53
|
+
} else if (Device.get().browser === Device.Browser.CHROME && this.isUriWithExternallyHandledProtocol(uri)) {
|
|
54
54
|
// "Hidden iframe"-solution is not working in Chromium (https://bugs.chromium.org/p/chromium/issues/detail?id=663325)
|
|
55
55
|
this.openUriInSameWindow(uri);
|
|
56
56
|
} else {
|
|
@@ -59,7 +59,7 @@ export default class OpenUriHandler {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
isUriWithExternallyHandledProtocol(uri) {
|
|
62
|
-
return /^(callto|facetime|fax|geo|mailto|maps|notes|sip|skype|tel|google.navigation):/.test(uri);
|
|
62
|
+
return /^(callto|facetime|fax|geo|mailto|maps|notes|sip|skype|tel|google.navigation|sms|msteams):/.test(uri);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
handleUriActionOpen(uri) {
|
|
@@ -69,7 +69,7 @@ export default class OpenUriHandler {
|
|
|
69
69
|
// Additionally, some url types require to be opened in the same window like tel or mailto, at least on mobile devices
|
|
70
70
|
this.openUriInSameWindow(uri);
|
|
71
71
|
} else if (this.isUriWithExternallyHandledProtocol(uri)) {
|
|
72
|
-
if (Device.get().browser === Device.Browser.CHROME) {
|
|
72
|
+
if (Device.get().browser === Device.Browser.CHROME || Device.get().isAndroid()) {
|
|
73
73
|
// "Hidden iframe"-solution is not working in Chromium (https://bugs.chromium.org/p/chromium/issues/detail?id=663325)
|
|
74
74
|
this.openUriInSameWindow(uri);
|
|
75
75
|
} else {
|
|
@@ -205,6 +205,7 @@ export default class DateField extends ValueField {
|
|
|
205
205
|
this.htmlDateTimeComposite.invalidateLayoutTree();
|
|
206
206
|
}
|
|
207
207
|
this._renderDateClearable();
|
|
208
|
+
this.$container.toggleClass('has-date', this.hasDate);
|
|
208
209
|
}
|
|
209
210
|
|
|
210
211
|
setHasTime(hasTime) {
|
|
@@ -257,6 +258,7 @@ export default class DateField extends ValueField {
|
|
|
257
258
|
this.htmlDateTimeComposite.invalidateLayoutTree();
|
|
258
259
|
}
|
|
259
260
|
this._renderTimeClearable();
|
|
261
|
+
this.$container.toggleClass('has-time', this.hasTime);
|
|
260
262
|
}
|
|
261
263
|
|
|
262
264
|
setTimePickerResolution(timePickerResolution) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2010-
|
|
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
|
|
6
|
-
*
|
|
6
|
+
* https://www.eclipse.org/legal/epl-v10.html
|
|
7
7
|
*
|
|
8
8
|
* Contributors:
|
|
9
9
|
* BSI Business Systems Integration AG - initial API and implementation
|
|
@@ -19,6 +19,8 @@ export default class SequenceBox extends CompositeField {
|
|
|
19
19
|
this.logicalGrid = scout.create('scout.HorizontalGrid');
|
|
20
20
|
this.layoutConfig = null;
|
|
21
21
|
this.fields = [];
|
|
22
|
+
this._fieldPropertyChangeHandler = this._onFieldPropertyChange.bind(this);
|
|
23
|
+
this._lastVisibleFieldSuppressStatusHandler = this._onLastVisibleFieldSuppressStatusChange.bind(this);
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
_init(model) {
|
|
@@ -65,7 +67,7 @@ export default class SequenceBox extends CompositeField {
|
|
|
65
67
|
for (i = 0; i < this.fields.length; i++) {
|
|
66
68
|
field = this.fields[i];
|
|
67
69
|
field.labelUseUiWidth = true;
|
|
68
|
-
field.on('propertyChange', this.
|
|
70
|
+
field.on('propertyChange', this._fieldPropertyChangeHandler);
|
|
69
71
|
field.render(this.$field);
|
|
70
72
|
this._modifyLabel(field);
|
|
71
73
|
|
|
@@ -83,6 +85,14 @@ export default class SequenceBox extends CompositeField {
|
|
|
83
85
|
return new SequenceBoxLayout(this, this.layoutConfig);
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
_remove() {
|
|
89
|
+
this.fields.forEach(f => f.off('propertyChange', this._fieldPropertyChangeHandler));
|
|
90
|
+
if (this._lastVisibleField) {
|
|
91
|
+
this._lastVisibleField.off('propertyChange:suppressStatus', this._lastVisibleFieldSuppressStatusHandler);
|
|
92
|
+
}
|
|
93
|
+
super._remove();
|
|
94
|
+
}
|
|
95
|
+
|
|
86
96
|
/**
|
|
87
97
|
* @override
|
|
88
98
|
*/
|
|
@@ -137,6 +147,7 @@ export default class SequenceBox extends CompositeField {
|
|
|
137
147
|
_handleStatus(visibilityChanged) {
|
|
138
148
|
if (visibilityChanged && this._lastVisibleField) {
|
|
139
149
|
// if there is a new last visible field, make sure the status is shown on the previously last one
|
|
150
|
+
this._lastVisibleField.off('propertyChange:suppressStatus', this._lastVisibleFieldSuppressStatusHandler);
|
|
140
151
|
this._lastVisibleField.setSuppressStatus(null);
|
|
141
152
|
if (this._lastVisibleField.rendered) {
|
|
142
153
|
this._lastVisibleField._renderErrorStatus();
|
|
@@ -184,6 +195,7 @@ export default class SequenceBox extends CompositeField {
|
|
|
184
195
|
|
|
185
196
|
// Make sure the last field won't display a status (but shows status CSS class)
|
|
186
197
|
this._lastVisibleField.setSuppressStatus(FormField.SuppressStatus.ICON);
|
|
198
|
+
this._lastVisibleField.on('propertyChange:suppressStatus', this._lastVisibleFieldSuppressStatusHandler);
|
|
187
199
|
if (visibilityChanged) {
|
|
188
200
|
// If the last field got invisible, make sure the new last field does not display a status anymore (now done by the seq box)
|
|
189
201
|
if (this._lastVisibleField.rendered) {
|
|
@@ -194,6 +206,11 @@ export default class SequenceBox extends CompositeField {
|
|
|
194
206
|
}
|
|
195
207
|
}
|
|
196
208
|
|
|
209
|
+
_onLastVisibleFieldSuppressStatusChange(e) {
|
|
210
|
+
// do not change suppressStatus
|
|
211
|
+
e.preventDefault();
|
|
212
|
+
}
|
|
213
|
+
|
|
197
214
|
setErrorStatus(errorStatus) {
|
|
198
215
|
if (this._isOverwritingStatusFromField && !this._isErrorStatusOverwritten) {
|
|
199
216
|
// was not overwritten, will be overwritten now -> backup old value
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
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
|
|
@@ -255,6 +255,14 @@ export default class StringField extends BasicField {
|
|
|
255
255
|
this.revalidateLayout();
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
/**
|
|
259
|
+
* @override
|
|
260
|
+
*/
|
|
261
|
+
_renderEnabled() {
|
|
262
|
+
super._renderEnabled();
|
|
263
|
+
this.revalidateLayout();
|
|
264
|
+
}
|
|
265
|
+
|
|
258
266
|
setFormatUpper(formatUpper) {
|
|
259
267
|
if (formatUpper) {
|
|
260
268
|
this.setFormat(StringField.Format.UPPER);
|
package/src/session/Session.js
CHANGED
|
@@ -100,36 +100,39 @@ export default class Session {
|
|
|
100
100
|
static EMPTY_UPLOAD_FILENAME = '*empty*';
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* $entryPoint
|
|
104
|
-
*
|
|
105
|
-
* @param
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* by the same window (portlet support). Each session's partId must be unique.
|
|
110
|
-
* @param model.clientSessionId
|
|
103
|
+
* @param {$} model.$entryPoint
|
|
104
|
+
* The HTML element that is used by the {@link Desktop} to render its content.
|
|
105
|
+
* @param {string} [model.portletPartId]
|
|
106
|
+
* Necessary when multiple UI sessions are managed by the same window (portlet support).
|
|
107
|
+
* Each session's partId must be unique. Default is 0.
|
|
108
|
+
* @param {string} [model.clientSessionId]
|
|
111
109
|
* Identifies the 'client instance' on the UI server. If the property is not set
|
|
112
110
|
* (which is the default case), the clientSessionId is taken from the browser's
|
|
113
111
|
* session storage (per browser window, survives F5 refresh of page). If no
|
|
114
112
|
* clientSessionId can be found, a new one is generated on the server.
|
|
115
|
-
* @param [model.
|
|
116
|
-
*
|
|
117
|
-
*
|
|
113
|
+
* @param {boolean} [model.forceNewClientSession]
|
|
114
|
+
* If set to true, the stored or passed clientSessionId will be ignored
|
|
115
|
+
* and a new one generated by the server.
|
|
116
|
+
* @param {UserAgent} [model.userAgent]
|
|
117
|
+
* By default the user agent for the running platform is used. Use this option if you want to set a custom one.
|
|
118
|
+
* @param {Locale|object} [model.locale]
|
|
119
|
+
* If not specified, {@link Locale.DEFAULT} is used.
|
|
120
|
+
* @param {boolean} [model.backgroundJobPollingEnabled]
|
|
118
121
|
* Unless websockets is used, this property turns on (default) or off background
|
|
119
122
|
* polling using an async ajax call together with setTimeout()
|
|
120
|
-
* @param [model.suppressErrors]
|
|
123
|
+
* @param {boolean} [model.suppressErrors]
|
|
121
124
|
* Basically added because of Jasmine-tests. When working with async tests that
|
|
122
125
|
* use setTimeout(), sometimes the Jasmine-Maven plug-in fails and aborts the
|
|
123
126
|
* build because there were console errors. These errors always happen in this
|
|
124
127
|
* class. That's why we can skip suppress error handling with this flag.
|
|
125
|
-
* @param [model.focusManagerActive]
|
|
128
|
+
* @param {boolean} [model.focusManagerActive]
|
|
126
129
|
* Forces the focus manager to be active or not. If undefined, the value is
|
|
127
130
|
* auto detected by Device.js.
|
|
128
|
-
* @param [model.reconnectorOptions]
|
|
129
|
-
*
|
|
130
|
-
* instance (see Reconnector
|
|
131
|
-
* @param [model.ajaxCallOptions]
|
|
132
|
-
*
|
|
131
|
+
* @param {object} [model.reconnectorOptions]
|
|
132
|
+
* Properties of this object are copied to the Session's reconnector
|
|
133
|
+
* instance (see {@link Reconnector}).
|
|
134
|
+
* @param {object} [model.ajaxCallOptions]
|
|
135
|
+
* Properties of this object are copied to all instances of {@link AjaxCall}.
|
|
133
136
|
*/
|
|
134
137
|
init(model) {
|
|
135
138
|
let options = model || {};
|
package/src/table/Table.js
CHANGED
|
@@ -5271,15 +5271,14 @@ export default class Table extends Widget {
|
|
|
5271
5271
|
|
|
5272
5272
|
for (i = 0; i < columns.length; i++) {
|
|
5273
5273
|
column = columns[i];
|
|
5274
|
-
currentPosition = this.columns.
|
|
5274
|
+
currentPosition = arrays.findIndex(this.columns, element => element.id === column.id);
|
|
5275
5275
|
if (currentPosition < 0) {
|
|
5276
5276
|
throw new Error('Column with id ' + column.id + 'not found.');
|
|
5277
5277
|
}
|
|
5278
5278
|
|
|
5279
5279
|
if (currentPosition !== i) {
|
|
5280
5280
|
// Update model
|
|
5281
|
-
arrays.
|
|
5282
|
-
arrays.insert(this.columns, column, i);
|
|
5281
|
+
arrays.move(this.columns, currentPosition, i);
|
|
5283
5282
|
}
|
|
5284
5283
|
}
|
|
5285
5284
|
|
|
@@ -147,7 +147,7 @@ export default class ColumnOptimalWidthMeasurer {
|
|
|
147
147
|
_build$CellForAggregateRow(row) {
|
|
148
148
|
let columns = this.table.visibleColumns();
|
|
149
149
|
let colIndex = columns.indexOf(this.column);
|
|
150
|
-
let $row = this.table.
|
|
150
|
+
let $row = this.table._build$AggregateRow(row);
|
|
151
151
|
|
|
152
152
|
$row.appendTo(this.table.$data);
|
|
153
153
|
columns
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2010-2022 BSI Business Systems Integration AG.
|
|
3
|
+
* All rights reserved. This program and the accompanying materials
|
|
4
|
+
* are made available under the terms of the Eclipse Public License v1.0
|
|
5
|
+
* which accompanies this distribution, and is available at
|
|
6
|
+
* https://www.eclipse.org/legal/epl-v10.html
|
|
7
|
+
*
|
|
8
|
+
* Contributors:
|
|
9
|
+
* BSI Business Systems Integration AG - initial API and implementation
|
|
10
|
+
*/
|
|
11
|
+
import {arrays, scout, strings} from '../index';
|
|
12
|
+
import $ from 'jquery';
|
|
13
|
+
|
|
14
|
+
let _jsonResourceCache = {};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Utility functions for jasmine tests.
|
|
18
|
+
*/
|
|
19
|
+
export const JasmineScoutUtil = {
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {string} jsonResourceUrl
|
|
23
|
+
* @param {object} [options]
|
|
24
|
+
* @param {boolean} [options.useCache=true]
|
|
25
|
+
* @return {Promise<object>} - the loaded JSON data structure
|
|
26
|
+
*/
|
|
27
|
+
loadJsonResource(jsonResourceUrl, options = {}) {
|
|
28
|
+
scout.assertParameter('jsonResourceUrl', jsonResourceUrl);
|
|
29
|
+
|
|
30
|
+
if (scout.nvl(options.useCache, true)) {
|
|
31
|
+
let json = _jsonResourceCache[jsonResourceUrl];
|
|
32
|
+
if (json) {
|
|
33
|
+
return $.resolvedPromise(json);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return $.ajax({
|
|
38
|
+
async: false,
|
|
39
|
+
type: 'GET',
|
|
40
|
+
dataType: 'json',
|
|
41
|
+
contentType: 'application/json; charset=UTF-8',
|
|
42
|
+
cache: false,
|
|
43
|
+
url: jsonResourceUrl
|
|
44
|
+
})
|
|
45
|
+
.done(json => {
|
|
46
|
+
if (scout.nvl(options.useCache, true)) {
|
|
47
|
+
_jsonResourceCache[jsonResourceUrl] = json;
|
|
48
|
+
}
|
|
49
|
+
return $.resolvedPromise(json);
|
|
50
|
+
})
|
|
51
|
+
.fail((jqXHR, textStatus, errorThrown) => {
|
|
52
|
+
throw new Error('Could not load resource from url: ' + jsonResourceUrl);
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {string} resourceUrlToMock
|
|
58
|
+
* @param {string} jsonResourceUrl
|
|
59
|
+
* @param {object} [options]
|
|
60
|
+
* @param {boolean} [options.useCache=true]
|
|
61
|
+
* @param {*} [options.restriction]
|
|
62
|
+
* @param {string} [options.method]
|
|
63
|
+
*/
|
|
64
|
+
loadJsonResourceAndMockRestCall(resourceUrlToMock, jsonResourceUrl, options = {}) {
|
|
65
|
+
scout.assertParameter('resourceUrlToMock', resourceUrlToMock);
|
|
66
|
+
|
|
67
|
+
this.loadJsonResource(jsonResourceUrl, options)
|
|
68
|
+
.then(json => this.mockRestCall(resourceUrlToMock, json, options));
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {string} resourceUrlToMock
|
|
73
|
+
* @param {array} lookupRows
|
|
74
|
+
* @param {*} [parentRestriction]
|
|
75
|
+
*/
|
|
76
|
+
mockRestLookupCall(resourceUrlToMock, lookupRows, parentRestriction) {
|
|
77
|
+
scout.assertParameter('resourceUrlToMock', resourceUrlToMock);
|
|
78
|
+
|
|
79
|
+
// Normalize lookup rows
|
|
80
|
+
lookupRows = arrays.ensure(lookupRows).map(lookupRow => $.extend({
|
|
81
|
+
active: true,
|
|
82
|
+
enabled: true,
|
|
83
|
+
parentId: null
|
|
84
|
+
}, lookupRow));
|
|
85
|
+
|
|
86
|
+
// getAll()
|
|
87
|
+
this.mockRestCall(resourceUrlToMock, {
|
|
88
|
+
rows: lookupRows
|
|
89
|
+
}, {
|
|
90
|
+
restriction: parentRestriction
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// getKey()
|
|
94
|
+
lookupRows.forEach(lookupRow => {
|
|
95
|
+
this.mockRestCall(resourceUrlToMock, {
|
|
96
|
+
rows: [lookupRow]
|
|
97
|
+
}, {
|
|
98
|
+
restriction: lookupRow.id
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {string} resourceUrlToMock
|
|
105
|
+
* @param {*} responseData
|
|
106
|
+
* @param {object} [options]
|
|
107
|
+
* @param {*} [options.restriction]
|
|
108
|
+
* @param {string} [options.method]
|
|
109
|
+
*/
|
|
110
|
+
mockRestCall(resourceUrlToMock, responseData, options = {}) {
|
|
111
|
+
let url = new RegExp('.*' + strings.quote(resourceUrlToMock) + '.*');
|
|
112
|
+
let data = options.restriction ? new RegExp('.*' + strings.quote(options.restriction) + '.*') : undefined;
|
|
113
|
+
jasmine.Ajax.stubRequest(url, data, options.method).andReturn({
|
|
114
|
+
status: 200,
|
|
115
|
+
responseText: JSON.stringify(responseData)
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* If a ajax call is not mocked, this fallback will be triggered to show information about which url is not mocked.
|
|
121
|
+
*/
|
|
122
|
+
captureNotMockedCalls() {
|
|
123
|
+
jasmine.Ajax.stubRequest(/.*/).andCallFunction((stub, mockAjax) => {
|
|
124
|
+
fail('Ajax call not mocked for url: ' + mockAjax.url + ', method: ' + mockAjax.method);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
};
|
package/src/testing/index.js
CHANGED
|
@@ -8,8 +8,14 @@
|
|
|
8
8
|
* Contributors:
|
|
9
9
|
* BSI Business Systems Integration AG - initial API and implementation
|
|
10
10
|
*/
|
|
11
|
+
|
|
12
|
+
// /////////////////////////////////////////////////////////////////
|
|
13
|
+
// TEST SUPPORT - DO NOT USE IN PRODUCTION CODE
|
|
14
|
+
// /////////////////////////////////////////////////////////////////
|
|
15
|
+
|
|
11
16
|
export {default as TestingApp} from './TestingApp';
|
|
12
17
|
export {default as JasmineScout} from './JasmineScout';
|
|
18
|
+
export {JasmineScoutUtil} from './JasmineScoutUtil';
|
|
13
19
|
export {default as LocaleSpecHelper} from './text/LocaleSpecHelper';
|
|
14
20
|
export {default as MenuSpecHelper} from './menu/MenuSpecHelper';
|
|
15
21
|
export {default as TreeSpecHelper} from './tree/TreeSpecHelper';
|
|
@@ -31,6 +37,4 @@ export {default as GroupBoxSpecHelper} from './form/fields/groupbox/GroupBoxSpec
|
|
|
31
37
|
import * as self from './index.js';
|
|
32
38
|
|
|
33
39
|
export default self;
|
|
34
|
-
|
|
35
|
-
window.scout = Object.assign(window.scout || {}, self);
|
|
36
|
-
}
|
|
40
|
+
window.scout = Object.assign(window.scout || {}, self);
|
package/src/tile/TileGrid.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2010-
|
|
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
|
|
6
|
-
*
|
|
6
|
+
* https://www.eclipse.org/legal/epl-v10.html
|
|
7
7
|
*
|
|
8
8
|
* Contributors:
|
|
9
9
|
* BSI Business Systems Integration AG - initial API and implementation
|
|
@@ -42,8 +42,6 @@ export default class TileGrid extends Widget {
|
|
|
42
42
|
this.selectedTiles = [];
|
|
43
43
|
this.selectionHandler = new TileGridSelectionHandler(this);
|
|
44
44
|
this.scrollable = true;
|
|
45
|
-
this.scrolling = false;
|
|
46
|
-
this.scrollTopDirty = false;
|
|
47
45
|
this.startupAnimationDone = false;
|
|
48
46
|
this.startupAnimationEnabled = false;
|
|
49
47
|
this.tiles = [];
|
|
@@ -594,18 +592,14 @@ export default class TileGrid extends Widget {
|
|
|
594
592
|
let scrollTop = this.$container[0].scrollTop;
|
|
595
593
|
let scrollLeft = this.$container[0].scrollLeft;
|
|
596
594
|
if (this.scrollTop !== scrollTop && this.virtual) {
|
|
597
|
-
this.
|
|
598
|
-
this.revalidateLayout();
|
|
599
|
-
this.scrolling = false;
|
|
595
|
+
this.htmlComp.layout.updateViewPort();
|
|
600
596
|
}
|
|
601
597
|
this.scrollTop = scrollTop;
|
|
602
598
|
this.scrollLeft = scrollLeft;
|
|
603
599
|
}
|
|
604
600
|
|
|
605
601
|
_onScrollParentScroll(event) {
|
|
606
|
-
this.
|
|
607
|
-
this.revalidateLayoutTree(false);
|
|
608
|
-
this.scrolling = false;
|
|
602
|
+
this.htmlComp.layout.updateViewPort();
|
|
609
603
|
}
|
|
610
604
|
|
|
611
605
|
setWithPlaceholders(withPlaceholders) {
|
|
@@ -961,12 +955,8 @@ export default class TileGrid extends Widget {
|
|
|
961
955
|
this.ensureTileRendered(tile);
|
|
962
956
|
// If tile was not rendered it is not yet positioned correctly -> make sure layout is valid before trying to scroll
|
|
963
957
|
// Layout must not render the viewport because scroll position is not correct yet -> just make sure tiles are at the correct position
|
|
964
|
-
this.
|
|
965
|
-
this.scrollTopDirty = true;
|
|
966
|
-
this.validateLayoutTree();
|
|
967
|
-
this.scrolling = false;
|
|
958
|
+
this.htmlComp.layout.updateViewPort(true);
|
|
968
959
|
tile.reveal(options);
|
|
969
|
-
this.scrollTopDirty = false;
|
|
970
960
|
}
|
|
971
961
|
|
|
972
962
|
revealSelection() {
|
|
@@ -3,7 +3,7 @@
|
|
|
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
|
|
6
|
-
*
|
|
6
|
+
* https://www.eclipse.org/legal/epl-v10.html
|
|
7
7
|
*
|
|
8
8
|
* Contributors:
|
|
9
9
|
* BSI Business Systems Integration AG - initial API and implementation
|
|
@@ -44,19 +44,29 @@ export default class TileGridLayout extends LogicalGridLayout {
|
|
|
44
44
|
this.maxWidth = -1;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this._layout($container);
|
|
56
|
-
this.widget.trigger('layoutAnimationDone');
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @param {boolean} [scrollTopDirty] If the scroll top position should be considered dirty while updating the view port.
|
|
50
|
+
* If true, the view port is not rendered, as the scroll positions are not reliable anyway. Then only the layout of the TileGrid is updated.
|
|
51
|
+
*/
|
|
52
|
+
updateViewPort(scrollTopDirty) {
|
|
53
|
+
let tileGrid = this.widget;
|
|
54
|
+
if (!tileGrid.rendered) {
|
|
57
55
|
return;
|
|
58
56
|
}
|
|
59
57
|
|
|
58
|
+
// Try to layout only as much as needed while scrolling in virtual mode
|
|
59
|
+
// Scroll top may be dirty when layout is validated before scrolling to a specific tile (see tileGrid.scrollTo)
|
|
60
|
+
if (!scout.nvl(scrollTopDirty, false)) {
|
|
61
|
+
tileGrid._renderViewPort();
|
|
62
|
+
}
|
|
63
|
+
this._layout(tileGrid.$container);
|
|
64
|
+
tileGrid.trigger('layoutAnimationDone');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
layout($container) {
|
|
68
|
+
let htmlComp = this.widget.htmlComp;
|
|
69
|
+
|
|
60
70
|
// Animate only once on startup (if enabled) but animate every time on resize
|
|
61
71
|
let animated = htmlComp.layouted || (this.widget.startupAnimationEnabled && !this.widget.startupAnimationDone) || this.widget.renderAnimationEnabled;
|
|
62
72
|
this.tiles = this.widget.renderedTiles();
|
|
@@ -3,7 +3,7 @@
|
|
|
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
|
|
6
|
-
*
|
|
6
|
+
* https://www.eclipse.org/legal/epl-v10.html
|
|
7
7
|
*
|
|
8
8
|
* Contributors:
|
|
9
9
|
* BSI Business Systems Integration AG - initial API and implementation
|
|
@@ -350,24 +350,7 @@ export default class TileAccordion extends Accordion {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
_filter() {
|
|
353
|
-
this.groups.forEach(group =>
|
|
354
|
-
group.body.filter();
|
|
355
|
-
|
|
356
|
-
// If the layout has not been invalidated as part of the filtering above, it even though must be validated here.
|
|
357
|
-
// This is because groups above might have fewer visible Tiles now which makes room for this group.
|
|
358
|
-
// The revalidateLayout() with scrolling=true here ensures TileGrid._renderViewPort() is called to ensure these Tiles become visible as there is space available now.
|
|
359
|
-
// It is executed as postValidateFunction because the groups above must have completed their layouting so that
|
|
360
|
-
// TileGrid._renderViewPort() knows that there is more space available now.
|
|
361
|
-
if (group.body.htmlComp && group.body.htmlComp.valid && !group.body._accordionLayoutHandler /* skip if already registered */) {
|
|
362
|
-
group.body._accordionLayoutHandler = () => {
|
|
363
|
-
group.body.scrolling = true;
|
|
364
|
-
group.body.revalidateLayout();
|
|
365
|
-
group.body.scrolling = false;
|
|
366
|
-
group.body._accordionLayoutHandler = null;
|
|
367
|
-
};
|
|
368
|
-
this.session.layoutValidator.schedulePostValidateFunction(group.body._accordionLayoutHandler);
|
|
369
|
-
}
|
|
370
|
-
});
|
|
353
|
+
this.groups.forEach(group => group.body.filter());
|
|
371
354
|
}
|
|
372
355
|
|
|
373
356
|
/**
|
|
@@ -700,10 +683,8 @@ export default class TileAccordion extends Accordion {
|
|
|
700
683
|
// Btw: another group may be doing it as well at the same time (e.g. because of exclusiveExpand)
|
|
701
684
|
return;
|
|
702
685
|
}
|
|
703
|
-
if (group.body.virtual) {
|
|
704
|
-
group.body.
|
|
705
|
-
group.body.revalidateLayout();
|
|
706
|
-
group.body.scrolling = false;
|
|
686
|
+
if (group.body.virtual && group.body.htmlComp) {
|
|
687
|
+
group.body.htmlComp.layout.updateViewPort();
|
|
707
688
|
}
|
|
708
689
|
});
|
|
709
690
|
}
|