@sapui5/sap.suite.ui.generic.template 1.150.1 → 1.152.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.
- package/package.json +1 -1
- package/src/sap/suite/ui/generic/template/.library +1 -1
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/control/visualfilterbar/SmartVisualFilterBar.js +4 -3
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_en_US_sappsd.properties +17 -9
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_en_US_saptrc.properties +113 -105
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/Canvas/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/AnnotationHelperSmartList.js +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/Component.js +4 -2
- package/src/sap/suite/ui/generic/template/ListReport/controller/ControllerImplementation.js +0 -6
- package/src/sap/suite/ui/generic/template/ListReport/controller/IappStateHandler.js +9 -0
- package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_en_US_sappsd.properties +8 -5
- package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_en_US_saptrc.properties +61 -58
- package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_fr.properties +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_sv.properties +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/view/fragments/FullscreenPage.fragment.xml +3 -0
- package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +3 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/controller/RelatedAppsHandler.js +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/controller/inlineCreationRows/InlineCreationRowsHelper.js +10 -7
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_de.properties +4 -4
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en_US_sappsd.properties +53 -9
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en_US_saprigi.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en_US_saptrc.properties +143 -95
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_fr.properties +3 -3
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_no.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ro.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ru.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_sl.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_sv.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_uk.properties +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/QuickCreate/i18n/i18n_en_US_saptrc.properties +14 -14
- package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/QuickView/i18n/i18n_en_US_saptrc.properties +2 -2
- package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/detailTemplates/i18n/i18n_en_US_saptrc.properties +6 -6
- package/src/sap/suite/ui/generic/template/fragments/AnalyticalTableColumns.fragment.xml +0 -10
- package/src/sap/suite/ui/generic/template/fragments/EasyFilter.fragment.xml +0 -2
- package/src/sap/suite/ui/generic/template/fragments/GridTableColumns.fragment.xml +5 -2
- package/src/sap/suite/ui/generic/template/fragments/TreeTableColumns.fragment.xml +5 -2
- package/src/sap/suite/ui/generic/template/genericUtilities/controlHelper.js +10 -1
- package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartFilterBarWrapper.js +45 -32
- package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartTableChartCommon.js +10 -0
- package/src/sap/suite/ui/generic/template/js/AnnotationHelper.js +21 -17
- package/src/sap/suite/ui/generic/template/lib/AppComponent.js +3 -1
- package/src/sap/suite/ui/generic/template/lib/Application.js +15 -2
- package/src/sap/suite/ui/generic/template/lib/CRUDManager.js +5 -24
- package/src/sap/suite/ui/generic/template/lib/CommonEventHandlers.js +30 -8
- package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +13 -5
- package/src/sap/suite/ui/generic/template/lib/PageLeaveHandler.js +19 -14
- package/src/sap/suite/ui/generic/template/lib/ShareUtils.js +1 -1
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator.js +1 -6
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler.js +25 -44
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillDialogController.js +80 -64
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector.js +442 -259
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFormRenderer.js +125 -161
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +134 -160
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer.js +55 -189
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +67 -86
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +175 -54
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterDataFetcherHelper.js +1 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_sappsd.properties +275 -14
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saptrc.properties +392 -163
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +4 -4
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +7 -7
- package/src/sap/suite/ui/generic/template/lib/insights/InsightsCardHelper.js +16 -4
- package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +3 -2
- package/src/sap/suite/ui/generic/template/lib/presentationControl/SmartTableHandler.js +13 -13
- package/src/sap/suite/ui/generic/template/library.js +1 -1
- package/src/sap/suite/ui/generic/template/listTemplates/controller/IappStateHandler.js +12 -3
- package/src/sap/suite/ui/generic/template/listTemplates/i18n/i18n_en_US_saptrc.properties +1 -1
- package/src/sap/suite/ui/generic/template/themes/base/ObjectPage.less +1 -1
|
@@ -52,9 +52,14 @@ sap.ui.define([
|
|
|
52
52
|
var oTransientContextForEasyFill = null; // Transient OData context for staged AI scalar values
|
|
53
53
|
var oObjectPageContext = null; // Live ObjectPage binding context
|
|
54
54
|
var oObjectPageModel = null; // OData model of the ObjectPage
|
|
55
|
-
var mUpdatableLookupMap = {}; // { fieldName:
|
|
55
|
+
var mUpdatableLookupMap = {}; // { fieldName: aiValue } updatable only
|
|
56
56
|
var oRb = null; // i18n resource bundle
|
|
57
57
|
var oAIPopoverRef = { popover: null }; // Mutable ref for lazy-loaded AINotice popover
|
|
58
|
+
// Built fresh on every AI submit by walking the rendered ObjectPage controls.
|
|
59
|
+
// Re-built each time so it reflects the latest edit-mode SmartField state,
|
|
60
|
+
// including extension fragment fields and custom fields.
|
|
61
|
+
var oOPStructureMap = null;
|
|
62
|
+
var mLiveEditable = null;
|
|
58
63
|
|
|
59
64
|
// Collection state — tracks OData row contexts and property metadata for SmartTable collections
|
|
60
65
|
var mCollectionState = {
|
|
@@ -67,6 +72,7 @@ sap.ui.define([
|
|
|
67
72
|
};
|
|
68
73
|
|
|
69
74
|
var mCollectionUpdates = Object.create(null); // { navProperty: [ rowUpdate ] } from AI response
|
|
75
|
+
var mRejectedNewRows = {}; // { navProperty: "all"|"mixed" } — hoisted so mode-switch can access it
|
|
70
76
|
var mLastFieldMapping = null; // retained so table sections can be re-rendered on mode switch
|
|
71
77
|
var oTableStagingState = {
|
|
72
78
|
mStagedRows: Object.create(null),
|
|
@@ -87,15 +93,11 @@ sap.ui.define([
|
|
|
87
93
|
oRb = oController.getView().getModel("i18n").getResourceBundle();
|
|
88
94
|
oObjectPageModel = oObjectPage.getModel();
|
|
89
95
|
|
|
90
|
-
// Initialize dialog model and deferred group once per view lifetime
|
|
91
96
|
EasyFillDialogController.initDialogModel(oController, oObjectPageModel, EasyFillLayoutMode);
|
|
92
97
|
|
|
93
|
-
// Use the provided context override or fall back to the current OP binding context
|
|
94
98
|
oObjectPageContext = oContext || oObjectPage.getBindingContext();
|
|
95
99
|
|
|
96
|
-
// Build the handler/formatter map that the dialog fragment binds to
|
|
97
100
|
var oHandlers = _buildDialogHandlers();
|
|
98
|
-
|
|
99
101
|
await EasyFillDialogController.openDialog(oController, oTemplateUtils, oHandlers);
|
|
100
102
|
}
|
|
101
103
|
|
|
@@ -114,37 +116,23 @@ sap.ui.define([
|
|
|
114
116
|
// immediately on whatever SmartForms are currently in the DOM, and then
|
|
115
117
|
// again via fnOnFieldChange once the new SmartFields are rendered.
|
|
116
118
|
onSelectionChange: function(oEvent) {
|
|
117
|
-
// Step 1: clean up table content injected for the CURRENT mode BEFORE the
|
|
118
|
-
// model update. This ensures the OPL aggregation is free of manually-added
|
|
119
|
-
// sections when the sections binding recreates controls for the new mode,
|
|
120
|
-
// so getSections() in renderCollectionPreviews returns only bound sections.
|
|
121
119
|
var oOpl = oController.byId("EasyFillObjectPageLayout");
|
|
122
120
|
if (oOpl && mLastFieldMapping && Object.keys(mCollectionUpdates).length > 0) {
|
|
123
121
|
EasyFillTableRenderer.removeTableSections(oOpl);
|
|
124
122
|
}
|
|
125
123
|
|
|
126
|
-
// Step 2: update model — this triggers the OPL sections binding to recreate
|
|
127
|
-
// bound section controls for the new mode.
|
|
128
124
|
EasyFillDialogController.onSelectionChange(
|
|
129
|
-
oEvent, oController,
|
|
130
|
-
EasyFillFieldCollector, EasyFillLayoutMode
|
|
125
|
+
oEvent, oController,
|
|
126
|
+
EasyFillFieldCollector, EasyFillLayoutMode, oOPStructureMap
|
|
131
127
|
);
|
|
128
|
+
_populateAllVisibleGroups();
|
|
132
129
|
|
|
133
|
-
// Step 3: re-render table previews for the new mode.
|
|
134
|
-
// _removeTableSections is skipped inside renderCollectionPreviews because
|
|
135
|
-
// bReuseStaging=true, since cleanup was already done in step 1 above.
|
|
136
130
|
if (mLastFieldMapping && Object.keys(mCollectionUpdates).length > 0) {
|
|
137
131
|
EasyFillTableRenderer.renderCollectionPreviews(
|
|
138
|
-
mCollectionUpdates,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
oRb,
|
|
143
|
-
mCollectionState,
|
|
144
|
-
oTableStagingState,
|
|
145
|
-
oObjectPageModel,
|
|
146
|
-
_validateFieldsAndUpdateConfirmState,
|
|
147
|
-
true // bReuseStaging — also skips re-cleanup (already done above)
|
|
132
|
+
mCollectionUpdates, mLastFieldMapping, [],
|
|
133
|
+
oController, oRb, mCollectionState, oTableStagingState,
|
|
134
|
+
oObjectPageModel, _validateFieldsAndUpdateConfirmState,
|
|
135
|
+
true, mRejectedNewRows
|
|
148
136
|
);
|
|
149
137
|
}
|
|
150
138
|
_validateFieldsAndUpdateConfirmState();
|
|
@@ -213,11 +201,6 @@ sap.ui.define([
|
|
|
213
201
|
EasyFillDialogController.closeDialog(oController);
|
|
214
202
|
},
|
|
215
203
|
|
|
216
|
-
// ── Field value formatter (binding expression builder) ────────────
|
|
217
|
-
formatFieldValue: function(sFieldName) {
|
|
218
|
-
return "{" + sFieldName + "}";
|
|
219
|
-
},
|
|
220
|
-
|
|
221
204
|
// ── Submit user text to AI ────────────────────────────────────────
|
|
222
205
|
onEasyFillSubmitInputToAI: async function() {
|
|
223
206
|
await _handleAISubmit();
|
|
@@ -228,41 +211,6 @@ sap.ui.define([
|
|
|
228
211
|
_resetEasyFill(true);
|
|
229
212
|
},
|
|
230
213
|
|
|
231
|
-
// ── SmartForm group population formatter ──────────────────────────
|
|
232
|
-
populateSmartFields: function(sId, aFields, sEasyFillMode) {
|
|
233
|
-
return EasyFillFormRenderer.populateSmartFields(
|
|
234
|
-
sId, aFields, sEasyFillMode,
|
|
235
|
-
oController,
|
|
236
|
-
oTransientContextForEasyFill,
|
|
237
|
-
oObjectPageContext,
|
|
238
|
-
mUpdatableLookupMap,
|
|
239
|
-
oDialogModel().getProperty("/llmData"),
|
|
240
|
-
_validateFieldsAndUpdateConfirmState
|
|
241
|
-
);
|
|
242
|
-
},
|
|
243
|
-
|
|
244
|
-
// ── Section visibility: hide SmartForm sections with no fields ──────────────
|
|
245
|
-
hasSectionFields: function(aFields, aChildren) {
|
|
246
|
-
if (Array.isArray(aFields) && aFields.length > 0) {
|
|
247
|
-
return true;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function hasFieldsInNode(oNode) {
|
|
251
|
-
if (!oNode) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
if (Array.isArray(oNode.fields) && oNode.fields.length > 0) {
|
|
255
|
-
return true;
|
|
256
|
-
}
|
|
257
|
-
if (Array.isArray(oNode.children)) {
|
|
258
|
-
return oNode.children.some(hasFieldsInNode);
|
|
259
|
-
}
|
|
260
|
-
return false;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return Array.isArray(aChildren) && aChildren.some(hasFieldsInNode);
|
|
264
|
-
},
|
|
265
|
-
|
|
266
214
|
// ── Fullscreen toggle ─────────────────────────────────────────────
|
|
267
215
|
onToggleFullScreen: function() {
|
|
268
216
|
EasyFillDialogController.onToggleFullScreen(oController);
|
|
@@ -286,8 +234,29 @@ sap.ui.define([
|
|
|
286
234
|
async function _handleAISubmit() {
|
|
287
235
|
var oModel = oDialogModel();
|
|
288
236
|
oModel.setProperty("/isBusy", true);
|
|
289
|
-
|
|
290
|
-
|
|
237
|
+
try {
|
|
238
|
+
|
|
239
|
+
var sEntitySetName = oController.getOwnerComponent().getEntitySet();
|
|
240
|
+
var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(sEntitySetName);
|
|
241
|
+
|
|
242
|
+
// Walk the rendered ObjectPage to build structure map + editability in one pass.
|
|
243
|
+
// Uses findAggregatedObjects on the real FLP ObjectPage — confirmed approach:
|
|
244
|
+
// OP SmartFields created via AHModel.simplePath DO expose getBindingInfo("value").path.
|
|
245
|
+
// Walking up the parent chain gives section/group context without reading annotations.
|
|
246
|
+
// Fallback: if walk produces no fields (edge case), retains previous map.
|
|
247
|
+
// Single walk of the rendered ObjectPage — same proven approach as buildLiveEditabilityMap.
|
|
248
|
+
// Called here (in edit mode, after entity context resolves) so getBindingInfo("value").path
|
|
249
|
+
// is available. Produces section/group/field structure AND live editability in one pass.
|
|
250
|
+
// Annotation fallback kicks in automatically if rendered walk finds nothing.
|
|
251
|
+
var oFreshMap = EasyFillFieldCollector.buildObjectPageStructureMap(oObjectPage, oEntityType, oRb);
|
|
252
|
+
oOPStructureMap = oFreshMap;
|
|
253
|
+
mLiveEditable = oFreshMap.liveEditable;
|
|
254
|
+
|
|
255
|
+
// Build complete LLM field mapping (entity fields + collection fields).
|
|
256
|
+
// All visible fields are sent to the LLM — including read-only ones —
|
|
257
|
+
// so the LLM can return suggestions for every field.
|
|
258
|
+
// mLiveEditable is used AFTER the LLM responds (in getUpdatableAndNonUpdatableFields)
|
|
259
|
+
// to classify returned fields as editable (Filled Fields) or read-only (Unfilled Fields).
|
|
291
260
|
var mFieldMapping = EasyFillAIOrchestrator.buildFieldMapping(
|
|
292
261
|
oTemplateUtils, oController, oObjectPage, oObjectPageModel,
|
|
293
262
|
oObjectPageContext, EasyFillFieldCollector, mCollectionState
|
|
@@ -300,9 +269,6 @@ sap.ui.define([
|
|
|
300
269
|
oTemplateUtils
|
|
301
270
|
);
|
|
302
271
|
|
|
303
|
-
// Reset editable fields tracker for fresh population
|
|
304
|
-
oModel.setProperty("/isBusy", false);
|
|
305
|
-
|
|
306
272
|
// Convert date strings in AI response to JS Date objects
|
|
307
273
|
EasyFillAIOrchestrator.formatDateValues(aiCallResult, mFieldMapping);
|
|
308
274
|
|
|
@@ -319,68 +285,49 @@ sap.ui.define([
|
|
|
319
285
|
var collectionFields = oSplitResult.collectionFields;
|
|
320
286
|
|
|
321
287
|
// Separate updatable from non-updatable fields
|
|
322
|
-
var sEntitySetName = oController.getOwnerComponent().getEntitySet();
|
|
323
|
-
var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(sEntitySetName);
|
|
324
288
|
var oMetaModel = oObjectPageModel.getMetaModel();
|
|
325
289
|
var oEntitySet = oMetaModel.getODataEntitySet(sEntitySetName);
|
|
326
290
|
var oSplit = EasyFillFieldCollector.getUpdatableAndNonUpdatableFields(
|
|
327
|
-
simpleFields, oEntityType, oObjectPageContext, oEntitySet
|
|
291
|
+
simpleFields, oEntityType, oObjectPageContext, oEntitySet, mLiveEditable
|
|
328
292
|
);
|
|
329
293
|
mUpdatableLookupMap = oSplit.updatableFields;
|
|
330
294
|
var mNonUpdatableFields = oSplit.nonUpdatableFields;
|
|
331
295
|
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
// instead of adding them as standalone OPL sections (OP mode) or vice-versa.
|
|
296
|
+
// Compute sections array for the selected view mode.
|
|
297
|
+
// Condensed: two flat groups from scratch.
|
|
298
|
+
// OP mode: O(fields) pass over the pre-built structure map — no annotation re-walk.
|
|
299
|
+
var aSections = (sSelectedKey === EasyFillLayoutMode.CondensedMode || !oOPStructureMap)
|
|
300
|
+
? EasyFillFieldCollector.getSectionInfoForCondensedMode(mUpdatableLookupMap, mNonUpdatableFields)
|
|
301
|
+
: EasyFillFieldCollector.applyLLMResultToStructureMap(
|
|
302
|
+
oOPStructureMap.fieldMap, oOPStructureMap.sections,
|
|
303
|
+
mUpdatableLookupMap, mNonUpdatableFields
|
|
304
|
+
);
|
|
305
|
+
|
|
343
306
|
_resetEasyFill();
|
|
344
307
|
oModel.setProperty("/easyFillMode", sSelectedKey);
|
|
345
308
|
oTransientContextForEasyFill = EasyFillFormRenderer.makeTransientContext(
|
|
346
309
|
null, oObjectPageModel, oController
|
|
347
310
|
);
|
|
348
311
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
oModel.setProperty("/llmData", simpleFields);
|
|
354
|
-
oModel.setProperty("/updatableFields", mUpdatableLookupMap);
|
|
355
|
-
oModel.setProperty("/nonUpdatableFields", mNonUpdatableFields);
|
|
356
|
-
oModel.setProperty("/sections", aData);
|
|
312
|
+
oModel.setProperty("/llmData", simpleFields);
|
|
313
|
+
oModel.setProperty("/updatableFields", mUpdatableLookupMap);
|
|
314
|
+
oModel.setProperty("/nonUpdatableFields", mNonUpdatableFields);
|
|
315
|
+
oModel.setProperty("/sections", aSections);
|
|
357
316
|
oModel.setProperty("/hasNonUpdatableFields", Object.keys(mNonUpdatableFields).length > 0);
|
|
358
|
-
|
|
359
|
-
// Show warning if AI attempted to add multiple new rows but only one was accepted
|
|
360
317
|
oModel.setProperty("/attemptedMultipleNewRows", oSplitResult.attemptedMultipleNewRows === true);
|
|
318
|
+
_populateAllVisibleGroups();
|
|
361
319
|
|
|
362
|
-
// Process collection/table updates
|
|
363
320
|
mCollectionUpdates = collectionFields;
|
|
364
321
|
mLastFieldMapping = mFieldMapping;
|
|
365
|
-
|
|
366
|
-
// hasTableUpdates is true when there are accepted updates OR rejected-only tables to show
|
|
322
|
+
mRejectedNewRows = oSplitResult.collectionsWithRejectedNewRows || {};
|
|
367
323
|
var bHasTableUpdates = Object.keys(mCollectionUpdates).length > 0 ||
|
|
368
324
|
Object.keys(mRejectedNewRows).length > 0;
|
|
369
325
|
oModel.setProperty("/hasTableUpdates", bHasTableUpdates);
|
|
370
326
|
|
|
371
|
-
// Render collection previews into the table preview container
|
|
372
327
|
EasyFillTableRenderer.renderCollectionPreviews(
|
|
373
|
-
mCollectionUpdates,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
oController,
|
|
377
|
-
oRb,
|
|
378
|
-
mCollectionState,
|
|
379
|
-
oTableStagingState,
|
|
380
|
-
oObjectPageModel,
|
|
381
|
-
_validateFieldsAndUpdateConfirmState,
|
|
382
|
-
false,
|
|
383
|
-
mRejectedNewRows
|
|
328
|
+
mCollectionUpdates, mFieldMapping, [],
|
|
329
|
+
oController, oRb, mCollectionState, oTableStagingState,
|
|
330
|
+
oObjectPageModel, _validateFieldsAndUpdateConfirmState, false, mRejectedNewRows
|
|
384
331
|
);
|
|
385
332
|
|
|
386
333
|
_validateFieldsAndUpdateConfirmState();
|
|
@@ -397,6 +344,9 @@ sap.ui.define([
|
|
|
397
344
|
// AI call failed — show error illustration
|
|
398
345
|
oModel.setProperty("/stateType", "Error");
|
|
399
346
|
}
|
|
347
|
+
} finally {
|
|
348
|
+
oModel.setProperty("/isBusy", false);
|
|
349
|
+
}
|
|
400
350
|
}
|
|
401
351
|
|
|
402
352
|
/**
|
|
@@ -417,41 +367,61 @@ sap.ui.define([
|
|
|
417
367
|
return true;
|
|
418
368
|
}
|
|
419
369
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
oObjectPageLayout.getSections().forEach(function(oSection) {
|
|
423
|
-
oSection.getSubSections().forEach(function(oSubSection) {
|
|
424
|
-
oSubSection.getBlocks().forEach(function(oBlock) {
|
|
425
|
-
var aSmartFormCandidates = [];
|
|
426
|
-
if (oBlock.isA("sap.ui.comp.smartform.SmartForm")) {
|
|
427
|
-
aSmartFormCandidates.push(oBlock);
|
|
428
|
-
} else if (typeof oBlock.getItems === "function") {
|
|
429
|
-
// In condensed mode the SmartForm is nested inside a wrapper VBox;
|
|
430
|
-
// look one level deeper to find it (mirrors EasyFillFormRenderer).
|
|
431
|
-
oBlock.getItems().forEach(function(oItem) {
|
|
432
|
-
if (oItem.isA("sap.ui.comp.smartform.SmartForm")) {
|
|
433
|
-
aSmartFormCandidates.push(oItem);
|
|
434
|
-
}
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
aSmartFormCandidates.forEach(function(oSmartForm) {
|
|
438
|
-
// .catch(() => []) absorbs internal SmartField metadata-promise rejections
|
|
439
|
-
// that fire when SmartFields are destroyed during a mode switch.
|
|
440
|
-
aCheckPromises.push(
|
|
441
|
-
Promise.resolve(oSmartForm.check()).catch(function() { return []; })
|
|
442
|
-
);
|
|
443
|
-
});
|
|
444
|
-
});
|
|
445
|
-
});
|
|
370
|
+
var aCheckPromises = EasyFillFormRenderer.collectSmartForms(oObjectPageLayout).map(async function(oSmartForm) {
|
|
371
|
+
try { return await oSmartForm.check(); } catch (e) { return []; }
|
|
446
372
|
});
|
|
447
373
|
|
|
448
|
-
// Resolve all checks in parallel; valid only when every SmartForm has no errors
|
|
449
374
|
var aResults = await Promise.all(aCheckPromises);
|
|
450
375
|
return aResults.every(function(aErrors) {
|
|
451
|
-
|
|
376
|
+
// SmartForm.check() with validationMode="Async" resolves with an array of
|
|
377
|
+
// error objects when invalid, or [] / null / true when valid.
|
|
378
|
+
// Array.isArray guard handles the non-array zero-error sentinel.
|
|
379
|
+
return Array.isArray(aErrors) ? aErrors.length === 0 : !aErrors || aErrors === true;
|
|
452
380
|
});
|
|
453
381
|
}
|
|
454
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Walks the current easyFillDialogModel>/sections array and calls
|
|
385
|
+
* EasyFillFormRenderer.populateGroupFields for every visible group that has
|
|
386
|
+
* activeFields. Deferred by setTimeout(0) so the sections= and groups= bindings
|
|
387
|
+
* have finished creating their controls before we try to find them.
|
|
388
|
+
*/
|
|
389
|
+
function _populateAllVisibleGroups() {
|
|
390
|
+
setTimeout(function() {
|
|
391
|
+
var aSections = oDialogModel().getProperty("/sections") || [];
|
|
392
|
+
var oLLMData = oDialogModel().getProperty("/llmData") || {};
|
|
393
|
+
aSections.forEach(function(oSection) {
|
|
394
|
+
if (!oSection.visible) { return; }
|
|
395
|
+
(oSection.children || []).forEach(function(oGroup) {
|
|
396
|
+
var aFields = Array.isArray(oGroup.aActiveFields) && oGroup.aActiveFields.length
|
|
397
|
+
? oGroup.aActiveFields : (oGroup.fields || []);
|
|
398
|
+
if (!oGroup.visible || !aFields.length) { return; }
|
|
399
|
+
EasyFillFormRenderer.populateGroupFields(
|
|
400
|
+
oGroup.id, aFields,
|
|
401
|
+
oController,
|
|
402
|
+
oTransientContextForEasyFill,
|
|
403
|
+
oObjectPageContext,
|
|
404
|
+
mUpdatableLookupMap,
|
|
405
|
+
oLLMData,
|
|
406
|
+
_validateFieldsAndUpdateConfirmState
|
|
407
|
+
);
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
}, 0);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Destroys all GroupElements in every visible SmartForm group — called by _resetEasyFill.
|
|
415
|
+
*/
|
|
416
|
+
function _destroyAllGroupElements() {
|
|
417
|
+
EasyFillFormRenderer.collectSmartForms(oController.byId("EasyFillObjectPageLayout"))
|
|
418
|
+
.forEach(function(oForm) {
|
|
419
|
+
oForm.getGroups().forEach(function(oGroup) {
|
|
420
|
+
oGroup.destroyGroupElements();
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
455
425
|
/**
|
|
456
426
|
* Re-computes isSaveEnabled from the combined SmartForm and table SmartField validity
|
|
457
427
|
* flag. Called as the single source of truth for the Confirm button state.
|
|
@@ -551,6 +521,10 @@ sap.ui.define([
|
|
|
551
521
|
*/
|
|
552
522
|
function _resetEasyFill(bRemoveTextAreaValue) {
|
|
553
523
|
mLastFieldMapping = null;
|
|
524
|
+
mRejectedNewRows = {};
|
|
525
|
+
// mUpdatableLookupMap is NOT reset here — it is overwritten by the next AI submit
|
|
526
|
+
// and explicitly cleared by EasyFillApplyHandler.resetEasyFill on Clear All / Cancel
|
|
527
|
+
_destroyAllGroupElements();
|
|
554
528
|
EasyFillApplyHandler.resetEasyFill(
|
|
555
529
|
!!bRemoveTextAreaValue,
|
|
556
530
|
oDialogModel(),
|
|
@@ -584,20 +558,14 @@ sap.ui.define([
|
|
|
584
558
|
|
|
585
559
|
// Collect all editable SmartFields from the EasyFill dialog SmartForms
|
|
586
560
|
var aEditableFields = [];
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
aEditableFields.push(oElement);
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
});
|
|
599
|
-
});
|
|
600
|
-
}
|
|
561
|
+
EasyFillFormRenderer.collectSmartForms(oObjectPageLayout).forEach(function(oSmartForm) {
|
|
562
|
+
oSmartForm.getGroups().forEach(function(oGroup) {
|
|
563
|
+
oGroup.getGroupElements().forEach(function(oGroupElement) {
|
|
564
|
+
oGroupElement.getElements().forEach(function(oElement) {
|
|
565
|
+
if (oElement.isA && oElement.isA("sap.ui.comp.smartfield.SmartField") && oElement.getEditable()) {
|
|
566
|
+
aEditableFields.push(oElement);
|
|
567
|
+
}
|
|
568
|
+
});
|
|
601
569
|
});
|
|
602
570
|
});
|
|
603
571
|
});
|
|
@@ -712,8 +680,10 @@ sap.ui.define([
|
|
|
712
680
|
* CRUDManager.addEntry directly ensures the SmartTable binding is refreshed and side
|
|
713
681
|
* effects are executed after the row is created — without that refresh the ObjectPage
|
|
714
682
|
* table would not show the newly created row.
|
|
683
|
+
* Multiple new rows per table are created sequentially to avoid race conditions on
|
|
684
|
+
* the draft document.
|
|
715
685
|
*
|
|
716
|
-
* @param {object} mNewRowValues - map of { navProperty: plainValuesObject }
|
|
686
|
+
* @param {object} mNewRowValues - map of { navProperty: plainValuesObject[] }
|
|
717
687
|
* @returns {Promise<void>}
|
|
718
688
|
*/
|
|
719
689
|
async function _createNewRows(mNewRowValues) {
|
|
@@ -729,13 +699,17 @@ sap.ui.define([
|
|
|
729
699
|
if (!oSmartTable) {
|
|
730
700
|
continue;
|
|
731
701
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
702
|
+
var aRowValues = mNewRowValues[sNavProp];
|
|
703
|
+
// aRowValues is now an array — iterate and create each row sequentially
|
|
704
|
+
if (!Array.isArray(aRowValues)) {
|
|
705
|
+
aRowValues = [aRowValues];
|
|
706
|
+
}
|
|
707
|
+
for (var j = 0; j < aRowValues.length; j++) {
|
|
708
|
+
try {
|
|
709
|
+
await oTemplateUtils.oCommonEventHandlers.addEntry(oSmartTable, true, undefined, aRowValues[j]);
|
|
710
|
+
} catch (e) {
|
|
711
|
+
// addEntry handles its own error messaging via CommonEventHandlers/CRUDManager
|
|
712
|
+
}
|
|
739
713
|
}
|
|
740
714
|
}
|
|
741
715
|
}
|