@sapui5/sap.suite.ui.generic.template 1.141.3 → 1.142.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 (136) hide show
  1. package/package.json +3 -4
  2. package/src/sap/suite/ui/generic/template/.library +3 -2
  3. package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_kk.properties +1 -1
  4. package/src/sap/suite/ui/generic/template/AnalyticalListPage/manifest.json +1 -1
  5. package/src/sap/suite/ui/generic/template/Canvas/manifest.json +1 -1
  6. package/src/sap/suite/ui/generic/template/ListReport/Component.js +3 -0
  7. package/src/sap/suite/ui/generic/template/ListReport/controller/ControllerImplementation.js +58 -12
  8. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n.properties +5 -0
  9. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_ar.properties +3 -0
  10. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_bg.properties +3 -0
  11. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_ca.properties +3 -0
  12. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_cnr.properties +3 -0
  13. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_cs.properties +3 -0
  14. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_cy.properties +3 -0
  15. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_da.properties +3 -0
  16. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_de.properties +3 -0
  17. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_el.properties +3 -0
  18. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_en.properties +3 -0
  19. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_en_GB.properties +3 -0
  20. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_es.properties +3 -0
  21. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_es_MX.properties +3 -0
  22. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_et.properties +3 -0
  23. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_fi.properties +3 -0
  24. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_fr.properties +3 -0
  25. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_fr_CA.properties +3 -0
  26. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_hi.properties +3 -0
  27. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_hr.properties +3 -0
  28. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_hu.properties +3 -0
  29. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_id.properties +5 -2
  30. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_it.properties +3 -0
  31. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_iw.properties +3 -0
  32. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_ja.properties +3 -0
  33. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_kk.properties +3 -0
  34. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_ko.properties +3 -0
  35. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_lt.properties +3 -0
  36. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_lv.properties +3 -0
  37. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_mk.properties +3 -0
  38. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_ms.properties +3 -0
  39. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_nl.properties +3 -0
  40. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_no.properties +3 -0
  41. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_pl.properties +3 -0
  42. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_pt.properties +4 -1
  43. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_pt_PT.properties +3 -0
  44. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_ro.properties +3 -0
  45. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_ru.properties +3 -0
  46. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_sh.properties +3 -0
  47. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_sk.properties +3 -0
  48. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_sl.properties +3 -0
  49. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_sr.properties +3 -0
  50. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_sv.properties +3 -0
  51. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_th.properties +3 -0
  52. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_tr.properties +3 -0
  53. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_uk.properties +3 -0
  54. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_vi.properties +5 -2
  55. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_zh_CN.properties +3 -0
  56. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_zh_TW.properties +3 -0
  57. package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
  58. package/src/sap/suite/ui/generic/template/ListReport/view/fragments/SmartTable.fragment.xml +29 -2
  59. package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +85 -21
  60. package/src/sap/suite/ui/generic/template/ObjectPage/controller/RelatedAppsHandler.js +1 -1
  61. package/src/sap/suite/ui/generic/template/ObjectPage/controllerFrameworkExtensions.js +8 -7
  62. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ar.properties +1 -1
  63. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_pt.properties +1 -1
  64. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_vi.properties +2 -2
  65. package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
  66. package/src/sap/suite/ui/generic/template/ObjectPage/templateSpecificPreparationHelper.js +2 -2
  67. package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/SmartTable.fragment.xml +0 -1
  68. package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
  69. package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
  70. package/src/sap/suite/ui/generic/template/fragments/MessagePopover.fragment.xml +1 -1
  71. package/src/sap/suite/ui/generic/template/js/AnnotationHelper.js +0 -5
  72. package/src/sap/suite/ui/generic/template/js/AnnotationHelperStreamSupport.js +2 -1
  73. package/src/sap/suite/ui/generic/template/lib/AppComponent.js +20 -2
  74. package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +47 -1
  75. package/src/sap/suite/ui/generic/template/lib/TableNoDataHandler.js +107 -0
  76. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +58 -6
  77. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +1 -1
  78. package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +44 -199
  79. package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterDataFetcherHelper.js +334 -0
  80. package/src/sap/suite/ui/generic/template/lib/i18n/i18n.properties +49 -13
  81. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ar.properties +30 -6
  82. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_bg.properties +29 -5
  83. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ca.properties +34 -10
  84. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cnr.properties +29 -5
  85. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cs.properties +29 -5
  86. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cy.properties +29 -5
  87. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_da.properties +31 -7
  88. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_de.properties +32 -8
  89. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_el.properties +32 -8
  90. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en.properties +33 -9
  91. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_GB.properties +33 -9
  92. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saprigi.properties +14 -6
  93. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es.properties +33 -9
  94. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es_MX.properties +33 -9
  95. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_et.properties +30 -6
  96. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +30 -6
  97. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr.properties +32 -8
  98. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr_CA.properties +31 -7
  99. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hi.properties +30 -6
  100. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hr.properties +28 -4
  101. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hu.properties +26 -2
  102. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_id.properties +38 -14
  103. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_it.properties +30 -6
  104. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_iw.properties +29 -5
  105. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ja.properties +31 -7
  106. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_kk.properties +30 -6
  107. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ko.properties +30 -6
  108. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lt.properties +30 -6
  109. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lv.properties +30 -6
  110. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_mk.properties +30 -6
  111. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ms.properties +30 -6
  112. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_nl.properties +30 -6
  113. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_no.properties +30 -6
  114. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pl.properties +31 -7
  115. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt.properties +31 -7
  116. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt_PT.properties +30 -6
  117. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ro.properties +33 -9
  118. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ru.properties +31 -7
  119. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sh.properties +29 -5
  120. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sk.properties +28 -4
  121. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +31 -7
  122. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sr.properties +29 -5
  123. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sv.properties +30 -6
  124. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_th.properties +30 -6
  125. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_tr.properties +30 -6
  126. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_uk.properties +29 -5
  127. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_vi.properties +33 -9
  128. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_CN.properties +32 -8
  129. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_TW.properties +30 -6
  130. package/src/sap/suite/ui/generic/template/lib/insights/InsightsCardHelper.js +10 -0
  131. package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +6 -1
  132. package/src/sap/suite/ui/generic/template/lib/presentationControl/SmartChartHandler.js +10 -5
  133. package/src/sap/suite/ui/generic/template/lib/presentationControl/SmartListHandler.js +6 -1
  134. package/src/sap/suite/ui/generic/template/lib/presentationControl/SmartTableHandler.js +36 -31
  135. package/src/sap/suite/ui/generic/template/library.js +1 -1
  136. package/src/sap/suite/ui/generic/template/listTemplates/fragments/DetailSmartTable.fragment.xml +29 -28
@@ -368,6 +368,20 @@ sap.ui.define([
368
368
  oComponentData.feEnvironment.getShareControlVisibility();
369
369
  }
370
370
 
371
+ // If the FE app is embedded within the Inbox app, the Inbox injects a dummy object named "feEnvironment"
372
+ // into the "componentData". In this case, we obtain the (mocked) shell service from "feEnvironment"
373
+ // instead of the standard ShellUIService.
374
+ // The mocked shell service exposes few methods like "setTitle" and "setHierarchy".
375
+ // They are invoked by NavigationController.
376
+ //
377
+ // Otherwise, we return the actual "ShellUIService" from the app component.
378
+ function fnGetShellUIServicePromise () {
379
+ var oComponentData = oAppComponent.getComponentData();
380
+ return oComponentData?.feEnvironment?.getShellService ?
381
+ Promise.resolve( oComponentData.feEnvironment.getShellService() ) :
382
+ oAppComponent.getService("ShellUIService");
383
+ }
384
+
371
385
  function attachToApplicationController() {
372
386
  oTemplateContract.fnAddSideEffectPromise = function(oPromise){
373
387
  var i = 0;
@@ -427,7 +441,7 @@ sap.ui.define([
427
441
  oViewDependencyHelper: new ViewDependencyHelper(oTemplateContract)
428
442
  };
429
443
  oTemplateContract.oViewDependencyHelper = oAppRegistryEntry.oViewDependencyHelper;
430
- oTemplateContract.oShellServicePromise = oAppComponent.getService("ShellUIService");
444
+ oTemplateContract.oShellServicePromise = fnGetShellUIServicePromise();
431
445
  oTemplateContract.oShellServicePromise.catch(function(){
432
446
  oLogger.warning("No ShellService available");
433
447
  });
@@ -945,7 +959,7 @@ sap.ui.define([
945
959
  * @public
946
960
  * @extends sap.ui.core.UIComponent
947
961
  * @author SAP SE
948
- * @version 1.141.3
962
+ * @version 1.142.0
949
963
  * @name sap.suite.ui.generic.template.lib.AppComponent
950
964
  */
951
965
  var oAppComponent = UIComponent.extend("sap.suite.ui.generic.template.lib.AppComponent", {
@@ -1049,6 +1063,10 @@ sap.ui.define([
1049
1063
  skipOPContextInfoInBrowserTitle: {
1050
1064
  type: "boolean",
1051
1065
  defaultValue: false
1066
+ },
1067
+ noDataRepresentation: {
1068
+ type: "string",
1069
+ defaultValue: "illustration" // Possible values: 'illustration', 'illustrationWithFallback' and 'textOnly'
1052
1070
  }
1053
1071
  },
1054
1072
  events: {
@@ -282,6 +282,51 @@ sap.ui.define(["sap/ui/base/Object",
282
282
  return getSpecializedText(sKey, sSpecificI18nKey, sFrameworkKey, aParameters);
283
283
  }
284
284
 
285
+ var aAppSpecificResourceBundles;
286
+ /**
287
+ * Returns i18n text from application's resource bundle.
288
+ *
289
+ * Background: On `lib.TemplateComponent#fnEnhanceI18nModel` method, FE's resource bundles are initialized.
290
+ * - The main resource bundle is `lib/i18n/i18n.properties`.
291
+ * - Additional bundles (floor-plan specific FE bundles + app bundles) are added as custom bundles (`ResourceBundle#aCustomBundles`).
292
+ *
293
+ * This method,
294
+ * 1. Creates an array of custom resource bundles ()`aAppSpecificResourceBundles`) which only contains the app's resource bundles.
295
+ * 2. Iterates through the app's bundles in reverse order to resolve the i18n key.
296
+ *
297
+ * Reason for reverse order:
298
+ * - The last bundle contains most specific text (floor-plan / entityset level).
299
+ * - The first bundle is more generic one.
300
+ * - This follows the same precedence logic as `sap.base.i18n.ResourceBundle#_getTextFromProperties`.
301
+ *
302
+ * @param {string} sKey i18n key
303
+ * @param {string[]} aArguments arguments for i18n text
304
+ * @returns {string|null} i18n text if found, otherwise null
305
+ */
306
+ function getCustomizedTextFromApp(sKey, aArguments) {
307
+ var sText = null, i;
308
+ if (aAppSpecificResourceBundles == null) {
309
+ var oComponent = oController.getOwnerComponent();
310
+ var oResourceBundle = oComponent.getModel("i18n").getResourceBundle();
311
+ // FE's bundles are omitted.
312
+ aAppSpecificResourceBundles = oResourceBundle.aCustomBundles.filter(oBundle => {
313
+ return !oBundle.oUrlInfo.url.includes("sap/suite/ui/generic/template");
314
+ });
315
+ }
316
+ // "aArguments" normalized to array
317
+ if (aArguments && !Array.isArray(aArguments)) {
318
+ aArguments = [aArguments];
319
+ }
320
+
321
+ for (i = aAppSpecificResourceBundles.length - 1; i >= 0; i--) {
322
+ sText = aAppSpecificResourceBundles[i].getText(sKey, aArguments, true);
323
+ if (sText != null) {
324
+ return sText;
325
+ }
326
+ }
327
+ return null;
328
+ }
329
+
285
330
  // This functions intends to give selection from different selection behavior
286
331
  function getSelectionPoints(oInnerChart, sSelectionBehavior) {
287
332
  var sSelectionBehavior = sSelectionBehavior || oInnerChart.getSelectionBehavior();
@@ -2044,7 +2089,8 @@ sap.ui.define(["sap/ui/base/Object",
2044
2089
  handleError: fnHandleError,
2045
2090
  transformTechnicalPropsOnExportedFile: fnTransformTechnicalPropsOnExportedFile,
2046
2091
  includeEntitySetParametersToExportedFile: fnIncludeEntitySetParametersToExportedFile,
2047
- openContextInNewTabFromListItem: fnOpenContextInNewTabFromListItem
2092
+ openContextInNewTabFromListItem: fnOpenContextInNewTabFromListItem,
2093
+ getCustomizedTextFromApp: getCustomizedTextFromApp
2048
2094
  };
2049
2095
  }
2050
2096
 
@@ -0,0 +1,107 @@
1
+ sap.ui.define([
2
+ "sap/base/util/extend",
3
+ "sap/ui/base/Object",
4
+ "sap/suite/ui/generic/template/genericUtilities/FeLogger"
5
+ ], function (
6
+ extend,
7
+ BaseObject,
8
+ FeLogger
9
+ ) {
10
+ "use strict";
11
+ var oLogger = new FeLogger("lib.TableNoDataHandler").getLogger();
12
+
13
+ function getMethods(oController, oTemplateUtils, oNoDataConfig) {
14
+ var sNoDataRepresentation = oController.getOwnerComponent().getAppComponent().getNoDataRepresentation();
15
+
16
+ function fnSetNoDataMessage (oSmartTable, sScenario) {
17
+ if (sNoDataRepresentation === "textOnly") {
18
+ fnSetTextMessage(oSmartTable, sScenario);
19
+ } else if (["illustration", "illustrationWithFallback"].includes(sNoDataRepresentation)) {
20
+ fnSetIllustratedMessage(oSmartTable, sScenario);
21
+ }
22
+ }
23
+
24
+ // Sets "text" based no data message
25
+ function fnSetTextMessage (oSmartTable, sScenario) {
26
+ var sSmartTableId = oSmartTable.getId();
27
+ var sI18nKey = oNoDataConfig[sScenario].i18nKey;
28
+ var sNoDataText = oTemplateUtils.oCommonUtils.getContextText(sI18nKey, sSmartTableId);
29
+ oSmartTable.setNoData(sNoDataText);
30
+ }
31
+
32
+ // Sets "illustration" based no data message
33
+ function fnSetIllustratedMessage (oSmartTable, sScenario) {
34
+ var sSmartTableId = oSmartTable.getId();
35
+ var sI18nPrefix = oNoDataConfig[sScenario].i18nKey;
36
+ // Derive title key from base key
37
+ var sTitleI18nKey = sI18nPrefix + "_ILLUSTRATION_TITLE";
38
+ // Get title from resource bundle.
39
+ var sTitle = oTemplateUtils.oCommonUtils.getContextText(sTitleI18nKey, sSmartTableId);
40
+ // Find description (this logic varies between "illustration" and "illustrationWithFallback")
41
+ var sDescription = fnDeriveIllustrationDescription(sI18nPrefix, sSmartTableId);
42
+ // Get illustration type from config
43
+ var sIllustrationType = oNoDataConfig[sScenario].illustrationType;
44
+
45
+
46
+ var oNoDataIllustratedMessage = oSmartTable.getNoData();
47
+ // oSmartTable.getNoData should actually return an illustrated message.
48
+ //
49
+ // Sometimes, app changes the no data message into text message using custom coding.
50
+ // Hence, adding this type check as a safety measure.
51
+ if ( !(oNoDataIllustratedMessage?.isA?.("sap.m.IllustratedMessage")) ) {
52
+ oLogger.error(`Unable to update the no data message of smart table ${oSmartTable.getId()} as it's not an IllustratedMessage`);
53
+ return;
54
+ }
55
+ // Table already has illustrated no data message. Just update the attributes
56
+ oNoDataIllustratedMessage.setIllustrationType(sIllustrationType);
57
+ oNoDataIllustratedMessage.setTitle(sTitle);
58
+ oNoDataIllustratedMessage.setDescription(sDescription);
59
+ }
60
+
61
+ /**
62
+ * Calculates the illustrated message's description based on the manifest flag "noDataRepresentation" value
63
+ * 1. If manifest flag is "illustration"
64
+ * - Just returns text for the new i18n key (legacy key + "_ILLUSTRATION_DESCRIPTION")
65
+ * - The text can be found on either app or FE
66
+ * 2. If flag is "illustrationWithFallback"
67
+ * a. Checks the app if customized text available for (legacy i18n key | tableId) (for e.g. "NOITEMS_LR_SMARTTABLE|C_SalesOrder")
68
+ * - If found, returns it.
69
+ * b. Checks the app if customized text available just for legacy i18n key (for e.g. "NOITEMS_LR_SMARTTABLE")
70
+ * - If found, returns it.
71
+ * c. Returns the text for the new i18n key (Same as "Case 1" above).
72
+ */
73
+ function fnDeriveIllustrationDescription (sI18nPrefix, sSmartTableId) {
74
+ var sLatestDescriptionI18nKey = sI18nPrefix + "_ILLUSTRATION_DESCRIPTION";
75
+ var sLatestDescription = oTemplateUtils.oCommonUtils.getContextText(sLatestDescriptionI18nKey, sSmartTableId);
76
+ if (sNoDataRepresentation === "illustration") {
77
+ return sLatestDescription;
78
+ }
79
+ // Below logic is for noDataRepresentation = "illustrationWithFallback"
80
+ var sLegacyDescription = null;
81
+ var sLegacyI18nKey = sI18nPrefix;
82
+ var sTableSpecificI18nSuffix = oTemplateUtils.oCommonUtils.getSpecificI18nKeyForSmartControl(sSmartTableId);
83
+ sTableSpecificI18nSuffix = (sTableSpecificI18nSuffix === "|") ? "" : sTableSpecificI18nSuffix; // Omit the suffix "|"
84
+ // If table specific i18n key is available, get the customized text for that.
85
+ if (sTableSpecificI18nSuffix) {
86
+ sLegacyDescription = oTemplateUtils.oCommonUtils.getCustomizedTextFromApp(sLegacyI18nKey + "|" + sTableSpecificI18nSuffix);
87
+ }
88
+ // If the description is not yet found, get the customized text just for the generic i18n key.
89
+ if (!sLegacyDescription) {
90
+ sLegacyDescription = oTemplateUtils.oCommonUtils.getCustomizedTextFromApp(sLegacyI18nKey);
91
+ }
92
+ // If legacy text is found, return it.
93
+ // Otherwise, return the latest one.
94
+ return sLegacyDescription || sLatestDescription;
95
+ }
96
+
97
+ return {
98
+ setNoDataMessage: fnSetNoDataMessage
99
+ };
100
+ }
101
+
102
+ return BaseObject.extend("sap.suite.ui.generic.template.lib.TableNoDataHandler", {
103
+ constructor: function (oController, oTemplateUtils, oNoDataConfig) {
104
+ extend(this, getMethods(oController, oTemplateUtils, oNoDataConfig));
105
+ }
106
+ });
107
+ });
@@ -15,8 +15,8 @@ sap.ui.define([
15
15
  * It gets initialized when the Fiori AI EasyFill is enabled
16
16
  * Below things are handled in this class:
17
17
  * 1. Prepare Field metadata
18
- * 2. Prepare EasyFill Dialog
19
- *
18
+ * 2. Prepare EasyFill Dialog
19
+ *
20
20
  */
21
21
  function getMethods(oState, oController, oTemplateUtils, oObjectPage) {
22
22
  let oTransientContextForEasyFill;
@@ -25,13 +25,14 @@ sap.ui.define([
25
25
  let mUpdatableLookupMap;
26
26
  let oRb;
27
27
  let oAIPopover;
28
+ let aEditableFields = [];
28
29
 
29
30
  async function openEasyFillDialog(oEvent,oContext) {
30
31
  let oEasyFillDialog;
31
32
  oRb = oController.getView().getModel("i18n").getResourceBundle();
32
33
  const bIsModelCreated = !!oController.getView().getModel("easyFillDialogModel");
34
+ oObjectPageModel = oObjectPage.getModel();
33
35
  if (!bIsModelCreated) {
34
- oObjectPageModel = oObjectPage.getModel();
35
36
  const aDeferredGroups = oObjectPageModel.getDeferredGroups();
36
37
  //Adding a defferred group will make sure that no batch call would get triggered to backend until submitChanges() is invoked
37
38
  aDeferredGroups.push("EasyFillFETransientChanges");
@@ -107,8 +108,9 @@ sap.ui.define([
107
108
  oObjectPageContext.setProperty(oProp, oTransientObject[oProp]);
108
109
  }
109
110
  }
111
+ activateSideEffects();
110
112
  resetEasyFill(true);
111
- oEasyFillDialog.close();
113
+ oEasyFillDialog?.close();
112
114
  },
113
115
  onLiveChange: function(oEvent) {
114
116
  const easyFillDialogModel = oController.getView().getModel("easyFillDialogModel");
@@ -124,6 +126,7 @@ sap.ui.define([
124
126
  easyFillDialogModel.setProperty("/isBusy",true);
125
127
  let mFieldMapping = getEntitySetMapForLLM();
126
128
  let aiCallResult = await oTemplateUtils.oServices.oFioriAIHandler.fioriaiLib.EasyFill.extractFieldValuesFromText(oController.byId("EasyFillInputTextArea").getValue(), mFieldMapping);
129
+ aEditableFields = [];
127
130
  easyFillDialogModel.setProperty("/isBusy",false);
128
131
  formatDateValues(aiCallResult,mFieldMapping);
129
132
  if (aiCallResult.success) {
@@ -170,10 +173,56 @@ sap.ui.define([
170
173
  }
171
174
  }, "easyFillPopup",undefined,true,true).then(function (oPopup) {
172
175
  oEasyFillDialog = oPopup;
173
- oPopup.open();
176
+ oPopup?.open();
174
177
  });
175
178
  }
176
179
 
180
+ function activateSideEffects() {
181
+ //Making a set so that , duplicate field group ids are not passed
182
+ const aFieldGroupIdSet = new Set();
183
+ aEditableFields.forEach((oSmartField)=>{
184
+ //SideEffect would be invoked only for the editable controls inside the SmartField
185
+ const aEditableInnerFields = oSmartField.getInnerControls().filter((oControl)=>oControl.getEditable());
186
+ aEditableInnerFields.forEach((oControl)=>{
187
+ const aControlFieldGroupId = oControl.getFieldGroupIds();
188
+ if (aControlFieldGroupId.length > 0) {
189
+ aControlFieldGroupId.forEach((sFieldGroupId)=>{
190
+ aFieldGroupIdSet.add(sFieldGroupId);
191
+ });
192
+ }
193
+ });
194
+
195
+ });
196
+
197
+ const oView = oController.getView();
198
+
199
+ aFieldGroupIdSet.forEach((sFieldGroupId)=>{
200
+ const oID = oView.data(sFieldGroupId);
201
+
202
+ /**
203
+ * Currently, the SmartFields are created using the TransientContext, which means both
204
+ * "context" and "contextObject" refer to the TransientContext instance.
205
+ *
206
+ * However, we need to use the original OP context so that side effects are triggered
207
+ * on the original OP context when the user saves data from the EasyFill dialog back to OP.
208
+ *
209
+ * Therefore, we update the "context" and "contextObject" to reference the original OP context.
210
+ */
211
+
212
+ if (oID) {
213
+ oID["context"] = oObjectPageContext.getPath();
214
+ oID["contextObject"] = oObjectPageContext;
215
+ oView.data(sFieldGroupId,oID);
216
+ }
217
+ //To make sure that all the fields sideeffect would be triggered
218
+ const sSideEffectQualifier = oTemplateUtils.oServices.oApplicationController._getSideEffectsQualifier(oID.name);
219
+ oTemplateUtils.oServices.oApplicationController.registerGroupChange(sSideEffectQualifier);
220
+ });
221
+
222
+
223
+ oView.triggerValidateFieldGroup([...aFieldGroupIdSet]);
224
+ }
225
+
177
226
  function getAIPopover() {
178
227
  return new Promise(async(resolve,reject) => {
179
228
  const sFragmentname = "sap.suite.ui.generic.template.fragments.AINotice";
@@ -358,7 +407,7 @@ sap.ui.define([
358
407
  var oGroup = new Group({
359
408
  title: (isTransient) ? oRb.getText("EASY_FILL_PROPOSED_VALUES") : oRb.getText("EASY_FILL_PREVIOUS_VALUES")
360
409
  });
361
-
410
+
362
411
  for (const key of Object.keys(oDataFromLLM)) {
363
412
  const oGroupElement = new GroupElement();
364
413
  const oSmartField = new SmartField({
@@ -368,6 +417,9 @@ sap.ui.define([
368
417
  contextEditable: isEditable,
369
418
  change: onSmartFieldChange.bind(this)
370
419
  });
420
+ if (isEditable) {
421
+ aEditableFields.push(oSmartField);
422
+ }
371
423
  const oSmartLabel = new SmartLabel();
372
424
  oSmartLabel.setLabelFor(oSmartField);
373
425
  oGroupElement.addElement(oSmartField);
@@ -73,7 +73,7 @@ xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1"
73
73
  </FlexBox>
74
74
  </content>
75
75
  <beginButton>
76
- <Button text="{i18n>EASY_FILL_SAVE}" enabled="{easyFillDialogModel>/isSaveEnabled}" press="onSaveFromEasyFillDialog" type="Emphasized"/>
76
+ <Button text="{i18n>EASY_FILL_CONFIRM}" enabled="{easyFillDialogModel>/isSaveEnabled}" press="onSaveFromEasyFillDialog" type="Emphasized"/>
77
77
  </beginButton>
78
78
  <endButton>
79
79
  <Button text="{i18n>CANCEL}" press="onCancelEasyFillDialog"/>
@@ -5,8 +5,9 @@ sap.ui.define([
5
5
  "sap/suite/ui/generic/template/genericUtilities/FeLogger",
6
6
  "sap/ui/model/FilterOperator",
7
7
  'sap/ui/model/Filter',
8
- 'sap/suite/ui/generic/template/js/AnnotationHelper'
9
- ], function(BaseObject, extend, filterHelper, FeLogger, FilterOperator,Filter,AnnotationHelper) {
8
+ 'sap/suite/ui/generic/template/js/AnnotationHelper',
9
+ "./EasyFilterDataFetcherHelper"
10
+ ], function(BaseObject, extend, filterHelper, FeLogger, FilterOperator,Filter,AnnotationHelper,EasyFilterDataFetcherHelper) {
10
11
  'use strict';
11
12
 
12
13
  /*
@@ -333,24 +334,28 @@ sap.ui.define([
333
334
  // keySpecificSelectedValues will have one selectedValues object for each operator
334
335
  // ex : [{operator: "EQ", selectedValues: ["HT-1010","HT-10001","1097"]}, {operator: "Contains", selectedValues: ["HT-100"]}]
335
336
  oFilterItem.keySpecificSelectedValues.forEach(function (oSelectedValues) {
336
- var oRange = {
337
- Sign: "I", // currently not considering "E"
338
- High: ""
339
- };
340
-
341
337
  if ((oSelectedValues.operator === "BT" || oSelectedValues.operator === "NB")) {
338
+ var oRange = {
339
+ Sign: oSelectedValues.operator === "NB" ? "E" : "I",
340
+ High: ""
341
+ };
342
342
  oRange.Low = oSelectedValues.selectedValues[0];
343
343
  oRange.High = oSelectedValues.selectedValues[1];
344
- oRange.Option = oSelectedValues.operator;
344
+ oRange.Option = "BT";
345
345
  oFilter.Ranges.push(oRange);
346
346
  } else {
347
- oSelectedValues.selectedValues.forEach(function (oValue) {
348
- if (oSelectedValues.operator === "Contains") { // need to check for other operators if special handling is required
347
+ oSelectedValues.selectedValues.forEach(function (sValue) {
348
+ var oRange = {
349
+ Sign: EasyFilterDataFetcherHelper.isNegationOperator(oSelectedValues.operator) ? "E" : "I",
350
+ High: ""
351
+ };
352
+
353
+ if (isCPOperator(oSelectedValues.operator)) {
349
354
  oRange.Option = "CP";
350
- oRange.Low = oValue;
355
+ oRange.Low = getValueForCPOperator(sValue,oSelectedValues.operator);
351
356
  } else {
352
- oRange.Option = oSelectedValues.operator;
353
- oRange.Low = oValue;
357
+ oRange.Option = EasyFilterDataFetcherHelper.isNegationOperator(oSelectedValues.operator) ? EasyFilterDataFetcherHelper.getReverseOperator(oSelectedValues.operator) : oSelectedValues.operator;
358
+ oRange.Low = sValue;
354
359
  }
355
360
  oFilter.Ranges.push(oRange);
356
361
  });
@@ -366,6 +371,29 @@ sap.ui.define([
366
371
  };
367
372
  }
368
373
 
374
+ function getValueForCPOperator(sValue,sOperator) {
375
+ sOperator = EasyFilterDataFetcherHelper.isNegationOperator(sOperator) ? EasyFilterDataFetcherHelper.getReverseOperator(sOperator) : sOperator;
376
+ switch (sOperator) {
377
+ case FilterOperator.Contains:
378
+ sValue = `*${sValue}*`;
379
+ break;
380
+ case FilterOperator.EndsWith:
381
+ sValue = `*${sValue}`;
382
+ break;
383
+ case FilterOperator.StartsWith:
384
+ sValue = `${sValue}*`;
385
+ break;
386
+ default:
387
+ break;
388
+ }
389
+ return sValue;
390
+ }
391
+
392
+ function isCPOperator(sOperator) {
393
+ return sOperator === FilterOperator.Contains || sOperator === FilterOperator.EndsWith || sOperator === FilterOperator.NotContains || sOperator === FilterOperator.NotEndsWith
394
+ || sOperator === FilterOperator.NotStartsWith || sOperator === FilterOperator.StartsWith;
395
+ }
396
+
369
397
  /**
370
398
  * This method is used to get the EasyFilter control from the floorplan
371
399
  * @returns EasyFilter control
@@ -431,7 +459,6 @@ sap.ui.define([
431
459
  if (oSmartFilterBarVariant.semanticDates) {
432
460
  var { Low: value1, High: value2 } = oVariantDataFromAI.aSelectOptions[0].Ranges[0];
433
461
  var dateData = oSmartFilterBarVariant.semanticDates.Dates[0].Data;
434
-
435
462
  dateData.operation = "DATERANGE";
436
463
  dateData.value1 = value1;
437
464
  dateData.value2 = value2 || value1;
@@ -541,191 +568,10 @@ sap.ui.define([
541
568
  }
542
569
  }
543
570
 
544
- function getFiltersForDataFetching(key,keySpecificSelectedResult) {
545
- const aFilters = [];
546
-
547
- for (var i = 0; i < keySpecificSelectedResult.length;++i) {
548
- const result = keySpecificSelectedResult[i];
549
- if (result.operator === FilterOperator.BT || result.operator === FilterOperator.NB) {
550
- aFilters.push(new Filter({
551
- path: key,
552
- operator: result.operator,
553
- value1: result.selectedValues[0],
554
- value2: result.selectedValues[1]
555
- }));
556
- } else {
557
- for (var j = 0; j < result.selectedValues.length; ++j) {
558
- aFilters.push(new Filter({
559
- path: key,
560
- operator: result.operator,
561
- value1: result.selectedValues[j]
562
- }));
563
- }
564
- }
565
- }
566
- return aFilters;
567
- }
568
-
569
571
  function onDataFetcher(key,keySpecificSelectedResult,totalAIResponse) {
570
- return new Promise((resolve,reject)=>{
571
-
572
- var aFinalResponse = [];
573
- var oOwnerFilterControl = oState.oSmartFilterbar;
574
- var sKey = key;
575
- var sEntitySet = oController.getOwnerComponent().getEntitySet();
576
- var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(sEntitySet);
577
- var oSFBModel = oOwnerFilterControl.getModel();
578
- var oSFBMetaModel = oSFBModel.getMetaModel();
579
- var aFilters = getFiltersForDataFetching(key,keySpecificSelectedResult);
580
- var oProperty = oSFBMetaModel.getODataProperty(oEntityType, key);
581
- var sPropertyPath = oSFBMetaModel.getODataProperty(oEntityType, key,true);
582
- var isValueHelpTableAvailable = AnnotationHelper.isValueHelpTableAvailable(oProperty);
583
-
584
- if (isValueHelpTableAvailable) {
585
- var oPropertyContext = oSFBMetaModel.createBindingContext(sPropertyPath);
586
- var oVHPromise = oSFBMetaModel.getODataValueLists(oPropertyContext);
587
- var filtersLength = aFilters.length;
588
- // //Every Search on a value, create a seperate call to backend,but they are grouped into one batch
589
- // //We need to ensure that once all calls are completed inside the batch to resolve the promise, else the system would be waiting indefenitely
590
- var ctr = 0;
591
- let fnForDescription = (oResponse,aMatchedFilterResults,sTextArrangementPath,sTextArrangement) => {
592
- ++ctr;
593
- var aResults = oResponse.results;
594
-
595
- //Check the description is present and follow the textArrangement annotation as well
596
- //If the value is not present ,make the ID and Description same
597
- aMatchedFilterResults.forEach((oFilter)=>{
598
- var result = aResults.find((res)=>res[key] === oFilter.getValue1());
599
- if (result) {
600
- aFinalResponse.push({
601
- operator: FilterOperator.EQ,
602
- selectedValues: [{
603
- value: result[key],
604
- description: AnnotationHelper.getTextArrangementFinalString(result,key,sTextArrangementPath.split("/")[1],sTextArrangement)
605
- }]
606
- });
607
- } else {
608
- //Ideally description should be present, if in case its not present we will fallback to our default case where value and description would be same
609
- aFinalResponse.push(getkeySpecifiedResultFromFilters(oFilter));
610
- }
611
- });
612
-
613
- if (ctr === filtersLength) {
614
- resolve(aFinalResponse);
615
- }
616
- };
617
-
618
-
619
-
620
- let fnSuccessForValueList = (oResponse,oFilter,sValueListEntity) => {
621
- var oValueHelpEntity = oTemplateUtils.oCommonUtils.getMetaModelEntityType(sValueListEntity);
622
- var oValueHelpProperty = oSFBMetaModel.getODataProperty(oValueHelpEntity, key);
623
- var aResults = oResponse.results;
624
- var sTextArrangementPath = AnnotationHelper.getTextArrangementPath(oValueHelpProperty);
625
- var sTextArrangement = AnnotationHelper.getTextArrangementForEasyFilter(oValueHelpEntity,oValueHelpProperty);
626
- var navigationProperty = null;
627
- var sEntityForTextDescription = null;
628
-
629
- if (sTextArrangementPath && sTextArrangementPath.split("/").length > 1) {
630
- navigationProperty = sTextArrangementPath.split("/")[0];
631
- sEntityForTextDescription = oSFBMetaModel.getODataAssociationSetEnd(oValueHelpEntity,navigationProperty).entitySet;
632
- }
633
-
634
- //We are triggering the below call, only for fetching of the TextDescription.If its a different entity than ValueList only then trigger it
635
- if (aResults.length === 0) {
636
- ++ctr;
637
- aFinalResponse.push(getkeySpecifiedResultFromFilters(oFilter));
638
- } else if (aResults.length !== 0 && sEntityForTextDescription && sValueListEntity !== sEntityForTextDescription) {
639
- var aAllMatchedResults = aResults.map((result)=>{
640
- return result[key];
641
- });
642
- var aMatchedFilterResults = aAllMatchedResults.map((matchedResult)=>{
643
- return new Filter({
644
- path: key,
645
- operator: FilterOperator.EQ,
646
- value1:matchedResult
647
- });
648
- });
649
- // The below code only be executed when the textDescription and ValueList entities are different
650
- oSFBModel.read("/" + sEntityForTextDescription, {
651
- filters: aMatchedFilterResults,
652
- success : function(response) {
653
- fnForDescription(response,aMatchedFilterResults);
654
- }
655
- });
656
- } else {
657
- //The below condition is when valueList entity and navigation property entity are same
658
- ++ctr;
659
- aResults.forEach((result)=>{
660
- aFinalResponse.push({
661
- operator: FilterOperator.EQ,
662
- selectedValues: [{
663
- value: result[key],
664
- description: AnnotationHelper.getTextArrangementFinalString(result,key,
665
- sTextArrangementPath,sTextArrangement)
666
- }]
667
- });
668
- });
669
- }
670
-
671
- if (ctr === filtersLength) {
672
- resolve(aFinalResponse);
673
- }
674
- };
675
-
676
- oVHPromise.then((oValueList)=>{
677
- var oValueListDefaultBinding = oValueList[""];
678
- var sValueListEntity = oValueListDefaultBinding.CollectionPath.String;
679
- if (Array.isArray(oValueListDefaultBinding.Parameters)) {
680
- var oParameter = oValueListDefaultBinding.Parameters.find(oParam => (oParam.RecordType === "com.sap.vocabularies.Common.v1.ValueListParameterInOut" && oParam.LocalDataProperty.PropertyPath === sKey));
681
- if (oParameter) {
682
- key = oParameter.ValueListProperty.String;
683
- }
684
- }
685
- //Get All Records using $search
686
- aFilters.forEach((oFilter)=>{
687
- oSFBModel.read("/" + sValueListEntity, {
688
- urlParameters : {
689
- search: oFilter.getValue1()
690
- },
691
- success : function(response) {
692
- fnSuccessForValueList(response,oFilter,sValueListEntity);
693
- }
694
- });
695
- });
696
- });
697
-
698
- } else {
699
- //When there is no valueList associate, just return the original value in CodeList type
700
- aFilters.forEach((oFilter)=>aFinalResponse.push(getkeySpecifiedResultFromFilters(oFilter)));
701
- resolve(aFinalResponse);
702
- }
703
- });
704
- }
705
-
706
- function getkeySpecifiedResultFromFilters(oFilter) {
707
- var values = [];
708
- if (oFilter.getOperator() === FilterOperator.BT || oFilter.getOperator() === FilterOperator.NB) {
709
- var values = [{
710
- value: oFilter.getValue1(),
711
- description: oFilter.getValue1()
712
- },{
713
- value: oFilter.getValue2(),
714
- description: oFilter.getValue2()
715
- }];
716
- } else {
717
- values.push({
718
- value: oFilter.getValue1(),
719
- description: oFilter.getValue1()
720
- });
721
- }
722
- return {
723
- operator: oFilter.getOperator(),
724
- selectedValues: values
725
- };
572
+ return EasyFilterDataFetcherHelper.fetchDataForKey(key, keySpecificSelectedResult, oState, oController, oTemplateUtils);
726
573
  }
727
574
 
728
-
729
575
  return {
730
576
  getEasyFilterBar : fnGetEasyFilterBar,
731
577
  initialiseEasyFilterBar : fnInitialiseEasyFilterBar,
@@ -739,8 +585,7 @@ sap.ui.define([
739
585
  onShowValueHelp: fnShowValueHelp,
740
586
  onFilterChange : fnOnFilterChange,
741
587
  handleVariantLoad : fnHandleVariantLoad,
742
- onDataFetcher,
743
- getkeySpecifiedResultFromFilters
588
+ onDataFetcher
744
589
  };
745
590
  }
746
591
 
@@ -749,5 +594,5 @@ sap.ui.define([
749
594
  extend(this, getMethods(oState, oController, oTemplateUtils));
750
595
  }
751
596
  });
752
-
597
+
753
598
  });