@sapui5/sap.suite.ui.generic.template 1.151.1 → 1.153.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/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/Canvas/manifest.json +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/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/Component.js +5 -0
- package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +31 -0
- package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/Actions.fragment.xml +1 -1
- package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartFilterBarWrapper.js +13 -7
- package/src/sap/suite/ui/generic/template/genericUtilities/designtime/messagebundle.properties +0 -0
- package/src/sap/suite/ui/generic/template/js/AnnotationHelper.js +21 -17
- package/src/sap/suite/ui/generic/template/lib/AppComponent.js +19 -3
- package/src/sap/suite/ui/generic/template/lib/ShareUtils.js +1 -1
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator.js +16 -6
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler.js +35 -47
- 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 +186 -161
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +137 -161
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer.js +157 -191
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +67 -85
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +56 -4
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n.properties +11 -2
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ar.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_bg.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ca.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cnr.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cs.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cy.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_da.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_de.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_el.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_GB.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_sappsd.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saprigi.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saptrc.properties +13 -7
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es_MX.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_et.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +11 -5
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr.properties +10 -4
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr_CA.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hi.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hr.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hu.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_id.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_it.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_iw.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ja.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_kk.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ko.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lt.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lv.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_mk.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ms.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_nl.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_no.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pl.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt_PT.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ro.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ru.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sh.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sk.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +8 -2
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sr.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sv.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_th.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_tr.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_uk.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_vi.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_CN.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_TW.properties +7 -1
- package/src/sap/suite/ui/generic/template/lib/insights/InsightsCardHelper.js +40 -8
- package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +3 -2
- package/src/sap/suite/ui/generic/template/lib/presentationControl/SmartTableHandler.js +4 -0
- package/src/sap/suite/ui/generic/template/library.js +1 -1
- package/src/sap/suite/ui/generic/template/themes/base/ObjectPage.less +7 -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,10 +72,13 @@ 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),
|
|
73
|
-
mPendingNewRowContexts: Object.create(null)
|
|
79
|
+
mPendingNewRowContexts: Object.create(null),
|
|
80
|
+
mExcludedRows: Object.create(null), // { navProp: { index: true } } existing rows excluded by user
|
|
81
|
+
mExcludedNewRows: Object.create(null) // { navProp: { index: true } } new rows excluded by user
|
|
74
82
|
};
|
|
75
83
|
|
|
76
84
|
// ─── Internal Helpers ────────────────────────────────────────────────────
|
|
@@ -87,15 +95,11 @@ sap.ui.define([
|
|
|
87
95
|
oRb = oController.getView().getModel("i18n").getResourceBundle();
|
|
88
96
|
oObjectPageModel = oObjectPage.getModel();
|
|
89
97
|
|
|
90
|
-
// Initialize dialog model and deferred group once per view lifetime
|
|
91
98
|
EasyFillDialogController.initDialogModel(oController, oObjectPageModel, EasyFillLayoutMode);
|
|
92
99
|
|
|
93
|
-
// Use the provided context override or fall back to the current OP binding context
|
|
94
100
|
oObjectPageContext = oContext || oObjectPage.getBindingContext();
|
|
95
101
|
|
|
96
|
-
// Build the handler/formatter map that the dialog fragment binds to
|
|
97
102
|
var oHandlers = _buildDialogHandlers();
|
|
98
|
-
|
|
99
103
|
await EasyFillDialogController.openDialog(oController, oTemplateUtils, oHandlers);
|
|
100
104
|
}
|
|
101
105
|
|
|
@@ -114,37 +118,23 @@ sap.ui.define([
|
|
|
114
118
|
// immediately on whatever SmartForms are currently in the DOM, and then
|
|
115
119
|
// again via fnOnFieldChange once the new SmartFields are rendered.
|
|
116
120
|
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
121
|
var oOpl = oController.byId("EasyFillObjectPageLayout");
|
|
122
122
|
if (oOpl && mLastFieldMapping && Object.keys(mCollectionUpdates).length > 0) {
|
|
123
123
|
EasyFillTableRenderer.removeTableSections(oOpl);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
// Step 2: update model — this triggers the OPL sections binding to recreate
|
|
127
|
-
// bound section controls for the new mode.
|
|
128
126
|
EasyFillDialogController.onSelectionChange(
|
|
129
|
-
oEvent, oController,
|
|
130
|
-
EasyFillFieldCollector, EasyFillLayoutMode
|
|
127
|
+
oEvent, oController,
|
|
128
|
+
EasyFillFieldCollector, EasyFillLayoutMode, oOPStructureMap
|
|
131
129
|
);
|
|
130
|
+
_populateAllVisibleGroups();
|
|
132
131
|
|
|
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
132
|
if (mLastFieldMapping && Object.keys(mCollectionUpdates).length > 0) {
|
|
137
133
|
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)
|
|
134
|
+
mCollectionUpdates, mLastFieldMapping, [],
|
|
135
|
+
oController, oRb, mCollectionState, oTableStagingState,
|
|
136
|
+
oObjectPageModel, _validateFieldsAndUpdateConfirmState,
|
|
137
|
+
true, mRejectedNewRows
|
|
148
138
|
);
|
|
149
139
|
}
|
|
150
140
|
_validateFieldsAndUpdateConfirmState();
|
|
@@ -213,11 +203,6 @@ sap.ui.define([
|
|
|
213
203
|
EasyFillDialogController.closeDialog(oController);
|
|
214
204
|
},
|
|
215
205
|
|
|
216
|
-
// ── Field value formatter (binding expression builder) ────────────
|
|
217
|
-
formatFieldValue: function(sFieldName) {
|
|
218
|
-
return "{" + sFieldName + "}";
|
|
219
|
-
},
|
|
220
|
-
|
|
221
206
|
// ── Submit user text to AI ────────────────────────────────────────
|
|
222
207
|
onEasyFillSubmitInputToAI: async function() {
|
|
223
208
|
await _handleAISubmit();
|
|
@@ -228,41 +213,6 @@ sap.ui.define([
|
|
|
228
213
|
_resetEasyFill(true);
|
|
229
214
|
},
|
|
230
215
|
|
|
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
216
|
// ── Fullscreen toggle ─────────────────────────────────────────────
|
|
267
217
|
onToggleFullScreen: function() {
|
|
268
218
|
EasyFillDialogController.onToggleFullScreen(oController);
|
|
@@ -286,8 +236,29 @@ sap.ui.define([
|
|
|
286
236
|
async function _handleAISubmit() {
|
|
287
237
|
var oModel = oDialogModel();
|
|
288
238
|
oModel.setProperty("/isBusy", true);
|
|
289
|
-
|
|
290
|
-
|
|
239
|
+
try {
|
|
240
|
+
|
|
241
|
+
var sEntitySetName = oController.getOwnerComponent().getEntitySet();
|
|
242
|
+
var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(sEntitySetName);
|
|
243
|
+
|
|
244
|
+
// Walk the rendered ObjectPage to build structure map + editability in one pass.
|
|
245
|
+
// Uses findAggregatedObjects on the real FLP ObjectPage — confirmed approach:
|
|
246
|
+
// OP SmartFields created via AHModel.simplePath DO expose getBindingInfo("value").path.
|
|
247
|
+
// Walking up the parent chain gives section/group context without reading annotations.
|
|
248
|
+
// Fallback: if walk produces no fields (edge case), retains previous map.
|
|
249
|
+
// Single walk of the rendered ObjectPage — same proven approach as buildLiveEditabilityMap.
|
|
250
|
+
// Called here (in edit mode, after entity context resolves) so getBindingInfo("value").path
|
|
251
|
+
// is available. Produces section/group/field structure AND live editability in one pass.
|
|
252
|
+
// Annotation fallback kicks in automatically if rendered walk finds nothing.
|
|
253
|
+
var oFreshMap = EasyFillFieldCollector.buildObjectPageStructureMap(oObjectPage, oEntityType, oRb);
|
|
254
|
+
oOPStructureMap = oFreshMap;
|
|
255
|
+
mLiveEditable = oFreshMap.liveEditable;
|
|
256
|
+
|
|
257
|
+
// Build complete LLM field mapping (entity fields + collection fields).
|
|
258
|
+
// All visible fields are sent to the LLM — including read-only ones —
|
|
259
|
+
// so the LLM can return suggestions for every field.
|
|
260
|
+
// mLiveEditable is used AFTER the LLM responds (in getUpdatableAndNonUpdatableFields)
|
|
261
|
+
// to classify returned fields as editable (Filled Fields) or read-only (Unfilled Fields).
|
|
291
262
|
var mFieldMapping = EasyFillAIOrchestrator.buildFieldMapping(
|
|
292
263
|
oTemplateUtils, oController, oObjectPage, oObjectPageModel,
|
|
293
264
|
oObjectPageContext, EasyFillFieldCollector, mCollectionState
|
|
@@ -300,9 +271,6 @@ sap.ui.define([
|
|
|
300
271
|
oTemplateUtils
|
|
301
272
|
);
|
|
302
273
|
|
|
303
|
-
// Reset editable fields tracker for fresh population
|
|
304
|
-
oModel.setProperty("/isBusy", false);
|
|
305
|
-
|
|
306
274
|
// Convert date strings in AI response to JS Date objects
|
|
307
275
|
EasyFillAIOrchestrator.formatDateValues(aiCallResult, mFieldMapping);
|
|
308
276
|
|
|
@@ -319,68 +287,49 @@ sap.ui.define([
|
|
|
319
287
|
var collectionFields = oSplitResult.collectionFields;
|
|
320
288
|
|
|
321
289
|
// Separate updatable from non-updatable fields
|
|
322
|
-
var sEntitySetName = oController.getOwnerComponent().getEntitySet();
|
|
323
|
-
var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(sEntitySetName);
|
|
324
290
|
var oMetaModel = oObjectPageModel.getMetaModel();
|
|
325
291
|
var oEntitySet = oMetaModel.getODataEntitySet(sEntitySetName);
|
|
326
292
|
var oSplit = EasyFillFieldCollector.getUpdatableAndNonUpdatableFields(
|
|
327
|
-
simpleFields, oEntityType, oObjectPageContext, oEntitySet
|
|
293
|
+
simpleFields, oEntityType, oObjectPageContext, oEntitySet, mLiveEditable
|
|
328
294
|
);
|
|
329
295
|
mUpdatableLookupMap = oSplit.updatableFields;
|
|
330
296
|
var mNonUpdatableFields = oSplit.nonUpdatableFields;
|
|
331
297
|
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
// instead of adding them as standalone OPL sections (OP mode) or vice-versa.
|
|
298
|
+
// Compute sections array for the selected view mode.
|
|
299
|
+
// Condensed: two flat groups from scratch.
|
|
300
|
+
// OP mode: O(fields) pass over the pre-built structure map — no annotation re-walk.
|
|
301
|
+
var aSections = (sSelectedKey === EasyFillLayoutMode.CondensedMode || !oOPStructureMap)
|
|
302
|
+
? EasyFillFieldCollector.getSectionInfoForCondensedMode(mUpdatableLookupMap, mNonUpdatableFields)
|
|
303
|
+
: EasyFillFieldCollector.applyLLMResultToStructureMap(
|
|
304
|
+
oOPStructureMap.fieldMap, oOPStructureMap.sections,
|
|
305
|
+
mUpdatableLookupMap, mNonUpdatableFields
|
|
306
|
+
);
|
|
307
|
+
|
|
343
308
|
_resetEasyFill();
|
|
344
309
|
oModel.setProperty("/easyFillMode", sSelectedKey);
|
|
345
310
|
oTransientContextForEasyFill = EasyFillFormRenderer.makeTransientContext(
|
|
346
311
|
null, oObjectPageModel, oController
|
|
347
312
|
);
|
|
348
313
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
oModel.setProperty("/llmData", simpleFields);
|
|
354
|
-
oModel.setProperty("/updatableFields", mUpdatableLookupMap);
|
|
355
|
-
oModel.setProperty("/nonUpdatableFields", mNonUpdatableFields);
|
|
356
|
-
oModel.setProperty("/sections", aData);
|
|
314
|
+
oModel.setProperty("/llmData", simpleFields);
|
|
315
|
+
oModel.setProperty("/updatableFields", mUpdatableLookupMap);
|
|
316
|
+
oModel.setProperty("/nonUpdatableFields", mNonUpdatableFields);
|
|
317
|
+
oModel.setProperty("/sections", aSections);
|
|
357
318
|
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
319
|
oModel.setProperty("/attemptedMultipleNewRows", oSplitResult.attemptedMultipleNewRows === true);
|
|
320
|
+
_populateAllVisibleGroups();
|
|
361
321
|
|
|
362
|
-
// Process collection/table updates
|
|
363
322
|
mCollectionUpdates = collectionFields;
|
|
364
323
|
mLastFieldMapping = mFieldMapping;
|
|
365
|
-
|
|
366
|
-
// hasTableUpdates is true when there are accepted updates OR rejected-only tables to show
|
|
324
|
+
mRejectedNewRows = oSplitResult.collectionsWithRejectedNewRows || {};
|
|
367
325
|
var bHasTableUpdates = Object.keys(mCollectionUpdates).length > 0 ||
|
|
368
326
|
Object.keys(mRejectedNewRows).length > 0;
|
|
369
327
|
oModel.setProperty("/hasTableUpdates", bHasTableUpdates);
|
|
370
328
|
|
|
371
|
-
// Render collection previews into the table preview container
|
|
372
329
|
EasyFillTableRenderer.renderCollectionPreviews(
|
|
373
|
-
mCollectionUpdates,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
oController,
|
|
377
|
-
oRb,
|
|
378
|
-
mCollectionState,
|
|
379
|
-
oTableStagingState,
|
|
380
|
-
oObjectPageModel,
|
|
381
|
-
_validateFieldsAndUpdateConfirmState,
|
|
382
|
-
false,
|
|
383
|
-
mRejectedNewRows
|
|
330
|
+
mCollectionUpdates, mFieldMapping, [],
|
|
331
|
+
oController, oRb, mCollectionState, oTableStagingState,
|
|
332
|
+
oObjectPageModel, _validateFieldsAndUpdateConfirmState, false, mRejectedNewRows
|
|
384
333
|
);
|
|
385
334
|
|
|
386
335
|
_validateFieldsAndUpdateConfirmState();
|
|
@@ -397,6 +346,9 @@ sap.ui.define([
|
|
|
397
346
|
// AI call failed — show error illustration
|
|
398
347
|
oModel.setProperty("/stateType", "Error");
|
|
399
348
|
}
|
|
349
|
+
} finally {
|
|
350
|
+
oModel.setProperty("/isBusy", false);
|
|
351
|
+
}
|
|
400
352
|
}
|
|
401
353
|
|
|
402
354
|
/**
|
|
@@ -417,41 +369,61 @@ sap.ui.define([
|
|
|
417
369
|
return true;
|
|
418
370
|
}
|
|
419
371
|
|
|
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
|
-
});
|
|
372
|
+
var aCheckPromises = EasyFillFormRenderer.collectSmartForms(oObjectPageLayout).map(async function(oSmartForm) {
|
|
373
|
+
try { return await oSmartForm.check(); } catch (e) { return []; }
|
|
446
374
|
});
|
|
447
375
|
|
|
448
|
-
// Resolve all checks in parallel; valid only when every SmartForm has no errors
|
|
449
376
|
var aResults = await Promise.all(aCheckPromises);
|
|
450
377
|
return aResults.every(function(aErrors) {
|
|
451
|
-
|
|
378
|
+
// SmartForm.check() with validationMode="Async" resolves with an array of
|
|
379
|
+
// error objects when invalid, or [] / null / true when valid.
|
|
380
|
+
// Array.isArray guard handles the non-array zero-error sentinel.
|
|
381
|
+
return Array.isArray(aErrors) ? aErrors.length === 0 : !aErrors || aErrors === true;
|
|
452
382
|
});
|
|
453
383
|
}
|
|
454
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Walks the current easyFillDialogModel>/sections array and calls
|
|
387
|
+
* EasyFillFormRenderer.populateGroupFields for every visible group that has
|
|
388
|
+
* activeFields. Deferred by setTimeout(0) so the sections= and groups= bindings
|
|
389
|
+
* have finished creating their controls before we try to find them.
|
|
390
|
+
*/
|
|
391
|
+
function _populateAllVisibleGroups() {
|
|
392
|
+
setTimeout(function() {
|
|
393
|
+
var aSections = oDialogModel().getProperty("/sections") || [];
|
|
394
|
+
var oLLMData = oDialogModel().getProperty("/llmData") || {};
|
|
395
|
+
aSections.forEach(function(oSection) {
|
|
396
|
+
if (!oSection.visible) { return; }
|
|
397
|
+
(oSection.children || []).forEach(function(oGroup) {
|
|
398
|
+
var aFields = Array.isArray(oGroup.aActiveFields) && oGroup.aActiveFields.length
|
|
399
|
+
? oGroup.aActiveFields : (oGroup.fields || []);
|
|
400
|
+
if (!oGroup.visible || !aFields.length) { return; }
|
|
401
|
+
EasyFillFormRenderer.populateGroupFields(
|
|
402
|
+
oGroup.id, aFields,
|
|
403
|
+
oController,
|
|
404
|
+
oTransientContextForEasyFill,
|
|
405
|
+
oObjectPageContext,
|
|
406
|
+
mUpdatableLookupMap,
|
|
407
|
+
oLLMData,
|
|
408
|
+
_validateFieldsAndUpdateConfirmState
|
|
409
|
+
);
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
}, 0);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Destroys all GroupElements in every visible SmartForm group — called by _resetEasyFill.
|
|
417
|
+
*/
|
|
418
|
+
function _destroyAllGroupElements() {
|
|
419
|
+
EasyFillFormRenderer.collectSmartForms(oController.byId("EasyFillObjectPageLayout"))
|
|
420
|
+
.forEach(function(oForm) {
|
|
421
|
+
oForm.getGroups().forEach(function(oGroup) {
|
|
422
|
+
oGroup.destroyGroupElements();
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
455
427
|
/**
|
|
456
428
|
* Re-computes isSaveEnabled from the combined SmartForm and table SmartField validity
|
|
457
429
|
* flag. Called as the single source of truth for the Confirm button state.
|
|
@@ -551,6 +523,10 @@ sap.ui.define([
|
|
|
551
523
|
*/
|
|
552
524
|
function _resetEasyFill(bRemoveTextAreaValue) {
|
|
553
525
|
mLastFieldMapping = null;
|
|
526
|
+
mRejectedNewRows = {};
|
|
527
|
+
// mUpdatableLookupMap is NOT reset here — it is overwritten by the next AI submit
|
|
528
|
+
// and explicitly cleared by EasyFillApplyHandler.resetEasyFill on Clear All / Cancel
|
|
529
|
+
_destroyAllGroupElements();
|
|
554
530
|
EasyFillApplyHandler.resetEasyFill(
|
|
555
531
|
!!bRemoveTextAreaValue,
|
|
556
532
|
oDialogModel(),
|
|
@@ -584,20 +560,14 @@ sap.ui.define([
|
|
|
584
560
|
|
|
585
561
|
// Collect all editable SmartFields from the EasyFill dialog SmartForms
|
|
586
562
|
var aEditableFields = [];
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
aEditableFields.push(oElement);
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
});
|
|
599
|
-
});
|
|
600
|
-
}
|
|
563
|
+
EasyFillFormRenderer.collectSmartForms(oObjectPageLayout).forEach(function(oSmartForm) {
|
|
564
|
+
oSmartForm.getGroups().forEach(function(oGroup) {
|
|
565
|
+
oGroup.getGroupElements().forEach(function(oGroupElement) {
|
|
566
|
+
oGroupElement.getElements().forEach(function(oElement) {
|
|
567
|
+
if (oElement.isA && oElement.isA("sap.ui.comp.smartfield.SmartField") && oElement.getEditable()) {
|
|
568
|
+
aEditableFields.push(oElement);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
601
571
|
});
|
|
602
572
|
});
|
|
603
573
|
});
|
|
@@ -712,8 +682,10 @@ sap.ui.define([
|
|
|
712
682
|
* CRUDManager.addEntry directly ensures the SmartTable binding is refreshed and side
|
|
713
683
|
* effects are executed after the row is created — without that refresh the ObjectPage
|
|
714
684
|
* table would not show the newly created row.
|
|
685
|
+
* Multiple new rows per table are created sequentially to avoid race conditions on
|
|
686
|
+
* the draft document.
|
|
715
687
|
*
|
|
716
|
-
* @param {object} mNewRowValues - map of { navProperty: plainValuesObject }
|
|
688
|
+
* @param {object} mNewRowValues - map of { navProperty: plainValuesObject[] }
|
|
717
689
|
* @returns {Promise<void>}
|
|
718
690
|
*/
|
|
719
691
|
async function _createNewRows(mNewRowValues) {
|
|
@@ -729,13 +701,17 @@ sap.ui.define([
|
|
|
729
701
|
if (!oSmartTable) {
|
|
730
702
|
continue;
|
|
731
703
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
704
|
+
var aRowValues = mNewRowValues[sNavProp];
|
|
705
|
+
// aRowValues is now an array — iterate and create each row sequentially
|
|
706
|
+
if (!Array.isArray(aRowValues)) {
|
|
707
|
+
aRowValues = [aRowValues];
|
|
708
|
+
}
|
|
709
|
+
for (var j = 0; j < aRowValues.length; j++) {
|
|
710
|
+
try {
|
|
711
|
+
await oTemplateUtils.oCommonEventHandlers.addEntry(oSmartTable, true, undefined, aRowValues[j]);
|
|
712
|
+
} catch (e) {
|
|
713
|
+
// addEntry handles its own error messaging via CommonEventHandlers/CRUDManager
|
|
714
|
+
}
|
|
739
715
|
}
|
|
740
716
|
}
|
|
741
717
|
}
|