@sapui5/sap.ui.export 1.98.0 → 1.101.0

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 (63) hide show
  1. package/package.json +1 -1
  2. package/src/sap/ui/export/.library +2 -2
  3. package/src/sap/ui/export/ExportBase.js +1 -1
  4. package/src/sap/ui/export/ExportUtils.js +222 -158
  5. package/src/sap/ui/export/PortableDocument.js +121 -63
  6. package/src/sap/ui/export/Spreadsheet.js +3 -3
  7. package/src/sap/ui/export/SpreadsheetExport.js +2 -3
  8. package/src/sap/ui/export/fragments/SettingsDialog.fragment.xml +52 -0
  9. package/src/sap/ui/export/js/XLSXBuilder.js +1 -1
  10. package/src/sap/ui/export/js/XLSXBuilder.js.map +1 -1
  11. package/src/sap/ui/export/library.js +17 -15
  12. package/src/sap/ui/export/messagebundle.properties +66 -6
  13. package/src/sap/ui/export/messagebundle_ar.properties +42 -2
  14. package/src/sap/ui/export/messagebundle_bg.properties +45 -5
  15. package/src/sap/ui/export/messagebundle_ca.properties +42 -2
  16. package/src/sap/ui/export/messagebundle_cs.properties +42 -2
  17. package/src/sap/ui/export/messagebundle_cy.properties +42 -2
  18. package/src/sap/ui/export/messagebundle_da.properties +42 -2
  19. package/src/sap/ui/export/messagebundle_de.properties +42 -2
  20. package/src/sap/ui/export/messagebundle_el.properties +42 -2
  21. package/src/sap/ui/export/messagebundle_en.properties +42 -2
  22. package/src/sap/ui/export/messagebundle_en_GB.properties +42 -2
  23. package/src/sap/ui/export/messagebundle_en_US_sappsd.properties +44 -4
  24. package/src/sap/ui/export/messagebundle_en_US_saprigi.properties +42 -2
  25. package/src/sap/ui/export/messagebundle_en_US_saptrc.properties +42 -2
  26. package/src/sap/ui/export/messagebundle_es.properties +42 -2
  27. package/src/sap/ui/export/messagebundle_es_MX.properties +42 -2
  28. package/src/sap/ui/export/messagebundle_et.properties +42 -2
  29. package/src/sap/ui/export/messagebundle_fi.properties +43 -3
  30. package/src/sap/ui/export/messagebundle_fr.properties +47 -7
  31. package/src/sap/ui/export/messagebundle_fr_CA.properties +42 -2
  32. package/src/sap/ui/export/messagebundle_hi.properties +42 -2
  33. package/src/sap/ui/export/messagebundle_hr.properties +42 -2
  34. package/src/sap/ui/export/messagebundle_hu.properties +42 -2
  35. package/src/sap/ui/export/messagebundle_id.properties +42 -2
  36. package/src/sap/ui/export/messagebundle_it.properties +42 -2
  37. package/src/sap/ui/export/messagebundle_iw.properties +42 -2
  38. package/src/sap/ui/export/messagebundle_ja.properties +42 -2
  39. package/src/sap/ui/export/messagebundle_kk.properties +42 -2
  40. package/src/sap/ui/export/messagebundle_ko.properties +42 -2
  41. package/src/sap/ui/export/messagebundle_lt.properties +42 -2
  42. package/src/sap/ui/export/messagebundle_lv.properties +42 -2
  43. package/src/sap/ui/export/messagebundle_ms.properties +42 -2
  44. package/src/sap/ui/export/messagebundle_nl.properties +42 -2
  45. package/src/sap/ui/export/messagebundle_no.properties +42 -2
  46. package/src/sap/ui/export/messagebundle_pl.properties +42 -2
  47. package/src/sap/ui/export/messagebundle_pt.properties +42 -2
  48. package/src/sap/ui/export/messagebundle_pt_PT.properties +42 -2
  49. package/src/sap/ui/export/messagebundle_ro.properties +42 -2
  50. package/src/sap/ui/export/messagebundle_ru.properties +42 -2
  51. package/src/sap/ui/export/messagebundle_sh.properties +42 -2
  52. package/src/sap/ui/export/messagebundle_sk.properties +42 -2
  53. package/src/sap/ui/export/messagebundle_sl.properties +42 -2
  54. package/src/sap/ui/export/messagebundle_sv.properties +42 -2
  55. package/src/sap/ui/export/messagebundle_th.properties +42 -2
  56. package/src/sap/ui/export/messagebundle_tr.properties +42 -2
  57. package/src/sap/ui/export/messagebundle_uk.properties +42 -2
  58. package/src/sap/ui/export/messagebundle_vi.properties +42 -2
  59. package/src/sap/ui/export/messagebundle_zh_CN.properties +42 -2
  60. package/src/sap/ui/export/messagebundle_zh_TW.properties +42 -2
  61. package/src/sap/ui/export/themes/sap_horizon_dark/library.source.less +8 -0
  62. package/src/sap/ui/export/themes/sap_horizon_hcb/library.source.less +8 -0
  63. package/src/sap/ui/export/themes/sap_horizon_hcw/library.source.less +8 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.ui.export",
3
- "version": "1.98.0",
3
+ "version": "1.101.0",
4
4
  "description": "SAPUI5 Library sap.ui.export",
5
5
  "homepage": "https://sap.github.io/ui5-tooling/pages/SAPUI5/",
6
6
  "author": "SAP SE (https://www.sap.com)",
@@ -5,7 +5,7 @@
5
5
  <vendor>SAP SE</vendor>
6
6
  <copyright>SAPUI5
7
7
  * (c) Copyright 2009-2022 SAP SE. All rights reserved.</copyright>
8
- <version>1.98.0</version>
8
+ <version>1.101.0</version>
9
9
 
10
10
  <documentation>UI5 library: sap.ui.export</documentation>
11
11
 
@@ -34,7 +34,7 @@
34
34
  </module-infos>
35
35
  <all-in-one>
36
36
  <!-- exclude third party bundles and the worker code -->
37
- <exclude name="sap/ui/export/js/**" />
37
+ <exclude name="sap/ui/export/js/" />
38
38
  </all-in-one>
39
39
  </packaging>
40
40
  <ownership xmlns="http://www.sap.com/ui5/buildext/ownership">
@@ -15,7 +15,7 @@ sap.ui.define([
15
15
  * @constructor The <code>sap.ui.export.ExportBase</code> class allows you to export table data from a UI5 application to a Portable Document Format (*.PDF) file.
16
16
  *
17
17
  * @author SAP SE
18
- * @version 1.98.0
18
+ * @version 1.101.0
19
19
  *
20
20
  * @since 1.96
21
21
  * @name sap.ui.export.ExportBase
@@ -3,33 +3,23 @@
3
3
  * (c) Copyright 2009-2022 SAP SE. All rights reserved.
4
4
  */
5
5
  sap.ui.define([
6
- 'sap/ui/core/library',
7
- 'sap/m/library',
8
6
  './library',
9
- 'sap/ui/core/Core',
10
7
  'sap/base/Log',
11
- 'sap/base/util/uid',
12
- 'sap/ui/core/Item',
8
+ 'sap/ui/core/Core',
9
+ 'sap/ui/core/Fragment',
10
+ 'sap/ui/core/library',
13
11
  'sap/ui/core/syncStyleClass',
14
12
  'sap/ui/model/json/JSONModel',
15
- 'sap/m/Button',
16
- 'sap/m/CheckBox',
17
- 'sap/m/Dialog',
18
- 'sap/m/Input',
19
- 'sap/m/Label',
20
- 'sap/m/Select',
21
- 'sap/m/Text',
22
- 'sap/m/VBox',
23
- 'sap/ui/VersionInfo',
24
- 'sap/ui/util/openWindow'
25
- ], function(coreLibrary, mLibrary, library, Core, Log, uid, Item, syncStyleClass, JSONModel, Button, CheckBox, Dialog, Input, Label, Select, Text, VBox, VersionInfo, openWindow) {
13
+ 'sap/ui/model/resource/ResourceModel',
14
+ 'sap/ui/util/openWindow',
15
+ 'sap/ui/VersionInfo'
16
+ ], function(library, Log, Core, Fragment, coreLibrary, syncStyleClass, JSONModel, ResourceModel, openWindow, VersionInfo) {
26
17
  'use strict';
27
18
 
28
19
  // eslint-disable-next-line
29
20
  /* global Blob, MouseEvent, FileReader, URL */
30
21
 
31
22
  // Shortcuts
32
- var ButtonType = mLibrary.ButtonType;
33
23
  var ValueState = coreLibrary.ValueState;
34
24
  var FileType = library.FileType;
35
25
  var EdmType = library.EdmType;
@@ -54,22 +44,39 @@ sap.ui.define([
54
44
  });
55
45
 
56
46
  /* Returns the Export Settings used by the User Settings Dialog */
57
- function getExportSettings(oCustomConfig, oResourceBundle, bDevMode) {
47
+ function getDefaultSettings(oCustomConfig, oResourceBundle, oExportCapabilities) {
58
48
  var sSelectedKey;
49
+ var aSupportedFormats = Object.keys(oExportCapabilities);
50
+
59
51
  var oDefaultConfig = {
60
52
  fileName: 'Standard',
61
- fileType: [
62
- {key: 'xlsx'}
63
- ],
64
- selectedFileType: 'xlsx',
53
+ fileType: [],
54
+ selectedFileType: 'XLSX',
55
+ selectedPaperSize: 'DIN_A4',
56
+ selectedOrientation: 'LANDSCAPE',
65
57
  splitCells: false,
66
58
  includeFilterSettings: false,
67
- addDateTime: false
59
+ addDateTime: false,
60
+ doEnableAccessibility: false,
61
+ pdfArchive: false,
62
+ capabilities: oExportCapabilities,
63
+ fitToPage: false,
64
+ paperSize: [
65
+ {key: "DIN_A4", text: oResourceBundle.getText("PAPER_SIZE_A4")},
66
+ {key: "US_LETTER", text: oResourceBundle.getText("PAPER_SIZE_US_LETTER")}
67
+ ],
68
+ orientation: [
69
+ {key:"LANDSCAPE", text: oResourceBundle.getText("ORIENTATION_LAND")},
70
+ {key:"PORTRAIT", text: oResourceBundle.getText("ORIENTATION_PORT")}
71
+ ],
72
+ fontSize: 10,
73
+ signature: false,
74
+ signatureReason: ''
68
75
  };
69
76
 
70
- if (bDevMode) {
71
- oDefaultConfig.fileType.push({key: 'pdf'});
72
- }
77
+ aSupportedFormats.forEach(function(sFormat) {
78
+ oDefaultConfig.fileType.push({key: sFormat.toUpperCase()});
79
+ });
73
80
 
74
81
  var oExportConfig = Object.assign({}, oDefaultConfig, oCustomConfig || {});
75
82
 
@@ -77,7 +84,7 @@ sap.ui.define([
77
84
  sSelectedKey = null;
78
85
 
79
86
  if (!oExportConfig.fileType[i].text) {
80
- oExportConfig.fileType[i].text = oResourceBundle.getText(oExportConfig.fileType[i].key.toUpperCase() + '_FILETYPE');
87
+ oExportConfig.fileType[i].text = oResourceBundle.getText(oExportConfig.fileType[i].key + '_FILETYPE');
81
88
  }
82
89
  if (oExportConfig.fileType[i].key === oExportConfig.selectedFileType) {
83
90
  sSelectedKey = oExportConfig.fileType[i].key;
@@ -90,11 +97,21 @@ sap.ui.define([
90
97
  return oExportConfig;
91
98
  }
92
99
 
100
+ function processExportSettings(oSettings) {
101
+ var oFinalSettings = {};
102
+
103
+ ["fileName", "selectedFileType", "selectedPaperSize", "selectedOrientation", "splitCells", "includeFilterSettings", "addDateTime", "doEnableAccessibility", "fitToPage", "fontSize", "signature", "signatureReason", "pdfArchive"].forEach(function(sProperty) {
104
+ oFinalSettings[sProperty] = oSettings[sProperty];
105
+ });
106
+
107
+ return oFinalSettings;
108
+ }
109
+
93
110
  /**
94
111
  * Utilities related to export to enable reuse in integration scenarios (e.g. tables).
95
112
  *
96
113
  * @author SAP SE
97
- * @version 1.98.0
114
+ * @version 1.101.0
98
115
  *
99
116
  * @since 1.59
100
117
  * @name sap.ui.export.ExportUtils
@@ -146,146 +163,138 @@ sap.ui.define([
146
163
  * Creates the Export settings dialog that can be used for configuring the spreadsheet before exporting.
147
164
  *
148
165
  * @param {Object} mCustomConfig Initial configuration of the settings dialog
149
- * @param {sap.ui.core.Control} oOpener The opener of the dialog
150
- * @param {function} [fnCallback] Handler function that is called once the dialog has been opened. A reference to the dialog is passed as parameter
151
- * @param {boolean} [bDevMode] Flag that allows to activate settings that are currently in development
166
+ * @param {Object} oExportCapabilities Definition of supported export features
167
+ * @param {sap.ui.core.Control} [oOpener] The opener of the dialog
168
+ * @param {function(sap.m.Dialog)} [fnCallback] Handler function that is called once the dialog has been opened. A reference to the dialog is passed as parameter
152
169
  *
153
170
  * @returns {Promise} Promise which resolves with the export settings defined by the user
154
171
  *
155
172
  * @static
156
173
  */
157
- getExportSettingsViaDialog: function(mCustomConfig, oOpener, fnCallback, bDevMode) {
174
+ getExportSettingsViaDialog: function(mCustomConfig, oExportCapabilities, oOpener, fnCallback) {
158
175
  return new Promise(function (fnResolve, fnReject) {
159
176
  var oExportSettingsDialog;
160
177
 
161
178
  oResourceBundlePromise.then(function (oResourceBundle) {
162
-
163
179
  var oExportConfigModel = new JSONModel();
164
- oExportConfigModel.setData(getExportSettings(mCustomConfig, oResourceBundle, bDevMode));
165
-
166
- var sDialogId = uid();
167
-
168
- oExportSettingsDialog = new Dialog({
169
- id: sDialogId,
170
- title: oResourceBundle.getText('EXPORT_SETTINGS_TITLE'),
171
- horizontalScrolling: false,
172
- verticalScrolling: false,
173
- content: [
174
- //TBD: Maybe use a form here for ACC purposes
175
- new VBox({
176
- // changing the render type to Bare in order to render the colon by resuing the style classes from Form layout
177
- renderType: 'Bare',
178
- width: '100%',
179
- items: [
180
- //TBD: Hide controls (visible=false) when functionality is not yet implemented
181
- new Label({
182
- text: oResourceBundle.getText('FILE_NAME'),
183
- labelFor: sDialogId + '-fileName'
184
- }),
185
- new Input({
186
- id: sDialogId + '-fileName',
187
- value: '{/fileName}',
188
- liveChange: function (oEvent) {
189
- // user input validation for file name
190
- var oInput = oEvent.getSource();
191
- var sFileName = oEvent.getParameter('value');
192
- var oRegEx = /[\\/:|?"*<>]/;
193
- var oExportBtn = Core.byId(sDialogId + '-export');
194
- var bValidate = oRegEx.test(sFileName);
195
- if (bValidate) {
196
- oInput.setValueState(ValueState.Error);
197
- oInput.setValueStateText(oResourceBundle.getText('FILENAME_ERROR'));
198
- } else if (sFileName.length > 100) {
199
- oInput.setValueState(ValueState.Warning);
200
- oInput.setValueStateText(oResourceBundle.getText('FILENAME_WARNING'));
201
- } else {
202
- oInput.setValueState(ValueState.None);
203
- oInput.setValueStateText(null);
204
- }
205
- oExportBtn.setEnabled(!bValidate);
206
- }
207
- }).addStyleClass('sapUiTinyMarginBottom'),
208
- new Label({
209
- text: oResourceBundle.getText('SELECT_FORMAT'),
210
- labelFor: sDialogId + '-fileType',
211
- visible: !!bDevMode
212
- }),
213
- // sap.m.Select control disabled as there is only 1 option for now
214
- // control must be enabled when more file types are supported
215
- new Select({
216
- id: sDialogId + '-fileType',
217
- width: '100%',
218
- selectedKey: '{/selectedFileType}',
219
- items: {
220
- path: '/fileType',
221
- template: new Item({key: '{key}', text: '{text}'})
222
- },
223
- visible: !!bDevMode
224
- }),
225
- new CheckBox({
226
- id: sDialogId + '-splitCells',
227
- selected: '{/splitCells}',
228
- text: oResourceBundle.getText('SPLIT_CELLS')
229
- }),
230
- new CheckBox({
231
- id: sDialogId + '-includeFilterSettings',
232
- selected: '{/includeFilterSettings}',
233
- text: oResourceBundle.getText('INCLUDE_FILTER_SETTINGS')
234
- }),
235
- new CheckBox({
236
- id: sDialogId + '-addDateTime',
237
- selected: '{/addDateTime}',
238
- text: oResourceBundle.getText('ADD_DATE_TIME'),
239
- visible: false
240
- })
241
- ]
242
- // using the style class from Form layout to render colon after the label
243
- }).addStyleClass('sapUiExportSettingsLabel')
244
- ],
245
- endButton: new Button({
246
- id: sDialogId + '-cancel',
247
- text: oResourceBundle.getText('CANCEL_BUTTON'),
248
- press: function () {
180
+
181
+ oExportConfigModel.setData(getDefaultSettings(mCustomConfig, oResourceBundle, oExportCapabilities));
182
+
183
+ Fragment.load({
184
+ name: 'sap.ui.export.fragments.SettingsDialog',
185
+ type: 'XML',
186
+ controller: {
187
+ isPDF: function(sValue) {
188
+ return sValue === FileType.PDF;
189
+ },
190
+ isXLSX: function(sValue) {
191
+ return sValue === FileType.XLSX;
192
+ },
193
+ onCancel: function() {
249
194
  oExportSettingsDialog.close();
250
- }
251
- }),
252
- beginButton: new Button({
253
- id: sDialogId + '-export',
254
- text: oResourceBundle.getText('EXPORT_BUTTON'),
255
- type: ButtonType.Emphasized,
256
- press: function () {
195
+ },
196
+ onExport: function() {
257
197
  if (oExportSettingsDialog) {
258
198
  oExportSettingsDialog._bSuccess = true;
259
199
  oExportSettingsDialog.close();
260
- fnResolve(oExportConfigModel.getData());
200
+ fnResolve(processExportSettings(oExportConfigModel.getData()));
261
201
  }
202
+ },
203
+
204
+ /**
205
+ * User input validation for file name
206
+ *
207
+ * @param {sap.ui.base.Event} oEvent LiveChange event of the Input control
208
+ */
209
+ onFileNameChange: function(oEvent) {
210
+ var oInput = oEvent.getSource();
211
+ var sFileName = oEvent.getParameter('value');
212
+ var oRegEx = /[\\/:|?"*<>]/;
213
+ var oExportBtn = Core.byId('exportSettingsDialog-exportButton');
214
+ var bValidate = oRegEx.test(sFileName);
215
+ if (bValidate) {
216
+ oInput.setValueState(ValueState.Error);
217
+ oInput.setValueStateText(oResourceBundle.getText('FILENAME_ERROR'));
218
+ } else if (sFileName.length > 100) {
219
+ oInput.setValueState(ValueState.Warning);
220
+ oInput.setValueStateText(oResourceBundle.getText('FILENAME_WARNING'));
221
+ } else {
222
+ oInput.setValueState(ValueState.None);
223
+ oInput.setValueStateText(null);
224
+ }
225
+ oExportBtn.setEnabled(!bValidate);
226
+ },
227
+ onFileTypeChange: function(oEvent) {
228
+ var oSelectedItem = oEvent.getParameter("selectedItem");
229
+ if (oSelectedItem && oSelectedItem.getKey() === FileType.PDF) {
230
+ oExportConfigModel.setProperty("/splitCells", true);
231
+ oExportConfigModel.setProperty("/includeFilterSettings", false);
232
+ } else {
233
+ Core.byId('exportSettingsDialog-signatureReason').setVisible(false);
234
+ Core.byId('exportSettingsDialog-signatureReasonLabel').setVisible(false);
235
+ }
236
+ },
237
+ onFontSizeChange: function(oEvent) {
238
+ // user input validation for font size
239
+ var oInput = oEvent.getSource();
240
+ var sFontValue = oEvent.getParameter('value');
241
+ var oRegEx = /[^\d]/g;
242
+ var oExportBtn = Core.byId('exportSettingsDialog-exportButton');
243
+ var bValidate = oRegEx.test(sFontValue);
244
+ if (bValidate) {
245
+ oInput.setValueState(ValueState.Error);
246
+ oInput.setValueStateText(oResourceBundle.getText('NUMBER_ERROR'));
247
+ } else {
248
+ oInput.setValueState(ValueState.None);
249
+ oInput.setValueStateText(null);
250
+ }
251
+ oExportBtn.setEnabled(!bValidate);
252
+ },
253
+ onAfterClose: function() {
254
+ if (!oExportSettingsDialog._bSuccess) {
255
+ // Handle Cancel after close when export button was not pressed
256
+ // because a close could also be triggered via Esc
257
+ fnReject(null);
258
+ }
259
+ oExportSettingsDialog.destroy();
260
+ oExportSettingsDialog = null;
262
261
  }
263
- }),
264
- afterClose: function () {
265
- if (!oExportSettingsDialog._bSuccess) {
266
- // Handle Cancel after close when export button was not pressed
267
- // because a close could also be triggered via Esc
268
- fnReject(null);
269
- }
270
- oExportSettingsDialog.destroy();
271
- oExportSettingsDialog = null;
272
262
  }
273
- });
274
- // using the style class from Form layout to render colon after the label
275
- oExportSettingsDialog.addStyleClass('sapUiContentPadding sapUiExportSettings');
276
- oExportSettingsDialog.setModel(oExportConfigModel);
277
- if (oOpener) {
278
- syncStyleClass('sapUiSizeCompact', oOpener, oExportSettingsDialog);
279
- }
280
- oExportSettingsDialog.open();
263
+ }).then(function(oDialog) {
264
+ oExportSettingsDialog = oDialog;
281
265
 
282
- if (fnCallback) {
283
- fnCallback(oExportSettingsDialog);
284
- }
266
+ oExportSettingsDialog.setModel(oExportConfigModel);
267
+ oExportSettingsDialog.setModel(new ResourceModel({
268
+ bundle: oResourceBundle
269
+ }), 'i18n');
270
+
271
+ if (oOpener) {
272
+ syncStyleClass('sapUiSizeCompact', oOpener, oExportSettingsDialog);
273
+ }
274
+ oExportSettingsDialog.open();
275
+
276
+ if (fnCallback) {
277
+ fnCallback(oExportSettingsDialog);
278
+ }
279
+ });
285
280
  });
286
281
  });
287
282
  },
288
283
 
284
+ /**
285
+ * Returns a different representation of the filter
286
+ * value in case the value is an instance of Date.
287
+ * The resutl of Date.prototype.toString function is
288
+ * too long and complex so we use the ISO-String
289
+ * instead.
290
+ *
291
+ * @param {*} vValue Filter value that might get converted
292
+ * @returns {*} The formatted value
293
+ */
294
+ _getFormattedFilterValue: function(vValue) {
295
+ return vValue instanceof Date ? vValue.toISOString() : vValue;
296
+ },
297
+
289
298
  /**
290
299
  * Combines the filter operator with the value and
291
300
  * creates a textual representation.
@@ -297,15 +306,15 @@ sap.ui.define([
297
306
  _getReadableFilterValue: function(oFilter) {
298
307
  switch (oFilter.op || oFilter.name) {
299
308
  case '==':
300
- return '=' + oFilter.right.value;
309
+ return '=' + Utils._getFormattedFilterValue(oFilter.right.value);
301
310
  case '>':
302
311
  case '<':
303
312
  case '!=':
304
313
  case '<=':
305
314
  case '>=':
306
- return oFilter.op + oFilter.right.value;
315
+ return oFilter.op + Utils._getFormattedFilterValue(oFilter.right.value);
307
316
  case 'between':
308
- return oFilter.args[1].value + '...' + oFilter.args[2].value;
317
+ return Utils._getFormattedFilterValue(oFilter.args[1].value) + '...' + Utils._getFormattedFilterValue(oFilter.args[2].value);
309
318
  case 'contains':
310
319
  return '*' + oFilter.args[1].value + '*';
311
320
  case 'endswith':
@@ -344,10 +353,11 @@ sap.ui.define([
344
353
  * subsequent filters.
345
354
  *
346
355
  * @param {Object} oLogicalFilter Filter object according to ListBinding#getFilterInfo
347
- * @returns {Array} Array containing all filter settings
356
+ * @returns {Array} Array containing evaluated filter settings
348
357
  * @private
349
358
  */
350
359
  _parseLogical: function(oLogicalFilter) {
360
+ var aFilters, sProperty;
351
361
 
352
362
  /* Breakout behavior for between filter */
353
363
  if (oLogicalFilter.op == '&&'
@@ -377,7 +387,27 @@ sap.ui.define([
377
387
  });
378
388
  }
379
389
 
380
- return Utils._parseFilter(oLogicalFilter.left).concat(Utils._parseFilter(oLogicalFilter.right));
390
+ aFilters = Utils._parseFilter(oLogicalFilter.left).concat(Utils._parseFilter(oLogicalFilter.right));
391
+
392
+ /* Group logical OR filter on the same property */
393
+ if (oLogicalFilter.op === '||' && aFilters.length) {
394
+ sProperty = aFilters[0].key;
395
+
396
+ if (aFilters.every(function(item) { return item.key === sProperty; })) {
397
+ aFilters = [
398
+ {
399
+ key: sProperty,
400
+ value: aFilters.reduce(function(acc, item) {
401
+ var sSeparator = acc ? '; ' : '';
402
+
403
+ return acc + sSeparator + item.value;
404
+ }, '')
405
+ }
406
+ ];
407
+ }
408
+ }
409
+
410
+ return aFilters;
381
411
  },
382
412
 
383
413
  /**
@@ -487,7 +517,25 @@ sap.ui.define([
487
517
  });
488
518
  }
489
519
 
520
+ /* Sort filter settings */
521
+ oFilterConfig.items.sort(function(firstElement, secondElement) {
522
+ var sFirstValue = firstElement.key.toLowerCase();
523
+ var sSecondValue = secondElement.key.toLowerCase();
524
+
525
+ if (sFirstValue > sSecondValue) {
526
+ return 1;
527
+ }
528
+
529
+ if (sFirstValue < sSecondValue) {
530
+ return -1;
531
+ }
532
+
533
+ return 0;
534
+ });
535
+
490
536
  fnResolve(oFilterConfig);
537
+
538
+ return oResourceBundle;
491
539
  });
492
540
  });
493
541
  },
@@ -808,7 +856,7 @@ sap.ui.define([
808
856
  });
809
857
 
810
858
  /* Validate string based properties (not column type String related) */
811
- ['inputFormat', 'unit', 'unitProperty', 'template', 'trueValue', 'falseValue'].forEach(function(sProperty) {
859
+ ['inputFormat', 'unit', 'unitProperty', 'template', 'trueValue', 'falseValue', 'timezone', 'timezoneProperty'].forEach(function(sProperty) {
812
860
  Utils._validateString(oColumn, sProperty);
813
861
  });
814
862
 
@@ -832,11 +880,27 @@ sap.ui.define([
832
880
  }
833
881
 
834
882
  /* Validate utc property */
835
- if (oColumn.utc != null && (oColumn.type === EdmType.Date || oColumn.type === EdmType.Time)) {
836
- oColumn.utc = true; // Date and Time always use UTC
837
- }
838
883
  if (oColumn.type === EdmType.DateTime) {
839
- Utils._validateProperty(oColumn, 'utc', 'boolean', true);
884
+
885
+ /*
886
+ * Apply local time or UTC as fixed timezone
887
+ * in case no timezone is defined. This also
888
+ * serves as a fallback if timezoneProperty
889
+ * is defined but the Line Item has no value
890
+ * for the referenced property name.
891
+ */
892
+ if (!oColumn.timezone) {
893
+ oColumn.timezone = oColumn.utc === false ? new Intl.DateTimeFormat().resolvedOptions().timeZone : 'UTC';
894
+ }
895
+
896
+ /* Remove obviously incorrect timezoneProperty settings */
897
+ if (oColumn.property === oColumn.timezoneProperty || (typeof oColumn.timezoneProperty === 'string' && oColumn.timezoneProperty.split(',').length > 1)) {
898
+ Log.warning(CLASS_NAME + ': Property timezoneProperty is invalid.');
899
+ delete oColumn.timezoneProperty;
900
+ }
901
+ } else if (typeof oColumn.utc === 'boolean') {
902
+ Log.warning(CLASS_NAME + ': Property utc is only supported for type DateTime.');
903
+ delete oColumn.utc;
840
904
  }
841
905
 
842
906
  /* Validate scale property */
@@ -911,7 +975,7 @@ sap.ui.define([
911
975
  *
912
976
  * @param {Object} oContext Context object
913
977
  * @param {string} [oContext.application] Name of the application (default: "SAP UI5")
914
- * @param {string} [oContext.version] Application version (default: "1.98.0")
978
+ * @param {string} [oContext.version] Application version (default: "1.101.0")
915
979
  * @param {string} [oContext.title] Title that will be written to the file (NOT the filename)
916
980
  * @param {string} [oContext.modifiedBy] Optional user context that will be written to the file
917
981
  * @param {string} [oContext.sheetName] Name of the data sheet - Maximum length of 31 characters
@@ -1005,7 +1069,7 @@ sap.ui.define([
1005
1069
  value = null;
1006
1070
  }
1007
1071
 
1008
- oContext[sProperty] = value == null && defaultValue ? defaultValue : value;
1072
+ oContext[sProperty] = value == null && typeof defaultValue !== 'undefined' ? defaultValue : value;
1009
1073
  },
1010
1074
 
1011
1075
  /**