@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
sap.ui.define([
|
|
2
2
|
"sap/ui/comp/smartfield/SmartField",
|
|
3
|
+
"sap/m/Button",
|
|
3
4
|
"sap/m/GenericTag",
|
|
4
5
|
"sap/m/MessageStrip",
|
|
5
6
|
"sap/m/Text",
|
|
@@ -16,8 +17,8 @@ sap.ui.define([
|
|
|
16
17
|
"sap/uxap/ObjectPageSubSection",
|
|
17
18
|
"sap/ui/core/CustomData",
|
|
18
19
|
"sap/suite/ui/generic/template/genericUtilities/FeLogger",
|
|
19
|
-
"sap/suite/ui/generic/template/
|
|
20
|
-
], function(SmartField, GenericTag, MessageStrip, Text, Title, Table, Column, ColumnListItem, VBox, HBox, ScrollContainer, SegmentedButton, SegmentedButtonItem, ObjectPageSection, ObjectPageSubSection, CustomData, FeLogger,
|
|
20
|
+
"sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector"
|
|
21
|
+
], function(SmartField, Button, GenericTag, MessageStrip, Text, Title, Table, Column, ColumnListItem, VBox, HBox, ScrollContainer, SegmentedButton, SegmentedButtonItem, ObjectPageSection, ObjectPageSubSection, CustomData, FeLogger, EasyFillFieldCollector) {
|
|
21
22
|
"use strict";
|
|
22
23
|
|
|
23
24
|
var sClassName = "lib.ai.EasyFill.EasyFillTableRenderer";
|
|
@@ -39,14 +40,8 @@ sap.ui.define([
|
|
|
39
40
|
* 1. Creates transient OData row contexts for preview rendering.
|
|
40
41
|
* 2. Creates a "Previous Values" read-only table and a "New Values" editable SmartField table.
|
|
41
42
|
* 3. Renders a SegmentedButton toggle between the two views.
|
|
42
|
-
* 4. Injects each collection as an ObjectPageSection into the shared EasyFillObjectPageLayout
|
|
43
|
-
* so the OPL header and anchor bar remain visible while scrolling through table content.
|
|
43
|
+
* 4. Injects each collection as an ObjectPageSection into the shared EasyFillObjectPageLayout.
|
|
44
44
|
* 5. Provides reset logic to discard staged values if the user cancels.
|
|
45
|
-
*
|
|
46
|
-
* Create mode:
|
|
47
|
-
* - Rows without _rowIndex or _contextPath are treated as new rows.
|
|
48
|
-
* - New rows are rendered as editable SmartField rows highlighted with "Information" row highlight.
|
|
49
|
-
* - Transient contexts for new rows are stored in oTableStagingState.mPendingNewRowContexts.
|
|
50
45
|
* - On confirm, EasyFillApplyHandler activates these contexts via submitChanges.
|
|
51
46
|
* - Only one new row per table is created (extra new rows are suppressed upstream).
|
|
52
47
|
*/
|
|
@@ -78,10 +73,6 @@ sap.ui.define([
|
|
|
78
73
|
return;
|
|
79
74
|
}
|
|
80
75
|
|
|
81
|
-
// Remove previously injected table content before re-rendering.
|
|
82
|
-
// On mode switch (bReuseStaging=true) cleanup is done BEFORE the model update
|
|
83
|
-
// in onSelectionChange, so we skip it here to avoid operating on the already-fresh OPL.
|
|
84
|
-
// On first render (bReuseStaging=false) we do the cleanup here.
|
|
85
76
|
if (!bReuseStaging) {
|
|
86
77
|
this._removeTableSections(oObjectPageLayout);
|
|
87
78
|
}
|
|
@@ -108,7 +99,7 @@ sap.ui.define([
|
|
|
108
99
|
// Bound sections always have a "easyFillDialogModel" binding context; manually-added
|
|
109
100
|
// ones never do, so there is no ambiguity.
|
|
110
101
|
var oFilledFieldsSubSection = null; // condensed mode: add table as block inside here
|
|
111
|
-
var oUnfilledFieldsSection
|
|
102
|
+
var oUnfilledFieldsSection = null; // OP mode: insert standalone section before this
|
|
112
103
|
oObjectPageLayout.getSections().forEach(function(oSection) {
|
|
113
104
|
var oCtx = oSection.getBindingContext("easyFillDialogModel");
|
|
114
105
|
if (!oCtx) { return; }
|
|
@@ -127,32 +118,26 @@ sap.ui.define([
|
|
|
127
118
|
|
|
128
119
|
// iInsertOffset keeps multiple consecutive tables in the correct order when
|
|
129
120
|
// inserting standalone sections before the Unfilled Fields section (OP mode).
|
|
121
|
+
// iBaseInsertIndex is captured ONCE before any insertions so it does not shift
|
|
122
|
+
// as tables are added — each table is inserted at base + offset, not re-queried.
|
|
123
|
+
var iBaseInsertIndex = oUnfilledFieldsSection
|
|
124
|
+
? oObjectPageLayout.indexOfSection(oUnfilledFieldsSection) : -1;
|
|
130
125
|
var iInsertOffset = 0;
|
|
131
|
-
|
|
132
126
|
var that = this;
|
|
133
127
|
var oRejected = mCollectionsWithRejectedNewRows || {};
|
|
134
128
|
|
|
135
|
-
// Render "all rejected" tables: AI only proposed new rows, creation not allowed.
|
|
136
|
-
// These collections have no entry in mCollectionUpdates so they need their own loop.
|
|
137
129
|
Object.keys(oRejected).forEach(function(sCollectionName) {
|
|
138
|
-
if (oRejected[sCollectionName] !== "all") {
|
|
139
|
-
return; // "mixed" is handled below alongside the diff table
|
|
140
|
-
}
|
|
130
|
+
if (oRejected[sCollectionName] !== "all") { return; }
|
|
141
131
|
var oCollectionMeta = mFieldMapping[sCollectionName];
|
|
142
132
|
var sTitle = (oCollectionMeta && oCollectionMeta.description) || sCollectionName;
|
|
143
|
-
var oStrip = new MessageStrip({
|
|
144
|
-
text: oRb.getText("EASY_FILL_TABLE_NEW_ROW_NOT_ALLOWED"),
|
|
145
|
-
type: "Warning",
|
|
146
|
-
showIcon: true
|
|
147
|
-
});
|
|
133
|
+
var oStrip = new MessageStrip({ text: oRb.getText("EASY_FILL_TABLE_NEW_ROW_NOT_ALLOWED"), type: "Warning", showIcon: true });
|
|
148
134
|
var oNotifVBox = new VBox({ items: [oStrip] });
|
|
149
135
|
oNotifVBox.addCustomData(new CustomData({ key: sTableSectionMarker, value: "true" }));
|
|
150
136
|
var oNotifSubSection = new ObjectPageSubSection({ title: sTitle, titleUppercase: false, blocks: [oNotifVBox] });
|
|
151
137
|
var oNotifSection = new ObjectPageSection({ title: sTitle, titleUppercase: false, subSections: [oNotifSubSection] });
|
|
152
138
|
oNotifSection.addCustomData(new CustomData({ key: sTableSectionMarker, value: "true" }));
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
oObjectPageLayout.insertSection(oNotifSection, iRejectedAt + iInsertOffset);
|
|
139
|
+
if (iBaseInsertIndex >= 0) {
|
|
140
|
+
oObjectPageLayout.insertSection(oNotifSection, iBaseInsertIndex + iInsertOffset);
|
|
156
141
|
iInsertOffset++;
|
|
157
142
|
} else {
|
|
158
143
|
oObjectPageLayout.addSection(oNotifSection);
|
|
@@ -162,100 +147,136 @@ sap.ui.define([
|
|
|
162
147
|
|
|
163
148
|
Object.keys(mCollectionUpdates).forEach(function(sCollectionName) {
|
|
164
149
|
var oCollectionMeta = mFieldMapping[sCollectionName];
|
|
165
|
-
if (!oCollectionMeta || !oCollectionMeta.itemProperties) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
150
|
+
if (!oCollectionMeta || !oCollectionMeta.itemProperties) { return; }
|
|
169
151
|
var aPropertyNames = Object.keys(oCollectionMeta.itemProperties || {});
|
|
170
|
-
if (!aPropertyNames.length) {
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
var aPreviewRows = (oTableStagingState.mStagedRows[sCollectionName] || []).filter(function(oStagedRow) {
|
|
174
|
-
return oStagedRow.isPreviewVisible;
|
|
175
|
-
});
|
|
152
|
+
if (!aPropertyNames.length) { return; }
|
|
153
|
+
|
|
154
|
+
var aPreviewRows = (oTableStagingState.mStagedRows[sCollectionName] || []).filter(function(r) { return r.isPreviewVisible; });
|
|
176
155
|
var aNewRows = oTableStagingState.mPendingNewRowContexts[sCollectionName] || [];
|
|
177
156
|
var bHasUneditableChanges = aPreviewRows.some(function(oPreviewRow) {
|
|
178
|
-
return oPreviewRow.update && that._hasUneditableCollectionChanges(oPreviewRow.update, sCollectionName, {
|
|
179
|
-
context: oPreviewRow.realContext,
|
|
180
|
-
rowIndex: oPreviewRow.rowIndex
|
|
181
|
-
}, mCollectionState);
|
|
157
|
+
return oPreviewRow.update && that._hasUneditableCollectionChanges(oPreviewRow.update, sCollectionName, { context: oPreviewRow.realContext, rowIndex: oPreviewRow.rowIndex }, mCollectionState);
|
|
182
158
|
});
|
|
183
|
-
if (!aPreviewRows.length && !aNewRows.length) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
159
|
+
if (!aPreviewRows.length && !aNewRows.length) { return; }
|
|
186
160
|
|
|
187
161
|
var iExistingRowCount = aPreviewRows.length;
|
|
188
162
|
var iNewRowCount = aNewRows.length;
|
|
189
163
|
var iTotalCount = iExistingRowCount + iNewRowCount;
|
|
190
164
|
|
|
191
|
-
|
|
192
|
-
var aPreviousRows = aPreviewRows.map(function(oPreviewRow) {
|
|
193
|
-
return that._buildCollectionPreviewRowFromContext(aPropertyNames, oPreviewRow.realContext);
|
|
194
|
-
});
|
|
165
|
+
var aPreviousRows = aPreviewRows.map(function(r) { return that._buildCollectionPreviewRowFromContext(aPropertyNames, r.realContext); });
|
|
195
166
|
var oPreviousTable = that._createPreviewTable(aPropertyNames, oCollectionMeta.itemProperties, aPreviousRows);
|
|
196
167
|
oPreviousTable.setVisible(false);
|
|
197
168
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
169
|
+
var aItemMetaOut = [];
|
|
170
|
+
var oNewTable = that._createEditableNewTable(aPropertyNames, oCollectionMeta.itemProperties, aPreviewRows, aNewRows, sCollectionName, mCollectionState, fnOnTableFieldChange, aItemMetaOut);
|
|
171
|
+
|
|
172
|
+
// "Exclude Changes" button — disabled until at least 1 active (non-excluded) row is checked
|
|
173
|
+
var oExcludeButton = new Button({
|
|
174
|
+
text: oRb.getText("EASY_FILL_EXCLUDE_ROW_BUTTON"),
|
|
175
|
+
type: "Ghost",
|
|
176
|
+
enabled: false
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Re-evaluate button enabled state whenever a checkbox changes
|
|
180
|
+
function refreshExcludeButtonState() {
|
|
181
|
+
var bAnyActiveChecked = aItemMetaOut.some(function(oMeta) {
|
|
182
|
+
if (!oMeta.item.isSelected()) { return false; }
|
|
183
|
+
var oExcludedSet = oMeta.isNew
|
|
184
|
+
? oTableStagingState.mExcludedNewRows[sCollectionName]
|
|
185
|
+
: oTableStagingState.mExcludedRows[sCollectionName];
|
|
186
|
+
return !oExcludedSet || !oExcludedSet[oMeta.index];
|
|
187
|
+
});
|
|
188
|
+
oExcludeButton.setEnabled(bAnyActiveChecked);
|
|
189
|
+
}
|
|
209
190
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
191
|
+
// Re-apply excluded row visual state after re-render (e.g. Condensed ↔ OP mode switch).
|
|
192
|
+
// mExcludedRows/mExcludedNewRows survive the mode switch but new controls are created fresh.
|
|
193
|
+
aItemMetaOut.forEach(function(oMeta) {
|
|
194
|
+
var mTarget = oMeta.isNew ? oTableStagingState.mExcludedNewRows : oTableStagingState.mExcludedRows;
|
|
195
|
+
var oExcludedSet = mTarget && mTarget[sCollectionName];
|
|
196
|
+
if (!oExcludedSet || !oExcludedSet[oMeta.index]) { return; }
|
|
197
|
+
|
|
198
|
+
oMeta.item.addStyleClass("sapEasyFillExcludedRow");
|
|
199
|
+
oMeta.item.getCells().forEach(function(oCell) {
|
|
200
|
+
if (oCell.isA && oCell.isA("sap.ui.comp.smartfield.SmartField")) {
|
|
201
|
+
oCell.setEditable(false);
|
|
202
|
+
oCell.setEnabled(false);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
});
|
|
216
206
|
|
|
217
|
-
var
|
|
218
|
-
|
|
207
|
+
var oActualTable = oNewTable.getContent && oNewTable.getContent()[0];
|
|
208
|
+
if (oActualTable) {
|
|
209
|
+
oActualTable.attachSelectionChange(function(oEvent) {
|
|
210
|
+
if (oEvent.getParameter("selectAll")) {
|
|
211
|
+
aItemMetaOut.forEach(function(oMeta) {
|
|
212
|
+
var oExcludedSet = oMeta.isNew
|
|
213
|
+
? oTableStagingState.mExcludedNewRows[sCollectionName]
|
|
214
|
+
: oTableStagingState.mExcludedRows[sCollectionName];
|
|
215
|
+
if (oExcludedSet && oExcludedSet[oMeta.index]) {
|
|
216
|
+
oMeta.item.setSelected(false);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
refreshExcludeButtonState();
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
oExcludeButton.attachPress(function() {
|
|
225
|
+
aItemMetaOut.forEach(function(oMeta) {
|
|
226
|
+
if (!oMeta.item.isSelected()) { return; }
|
|
227
|
+
var mTarget = oMeta.isNew ? oTableStagingState.mExcludedNewRows : oTableStagingState.mExcludedRows;
|
|
228
|
+
var oExcludedSet = mTarget[sCollectionName];
|
|
229
|
+
if (oExcludedSet && oExcludedSet[oMeta.index]) { return; } // already excluded
|
|
230
|
+
|
|
231
|
+
if (!mTarget[sCollectionName]) { mTarget[sCollectionName] = Object.create(null); }
|
|
232
|
+
mTarget[sCollectionName][oMeta.index] = true;
|
|
233
|
+
|
|
234
|
+
oMeta.item.addStyleClass("sapEasyFillExcludedRow");
|
|
235
|
+
oMeta.item.getCells().forEach(function(oCell) {
|
|
236
|
+
if (oCell.isA && oCell.isA("sap.ui.comp.smartfield.SmartField")) {
|
|
237
|
+
oCell.setEditable(false);
|
|
238
|
+
oCell.setEnabled(false);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
oMeta.item.setSelected(false);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
oExcludeButton.setEnabled(false);
|
|
245
|
+
if (typeof fnOnTableFieldChange === "function") { fnOnTableFieldChange(); }
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
var oReadonlyTag = bHasUneditableChanges ? new GenericTag({ text: oRb.getText("EASYFILL_TABLE_READONLY_TAG"), status: "Warning" }).addStyleClass("sapUiTinyMarginBegin") : null;
|
|
249
|
+
var sLabel = oCollectionMeta.description || sCollectionName;
|
|
250
|
+
var oTitleControl = new Title({ text: sLabel + " (" + iTotalCount + ")", titleStyle: "H4" });
|
|
219
251
|
|
|
220
|
-
// Toggle button between "Previous" and "New" views
|
|
221
252
|
var oSegmentedButton = new SegmentedButton({
|
|
222
|
-
selectedKey: "new",
|
|
223
|
-
width: "auto",
|
|
253
|
+
selectedKey: "new", width: "auto",
|
|
224
254
|
items: [
|
|
225
255
|
new SegmentedButtonItem({ key: "previous", text: oRb.getText("EASY_FILL_TABLE_VIEW_PREVIOUS"), width: "auto" }),
|
|
226
|
-
new SegmentedButtonItem({ key: "new",
|
|
256
|
+
new SegmentedButtonItem({ key: "new", text: oRb.getText("EASY_FILL_TABLE_VIEW_NEW"), width: "auto" })
|
|
227
257
|
],
|
|
228
258
|
selectionChange: function() {
|
|
229
259
|
var sKey = oSegmentedButton.getSelectedKey();
|
|
230
260
|
oPreviousTable.setVisible(sKey === "previous");
|
|
231
261
|
oNewTable.setVisible(sKey === "new");
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
oTitleControl.setText(sCollectionName_label + " (" + (sKey === "previous" ? iExistingRowCount : iTotalCount) + ")");
|
|
262
|
+
oExcludeButton.setVisible(sKey === "new");
|
|
263
|
+
if (oReadonlyTag) { oReadonlyTag.setVisible(sKey === "new"); }
|
|
264
|
+
oTitleControl.setText(sLabel + " (" + (sKey === "previous" ? iExistingRowCount : iTotalCount) + ")");
|
|
236
265
|
}
|
|
237
266
|
});
|
|
238
|
-
|
|
267
|
+
|
|
268
|
+
var oLeftGroup = new HBox({ alignItems: "Center", items: oReadonlyTag ? [oTitleControl, oReadonlyTag] : [oTitleControl] });
|
|
269
|
+
var oRightGroup = new HBox({ alignItems: "Center", items: [oExcludeButton, oSegmentedButton] });
|
|
239
270
|
var oHeader = new HBox({
|
|
240
|
-
justifyContent: "SpaceBetween",
|
|
241
|
-
|
|
242
|
-
wrap: "Wrap",
|
|
243
|
-
items: [oTitleControl].concat(aRightItems)
|
|
271
|
+
justifyContent: "SpaceBetween", alignItems: "Center", wrap: "Wrap",
|
|
272
|
+
items: [oLeftGroup, oRightGroup]
|
|
244
273
|
}).addStyleClass("sapUiSmallMarginTop sapUiSmallMarginBottom");
|
|
245
274
|
|
|
246
|
-
var oTableVBox = new VBox({
|
|
247
|
-
|
|
248
|
-
}).addStyleClass("sapSmartTemplatesObjectPageEasyFillTableSection");
|
|
275
|
+
var oTableVBox = new VBox({ items: [oHeader, oPreviousTable, oNewTable] })
|
|
276
|
+
.addStyleClass("sapSmartTemplatesObjectPageEasyFillTableSection");
|
|
249
277
|
|
|
250
|
-
// "mixed" rejection: AI also proposed new rows but creation is not allowed.
|
|
251
|
-
// Show a warning strip after the toggle header, before the tables.
|
|
252
278
|
if (oRejected[sCollectionName] === "mixed") {
|
|
253
|
-
|
|
254
|
-
text: oRb.getText("EASY_FILL_TABLE_NEW_ROW_NOT_ALLOWED"),
|
|
255
|
-
type: "Warning",
|
|
256
|
-
showIcon: true
|
|
257
|
-
});
|
|
258
|
-
oTableVBox.insertItem(oRejectionStrip, 1); // after toggle header, before tables
|
|
279
|
+
oTableVBox.insertItem(new MessageStrip({ text: oRb.getText("EASY_FILL_TABLE_NEW_ROW_NOT_ALLOWED"), type: "Warning", showIcon: true }), 1);
|
|
259
280
|
}
|
|
260
281
|
|
|
261
282
|
if (bIsCondensedMode && oFilledFieldsSubSection) {
|
|
@@ -269,12 +290,9 @@ sap.ui.define([
|
|
|
269
290
|
|
|
270
291
|
// Check if a wrapper VBox already exists (multiple collections: re-use it)
|
|
271
292
|
var aExistingBlocks = oFilledFieldsSubSection.getBlocks();
|
|
272
|
-
var oExistingWrapper = aExistingBlocks.find(function(
|
|
273
|
-
return
|
|
274
|
-
return oData.getKey() === sCondensedWrapperMarker;
|
|
275
|
-
});
|
|
293
|
+
var oExistingWrapper = aExistingBlocks.find(function(b) {
|
|
294
|
+
return b.getCustomData && b.getCustomData().some(function(d) { return d.getKey() === sCondensedWrapperMarker; });
|
|
276
295
|
});
|
|
277
|
-
|
|
278
296
|
if (oExistingWrapper) {
|
|
279
297
|
// Append the new table VBox to the already-created wrapper
|
|
280
298
|
oExistingWrapper.addItem(oTableVBox);
|
|
@@ -283,13 +301,8 @@ sap.ui.define([
|
|
|
283
301
|
// place them inside a new wrapper VBox alongside the table VBox,
|
|
284
302
|
// and add the wrapper as the sole block.
|
|
285
303
|
var aOriginalBlocks = aExistingBlocks.slice();
|
|
286
|
-
aOriginalBlocks.forEach(function(
|
|
287
|
-
|
|
288
|
-
});
|
|
289
|
-
var oWrapper = new VBox({
|
|
290
|
-
width: "100%",
|
|
291
|
-
items: aOriginalBlocks.concat([oTableVBox])
|
|
292
|
-
});
|
|
304
|
+
aOriginalBlocks.forEach(function(b) { oFilledFieldsSubSection.removeBlock(b); });
|
|
305
|
+
var oWrapper = new VBox({ width: "100%", items: aOriginalBlocks.concat([oTableVBox]) });
|
|
293
306
|
oWrapper.addCustomData(new CustomData({ key: sCondensedWrapperMarker, value: "true" }));
|
|
294
307
|
oFilledFieldsSubSection.addBlock(oWrapper);
|
|
295
308
|
}
|
|
@@ -298,24 +311,14 @@ sap.ui.define([
|
|
|
298
311
|
// Wrap in a standalone ObjectPageSection so the anchor bar shows the table
|
|
299
312
|
// name. Insert just before the Unfilled Fields section (if present) so the
|
|
300
313
|
// order is: annotation sections → table sections → Unfilled Fields.
|
|
301
|
-
var oSubSection = new ObjectPageSubSection({
|
|
302
|
-
|
|
303
|
-
titleUppercase: false,
|
|
304
|
-
showTitle: false,
|
|
305
|
-
blocks: [oTableVBox]
|
|
306
|
-
});
|
|
307
|
-
var oOpSection = new ObjectPageSection({
|
|
308
|
-
title: sCollectionName_label,
|
|
309
|
-
titleUppercase: false,
|
|
310
|
-
subSections: [oSubSection]
|
|
311
|
-
});
|
|
314
|
+
var oSubSection = new ObjectPageSubSection({ title: sLabel, titleUppercase: false, showTitle: false, blocks: [oTableVBox] });
|
|
315
|
+
var oOpSection = new ObjectPageSection({ title: sLabel, titleUppercase: false, subSections: [oSubSection] });
|
|
312
316
|
oOpSection.addCustomData(new CustomData({ key: sTableSectionMarker, value: "true" }));
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
|
|
318
|
-
oObjectPageLayout.insertSection(oOpSection, iInsertAt + iInsertOffset);
|
|
317
|
+
if (iBaseInsertIndex >= 0) {
|
|
318
|
+
// Use the base index captured before any insertions — not re-queried.
|
|
319
|
+
// This prevents the second+ table from overshooting past Unfilled Fields
|
|
320
|
+
// because indexOfSection(oUnfilledFieldsSection) shifts as tables are added.
|
|
321
|
+
oObjectPageLayout.insertSection(oOpSection, iBaseInsertIndex + iInsertOffset);
|
|
319
322
|
iInsertOffset++;
|
|
320
323
|
} else {
|
|
321
324
|
oObjectPageLayout.addSection(oOpSection);
|
|
@@ -374,17 +377,16 @@ sap.ui.define([
|
|
|
374
377
|
// ─── Private Helpers ─────────────────────────────────────────────────────
|
|
375
378
|
|
|
376
379
|
/**
|
|
377
|
-
* Removes all ObjectPageSections
|
|
378
|
-
* Identified by the custom data
|
|
380
|
+
* Removes all ObjectPageSections and condensed-mode wrapper VBoxes that were
|
|
381
|
+
* dynamically added by renderCollectionPreviews. Identified by the custom data
|
|
382
|
+
* marker keys set during creation.
|
|
379
383
|
*
|
|
380
384
|
* @param {sap.uxap.ObjectPageLayout} oObjectPageLayout
|
|
381
385
|
*/
|
|
382
386
|
_removeTableSections: function(oObjectPageLayout) {
|
|
383
387
|
// OP mode: remove marked standalone ObjectPageSections.
|
|
384
388
|
oObjectPageLayout.getSections().filter(function(oSection) {
|
|
385
|
-
return oSection.getCustomData().some(function(oData) {
|
|
386
|
-
return oData.getKey() === sTableSectionMarker;
|
|
387
|
-
});
|
|
389
|
+
return oSection.getCustomData().some(function(oData) { return oData.getKey() === sTableSectionMarker; });
|
|
388
390
|
}).forEach(function(oSection) {
|
|
389
391
|
oObjectPageLayout.removeSection(oSection);
|
|
390
392
|
oSection.destroy();
|
|
@@ -395,22 +397,14 @@ sap.ui.define([
|
|
|
395
397
|
oObjectPageLayout.getSections().forEach(function(oSection) {
|
|
396
398
|
oSection.getSubSections().forEach(function(oSubSec) {
|
|
397
399
|
oSubSec.getBlocks().filter(function(oBlock) {
|
|
398
|
-
return oBlock.getCustomData && oBlock.getCustomData().some(function(
|
|
399
|
-
return oData.getKey() === sCondensedWrapperMarker;
|
|
400
|
-
});
|
|
400
|
+
return oBlock.getCustomData && oBlock.getCustomData().some(function(d) { return d.getKey() === sCondensedWrapperMarker; });
|
|
401
401
|
}).forEach(function(oWrapper) {
|
|
402
402
|
// Separate original (non-table) items from table VBox items
|
|
403
403
|
var aItems = oWrapper.getItems().slice();
|
|
404
404
|
aItems.forEach(function(oItem) {
|
|
405
|
-
var bIsTableVBox = oItem.getCustomData && oItem.getCustomData().some(function(
|
|
406
|
-
return oData.getKey() === sTableSectionMarker;
|
|
407
|
-
});
|
|
405
|
+
var bIsTableVBox = oItem.getCustomData && oItem.getCustomData().some(function(d) { return d.getKey() === sTableSectionMarker; });
|
|
408
406
|
oWrapper.removeItem(oItem);
|
|
409
|
-
if (bIsTableVBox) {
|
|
410
|
-
oItem.destroy();
|
|
411
|
-
} else {
|
|
412
|
-
oSubSec.addBlock(oItem); // restore SmartForm
|
|
413
|
-
}
|
|
407
|
+
if (bIsTableVBox) { oItem.destroy(); } else { oSubSec.addBlock(oItem); } // restore SmartForm
|
|
414
408
|
});
|
|
415
409
|
oSubSec.removeBlock(oWrapper);
|
|
416
410
|
oWrapper.destroy();
|
|
@@ -571,9 +565,10 @@ sap.ui.define([
|
|
|
571
565
|
* @param {string} sCollectionName - navigation property name (used to look up property metadata)
|
|
572
566
|
* @param {object} mCollectionState - collection tracking state (used to get property metadata)
|
|
573
567
|
* @param {function} fnOnTableFieldChange - callback when a cell value changes
|
|
568
|
+
* @param {Array} [aItemMetaOut] - optional collector: receives { item, isNew, index } per row
|
|
574
569
|
* @returns {sap.m.ScrollContainer} ScrollContainer wrapping the table with horizontal scrolling enabled
|
|
575
570
|
*/
|
|
576
|
-
_createEditableNewTable: function(aPropertyNames, oItemProperties, aPreviewRows, aNewRowContexts, sCollectionName, mCollectionState, fnOnTableFieldChange) {
|
|
571
|
+
_createEditableNewTable: function(aPropertyNames, oItemProperties, aPreviewRows, aNewRowContexts, sCollectionName, mCollectionState, fnOnTableFieldChange, aItemMetaOut) {
|
|
577
572
|
var aColumns = aPropertyNames.map(function(sPropName) {
|
|
578
573
|
return new Column({
|
|
579
574
|
header: new Text({
|
|
@@ -587,7 +582,7 @@ sap.ui.define([
|
|
|
587
582
|
var that = this;
|
|
588
583
|
|
|
589
584
|
// Rows for existing rows with AI-proposed updates
|
|
590
|
-
var aExistingItems = aPreviewRows.map(function(oPreviewRow) {
|
|
585
|
+
var aExistingItems = aPreviewRows.map(function(oPreviewRow, iIndex) {
|
|
591
586
|
var oContext = oPreviewRow.transientContext;
|
|
592
587
|
var oRowObject = oPreviewRow.realContext && oPreviewRow.realContext.getObject && oPreviewRow.realContext.getObject();
|
|
593
588
|
|
|
@@ -631,6 +626,11 @@ sap.ui.define([
|
|
|
631
626
|
if (oContext) {
|
|
632
627
|
oItem.setBindingContext(oContext);
|
|
633
628
|
}
|
|
629
|
+
|
|
630
|
+
if (Array.isArray(aItemMetaOut)) {
|
|
631
|
+
aItemMetaOut.push({ item: oItem, isNew: false, index: iIndex });
|
|
632
|
+
}
|
|
633
|
+
|
|
634
634
|
return oItem;
|
|
635
635
|
});
|
|
636
636
|
|
|
@@ -638,7 +638,7 @@ sap.ui.define([
|
|
|
638
638
|
// sEntitySetName is set explicitly on SmartField so it can resolve OData metadata
|
|
639
639
|
// even though it lives inside a plain sap.m.Table (not a SmartTable).
|
|
640
640
|
var sEntitySetName = (oEntitySet && oEntitySet.name) || sCollectionName;
|
|
641
|
-
var aNewItems = (aNewRowContexts || []).map(function(oNewContext) {
|
|
641
|
+
var aNewItems = (aNewRowContexts || []).map(function(oNewContext, iIndex) {
|
|
642
642
|
var aCells = aPropertyNames.map(function(sPropName) {
|
|
643
643
|
if (!oNewContext) {
|
|
644
644
|
return new Text({ text: "" });
|
|
@@ -668,17 +668,24 @@ sap.ui.define([
|
|
|
668
668
|
});
|
|
669
669
|
return oSmartField;
|
|
670
670
|
});
|
|
671
|
+
|
|
671
672
|
var oItem = new ColumnListItem({
|
|
672
673
|
cells: aCells,
|
|
673
674
|
highlight: "Information"
|
|
674
675
|
});
|
|
675
676
|
oItem.setBindingContext(oNewContext);
|
|
677
|
+
|
|
678
|
+
if (Array.isArray(aItemMetaOut)) {
|
|
679
|
+
aItemMetaOut.push({ item: oItem, isNew: true, index: iIndex });
|
|
680
|
+
}
|
|
681
|
+
|
|
676
682
|
return oItem;
|
|
677
683
|
});
|
|
678
684
|
|
|
679
685
|
var oTable = new Table({
|
|
680
686
|
columns: aColumns,
|
|
681
687
|
items: aExistingItems.concat(aNewItems),
|
|
688
|
+
mode: "MultiSelect",
|
|
682
689
|
fixedLayout: false,
|
|
683
690
|
autoPopinMode: false
|
|
684
691
|
}).addStyleClass("sapSmartTemplatesObjectPageEasyFillTablePreview");
|
|
@@ -751,6 +758,12 @@ sap.ui.define([
|
|
|
751
758
|
Object.keys((oTableStagingState && oTableStagingState.mPendingNewRowContexts) || {}).forEach(function(sCollectionName) {
|
|
752
759
|
delete oTableStagingState.mPendingNewRowContexts[sCollectionName];
|
|
753
760
|
});
|
|
761
|
+
Object.keys((oTableStagingState && oTableStagingState.mExcludedRows) || {}).forEach(function(sCollectionName) {
|
|
762
|
+
delete oTableStagingState.mExcludedRows[sCollectionName];
|
|
763
|
+
});
|
|
764
|
+
Object.keys((oTableStagingState && oTableStagingState.mExcludedNewRows) || {}).forEach(function(sCollectionName) {
|
|
765
|
+
delete oTableStagingState.mExcludedNewRows[sCollectionName];
|
|
766
|
+
});
|
|
754
767
|
},
|
|
755
768
|
|
|
756
769
|
/**
|
|
@@ -860,63 +873,16 @@ sap.ui.define([
|
|
|
860
873
|
},
|
|
861
874
|
|
|
862
875
|
/**
|
|
863
|
-
*
|
|
864
|
-
*
|
|
865
|
-
* Duplicated here to keep TableRenderer self-contained (no circular dependency).
|
|
876
|
+
* Delegates property editability check to EasyFillFieldCollector.isEditableByContextObject —
|
|
877
|
+
* the single authoritative implementation shared across all EasyFill modules.
|
|
866
878
|
*
|
|
867
879
|
* @param {object} oPropertyMeta - OData property metadata
|
|
868
880
|
* @param {object} oRowObject - plain row data object
|
|
881
|
+
* @param {object} oEntitySet - OData entity set metadata
|
|
869
882
|
* @returns {boolean}
|
|
870
883
|
*/
|
|
871
884
|
_isEditableProperty: function(oPropertyMeta, oRowObject, oEntitySet) {
|
|
872
|
-
|
|
873
|
-
return false;
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
// Check entity-set-level sap:updatable (entire entity set is read-only)
|
|
877
|
-
if (oEntitySet) {
|
|
878
|
-
var sEntitySetUpdatable = oEntitySet["sap:updatable"];
|
|
879
|
-
if (sEntitySetUpdatable === "false") {
|
|
880
|
-
return false;
|
|
881
|
-
}
|
|
882
|
-
// sap:updatable-path: resolved against the row context object (boolean property)
|
|
883
|
-
var sEntitySetUpdatablePath = oEntitySet["sap:updatable-path"];
|
|
884
|
-
if (sEntitySetUpdatablePath && oRowObject) {
|
|
885
|
-
var bUpdatableFromPath = oRowObject[sEntitySetUpdatablePath];
|
|
886
|
-
if (bUpdatableFromPath === false || bUpdatableFromPath === "false") {
|
|
887
|
-
return false;
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
var sUpdatable = oPropertyMeta["sap:updatable"];
|
|
893
|
-
if (sUpdatable) {
|
|
894
|
-
return sUpdatable !== "false";
|
|
895
|
-
}
|
|
896
|
-
var oAnnotation = oPropertyMeta["com.sap.vocabularies.Common.v1.FieldControl"];
|
|
897
|
-
if (oAnnotation && oAnnotation["EnumMember"]) {
|
|
898
|
-
return oAnnotation["EnumMember"] !== "com.sap.vocabularies.Common.v1.FieldControlType/ReadOnly";
|
|
899
|
-
}
|
|
900
|
-
// Dynamic FieldControl via Path (e.g. { "Path": "SomeField_fc" })
|
|
901
|
-
// FieldControl values: 0=Hidden, 1=ReadOnly, 3=Optional, 7=Mandatory
|
|
902
|
-
if (oAnnotation && oAnnotation["Path"]) {
|
|
903
|
-
var iDynamicFieldControl = oRowObject && oRowObject[oAnnotation["Path"]];
|
|
904
|
-
if (iDynamicFieldControl !== undefined && iDynamicFieldControl !== null) {
|
|
905
|
-
return iDynamicFieldControl !== 0 && iDynamicFieldControl !== 1;
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
// Check "sap:field-control" dynamic path (value 1 = read-only)
|
|
909
|
-
// If the _fc property is defined in metadata but its runtime value is absent from
|
|
910
|
-
// the row object (not fetched / not in $select), treat as non-editable (safe fallback).
|
|
911
|
-
var sFieldControl = oPropertyMeta["sap:field-control"];
|
|
912
|
-
if (sFieldControl) {
|
|
913
|
-
if (!oRowObject || !(sFieldControl in oRowObject)) {
|
|
914
|
-
return false;
|
|
915
|
-
}
|
|
916
|
-
var iFieldControlValue = oRowObject[sFieldControl];
|
|
917
|
-
return iFieldControlValue !== 0 && iFieldControlValue !== 1;
|
|
918
|
-
}
|
|
919
|
-
return true;
|
|
885
|
+
return EasyFillFieldCollector.isEditableByContextObject(oPropertyMeta, oRowObject, oEntitySet);
|
|
920
886
|
},
|
|
921
887
|
|
|
922
888
|
/**
|