@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
@@ -6,8 +6,9 @@ sap.ui.define([
6
6
  "sap/ui/model/FilterOperator",
7
7
  'sap/ui/model/Filter',
8
8
  'sap/suite/ui/generic/template/js/AnnotationHelper',
9
- "./EasyFilterDataFetcherHelper"
10
- ], function(BaseObject, extend, filterHelper, FeLogger, FilterOperator,Filter,AnnotationHelper,EasyFilterDataFetcherHelper) {
9
+ "./EasyFilterDataFetcherHelper",
10
+ "sap/suite/ui/generic/template/genericUtilities/controlHelper"
11
+ ], function(BaseObject, extend, filterHelper, FeLogger, FilterOperator,Filter,AnnotationHelper,EasyFilterDataFetcherHelper,controlHelper) {
11
12
  'use strict';
12
13
 
13
14
  /*
@@ -25,7 +26,34 @@ sap.ui.define([
25
26
  // used for busyHandling between query triggered and query resolved.
26
27
  var oQueryPromise, oQueryPromiseResolve;
27
28
  var fnValueHelpPromiseResolve;
29
+ // Guard flag to distinguish EasyFilter-initiated state changes from user-initiated ones
30
+ var bApplyingSorting = false;
31
+
32
+ var bApplyingGrouplevels = false;
33
+
28
34
  // fnValueHelpPromiseReject;
35
+ // Tracks the filterMode that was saved in the most recently loaded variant.
36
+ // Used in onFilterSwitch to compare against the current toggle state without
37
+ // relying on getCustomFilterData() which can be overwritten by intermediate
38
+ // beforeVariantFetch calls during the async Go press flow.
39
+ var sLoadedVariantFilterMode = "classic";
40
+ // Set to true when the user manually deletes or modifies a token, reset to false on
41
+ // variant load or Go press result. Used to suppress fnApplyEasyFilterVariantState from
42
+ // overwriting the stale-query (placeholder) state that fnTokensChanged put in place.
43
+ var bTokensModifiedByUser = false;
44
+
45
+ /**
46
+ * Calls setVariantCreationByUserAllowed(bAllowed) on the SmartVariantManagement control
47
+ * that owns the SmartFilterBar. Disabling creation blocks both Save and Save As in the VM
48
+ * popup. Re-enabling restores the default behaviour.
49
+ * @param {boolean} bAllowed
50
+ */
51
+ function fnSetCreationAllowed(bAllowed) {
52
+ var oSmartVariant = oState.oSmartFilterbar.getSmartVariant();
53
+ if (oSmartVariant) {
54
+ oSmartVariant.setVariantCreationByUserAllowed(bAllowed);
55
+ }
56
+ }
29
57
 
30
58
  /**
31
59
  * This method prepares the metadata calculation after the smart filter bar is initialized
@@ -59,8 +87,25 @@ sap.ui.define([
59
87
  var mFilterProperties = {}; // Now also includes 1:1 navigation properties
60
88
  var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(sEntitySet);
61
89
 
62
- // Helper to add properties to mFilterProperties, with optional prefix
63
- function addPropertiesFromEntityType(entityType, prefix) {
90
+ // Collect non-sortable properties from SortRestrictions annotation
91
+ var oEntitySetMeta = oSFBMetaModel?.getODataEntitySet && oSFBMetaModel?.getODataEntitySet(sEntitySet);
92
+ var oSortRestrictions = oEntitySetMeta && oEntitySetMeta["Org.OData.Capabilities.V1.SortRestrictions"];
93
+ var bEntitySetSortable = !oSortRestrictions || oSortRestrictions.Sortable !== "false";
94
+ var mNonSortableProperties = {};
95
+ if (oSortRestrictions && oSortRestrictions.NonSortableProperties) {
96
+ oSortRestrictions.NonSortableProperties.forEach(function(oProperty) {
97
+ if (oProperty.PropertyPath) {
98
+ mNonSortableProperties[oProperty.PropertyPath] = true;
99
+ }
100
+ });
101
+ }
102
+
103
+ // Helper to add properties to mFilterProperties, with optional prefix.
104
+ // bOverrideSortable and mOverrideNonSortable allow callers (e.g. nav property processing)
105
+ // to pass entity-set-specific sort restrictions instead of the root entity set's.
106
+ function addPropertiesFromEntityType(entityType, prefix, bOverrideSortable, mOverrideNonSortable) {
107
+ var bEffectiveSortable = (bOverrideSortable !== undefined) ? bOverrideSortable : bEntitySetSortable;
108
+ var mEffectiveNonSortable = mOverrideNonSortable || mNonSortableProperties;
64
109
  entityType.property.forEach(function (oProperty) {
65
110
  var sTokenType = "ValueHelp";
66
111
  if (filterHelper.isPropertyFilterable(oProperty)) {
@@ -90,12 +135,18 @@ sap.ui.define([
90
135
  sTokenType = "Time";
91
136
  }
92
137
  var propName = prefix ? prefix + "." + oProperty.name : oProperty.name;
138
+ // Determine sortability: property is sortable unless entity set is not sortable,
139
+ // property is in NonSortableProperties, or property has sap:sortable="false"
140
+ var bSortable = bEffectiveSortable && !mEffectiveNonSortable[oProperty.name] && oProperty["sap:sortable"] !== "false";
141
+ // Groupable follows the same logic as sortable: a property is groupable if it is sortable
142
+ var bGroupable = bSortable;
93
143
  mFilterProperties[propName] = {
94
144
  name: propName,
95
145
  dataType: oProperty.type,
96
146
  defaultValue : [],
97
147
  filterable: true,
98
- sortable: false,
148
+ sortable: bSortable,
149
+ groupable: bGroupable,
99
150
  codeList : bIsCodeListRequired,
100
151
  type: sTokenType,
101
152
  unit: oProperty["sap:unit"] || "",
@@ -137,7 +188,26 @@ sap.ui.define([
137
188
  //var sShortType = sTargetType.split(".").pop();
138
189
  var oTargetEntityType = oSFBMetaModel.getODataEntityType && oSFBMetaModel.getODataEntityType(sTargetType);
139
190
  if (oTargetEntityType) {
140
- addPropertiesFromEntityType(oTargetEntityType, navProp.name);
191
+ // Resolve SortRestrictions for the navigation target entity set,
192
+ // mirroring the same check EasyFilterBar.tsx (V4) does for nav property bindings.
193
+ var bNavSortable = bEntitySetSortable;
194
+ var mNavNonSortable = {};
195
+ var oAssocSetEnd = oSFBMetaModel.getODataAssociationSetEnd && oSFBMetaModel.getODataAssociationSetEnd(oEntityType, navProp.name);
196
+ var oNavEntitySetMeta = oAssocSetEnd && oAssocSetEnd.entitySet && oSFBMetaModel.getODataEntitySet(oAssocSetEnd.entitySet);
197
+ if (oNavEntitySetMeta) {
198
+ var oNavSortRestrictions = oNavEntitySetMeta["Org.OData.Capabilities.V1.SortRestrictions"];
199
+ if (oNavSortRestrictions) {
200
+ bNavSortable = oNavSortRestrictions.Sortable !== "false";
201
+ if (oNavSortRestrictions.NonSortableProperties) {
202
+ oNavSortRestrictions.NonSortableProperties.forEach(function(oProperty) {
203
+ if (oProperty.PropertyPath) {
204
+ mNavNonSortable[oProperty.PropertyPath] = true;
205
+ }
206
+ });
207
+ }
208
+ }
209
+ }
210
+ addPropertiesFromEntityType(oTargetEntityType, navProp.name, bNavSortable, mNavNonSortable);
141
211
  }
142
212
  }
143
213
  }
@@ -434,6 +504,43 @@ sap.ui.define([
434
504
  return oController.byId("template::easyFilterContainer");
435
505
  }
436
506
 
507
+ /**
508
+ * Applies EasyFilter variant state: sets the filterMode and, if easyFilter mode,
509
+ * restores the query string and triggers AI resolution to rebuild the token display.
510
+ * The SFB selectOptions are already restored by the variant mechanism — this only
511
+ * restores the visual state of the EasyFilter bar.
512
+ * @param {object} oVariantState - { filterMode: string, easyFilter: { query: string } }
513
+ */
514
+ function fnApplyEasyFilterVariantState(oVariantState) {
515
+ if (!oVariantState || !oVariantState.filterMode) {
516
+ return;
517
+ }
518
+ var oTempModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
519
+ var oSmartFilterbar = oState.oSmartFilterbar;
520
+
521
+ oTempModel.setProperty("/listReport/filterMode", oVariantState.filterMode);
522
+
523
+ if (oVariantState.filterMode === "easyFilter") {
524
+ oSmartFilterbar.setVisible(false);
525
+ var sQuery = oVariantState.easyFilter && oVariantState.easyFilter.query;
526
+ if (sQuery) {
527
+ // Tokens have been manually changed — the query in the input is intentionally
528
+ // stale (shown as placeholder). Do not overwrite it with the saved query.
529
+ if (!bTokensModifiedByUser) {
530
+ var oEasyFilterBar = fnGetEasyFilterBar();
531
+ if (oEasyFilterBar) {
532
+ var sCurrentQuery = oEasyFilterBar.getQuery();
533
+ if (!sCurrentQuery || sCurrentQuery === sQuery) {
534
+ oEasyFilterBar.setQuery(sQuery);
535
+ }
536
+ }
537
+ }
538
+ }
539
+ } else {
540
+ oSmartFilterbar.setVisible(true);
541
+ }
542
+ }
543
+
437
544
  /**
438
545
  * This method is used to initialise the EasyFilter control with the metadata from the smart filter bar
439
546
  */
@@ -446,6 +553,46 @@ sap.ui.define([
446
553
  oEasyFilter.setAppId(oController.getOwnerComponent().getAppComponent().getManifestEntry("sap.app").id);
447
554
  oEasyFilter.setFilterBarMetadata(oEasyFilterMetadata.fields);
448
555
  oEasyFilter.easyfilter = oTemplateUtils.oServices.oFioriAIHandler.fioriaiLib.EasyFilter;
556
+
557
+ // Register callbacks on SmartFilterBarWrapper so filterMode and query are
558
+ // included in the genericData bucket when a variant is saved or loaded.
559
+ var sSmartFilterBarId = oState.oSmartFilterbar.getId();
560
+ var oSmartFilterBarWrapper = oTemplateUtils.oCommonUtils.getControlStateWrapperById(sSmartFilterBarId, "SmartFilterBar");
561
+ oSmartFilterBarWrapper.setEasyFilterCallbacks({
562
+ getState: function() {
563
+ var oTMModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
564
+ var oEFBar = fnGetEasyFilterBar();
565
+ return {
566
+ filterMode: oTMModel.getProperty("/listReport/filterMode"),
567
+ easyFilter: {
568
+ query: oEFBar ? oEFBar.getQuery() : undefined
569
+ }
570
+ };
571
+ },
572
+ setState: fnApplyEasyFilterVariantState
573
+ });
574
+
575
+ // Handle INIT timing gap: the "INIT" afterVariantLoad fires before this handler
576
+ // is created. Read whatever the variant already loaded into customFilterData now.
577
+ var oCustomData = oState.oSmartFilterbar.getCustomFilterData();
578
+ var oGenericData = oCustomData && oCustomData["sap.suite.ui.generic.template.genericData"];
579
+ if (oGenericData && oGenericData.filterMode) {
580
+ sLoadedVariantFilterMode = oGenericData.filterMode;
581
+ fnApplyEasyFilterVariantState({
582
+ filterMode: oGenericData.filterMode,
583
+ easyFilter: oGenericData.easyFilter
584
+ });
585
+ // If the default variant has AutoApply checked, trigger Go now.
586
+ // The SFB would have called search() itself (IappStateHandler line ~773),
587
+ // but EasyFilter is hidden so we need onGoPress instead.
588
+ // areDataShownInTable() being true at this point is the same signal
589
+ // the SFB uses to decide whether to auto-search on startup.
590
+ if (oGenericData.filterMode === "easyFilter" &&
591
+ oGenericData.easyFilter && oGenericData.easyFilter.query &&
592
+ oState.oIappStateHandler.areDataShownInTable()) {
593
+ oEasyFilter.onGoPress(oGenericData.easyFilter.query);
594
+ }
595
+ }
449
596
  });
450
597
  }
451
598
 
@@ -470,10 +617,24 @@ sap.ui.define([
470
617
  function fnTokensChanged(oEvent) {
471
618
  //When reset button is clicked no batch call should be triggered
472
619
  if (oEvent.getParameter("reset")) {
620
+ fnSetCreationAllowed(true);
473
621
  return;
474
622
  }
475
623
  var oSmartFilterbar = oState.oSmartFilterbar;
476
624
  var oFiltersFromAI = oEvent.getParameter("tokens");
625
+
626
+ // tokensChanged fires for both AI-resolved tokens (Go press result) and user
627
+ // manual token edits. tokensChangedByUser fires first on a user edit and sets
628
+ // bTokensModifiedByUser — use that to tell the two cases apart.
629
+ if (bTokensModifiedByUser) {
630
+ // User manually edited a token — tokensChangedByUser already disabled
631
+ // Save/SaveAs. Mark the variant dirty and stop; do not trigger search.
632
+ oSmartFilterbar.getSmartVariant() && oSmartFilterbar.getSmartVariant().currentVariantSetModified(true);
633
+ return;
634
+ }
635
+ // AI-resolved result path: reset the user-edit flag and re-enable Save/SaveAs.
636
+ bTokensModifiedByUser = false;
637
+ fnSetCreationAllowed(true);
477
638
  var sSmartFilterBarId = oSmartFilterbar.getId();
478
639
  var oSmartFilterBarWrapper = oTemplateUtils.oCommonUtils.getControlStateWrapperById(sSmartFilterBarId, "SmartFilterBar");
479
640
  var oSmartFilterBarVariant = oSmartFilterBarWrapper.getState();
@@ -505,24 +666,145 @@ sap.ui.define([
505
666
  // If matching property found and has ranges
506
667
  if (matchingSelectOption?.Ranges?.length > 0) {
507
668
  var { Low: value1 = null, High: value2 = null } = matchingSelectOption.Ranges[0];
508
- // Update the semantic date data in the smart filter bar
669
+ // Update the semantic date data in the smart filter bar
509
670
  var dateData = semanticDate.Data;
510
671
  dateData.operation = "DATERANGE";
511
672
  dateData.value1 = value1;
512
673
  dateData.value2 = value2 || value1; // Use value1 if value2 is null/empty
513
- }
674
+ }
514
675
  });
515
676
  }
516
677
 
517
678
  oSmartFilterBarWrapper.setState(oSmartFilterBarVariant);
518
- oSmartFilterbar.getSmartVariant() && oSmartFilterbar.getSmartVariant().currentVariantSetModified(true);
679
+ // currentVariantSetModified intentionally omitted — pressing Go with the same
680
+ // query must not mark the variant as dirty.
681
+ // oSmartFilterbar.getSmartVariant() && oSmartFilterbar.getSmartVariant().currentVariantSetModified(true);
519
682
  oSmartFilterbar.search();
520
683
  }
684
+
685
+ /**
686
+ * Event handler for the EasyFilterBarContainer's tokensChangedByUser event.
687
+ * Fired when the user manually deletes or modifies a token (distinct from AI-resolved tokens).
688
+ * Disables Save/SaveAs in the variant management popup until a fresh Go press resolves new tokens.
689
+ */
690
+ function fnTokensChangedByUser() {
691
+ bTokensModifiedByUser = true;
692
+ fnSetCreationAllowed(false);
693
+ }
694
+
695
+ /**
696
+ /**
697
+ * Event handler for the EasyFilter control's sortersChanged event.
698
+ * Applies the AI-determined sort order to the SmartTable via setUiState,
699
+ * which updates the data binding, column sort indicators, and P13n state
700
+ * through the PersonalizationController.
701
+ * @param {sap.ui.base.Event} oEvent The sortersChanged event containing sort definitions
702
+ */
703
+ function fnSortersChanged(oEvent) {
704
+ try {
705
+ var aSorters = oEvent.getParameter("sorters");
706
+
707
+ var oPresentationControlHandler = oState.oPresentationControlHandler;
708
+ if (!oPresentationControlHandler) {
709
+ oLogger.error("EasyFilterBarHandler.onSortersChanged: PresentationControlHandler not found.");
710
+ return;
711
+ }
712
+
713
+ var oControl = oPresentationControlHandler.getControl();
714
+ if (!oControl) {
715
+ oLogger.error("EasyFilterBarHandler.onSortersChanged: Presentation control not found.");
716
+ return;
717
+ }
718
+
719
+ if (!controlHelper.isSmartTable(oControl)) {
720
+ oLogger.warning("EasyFilterBarHandler.onSortersChanged: Sorting is only supported for SmartTable.");
721
+ return;
722
+ }
723
+
724
+ var oUiState = oControl.getUiState();
725
+ var oPresentationVariant = oUiState.getPresentationVariant();
726
+
727
+ oPresentationVariant.SortOrder = undefined; // Clear existing sort order before applying new one
728
+
729
+ // Set new sort order (empty array clears sorting)
730
+ if (aSorters?.length) {
731
+ const aSortersMapped = aSorters.map(function(oSorter) {
732
+ return {
733
+ Property: oSorter.key,
734
+ Descending: !!oSorter.descending
735
+ };
736
+ });
737
+ oPresentationVariant.SortOrder = aSortersMapped;
738
+ bApplyingSorting = true;
739
+ try {
740
+ oUiState.setPresentationVariant(oPresentationVariant);
741
+ oControl.setUiState(oUiState);
742
+ } finally {
743
+ bApplyingSorting = false;
744
+ }
745
+ }
746
+
747
+ } catch (error) {
748
+ bApplyingSorting = false;
749
+ oLogger.warning("EasyFilterBar: unexpected error while handling sortersChanged", String(error));
750
+ }
751
+ }
752
+
753
+ /**
754
+ * Event handler for the EasyFilter control's groupLevelsChanged event.
755
+ * Applies the AI-determined group levels to the SmartTable via setUiState,
756
+ * which updates the data binding and table grouping state
757
+ * through the PersonalizationController.
758
+ * @param {sap.ui.base.Event} oEvent The groupLevelsChanged event containing group level definitions
759
+ */
760
+ function fnGroupLevelsChanged(oEvent) {
761
+ try {
762
+ var aGroupLevels = oEvent.getParameter("groupLevels");
763
+
764
+ var oPresentationControlHandler = oState.oPresentationControlHandler;
765
+ if (!oPresentationControlHandler) {
766
+ oLogger.error("EasyFilterBarHandler.onGroupLevelsChanged: PresentationControlHandler not found.");
767
+ return;
768
+ }
769
+
770
+ var oControl = oPresentationControlHandler.getControl();
771
+ if (!oControl) {
772
+ oLogger.error("EasyFilterBarHandler.onGroupLevelsChanged: Presentation control not found.");
773
+ return;
774
+ }
775
+
776
+ if (!controlHelper.isSmartTable(oControl)) {
777
+ oLogger.warning("EasyFilterBarHandler.onGroupLevelsChanged: Grouping is only supported for SmartTable.");
778
+ return;
779
+ }
780
+
781
+ var oUiState = oControl.getUiState();
782
+ var oPresentationVariant = oUiState.getPresentationVariant();
783
+
784
+ oPresentationVariant.GroupBy = undefined; // Clear existing group levels before applying new ones
785
+
786
+ // SmartTable supports grouping by only one column at a time,
787
+ // so we take only the first group level even if multiple are provided.
788
+ oPresentationVariant.GroupBy = (aGroupLevels && aGroupLevels.length) ?
789
+ aGroupLevels?.flatMap(aGroup => Object.values(aGroup)) : undefined;
790
+
791
+ bApplyingGrouplevels = true;
792
+ try {
793
+ oControl.setUiState(oUiState);
794
+ } finally {
795
+ bApplyingGrouplevels = false;
796
+ }
797
+ } catch (error) {
798
+ bApplyingGrouplevels = false;
799
+ oLogger.warning("EasyFilterBar: unexpected error while handling groupLevelsChanged", String(error));
800
+ }
801
+ }
802
+
521
803
  /**
522
804
  * Event handler for the EasyFilter control's showValueHelp event.
523
805
  * Identifies the input field for which the value help is requested and triggers the value help opening from SFB.
524
- * @param {*} oEvent
525
- * @param {*} oState
806
+ * @param {*} oEvent
807
+ * @param {*} oState
526
808
  */
527
809
  function fnShowValueHelp(oEvent) {
528
810
  var oSmartFilterbar = oState.oSmartFilterbar;
@@ -540,6 +822,8 @@ sap.ui.define([
540
822
  function fnQueryChanged() {
541
823
  var oSmartFilterbar = oState.oSmartFilterbar;
542
824
  oSmartFilterbar.fireFilterChange();
825
+ // Query string is now part of variant state — mark dirty so user is prompted to save
826
+ oSmartFilterbar.getSmartVariant() && oSmartFilterbar.getSmartVariant().currentVariantSetModified(true);
543
827
  }
544
828
  // function fnUpdateEasyFilterBarTokens() {
545
829
  // // todo : update the easy filter bar tokens with new values from the SFB VHD
@@ -602,18 +886,70 @@ sap.ui.define([
602
886
  }
603
887
 
604
888
  /**
605
- *
606
- * This method is called when the variant is loaded in SFB
607
- * Always set the filterMode to classic when the variant is loaded as the variant filters are not supported in the EasyFilter
608
- * */
889
+ * Called when a variant is loaded in SFB.
890
+ * Restores filterMode and EasyFilter query from the variant's genericData.
891
+ * Only reacts to user-initiated variant switches (context === undefined/null).
892
+ * INIT is handled separately in fnInitialiseEasyFilterBar by reading getCustomFilterData().
893
+ * Other contexts (CANCEL, RESET, SET_VM_ID, DATA_SUITE, KEY_USER) leave filterMode unchanged.
894
+ * @param {object} oEvent - The variant load event
895
+ */
609
896
  function fnHandleVariantLoad(oEvent) {
897
+ var sContext = oEvent.getParameter("context");
898
+
899
+ // Only handle user-initiated variant switch (context is undefined/null)
900
+ if (sContext) {
901
+ return;
902
+ }
903
+
904
+ // A variant switch always resets the "tokens modified" disable state —
905
+ // the incoming variant represents a fresh, valid saved state.
906
+ bTokensModifiedByUser = false;
907
+ fnSetCreationAllowed(true);
908
+
610
909
  var oTempModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
611
- // 'context' is undefined or null when the user switches variant , in this case switch to classic mode
612
- // other values are "CANCEL" , "RESET" , "SET_VM_ID" , "DATA_SUITE" , "INIT" , "KEY_USER" etc : Do not switch filter mode in these cases
613
- if (!oEvent.getParameter("context") && oTempModel.getProperty("/listReport/filterMode") !== "classic") {
614
- var oSmartFilterbar = oState.oSmartFilterbar;
615
- oTempModel.setProperty("/listReport/filterMode", "classic");
616
- oSmartFilterbar.setVisible(true);
910
+ var oCustomData = oState.oSmartFilterbar.getCustomFilterData();
911
+ var oGenericData = oCustomData && oCustomData["sap.suite.ui.generic.template.genericData"];
912
+
913
+ var oEasyFilterBar = fnGetEasyFilterBar();
914
+ if (oGenericData && oGenericData.filterMode === "easyFilter") {
915
+ // Genuine user-initiated variant switch — restore the saved query
916
+ // unconditionally (no getQuery guard needed here, unlike the
917
+ // afterVariantLoad path which fires spuriously from setUiState calls).
918
+ sLoadedVariantFilterMode = "easyFilter";
919
+ oTempModel.setProperty("/listReport/filterMode", "easyFilter");
920
+ oState.oSmartFilterbar.setVisible(false);
921
+ var sQuery = oGenericData.easyFilter && oGenericData.easyFilter.query;
922
+ if (oEasyFilterBar) {
923
+ if (sQuery) {
924
+ oEasyFilterBar.setQuery(sQuery);
925
+ // Only auto-trigger Go if "Apply Automatically" is checked on the variant.
926
+ // If not checked, only the search string is restored — no search triggered.
927
+ var bExecuteOnSelect = oEvent.getParameter("executeOnSelect");
928
+ if (bExecuteOnSelect) {
929
+ oEasyFilterBar.onGoPress(sQuery);
930
+ }
931
+ } else {
932
+ oEasyFilterBar.resetState(false);
933
+ }
934
+ }
935
+ } else if (oGenericData && oGenericData.filterMode) {
936
+ sLoadedVariantFilterMode = oGenericData.filterMode;
937
+ fnApplyEasyFilterVariantState({
938
+ filterMode: oGenericData.filterMode,
939
+ easyFilter: oGenericData.easyFilter
940
+ });
941
+ } else {
942
+ // Variant has no EasyFilter state → implicitly classic
943
+ sLoadedVariantFilterMode = "classic";
944
+ if (oTempModel.getProperty("/listReport/filterMode") !== "classic") {
945
+ oTempModel.setProperty("/listReport/filterMode", "classic");
946
+ oState.oSmartFilterbar.setVisible(true);
947
+ }
948
+ // Clear the EasyFilter input and tokens so the old query is not shown
949
+ // when the user switches back to a classic variant.
950
+ if (oEasyFilterBar) {
951
+ oEasyFilterBar.resetState(false);
952
+ }
617
953
  }
618
954
  }
619
955
 
@@ -621,6 +957,51 @@ sap.ui.define([
621
957
  return EasyFilterDataFetcherHelper.fetchDataForKey(key, keySpecificSelectedResult, oState, oController, oTemplateUtils);
622
958
  }
623
959
 
960
+ /**
961
+ * Handles SmartTable uiStateChange events to detect user-initiated sort/group changes.
962
+ * When the user changes sort/group via column menu or P13n dialog (not triggered by EasyFilter),
963
+ * notifies the EasyFilterBarContainer so it can mark the filter input as dirty.
964
+ */
965
+ function fnOnSmartTableUiStateChange() {
966
+ if (bApplyingSorting || bApplyingGrouplevels) {
967
+ return;
968
+ }
969
+ var oEasyFilter = fnGetEasyFilterBar();
970
+ if (oEasyFilter && typeof oEasyFilter.notifyExternalTableStateChange === "function") {
971
+ oEasyFilter.notifyExternalTableStateChange();
972
+ }
973
+ }
974
+
975
+ /**
976
+ * Attaches the uiStateChange handler to the SmartTable to track external sort/group changes.
977
+ * Should be called after SmartTable is initialized.
978
+ */
979
+ function fnAttachSmartTableStateChangeHandler() {
980
+ var oPresentationControlHandler = oState.oPresentationControlHandler;
981
+ if (!oPresentationControlHandler) {
982
+ return;
983
+ }
984
+ var oSmartTable = oPresentationControlHandler.getControl();
985
+ if (oSmartTable && typeof oSmartTable.attachUiStateChange === "function") {
986
+ oSmartTable.attachUiStateChange(fnOnSmartTableUiStateChange);
987
+ }
988
+ }
989
+
990
+ /**
991
+ * Detaches the uiStateChange handler from the SmartTable.
992
+ * Should be called on cleanup/destroy.
993
+ */
994
+ function fnDetachSmartTableStateChangeHandler() {
995
+ var oPresentationControlHandler = oState.oPresentationControlHandler;
996
+ if (!oPresentationControlHandler) {
997
+ return;
998
+ }
999
+ var oSmartTable = oPresentationControlHandler.getControl();
1000
+ if (oSmartTable && typeof oSmartTable.detachUiStateChange === "function") {
1001
+ oSmartTable.detachUiStateChange(fnOnSmartTableUiStateChange);
1002
+ }
1003
+ }
1004
+
624
1005
  return {
625
1006
  getEasyFilterBar : fnGetEasyFilterBar,
626
1007
  initialiseEasyFilterBar : fnInitialiseEasyFilterBar,
@@ -631,10 +1012,16 @@ sap.ui.define([
631
1012
  onBeforeQueryProcessing: fnBeforeQueryProcessing,
632
1013
  onQueryChanged : fnQueryChanged,
633
1014
  onTokensChanged: fnTokensChanged,
1015
+ onTokensChangedByUser: fnTokensChangedByUser,
1016
+ onSortersChanged: fnSortersChanged,
1017
+ onGroupLevelsChanged: fnGroupLevelsChanged,
634
1018
  onShowValueHelp: fnShowValueHelp,
635
1019
  onFilterChange : fnOnFilterChange,
636
1020
  handleVariantLoad : fnHandleVariantLoad,
637
- onDataFetcher
1021
+ onDataFetcher,
1022
+ getLoadedVariantFilterMode: function() { return sLoadedVariantFilterMode; },
1023
+ attachSmartTableStateChangeHandler: fnAttachSmartTableStateChangeHandler,
1024
+ detachSmartTableStateChangeHandler: fnDetachSmartTableStateChangeHandler
638
1025
  };
639
1026
  }
640
1027
 
@@ -764,13 +764,13 @@ RTA_CONTEXT_MENU_CONFIG=Configuration
764
764
  EASY_FILL_TITLE = Easy Fill
765
765
 
766
766
  # XTXT: EasyFill Description 1
767
- EASY_FILL_FIRST_LABEL_TEXT = You can use the Easy Fill feature to fill multiple fields simultaneously.
767
+ EASY_FILL_FIRST_LABEL_TEXT = You can use the Easy Fill feature to fill multiple fields simultaneously using natural language.
768
768
 
769
769
  # XTXT: EasyFill Description 1
770
- EASY_FILL_SECOND_LABEL_TEXT = Use data sources like spreadsheets, notes, and emails to populate the fields, or clearly describe the information you want to fill in. Then click Easy Fill.
770
+ EASY_FILL_SECOND_LABEL_TEXT = Provide any information that helps AI fill the appropriate fields. You can also upload a file containing the relevant information.
771
771
 
772
772
  # XTXT: EasyFill TextArea placeholder
773
- EASY_FILL_TEXTAREA_PLACEHOLDER = Provide the required information using data sources or by typing
773
+ EASY_FILL_TEXTAREA_PLACEHOLDER = Provide any information that helps AI fill the appropriate fields. Note that AI can only assist with visible fields and rows.
774
774
 
775
775
  # XTIT: EasyFill initial Illustration title
776
776
  EASY_FILL_ILLUSTRATION_TITLE_INITIAL = Let\u2019s fill in some fields
@@ -794,10 +794,7 @@ EASY_FILL_ILLUSTRATION_DESCRIPTION_ERROR =It looks like an error occurred. Try a
794
794
  EASY_FILL_CONFIRM = Confirm
795
795
 
796
796
  # XTXT: EasyFill AI Notice link
797
- AI_LINK_NOTICE_TITLE = Created with AI.
798
-
799
- # XTXT: EasyFill AI Notice warning
800
- AI_WARNING_TEXT = Verify results before use.
797
+ AI_LINK_NOTICE_TITLE = Created with AI. Verify results before use.
801
798
 
802
799
  # XTIT: EasyFill fillable fields title
803
800
  EASY_FILL_FILLED_FIELDS = Filled Fields
@@ -815,7 +812,7 @@ EASY_FILL_PROPOSED_VALUES = Proposed Values
815
812
  EASY_FILL_PREVIOUS_VALUES = Previous Values
816
813
 
817
814
  # XTXT: EasyFill AINotice link popover text
818
- EASY_FILL_POPOVER_AI_TEXT_1=The content was partially or fully generated by artificial intelligence(AI) technologies.
815
+ EASY_FILL_POPOVER_AI_TEXT_1=The content was partially or fully generated by AI.
819
816
 
820
817
  # XTXT: EasyFill AINotice link popover text
821
818
  EASY_FILL_POPOVER_AI_TEXT_2=The AI-generated content may contain inaccuracies due to using multiple information sources. Verify results before use.
@@ -828,3 +825,30 @@ EASYFILL_RESULT_FEEDBACK=Feedback sent
828
825
 
829
826
  # XBUT: EasyFill clear all
830
827
  EASYFILL_CLEAR_ALL=Clear All
828
+
829
+ # XTXT: EasyFill informational message for staged table row updates
830
+ EASY_FILL_TABLE_UPDATES_INFO = Table row updates were detected and will be applied when you confirm.
831
+
832
+ # XBUT: EasyFill table preview previous values segment
833
+ EASY_FILL_TABLE_VIEW_PREVIOUS = Previous
834
+
835
+ # XBUT: EasyFill table preview new values segment
836
+ EASY_FILL_TABLE_VIEW_NEW = New
837
+
838
+ # XTXT: EasyFill table row label used in validation messages
839
+ EASY_FILL_TABLE_ROW_LABEL = Row {0}
840
+
841
+ # XTXT: EasyFill table value-help validation error summary
842
+ EASY_FILL_TABLE_VALIDATION_MESSAGE = Some table values are invalid for value help: {0}. Update your request and try again.
843
+
844
+ # XTXT: EasyFill suffix shown in table preview cells with invalid value-help values
845
+ EASY_FILL_TABLE_INVALID_CELL_SUFFIX = (invalid)
846
+
847
+ # XTIT: EasyFill Section Title
848
+ EASY_FILL_SECTION_HEADER = Header
849
+
850
+ # XTOL: EasyFill condensed view mode tooltip
851
+ EASY_FILL_CONDENSED_VIEW_TOOLTIP=Switch to condensed layout
852
+
853
+ # XTOL: EasyFill detailed view mode tooltip
854
+ EASY_FILL_DETAILED_VIEW_TOOLTIP=Switch to object page layout
@@ -543,3 +543,17 @@ EASY_FILL_POPOVER_AI_TITLE=\u062A\u0645 \u0627\u0644\u0625\u0646\u0634\u0627\u06
543
543
  EASYFILL_RESULT_FEEDBACK=\u062A\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0645\u0644\u0627\u062D\u0638\u0627\u062A
544
544
 
545
545
  EASYFILL_CLEAR_ALL=\u062D\u0630\u0641 \u0627\u0644\u0627\u0633\u062A\u0639\u0644\u0627\u0645
546
+
547
+ EASY_FILL_TABLE_UPDATES_INFO=\u062A\u0645 \u0627\u0643\u062A\u0634\u0627\u0641 \u062A\u062D\u062F\u064A\u062B\u0627\u062A \u0635\u0641\u0648\u0641 \u0627\u0644\u062C\u062F\u0648\u0644 \u0648\u0633\u064A\u062A\u0645 \u062A\u0637\u0628\u064A\u0642\u0647\u0627 \u0639\u0646\u062F \u0627\u0644\u062A\u0623\u0643\u064A\u062F.
548
+
549
+ EASY_FILL_TABLE_VIEW_PREVIOUS=\u0627\u0644\u0633\u0627\u0628\u0642
550
+
551
+ EASY_FILL_TABLE_VIEW_NEW=\u062C\u062F\u064A\u062F
552
+
553
+ EASY_FILL_TABLE_ROW_LABEL=\u0627\u0644\u0635\u0641 {0}
554
+
555
+ EASY_FILL_TABLE_VALIDATION_MESSAGE=\u0628\u0639\u0636 \u0642\u064A\u0645 \u0627\u0644\u062C\u062F\u0648\u0644 \u063A\u064A\u0631 \u0635\u0627\u0644\u062D\u0629 \u0644\u0645\u0633\u0627\u0639\u062F\u0629 \u0627\u0644\u0625\u062F\u062E\u0627\u0644\: {0}. \u0642\u0645 \u0628\u062A\u062D\u062F\u064A\u062B \u0637\u0644\u0628\u0643 \u0648\u062D\u0627\u0648\u0644 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649.
556
+
557
+ EASY_FILL_TABLE_INVALID_CELL_SUFFIX=(\u063A\u064A\u0631 \u0635\u0627\u0644\u062D)
558
+
559
+ EASY_FILL_SECTION_HEADER=\u0627\u0644\u0645\u0642\u062F\u0645\u0629
@@ -543,3 +543,17 @@ EASY_FILL_POPOVER_AI_TITLE=\u0421\u044A\u0437\u0434\u0430\u0434\u0435\u043D\u043
543
543
  EASYFILL_RESULT_FEEDBACK=\u041E\u0431\u0440\u0430\u0442\u043D\u0430\u0442\u0430 \u0432\u0440\u044A\u0437\u043A\u0430 \u0435 \u0438\u0437\u043F\u0440\u0430\u0442\u0435\u043D\u0430
544
544
 
545
545
  EASYFILL_CLEAR_ALL=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043D\u0435 \u043D\u0430 \u0437\u0430\u043F\u0438\u0442\u0432\u0430\u043D\u0435\u0442\u043E
546
+
547
+ EASY_FILL_TABLE_UPDATES_INFO=\u041E\u0442\u043A\u0440\u0438\u0442\u0438 \u0441\u0430 \u0430\u043A\u0442\u0443\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 \u043D\u0430 \u0440\u0435\u0434\u043E\u0432\u0435\u0442\u0435 \u043D\u0430 \u0442\u0430\u0431\u043B\u0438\u0446\u0430\u0442\u0430 \u0438 \u0449\u0435 \u0431\u044A\u0434\u0430\u0442 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438, \u043A\u043E\u0433\u0430\u0442\u043E \u043F\u043E\u0442\u0432\u044A\u0440\u0434\u0438\u0442\u0435.
548
+
549
+ EASY_FILL_TABLE_VIEW_PREVIOUS=\u041D\u0430\u0437\u0430\u0434
550
+
551
+ EASY_FILL_TABLE_VIEW_NEW=\u041D\u043E\u0432\u043E
552
+
553
+ EASY_FILL_TABLE_ROW_LABEL=\u0420\u0435\u0434 {0}
554
+
555
+ EASY_FILL_TABLE_VALIDATION_MESSAGE=\u041D\u044F\u043A\u043E\u0438 \u0441\u0442\u043E\u0439\u043D\u043E\u0441\u0442\u0438 \u043E\u0442 \u0442\u0430\u0431\u043B\u0438\u0446\u0430\u0442\u0430 \u0441\u0430 \u043D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u0438 \u0437\u0430 \u043F\u043E\u043C\u043E\u0449\u0442\u0430 \u043F\u0440\u0438 \u0432\u044A\u0432\u0435\u0436\u0434\u0430\u043D\u0435 \u043D\u0430 \u0441\u0442\u043E\u0439\u043D\u043E\u0441\u0442\: {0}. \u0410\u043A\u0442\u0443\u0430\u043B\u0438\u0437\u0438\u0440\u0430\u0439\u0442\u0435 \u0437\u0430\u044F\u0432\u043A\u0430\u0442\u0430 \u0441\u0438 \u0438 \u043E\u043F\u0438\u0442\u0430\u0439\u0442\u0435 \u043E\u0442\u043D\u043E\u0432\u043E.
556
+
557
+ EASY_FILL_TABLE_INVALID_CELL_SUFFIX=(\u043D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u043E)
558
+
559
+ EASY_FILL_SECTION_HEADER=\u0417\u0430\u0433\u043B\u0430\u0432\u043A\u0430