@sapui5/sap.suite.ui.generic.template 1.147.2 → 1.148.1

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 (98) hide show
  1. package/package.json +1 -1
  2. package/src/sap/suite/ui/generic/template/.library +1 -1
  3. package/src/sap/suite/ui/generic/template/AnalyticalListPage/controller/ControllerImplementation.js +5 -3
  4. package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_bg.properties +3 -3
  5. package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_da.properties +3 -3
  6. package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_fr_CA.properties +2 -2
  7. package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_id.properties +2 -2
  8. package/src/sap/suite/ui/generic/template/AnalyticalListPage/manifest.json +1 -1
  9. package/src/sap/suite/ui/generic/template/Canvas/manifest.json +1 -1
  10. package/src/sap/suite/ui/generic/template/ListReport/controller/ControllerImplementation.js +32 -3
  11. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_fr.properties +1 -1
  12. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_id.properties +1 -1
  13. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_uk.properties +1 -1
  14. package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
  15. package/src/sap/suite/ui/generic/template/ObjectPage/Component.js +4 -0
  16. package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +57 -25
  17. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n.properties +6 -0
  18. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en_US_saprigi.properties +4 -0
  19. package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +6 -1
  20. package/src/sap/suite/ui/generic/template/ObjectPage/templateSpecificPreparationHelper.js +35 -19
  21. package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/Actions.fragment.xml +13 -13
  22. package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/Footer.fragment.xml +103 -42
  23. package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
  24. package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
  25. package/src/sap/suite/ui/generic/template/fragments/EasyFilter.fragment.xml +3 -0
  26. package/src/sap/suite/ui/generic/template/genericUtilities/controlHelper.js +30 -29
  27. package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartFilterBarWrapper.js +15 -0
  28. package/src/sap/suite/ui/generic/template/lib/AppComponent.js +1 -1
  29. package/src/sap/suite/ui/generic/template/lib/CRUDHelper.js +93 -55
  30. package/src/sap/suite/ui/generic/template/lib/CRUDManager.js +7 -0
  31. package/src/sap/suite/ui/generic/template/lib/CommonEventHandlers.js +76 -19
  32. package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +4 -1
  33. package/src/sap/suite/ui/generic/template/lib/ComponentUtils.js +17 -7
  34. package/src/sap/suite/ui/generic/template/lib/StableIdDefinition.js +35 -34
  35. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator.js +185 -0
  36. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler.js +476 -0
  37. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillDialogController.js +311 -0
  38. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector.js +669 -0
  39. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFormRenderer.js +217 -0
  40. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +348 -422
  41. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer.js +491 -0
  42. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +142 -72
  43. package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +409 -22
  44. package/src/sap/suite/ui/generic/template/lib/i18n/i18n.properties +32 -8
  45. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ar.properties +14 -0
  46. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_bg.properties +14 -0
  47. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ca.properties +14 -0
  48. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cnr.properties +14 -0
  49. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cs.properties +14 -0
  50. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cy.properties +14 -0
  51. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_da.properties +14 -0
  52. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_de.properties +14 -0
  53. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_el.properties +14 -0
  54. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en.properties +14 -0
  55. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_GB.properties +14 -0
  56. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saprigi.properties +14 -0
  57. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es.properties +14 -0
  58. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es_MX.properties +14 -0
  59. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_et.properties +14 -0
  60. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +14 -0
  61. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr.properties +15 -1
  62. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr_CA.properties +15 -1
  63. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hi.properties +14 -0
  64. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hr.properties +15 -1
  65. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hu.properties +14 -0
  66. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_id.properties +14 -0
  67. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_it.properties +14 -0
  68. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_iw.properties +14 -0
  69. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ja.properties +20 -6
  70. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_kk.properties +14 -0
  71. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ko.properties +14 -0
  72. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lt.properties +14 -0
  73. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lv.properties +14 -0
  74. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_mk.properties +14 -0
  75. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ms.properties +14 -0
  76. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_nl.properties +15 -1
  77. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_no.properties +14 -0
  78. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pl.properties +14 -0
  79. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt.properties +14 -0
  80. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt_PT.properties +14 -0
  81. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ro.properties +14 -0
  82. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ru.properties +14 -0
  83. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sh.properties +14 -0
  84. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sk.properties +14 -0
  85. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +14 -0
  86. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sr.properties +14 -0
  87. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sv.properties +14 -0
  88. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_th.properties +14 -0
  89. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_tr.properties +14 -0
  90. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_uk.properties +17 -3
  91. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_vi.properties +14 -0
  92. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_CN.properties +20 -6
  93. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_TW.properties +20 -6
  94. package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +1 -1
  95. package/src/sap/suite/ui/generic/template/library.js +25 -2
  96. package/src/sap/suite/ui/generic/template/themes/base/ObjectPage.less +22 -3
  97. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillNonUpdatableSmartForm.fragment.xml +0 -18
  98. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillUpdatebleSmartForm.fragment.xml +0 -15
@@ -95,6 +95,7 @@ sap.ui.define(["sap/ui/base/Object",
95
95
  }
96
96
 
97
97
  var mVirtualItems = Object.create(null); // cache for virtual items passed to onListNavigateExtension.
98
+ var mCellHideRowsUpdateHandlers = Object.create(null); // keyed by SmartTable ID: stores rowsUpdated/updateFinished handler for cell hiding
98
99
  var oCurrentPaginatorInfo; // store paginator info while using the pagination
99
100
  function getPaginatorInfo(oTable, oRow, oState){
100
101
  var oRet = oCurrentPaginatorInfo;
@@ -173,7 +174,10 @@ sap.ui.define(["sap/ui/base/Object",
173
174
  oCurrentPaginatorInfo = oRet; // make sure that the navigation below does not create a new paginator info but reuses the existing one
174
175
  onListNavigate(oSourceItem, oState, oTargetContext, true, oViewProxy);
175
176
  };
176
- if (bIsActive && bIsEditItem){ // in this case oListBinding (and thus oContext which was derived from it) points to the active version, but we are already in the draft version
177
+ var oComponent = oController.getOwnerComponent();
178
+ var bOpenInEditMode = !!oComponent.getEditFlow && oComponent.getEditFlow() === "direct";
179
+
180
+ if (bIsActive && bIsEditItem && !bOpenInEditMode){ // in this case oListBinding (and thus oContext which was derived from it) points to the active version, but we are already in the draft version
177
181
  oServices.oApplication.registerContext(oContext, oComponentUtils.getViewLevel() + 1); // determine the sibling context
178
182
  var oSiblingPromise = oServices.oApplication.getDraftSiblingPromise(oContext); // as the "real" target of this pagination
179
183
  oSiblingPromise.then(fnPaginateImpl);
@@ -1359,50 +1363,96 @@ sap.ui.define(["sap/ui/base/Object",
1359
1363
  /**
1360
1364
  * This method is called in the onDataReceived event of the specified SmartTable.
1361
1365
  * It handles everything which can be done regarding hiding of cells at this point in time.
1366
+ * It also ensures that cell-level hiding is reapplied when rows are updated (e.g. after
1367
+ * scrolling in a GridTable or after the SmartTable rebuilds its inner table columns).
1362
1368
  */
1363
1369
  function fnHideTableCells(oSmartTable, oHiddenColumnInfo) {
1370
+ if (!oHiddenColumnInfo.columnKeyToCellHiddenPath) {
1371
+ return;
1372
+ }
1373
+ fnApplyCellHiddenBindings(oSmartTable, oHiddenColumnInfo);
1374
+ // Ensure that cell hiding is reapplied whenever the inner table updates its rows.
1375
+ // This is needed because row controls may be recreated (e.g. when the SmartTable
1376
+ // rebuilds columns after setUiState or deactivateColumns), which causes previously
1377
+ // applied cell-level bindings to be lost.
1378
+ fnAttachRowsUpdateHandler(oSmartTable, oHiddenColumnInfo);
1379
+ }
1380
+
1381
+ /**
1382
+ * Applies cell-level visible bindings for all column keys in columnKeyToCellHiddenPath.
1383
+ */
1384
+ function fnApplyCellHiddenBindings(oSmartTable, oHiddenColumnInfo) {
1364
1385
  for (var sColumnKey in oHiddenColumnInfo.columnKeyToCellHiddenPath) {
1365
1386
  var sPath = oHiddenColumnInfo.columnKeyToCellHiddenPath[sColumnKey];
1366
1387
  fnHandleTableCellVisibility(oSmartTable, sColumnKey, sPath);
1367
1388
  }
1368
1389
  }
1369
1390
 
1391
+ /**
1392
+ * Attaches a one-time event handler to the inner table's row update event so that
1393
+ * cell-level hiding is reapplied when rows are recreated. The handler re-attaches
1394
+ * itself on every dataReceived to keep working across rebinds.
1395
+ */
1396
+ function fnAttachRowsUpdateHandler(oSmartTable, oHiddenColumnInfo) {
1397
+ var oTable = oSmartTable.getTable();
1398
+ var sSmartTableId = oSmartTable.getId();
1399
+ var sEventName = controlHelper.isUiTable(oTable) ? "rowsUpdated" : "updateFinished";
1400
+ // Detach any previously attached handler to avoid duplicates
1401
+ if (mCellHideRowsUpdateHandlers[sSmartTableId]) {
1402
+ oTable.detachEvent(sEventName, mCellHideRowsUpdateHandlers[sSmartTableId]);
1403
+ }
1404
+ mCellHideRowsUpdateHandlers[sSmartTableId] = function () {
1405
+ fnApplyCellHiddenBindings(oSmartTable, oHiddenColumnInfo);
1406
+ };
1407
+ oTable.attachEvent(sEventName, mCellHideRowsUpdateHandlers[sSmartTableId]);
1408
+ }
1409
+
1370
1410
  /**
1371
1411
  * This method is called for each Row of Table,to control the visibility of the Cell based on the Hidden property in LineItem.
1372
1412
  */
1373
1413
  function fnHandleTableCellVisibility(oSmartTable, sColumnKey, sPath) {
1374
1414
  var oSmartTableHandler = oServices.oPresentationControlHandlerFactory.getPresentationControlHandler(oSmartTable);
1375
1415
  var oTable = oSmartTable.getTable();
1376
- var aItems = oTable.getRows ? oTable.getRows() : oTable.getItems();
1416
+ var aItems = controlHelper.isUiTable(oTable) ? oTable.getRows() : oTable.getItems();
1377
1417
  var oColumn = oSmartTableHandler.getColumnByKey(sColumnKey);
1378
1418
  //if the column is visible in the table, then only we bind the visible property of the cell
1379
1419
  if (oColumn && oColumn.getVisible()){
1380
1420
  aItems.forEach(function(oItem) {
1381
1421
  var oCell = oItem.getCells()[oTable.indexOfColumn(oColumn)];
1382
- oCell && oCell.bindProperty("visible", {
1383
- path: sPath,
1384
- formatter: function (bIsHidden) {
1385
- return !bIsHidden;
1422
+ if (oCell) {
1423
+ // Only apply the binding if it is not already set with the correct path.
1424
+ // This avoids unnecessary teardown/recreation during scroll (rowsUpdated),
1425
+ // while still applying the binding to new cell instances created after a
1426
+ // column rebuild. If a different visible binding already exists (e.g. from
1427
+ // the application), we overwrite it with the cell-hiding binding.
1428
+ var oExistingBinding = oCell.getBindingInfo("visible");
1429
+ if (!oExistingBinding || oExistingBinding.parts[0].path !== sPath) {
1430
+ oCell.bindProperty("visible", {
1431
+ path: sPath,
1432
+ formatter: function (bIsHidden) {
1433
+ return !bIsHidden;
1434
+ }
1435
+ });
1386
1436
  }
1387
- });
1437
+ }
1388
1438
  });
1389
1439
  }
1390
1440
  }
1391
1441
 
1392
1442
  function fnAddMultiEditFieldGroupProperties(oEntityType, sAnnotationPath, aProperties) {
1393
1443
  if (!sAnnotationPath) { return; }
1394
-
1444
+
1395
1445
  // Remove leading '@' if present
1396
- var sPath = sAnnotationPath.charAt(0) === "@"
1397
- ? sAnnotationPath.substring(1)
1446
+ var sPath = sAnnotationPath.charAt(0) === "@"
1447
+ ? sAnnotationPath.substring(1)
1398
1448
  : sAnnotationPath;
1399
-
1449
+
1400
1450
  var oFieldGroup = oEntityType[sPath];
1401
-
1451
+
1402
1452
  if (oFieldGroup && oFieldGroup.Data && Array.isArray(oFieldGroup.Data)) {
1403
1453
  oFieldGroup.Data
1404
- .map(function(oField) {
1405
- return oField.Value && oField.Value.Path;
1454
+ .map(function(oField) {
1455
+ return oField.Value && oField.Value.Path;
1406
1456
  })
1407
1457
  .filter(Boolean)
1408
1458
  .forEach(function(sProp) {
@@ -1647,9 +1697,9 @@ sap.ui.define(["sap/ui/base/Object",
1647
1697
  }
1648
1698
  }
1649
1699
  }
1650
-
1700
+
1651
1701
  fnAddMultiEditFieldGroupProperties(oEntityType, oCallbacks.multiEditAnnotationPath, aProperties);
1652
-
1702
+
1653
1703
  }
1654
1704
  // sortOrder Annotation of presentation variant - only relevant for sap.m.Table
1655
1705
  var oVariant = oSmartTable.fetchVariant();
@@ -1707,7 +1757,10 @@ sap.ui.define(["sap/ui/base/Object",
1707
1757
  var bOpenInEditMode = !!oComponent.getEditFlow && oComponent.getEditFlow() === "direct";
1708
1758
  if (bOpenInEditMode){
1709
1759
  var sEntitySet = oTable.getEntitySet();
1710
- var oEditPromise = CRUDHelper.directEdit(oServices.oTransactionController, sEntitySet, oBindingContext.sPath, oBindingContext.getModel(), oServices.oApplication, oCommonUtils, oServices.oViewDependencyHelper, oViewProxy, bOpenInEditMode);
1760
+ // oBindingContext is passed directly; the OData model and binding path are resolved inside directEdit.
1761
+ // sAppId is derived here because oController is not accessible inside CRUDHelper.
1762
+ var sAppId = oComponent.getAppComponent().getId();
1763
+ var oEditPromise = CRUDHelper.directEdit(oServices.oTransactionController, sEntitySet, oBindingContext, oServices.oApplication, sAppId, oCommonUtils, oServices.oViewDependencyHelper, oViewProxy, bOpenInEditMode);
1711
1764
  oEditPromise.then(function(oResult){
1712
1765
  oCommonUtils.navigateFromListItem(oResult.context, bReplace, true);
1713
1766
  }, function(oError){
@@ -2719,7 +2772,7 @@ sap.ui.define(["sap/ui/base/Object",
2719
2772
 
2720
2773
  /**
2721
2774
  * Function modifies dataUrl, where we remove all 1:n properties from dataUrl.
2722
- *
2775
+ *
2723
2776
  * @param {*} oExportEvent - event handler for export.
2724
2777
  * @param {*} aNavRestriction - list of 1:n navigation properties
2725
2778
  */
@@ -2785,7 +2838,7 @@ sap.ui.define(["sap/ui/base/Object",
2785
2838
  if (oColumn.columnId && typeof oColumn.property === "string") {
2786
2839
  // checking for additional column.
2787
2840
  // in general, additional column don't have column Id.
2788
- var bHasAdditionalColumns = i < oExportEvent.mParameters.exportSettings.workbook.columns.length - 2 && !oExportEvent.mParameters.exportSettings.workbook.columns[i + 1].columnId;
2841
+ var bHasAdditionalColumns = i < oExportEvent.mParameters.exportSettings.workbook.columns.length - 1 && !oExportEvent.mParameters.exportSettings.workbook.columns[i + 1].columnId;
2789
2842
  if (bHasAdditionalColumns) {
2790
2843
  const sNavProperty = metadataAnalyser.checkFor1ToNProperty(oTable, sEntitySet, oColumn.property) || metadataAnalyser.checkFor1ToNProperty(oTable, sEntitySet, oExportEvent.mParameters.exportSettings.workbook.columns[i + 1].property);
2791
2844
  if (sNavProperty) {
@@ -2895,6 +2948,10 @@ sap.ui.define(["sap/ui/base/Object",
2895
2948
  var fnRenderTeamsContactCollabOptions = testableHelper.testable(fnRenderTeamsContactCollabOptions, "fnRenderTeamsContactCollabOptions");
2896
2949
  var removeUnsupportedColumnsToExport = testableHelper.testable(removeUnsupportedColumnsToExport, "removeUnsupportedColumnsToExport");
2897
2950
  var fnAddMultiEditFieldGroupProperties = testableHelper.testable(fnAddMultiEditFieldGroupProperties,"fnAddMultiEditFieldGroupProperties");
2951
+ var fnHideTableCells = testableHelper.testable(fnHideTableCells, "fnHideTableCells");
2952
+ var fnApplyCellHiddenBindings = testableHelper.testable(fnApplyCellHiddenBindings, "fnApplyCellHiddenBindings");
2953
+ var fnAttachRowsUpdateHandler = testableHelper.testable(fnAttachRowsUpdateHandler, "fnAttachRowsUpdateHandler");
2954
+ var fnHandleTableCellVisibility = testableHelper.testable(fnHandleTableCellVisibility, "fnHandleTableCellVisibility");
2898
2955
  /* eslint-enable */
2899
2956
 
2900
2957
  return {
@@ -2,6 +2,7 @@ sap.ui.define(["sap/ui/base/Object",
2
2
  "sap/ui/core/mvc/ControllerExtension",
3
3
  "sap/m/MessageBox",
4
4
  "sap/fe/navigation/SelectionVariant",
5
+ "sap/fe/navigation/library",
5
6
  "sap/suite/ui/generic/template/genericUtilities/controlHelper",
6
7
  "sap/suite/ui/generic/template/genericUtilities/metadataAnalyser",
7
8
  "sap/suite/ui/generic/template/genericUtilities/testableHelper",
@@ -22,6 +23,7 @@ sap.ui.define(["sap/ui/base/Object",
22
23
  ControllerExtension,
23
24
  MessageBox,
24
25
  SelectionVariant,
26
+ FENavLibrary,
25
27
  controlHelper,
26
28
  metadataAnalyser,
27
29
  testableHelper,
@@ -1018,6 +1020,7 @@ sap.ui.define(["sap/ui/base/Object",
1018
1020
  var oSelectionVariant, sSelectionVariantPrepared, sParameter, sSemanticObject, aSelVariantPropertyNames, aSelOptionPropertyNames, aParameterNames;
1019
1021
  var oEventParameters = oEvent.getParameters();
1020
1022
  var oNavigationHandler = oServices.oApplication.getNavigationHandler();
1023
+ var SuppressionBehavior = FENavLibrary.SuppressionBehavior;
1021
1024
  // fill oSelectionVariant with the selectOptions from sSelectionVariant
1022
1025
  oSelectionVariant = oNavigationHandler.mixAttributesAndSelectionVariant({}, sSelectionVariant);
1023
1026
  //Invoke the "beforeSmartLinkPopoverOpensExtension" method to determine whether FE can process the event.
@@ -1065,7 +1068,7 @@ sap.ui.define(["sap/ui/base/Object",
1065
1068
  }
1066
1069
  });
1067
1070
  // add the resulting selectOptions and parameters (if any!) in oSelectionVariant with the ones of the semanticObject in oEventParameters as selectOptions to oSelectionVariant
1068
- oSelectionVariant = oNavigationHandler.mixAttributesAndSelectionVariant(mSemanticAttributesOfEventSemanticObject, oSelectionVariant.toJSONString());
1071
+ oSelectionVariant = oNavigationHandler.mixAttributesAndSelectionVariant(mSemanticAttributesOfEventSemanticObject, oSelectionVariant.toJSONString(), SuppressionBehavior.ignoreEmptyString);
1069
1072
  // Remove sensitive data from the context
1070
1073
  oSelectionVariant = fnRemovePropertiesFromNavigationContext(oSelectionVariant, oEvent.getSource(), oState);
1071
1074
  var oObjectInfo = {
@@ -1,6 +1,7 @@
1
1
  sap.ui.define([
2
2
  "sap/ui/base/Object",
3
3
  "sap/ui/model/base/ManagedObjectModel",
4
+ "sap/ui/core/routing/History",
4
5
  "sap/suite/ui/generic/template/genericUtilities/controlHelper",
5
6
  "sap/suite/ui/generic/template/genericUtilities/FeLogger",
6
7
  "sap/suite/ui/generic/template/genericUtilities/oDataModelHelper",
@@ -15,6 +16,7 @@ sap.ui.define([
15
16
  ], function(
16
17
  BaseObject,
17
18
  ManagedObjectModel,
19
+ History,
18
20
  controlHelper,
19
21
  FeLogger,
20
22
  oDataModelHelper,
@@ -552,7 +554,14 @@ sap.ui.define([
552
554
  } else {
553
555
  var oElementBinding = oComponentContainer.getElementBinding();
554
556
  if (oElementBinding){
555
- if (sLogicalBindingPath === sBindingPath) {
557
+ // NEW: Force rebind on browser back for nested pages
558
+ var bIsBrowserBack = false;
559
+ if (History && History.getInstance() && !bIsComponentCurrentlyActive) {
560
+ var bIsNestedPage = oTreeNode.level > 1;
561
+ bIsBrowserBack = History.getInstance().getDirection() === "Backwards" && bIsNestedPage;
562
+ }
563
+
564
+ if (sLogicalBindingPath === sBindingPath && !bIsBrowserBack) {
556
565
  /*
557
566
  * component is already bound to this object - no rebound to avoid that 1:1, 1:N and expands are read
558
567
  * again
@@ -1098,20 +1107,21 @@ sap.ui.define([
1098
1107
  }
1099
1108
 
1100
1109
  function fnGetOutboundNavigationIntent(oInternalManifest, sOutbound) {
1101
- var oManifestOutbounds = oInternalManifest["sap.app"].crossNavigation && oInternalManifest["sap.app"].crossNavigation.outbounds;
1102
- return (oManifestOutbounds && oManifestOutbounds[sOutbound]) || Object.create(null);
1103
- }
1110
+ var oManifestOutbounds = oInternalManifest["sap.app"].crossNavigation && oInternalManifest["sap.app"].crossNavigation.outbounds;
1111
+ return (oManifestOutbounds && oManifestOutbounds[sOutbound]) || Object.create(null);
1112
+ }
1104
1113
 
1105
1114
  function fnCanNavigateToSubEntitySet(sEntitySet) {
1106
1115
  var aSubPages = oTreeNode.page.pages;
1116
+ var sCreationEntitySet = oTreeNode.page.component?.settings?.creationEntitySet;
1107
1117
  return !!(aSubPages && aSubPages.some(function (oSubPage) {
1108
- return sEntitySet === oSubPage.entitySet;
1118
+ return sEntitySet === oSubPage.entitySet || sCreationEntitySet === oSubPage.entitySet;
1109
1119
  }));
1110
1120
  }
1111
1121
 
1112
- function fnIsStateHandlingSuspended() {
1122
+ function fnIsStateHandlingSuspended() {
1113
1123
  return oComponentRegistryEntry.oTemplateContract.bStateHandlingSuspended;
1114
- }
1124
+ }
1115
1125
 
1116
1126
  function fnGetUI5VersionInfo() {
1117
1127
  var oTemplatePrivateGlobalModel = getTemplatePrivateGlobalModel();
@@ -3,63 +3,63 @@ sap.ui.define(["sap/suite/ui/generic/template/genericUtilities/FeError"],functio
3
3
 
4
4
  /* This class aims to provide the structure of all stable ids created by Fiori elements.
5
5
  * Currently still missing: Legacy ids not yet migrated.
6
- *
7
- * In Fiori elements apps, the controls created depend on the annotations and manifest settings. Therefore, stable ids given by Fiori elements cannot be just fixed strings in all cases, but must
8
- * be generated out of annotations and manifest settings. When these settings are changed, this can be considered as a change to the app, that might allow a change of the generated ids. However,
9
- * some changes should be considered as being compatible, e.g. adding a new section to the ObjectPage. In such a case, the ids of any controls not related to the change, e.g. controls on other
6
+ *
7
+ * In Fiori elements apps, the controls created depend on the annotations and manifest settings. Therefore, stable ids given by Fiori elements cannot be just fixed strings in all cases, but must
8
+ * be generated out of annotations and manifest settings. When these settings are changed, this can be considered as a change to the app, that might allow a change of the generated ids. However,
9
+ * some changes should be considered as being compatible, e.g. adding a new section to the ObjectPage. In such a case, the ids of any controls not related to the change, e.g. controls on other
10
10
  * sections, must not be changed.
11
11
  * To achieve this, all possible ids are classified as types and subtypes corresponding to Fiori elements features, using parameters for all input derived from annotations or manifest settings.
12
- *
12
+ *
13
13
  * Originally, the stable ids were created within the xml fragments, sometimes using different formatters (AnnotationHelpers). With the library growing more and more, this made it quite cumbersome
14
14
  * to understand which possible ids might be created (and in fact, several unwanted possibilities of clashes were introduced).
15
15
  * Therefore, the so-called stable id concept introduced a more generic approach to build stable ids. With this, all stable ids should be generated using the StableIdHelper method getStableId,
16
16
  * which in turn uses this class as definition for the rules how to create the ids.
17
- *
18
- * Of course, all ids used before must not be changed. Therefore, this class allows to describe how those ids were created. All these ids are referred to as legacy ids, while all newer ids are
17
+ *
18
+ * Of course, all ids used before must not be changed. Therefore, this class allows to describe how those ids were created. All these ids are referred to as legacy ids, while all newer ids are
19
19
  * referred to as standard ids.
20
20
  *
21
- *
21
+ *
22
22
  * The returned JSON object contains two properties:
23
23
  * 1. parameters: An array of all possible parameters. First character of the parameter describes the type - as in most cases (for standard always) they become directly part of the generated id,
24
24
  * most parameter names start with s. In case of new (standard) ids with multiple parameters the order here defines the order used in the generated id, therefore new parameters may only be
25
- * added to the end.
26
- * 2. types: JSON-object. Its properties define the types. New property names can be added (for new ids), but existing ones must not be changed.
25
+ * added to the end.
26
+ * 2. types: JSON-object. Its properties define the types. New property names can be added (for new ids), but existing ones must not be changed.
27
27
  * subTypes: JSON-object. The properties of the type object are the possible subTypes. The same rules as for types apply for subTypes. (subTyoes are only introduced to create better
28
- * structure. However, depth is fixed, i.e. each stable id belongs to one type and subType).
28
+ * structure. However, depth is fixed, i.e. each stable id belongs to one type and subType).
29
29
  * The subType object describes the actual definition of the stable id. It has the properties (all of them optional):
30
30
  * parameters: parameter names relevant (and mandatory) for this id. Only names defined in the parameters array are allowed.
31
31
  * optionalParameters: optional parameter names relevant for this id. Only names defined in the parameters array are allowed.
32
32
  * value: Only relevant for legacy ids!
33
- * Can be a string (in case of legacy ids without parameters) used as id or a function returning the stable id. In this case, the function is called with a json object as parameter,
34
- * with properties according to the parameters and optionalParameters defined.
35
- * The function may return undefined, in this case the id is created as standard id. (This may be used for legacy ids enhanced with optional parameters for new feature - e.g. multiple
36
- * views on ALP: Single view existed before the stable id concept, so ids for single table are legacy, but multiple views (with optional parameter sQuickVariantKey) was only
33
+ * Can be a string (in case of legacy ids without parameters) used as id or a function returning the stable id. In this case, the function is called with a json object as parameter,
34
+ * with properties according to the parameters and optionalParameters defined.
35
+ * The function may return undefined, in this case the id is created as standard id. (This may be used for legacy ids enhanced with optional parameters for new feature - e.g. multiple
36
+ * views on ALP: Single view existed before the stable id concept, so ids for single table are legacy, but multiple views (with optional parameter sQuickVariantKey) was only
37
37
  * introduced later, so new ids used here should be standard.)
38
38
  * If the function needs to indicate that no stable id could be generated (and it should also not be generated as standard id), it may throw an error. Currently, in this case the id
39
39
  * would be undefined, which would make UI5 generate an id which is not stable (and tools would know that it's not stable).
40
- *
40
+ *
41
41
  * Some ids are also used as parameters for other ids. This makes sense especially in case of nested collections (e.g. columns of tables on OP: To avoid clashes for tables in different section,
42
- * some information of the section must be part of the id for the table. Now, several tables could have columns for properties with same name (esp. for were common names - like "id") - to avoid
43
- * clashes here, we need to take the section information into account. But we don't want to think of this explicitly over and again, therefore we just take the id of the smart table as parameter
42
+ * some information of the section must be part of the id for the table. Now, several tables could have columns for properties with same name (esp. for were common names - like "id") - to avoid
43
+ * clashes here, we need to take the section information into account. But we don't want to think of this explicitly over and again, therefore we just take the id of the smart table as parameter
44
44
  * for the id of the column.
45
- * Parameters in ids currently using other ids [type/subType] as values:
45
+ * Parameters in ids currently using other ids [type/subType] as values:
46
46
  * - sSmartTableId: ListReportTable/SmartTable, ALPTable/SmartTable, ObjectPageTable/SmartTable, all also used directly
47
47
  * - sFacet: ObjectPage/HeaderFacet, ObjectPage/EditableHeaderFacet, ObjectPage/StandardFacet, ObjectPage/Facet, not used directly
48
- * - sDataField:
48
+ * - sDataField:
49
49
  * - ObjectPage/DataField: not used directly
50
- * - MultiEditDialog/DataField: currently no direct usage under investigation, if id for smartMultiEdit.Field becomes necessary, this id must be used there directly (see also comment in
51
- * MultiEditDialog.fragment)
50
+ * - MultiEditDialog/DataField: currently no direct usage under investigation, if id for smartMultiEdit.Field becomes necessary, this id must be used there directly (see also comment in
51
+ * MultiEditDialog.fragment)
52
52
  * - Remark: TableColumn/DataField in contrast is the (directly used) id of a table column build from a DataField
53
- *
53
+ *
54
54
  */
55
-
56
-
55
+
56
+
57
57
  // Ids for facets are constructed in a very special way, therefore the needed functions are separated here. Don't do the same for other ids!
58
58
  // Actually there are no controls using these ids directly as there id, but only as a part (i.e. as parameter sFacet)
59
-
60
- // getHeaderFacets provides the ids for facets pointed to from annotation UI.HeaderFacets
59
+
60
+ // getHeaderFacets provides the ids for facets pointed to from annotation UI.HeaderFacets
61
61
  // In header (i.e. in display mode), ids start always with header::headerEditable::
62
- // In edit mode, in the section to edit the header fields, ids start with headerEditable::
62
+ // In edit mode, in the section to edit the header fields, ids start with headerEditable::
63
63
  function getHeaderFacetId(oParams){
64
64
  if (oParams.sAnnotationId) {
65
65
  return "headerEditable::" + oParams.sAnnotationId;
@@ -70,17 +70,17 @@ sap.ui.define(["sap/suite/ui/generic/template/genericUtilities/FeError"],functio
70
70
  return "headerEditable::" + oParams.sAnnotationPath;
71
71
  }
72
72
  }
73
-
73
+
74
74
  function getStandardFacetId(oParams){
75
75
  if (oParams.sAnnotationId) {
76
76
  return oParams.sAnnotationId;
77
77
  }
78
78
  if (oParams.sRecordType !== "com.sap.vocabularies.UI.v1.ReferenceFacet") {
79
79
  throw new FeError();
80
- }
80
+ }
81
81
  return oParams.sAnnotationPath;
82
82
  }
83
-
83
+
84
84
  // getFacetId is only a wrapper for headerFacets (pointed to from annotation UI.HeaderFacets) and normal facets (pointed to from annotation UI.Facets)
85
85
  function getFacetId(oParams){
86
86
  return oParams.bIsHeaderFacet ? getHeaderFacetId(oParams) : getStandardFacetId(oParams);
@@ -279,7 +279,7 @@ sap.ui.define(["sap/suite/ui/generic/template/genericUtilities/FeError"],functio
279
279
  } else {
280
280
  if (oParams.sRecordType !== "com.sap.vocabularies.UI.v1.ReferenceFacet"){
281
281
  throw new FeError();
282
- }
282
+ }
283
283
  return "header::headerEditable::" + oParams.sAnnotationPath;
284
284
  }
285
285
  }
@@ -287,7 +287,7 @@ sap.ui.define(["sap/suite/ui/generic/template/genericUtilities/FeError"],functio
287
287
  EditableHeaderFacet: {
288
288
  parameters: ["sRecordType"],
289
289
  optionalParameters: ["sAnnotationPath", "sAnnotationId"],
290
- value: getHeaderFacetId
290
+ value: getHeaderFacetId
291
291
  },
292
292
  StandardFacet: {
293
293
  parameters: ["sRecordType"],
@@ -379,6 +379,7 @@ sap.ui.define(["sap/suite/ui/generic/template/genericUtilities/FeError"],functio
379
379
  value: "template::Share"
380
380
  },
381
381
  ActivateMenu: {},
382
+ ActivateAndBackMenu: {},
382
383
  ApplyMenu: {}
383
384
  },
384
385
  ObjectPageSection: {
@@ -608,7 +609,7 @@ sap.ui.define(["sap/suite/ui/generic/template/genericUtilities/FeError"],functio
608
609
  },
609
610
  ImplementingComponentContainerContent: {
610
611
  value: function(){ return "template::ImplementingComponentContent"; }
611
- }
612
+ }
612
613
  },
613
614
  Action: {
614
615
  Global: {
@@ -0,0 +1,185 @@
1
+ sap.ui.define([
2
+ "sap/suite/ui/generic/template/genericUtilities/FeLogger",
3
+ "sap/suite/ui/generic/template/genericUtilities/FeError"
4
+ ], function(FeLogger, FeError) {
5
+ "use strict";
6
+
7
+ var sClassName = "lib.ai.EasyFill.EasyFillAIOrchestrator";
8
+ var oLogger = new FeLogger(sClassName).getLogger();
9
+
10
+ /**
11
+ * EasyFillAIOrchestrator
12
+ *
13
+ * Responsible for:
14
+ * 1. Submitting user input text to the AI (LLM) service and returning parsed results.
15
+ * 2. Post-processing the AI response: date conversion, splitting simple vs. collection fields.
16
+ * 3. Building the complete field mapping payload (entity fields + collection fields) to send to the LLM.
17
+ *
18
+ * This module contains no UI logic — it only bridges the user input and AI service.
19
+ * All UI state updates after the AI call are handled by the caller (EasyFillHandler / EasyFillDialogController).
20
+ */
21
+ return {
22
+
23
+ /**
24
+ * Builds the complete LLM field mapping by combining main entity fields and collection (table) fields.
25
+ * Delegates to EasyFillFieldCollector for the actual metadata extraction.
26
+ *
27
+ * @param {object} oTemplateUtils - FE template utilities (used for entity type lookup)
28
+ * @param {object} oController - MVC controller instance
29
+ * @param {object} oObjectPage - the ObjectPage control
30
+ * @param {object} oObjectPageModel - the OData model of the ObjectPage
31
+ * @param {object} oObjectPageContext - current ObjectPage binding context
32
+ * @param {object} oFieldCollector - EasyFillFieldCollector instance
33
+ * @param {object} mCollectionState - mutable collection state object (passed into appendCollectionMap)
34
+ * @returns {object} mFieldMapping — flat map of all fields to send to the LLM
35
+ */
36
+ buildFieldMapping: function(oTemplateUtils, oController, oObjectPage, oObjectPageModel, oObjectPageContext, oFieldCollector, mCollectionState) {
37
+ var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(
38
+ oController.getOwnerComponent().getEntitySet()
39
+ );
40
+
41
+ /**
42
+ * Resolves the display label for an OData property.
43
+ * Prefers the Common.Label annotation, falls back to sap:label attribute.
44
+ *
45
+ * @param {object} oProperty - OData property metadata
46
+ * @returns {string} label string
47
+ */
48
+ var fnGetLabel = function(oProperty) {
49
+ if (oProperty["com.sap.vocabularies.Common.v1.Label"]) {
50
+ // Use the annotation helper to format the label expression
51
+ try {
52
+ var AnnotationHelperModel = sap.ui.require("sap/ui/model/odata/AnnotationHelper");
53
+ if (AnnotationHelperModel) {
54
+ return AnnotationHelperModel.format(oObjectPageContext, oProperty["com.sap.vocabularies.Common.v1.Label"]);
55
+ }
56
+ } catch (e) {
57
+ oLogger.warning("buildFieldMapping: could not format annotation label for " + oProperty.name);
58
+ }
59
+ }
60
+ return oProperty["sap:label"] || oProperty.name;
61
+ };
62
+
63
+ // Build entity set field map (simple fields)
64
+ var mFieldMapping = oFieldCollector.getEntitySetMap(oEntityType, oObjectPageContext, fnGetLabel);
65
+
66
+ // Append collection (SmartTable) fields and update collection state tracking maps
67
+ oFieldCollector.appendCollectionMap(
68
+ mFieldMapping,
69
+ oObjectPage,
70
+ oObjectPageModel,
71
+ oTemplateUtils,
72
+ mCollectionState,
73
+ fnGetLabel
74
+ );
75
+
76
+ return mFieldMapping;
77
+ },
78
+
79
+ /**
80
+ * Sends the user's free-text input to the AI service and returns the structured result.
81
+ * The AI service is accessed via oTemplateUtils.oServices.oFioriAIHandler.
82
+ *
83
+ * @param {string} sInputText - the user's free-text input from the EasyFill textarea
84
+ * @param {object} mFieldMapping - the complete field mapping built by buildFieldMapping()
85
+ * @param {object} oTemplateUtils - FE template utilities (used to access oFioriAIHandler)
86
+ * @returns {Promise<object>} AI service result: { success: boolean, data: object }
87
+ */
88
+ submitToAI: async function(sInputText, mFieldMapping, oTemplateUtils) {
89
+ oLogger.debug("submitToAI: sending input to AI service");
90
+ try {
91
+ var aiCallResult = await oTemplateUtils.oServices.oFioriAIHandler.fioriaiLib.EasyFill.extractFieldValuesFromText(
92
+ sInputText,
93
+ mFieldMapping
94
+ );
95
+ return aiCallResult;
96
+ } catch (e) {
97
+ oLogger.error("submitToAI: AI call failed: " + (e && e.message));
98
+ return { success: false, data: {} };
99
+ }
100
+ },
101
+
102
+ /**
103
+ * Converts date-like string values in the AI response to JavaScript Date objects,
104
+ * based on the OData data type declared in the field mapping.
105
+ * Handles Edm.DateTimeOffset and Edm.DateTime types.
106
+ *
107
+ * @param {object} aiCallResult - the raw AI service result ({ success, data })
108
+ * @param {object} mFieldMapping - the field mapping used during the AI call
109
+ */
110
+ formatDateValues: function(aiCallResult, mFieldMapping) {
111
+ if (!aiCallResult || !aiCallResult.success || !aiCallResult.data) {
112
+ return;
113
+ }
114
+ Object.keys(aiCallResult.data).forEach(function(sKey) {
115
+ var oFieldMeta = mFieldMapping[sKey];
116
+ if (!oFieldMeta) { return; }
117
+ var sDataType = oFieldMeta.dataType;
118
+ if (sDataType === "Edm.DateTimeOffset" || sDataType === "Edm.DateTime") {
119
+ var vValue = aiCallResult.data[sKey];
120
+ if (vValue && typeof vValue === "string") {
121
+ aiCallResult.data[sKey] = new Date(vValue);
122
+ oLogger.debug("formatDateValues: converted field '" + sKey + "' to Date");
123
+ }
124
+ }
125
+ });
126
+ },
127
+
128
+ /**
129
+ * Splits the flat AI response data into two buckets:
130
+ * - simpleFields: scalar field values for the main entity (SmartForm fields)
131
+ * - collectionFields: row-level updates for SmartTable collections
132
+ *
133
+ * Collection fields are identified by the isCollection flag in the field mapping.
134
+ * Currently only the first valid collection is processed (single-table limitation).
135
+ *
136
+ * @param {object} oAiData - the AI response data map { fieldName: value | rowArray }
137
+ * @param {object} mFieldMapping - the complete field mapping
138
+ * @param {object} oFieldCollector - EasyFillFieldCollector (used for SmartTable validation)
139
+ * @param {object} oObjectPage - the ObjectPage control (used for SmartTable validation)
140
+ * @returns {{ simpleFields: object, collectionFields: object }}
141
+ */
142
+ splitAIResultByCollection: function(oAiData, mFieldMapping, oFieldCollector, oObjectPage) {
143
+ var oSplitResult = {
144
+ simpleFields: {},
145
+ collectionFields: {}
146
+ };
147
+
148
+ Object.keys(oAiData || {}).forEach(function(sFieldName) {
149
+ var oFieldMeta = mFieldMapping[sFieldName];
150
+ var vFieldValue = oAiData[sFieldName];
151
+
152
+ // Determine if this field value is a collection (array of row updates)
153
+ var aCollectionRows = null;
154
+ if (Array.isArray(vFieldValue)) {
155
+ aCollectionRows = vFieldValue;
156
+ } else if (vFieldValue && Array.isArray(vFieldValue.rows)) {
157
+ aCollectionRows = vFieldValue.rows;
158
+ }
159
+
160
+ if (oFieldMeta && oFieldMeta.isCollection === true && aCollectionRows) {
161
+ // Validate that each row update has at least a context path or row index for binding
162
+ var aRowUpdates = aCollectionRows.filter(function(oRow) {
163
+ return oRow && typeof oRow === "object" &&
164
+ (typeof oRow._contextPath === "string" || typeof oRow._rowIndex === "number");
165
+ });
166
+
167
+ // Single-table limitation: only the first valid collection is accepted.
168
+ // Future work: extend collectionFields structure to support multiple tables.
169
+ var oValidation = oFieldCollector.isValidSmartTable(oFieldMeta.entitySet, oObjectPage);
170
+ if (aRowUpdates.length > 0 &&
171
+ Object.keys(oSplitResult.collectionFields).length === 0 &&
172
+ oValidation.isValid) {
173
+ oSplitResult.collectionFields[sFieldName] = aRowUpdates;
174
+ oLogger.debug("splitAIResultByCollection: accepted collection field '" + sFieldName + "' with " + aRowUpdates.length + " rows");
175
+ }
176
+ } else {
177
+ // Scalar field → goes to simpleFields
178
+ oSplitResult.simpleFields[sFieldName] = vFieldValue;
179
+ }
180
+ });
181
+
182
+ return oSplitResult;
183
+ }
184
+ };
185
+ });