@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
|
@@ -2,10 +2,11 @@ sap.ui.define([
|
|
|
2
2
|
"sap/ui/comp/smartform/GroupElement",
|
|
3
3
|
"sap/ui/comp/smartfield/SmartField",
|
|
4
4
|
"sap/m/Text",
|
|
5
|
+
"sap/m/Link",
|
|
6
|
+
"sap/m/Button",
|
|
5
7
|
"sap/ui/layout/form/ColumnElementData",
|
|
6
|
-
"sap/suite/ui/generic/template/genericUtilities/FeLogger"
|
|
7
|
-
|
|
8
|
-
], function(GroupElement, SmartField, Text, ColumnElementData, FeLogger, FeError) {
|
|
8
|
+
"sap/suite/ui/generic/template/genericUtilities/FeLogger"
|
|
9
|
+
], function(GroupElement, SmartField, Text, Link, Button, ColumnElementData, FeLogger) {
|
|
9
10
|
"use strict";
|
|
10
11
|
|
|
11
12
|
var sClassName = "lib.ai.EasyFill.EasyFillFormRenderer";
|
|
@@ -28,103 +29,101 @@ sap.ui.define([
|
|
|
28
29
|
return {
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* - Creates a display-only SmartField bound to the OP context (if non-updatable).
|
|
32
|
+
* Collects all SmartForm controls from an ObjectPageLayout.
|
|
33
|
+
* In condensed mode the SmartForm is nested inside a wrapper VBox; this helper
|
|
34
|
+
* handles that one-level-deep wrapping transparently.
|
|
35
|
+
* Extracted as a shared helper so EasyFillHandler no longer duplicates this walk.
|
|
36
36
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @param {string} sId - the CustomData "id" value identifying the target SmartForm group
|
|
41
|
-
* @param {Array<string>} aFields - array of property names to render as SmartFields
|
|
42
|
-
* @param {string} sEasyFillMode - current layout mode (Condensed / ObjectPage) — for future use
|
|
43
|
-
* @param {object} oController - MVC controller (used to byId the ObjectPageLayout)
|
|
44
|
-
* @param {object} oTransientContextForEasyFill - transient OData context for AI-suggested values
|
|
45
|
-
* @param {object} oObjectPageContext - original ObjectPage binding context (current values)
|
|
46
|
-
* @param {object} mUpdatableLookupMap - map of { fieldName: value } for updatable fields only
|
|
47
|
-
* @param {object} oLLMData - flat map of { fieldName: aiValue } from the LLM response
|
|
48
|
-
* @returns {boolean} always returns true (used as a formatter return value in XML)
|
|
37
|
+
* @param {object} oObjectPageLayout - sap.uxap.ObjectPageLayout
|
|
38
|
+
* @returns {Array<sap.ui.comp.smartform.SmartForm>}
|
|
49
39
|
*/
|
|
50
|
-
|
|
51
|
-
var
|
|
52
|
-
if (!oObjectPageLayout
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// matching the given CustomData "id" value.
|
|
64
|
-
// In condensed mode the SmartForm may be nested inside a wrapper VBox
|
|
65
|
-
// (used to prevent BlockLayout from placing the table side-by-side with
|
|
66
|
-
// the SmartForm on resize). We therefore check one level deeper when the
|
|
67
|
-
// direct block is not a SmartForm.
|
|
68
|
-
oObjectPageLayout.getSections().forEach(function(oSection) {
|
|
69
|
-
oSection.getSubSections().forEach(function(oSubSection) {
|
|
70
|
-
oSubSection.getBlocks().forEach(function(oBlock) {
|
|
71
|
-
var aSmartFormCandidates = [];
|
|
72
|
-
if (oBlock.isA("sap.ui.comp.smartform.SmartForm")) {
|
|
73
|
-
aSmartFormCandidates.push(oBlock);
|
|
74
|
-
} else if (typeof oBlock.getItems === "function") {
|
|
75
|
-
// Look one level inside (e.g. condensed-mode wrapper VBox)
|
|
76
|
-
oBlock.getItems().forEach(function(oItem) {
|
|
77
|
-
if (oItem.isA("sap.ui.comp.smartform.SmartForm")) {
|
|
78
|
-
aSmartFormCandidates.push(oItem);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
aSmartFormCandidates.forEach(function(oSmartForm) {
|
|
83
|
-
oSmartForm.getGroups().forEach(function(oGroup) {
|
|
84
|
-
var oMatchedCustomData = oGroup.getCustomData().find(function(oData) {
|
|
85
|
-
return oData.getKey() === "id" && oData.getValue() === sId;
|
|
86
|
-
});
|
|
87
|
-
if (oMatchedCustomData) {
|
|
88
|
-
oTargetGroup = oGroup;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
40
|
+
collectSmartForms: function(oObjectPageLayout) {
|
|
41
|
+
var aForms = [];
|
|
42
|
+
if (!oObjectPageLayout) { return aForms; }
|
|
43
|
+
oObjectPageLayout.getSections().forEach(function(oSection) {
|
|
44
|
+
oSection.getSubSections().forEach(function(oSubSection) {
|
|
45
|
+
oSubSection.getBlocks().forEach(function(oBlock) {
|
|
46
|
+
if (oBlock.isA("sap.ui.comp.smartform.SmartForm")) {
|
|
47
|
+
aForms.push(oBlock);
|
|
48
|
+
} else if (typeof oBlock.getItems === "function") {
|
|
49
|
+
oBlock.getItems().forEach(function(oItem) {
|
|
50
|
+
if (oItem.isA("sap.ui.comp.smartform.SmartForm")) {
|
|
51
|
+
aForms.push(oItem);
|
|
52
|
+
}
|
|
91
53
|
});
|
|
92
|
-
}
|
|
54
|
+
}
|
|
93
55
|
});
|
|
94
56
|
});
|
|
57
|
+
});
|
|
58
|
+
return aForms;
|
|
59
|
+
},
|
|
95
60
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Finds a SmartForm.Group by its CustomData "id" value within an ObjectPageLayout.
|
|
63
|
+
* Returns null if not found. O(groups) — linear in the number of groups across all forms.
|
|
64
|
+
*
|
|
65
|
+
* @param {object} oObjectPageLayout - sap.uxap.ObjectPageLayout
|
|
66
|
+
* @param {string} sId - the CustomData "id" value to match
|
|
67
|
+
* @returns {sap.ui.comp.smartform.Group|null}
|
|
68
|
+
*/
|
|
69
|
+
findGroupById: function(oObjectPageLayout, sId) {
|
|
70
|
+
var oFound = null;
|
|
71
|
+
this.collectSmartForms(oObjectPageLayout).some(function(oSmartForm) {
|
|
72
|
+
return oSmartForm.getGroups().some(function(oGroup) {
|
|
73
|
+
var bMatch = oGroup.getCustomData().some(function(oData) {
|
|
74
|
+
return oData.getKey() === "id" && oData.getValue() === sId;
|
|
75
|
+
});
|
|
76
|
+
if (bMatch) { oFound = oGroup; }
|
|
77
|
+
return bMatch;
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
return oFound;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Populates a SmartForm.Group (looked up by CustomData "id" walk via findGroupById) with
|
|
85
|
+
* GroupElements containing dual SmartFields. Called DIRECTLY by EasyFillHandler
|
|
86
|
+
* after the LLM result arrives — not via a formatter, not via setTimeout.
|
|
87
|
+
*
|
|
88
|
+
* The group is created by the sections= JSONModel binding in the XML fragment.
|
|
89
|
+
* If the group is not yet in the DOM when called, an afterRendering delegate on the
|
|
90
|
+
* OPL retries injection once the binding has created the controls.
|
|
91
|
+
*
|
|
92
|
+
* @param {string} sGroupId - the CustomData "id" value of the target SmartForm.Group
|
|
93
|
+
* @param {Array} aFields - field names to render
|
|
94
|
+
* @param {object} oController - MVC controller
|
|
95
|
+
* @param {object} oTransientContextForEasyFill
|
|
96
|
+
* @param {object} oObjectPageContext
|
|
97
|
+
* @param {object} mUpdatableLookupMap - { fieldName: aiValue } updatable only
|
|
98
|
+
* @param {object} oLLMData - { fieldName: aiValue } full LLM result
|
|
99
|
+
* @param {function} fnOnFieldChange
|
|
100
|
+
*/
|
|
101
|
+
populateGroupFields: function(sGroupId, aFields, oController, oTransientContextForEasyFill, oObjectPageContext, mUpdatableLookupMap, oLLMData, fnOnFieldChange) {
|
|
102
|
+
if (!Array.isArray(aFields) || aFields.length === 0) { return; }
|
|
100
103
|
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
var oObjectPageLayout = oController.byId("EasyFillObjectPageLayout");
|
|
105
|
+
var oRb = oController.getView().getModel("i18n").getResourceBundle();
|
|
106
|
+
var sOriginalValueLabel = oRb.getText("EASY_FILL_ORIGINAL_VALUE_LABEL");
|
|
107
|
+
var sProposedValueLabel = oRb.getText("EASY_FILL_PROPOSED_VALUE_LABEL");
|
|
108
|
+
var sRevertTooltip = oRb.getText("EASY_FILL_REVERT_FIELD_TOOLTIP");
|
|
109
|
+
var that = this;
|
|
110
|
+
|
|
111
|
+
function tryInject() {
|
|
112
|
+
var oGroup = that.findGroupById(oObjectPageLayout, sGroupId);
|
|
113
|
+
if (!oGroup || oGroup.bIsDestroyed) { return false; }
|
|
114
|
+
|
|
115
|
+
oGroup.destroyGroupElements();
|
|
103
116
|
|
|
104
117
|
aFields.forEach(function(sKey) {
|
|
105
118
|
var bIsEditable = Object.prototype.hasOwnProperty.call(mUpdatableLookupMap || {}, sKey);
|
|
106
119
|
|
|
107
|
-
var oGroupElement = new GroupElement({
|
|
108
|
-
useHorizontalLayout: false
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Primary SmartField:
|
|
113
|
-
* - If editable: bound to transient context, shows AI-suggested value
|
|
114
|
-
* - If non-editable: bound to OP context, display-only
|
|
115
|
-
*/
|
|
116
120
|
var oSmartField = new SmartField({
|
|
117
121
|
value: "{" + sKey + "}",
|
|
118
122
|
editable: bIsEditable,
|
|
119
123
|
enabled: bIsEditable,
|
|
120
124
|
contextEditable: bIsEditable,
|
|
121
|
-
layoutData: new ColumnElementData({
|
|
122
|
-
cellsSmall: 12,
|
|
123
|
-
cellsLarge: 12
|
|
124
|
-
}),
|
|
125
|
+
layoutData: new ColumnElementData({ cellsSmall: 12, cellsLarge: 12 }),
|
|
125
126
|
editableChanged: function(oEvent) {
|
|
126
|
-
// Prevent the SmartField from toggling its own editability;
|
|
127
|
-
// editability is controlled exclusively by EasyFill logic
|
|
128
127
|
if (oEvent.getParameter("editable") !== bIsEditable) {
|
|
129
128
|
oEvent.getSource().setEditable(bIsEditable);
|
|
130
129
|
}
|
|
@@ -132,45 +131,17 @@ sap.ui.define([
|
|
|
132
131
|
});
|
|
133
132
|
|
|
134
133
|
if (!bIsEditable) {
|
|
135
|
-
// Keep read-only behavior, but render like an input field (v4-like visual parity)
|
|
136
134
|
oSmartField.addStyleClass("sapUiEasyFillReadOnlyInputLike sapMInputBaseContentWrapper");
|
|
137
135
|
}
|
|
138
136
|
|
|
139
|
-
// Notify on user edits so SmartForm validity can re-gate the Confirm button.
|
|
140
137
|
if (bIsEditable && typeof fnOnFieldChange === "function") {
|
|
141
138
|
oSmartField.attachChange(fnOnFieldChange);
|
|
142
|
-
|
|
143
|
-
// Validate AI-seeded values on initial load — mirrors ObjectPage behaviour.
|
|
144
|
-
//
|
|
145
|
-
// In the OP, validation triggers because when a user TYPES a value the browser
|
|
146
|
-
// fires a change event which causes UI5 to call setExternalValue() on the inner
|
|
147
|
-
// control's binding. setExternalValue() has no fast-path: it always calls
|
|
148
|
-
// parseValue → validateValue → OData value-list lookup. If the lookup fails the
|
|
149
|
-
// binding calls setInvalidValue() + checkDataState() → ManagedObject fires
|
|
150
|
-
// validationError → inner control gets valueState="Error" (red mark).
|
|
151
|
-
//
|
|
152
|
-
// SmartForm.check() / SmartField.checkValuesValidity() do NOT work for
|
|
153
|
-
// AI-seeded values because SmartField._checkErrors() contains a fast-path:
|
|
154
|
-
// if (!isControlDirty() && formattedModelValue === displayedValue) → skip
|
|
155
|
-
// AI values always satisfy this (model = display = AI value, user never typed),
|
|
156
|
-
// so _checkErrors() short-circuits to "valid" without the OData lookup.
|
|
157
|
-
//
|
|
158
|
-
// Fix: after innerControlsCreated, call setExternalValue() on the inner
|
|
159
|
-
// control's own binding with the currently displayed value. This is exactly
|
|
160
|
-
// the same path the OP uses when the user types. For async types (TextArrangement
|
|
161
|
-
// with ValueList) the call starts the OData lookup:
|
|
162
|
-
// valid value → resolves quietly, no red mark
|
|
163
|
-
// invalid value → rejects → setInvalidValue + checkDataState → red mark
|
|
164
|
-
// Non-async types fall through to a plain fnOnFieldChange call because
|
|
165
|
-
// SmartForm.check() already handles them correctly (no fast-path for sync).
|
|
166
139
|
oSmartField.attachInnerControlsCreated(function() {
|
|
167
140
|
var oInnerControl = oSmartField.getFirstInnerControl();
|
|
168
141
|
if (oInnerControl && typeof oInnerControl.getValue === "function") {
|
|
169
142
|
var oBinding = oInnerControl.getBinding("value");
|
|
170
143
|
var oType = oBinding && typeof oBinding.getType === "function" && oBinding.getType();
|
|
171
144
|
if (oType && oType.async && typeof oBinding.setExternalValue === "function") {
|
|
172
|
-
// setExternalValue replicates the "user typed this value" path:
|
|
173
|
-
// parseValue → validateValue → OData lookup → validationError/Success
|
|
174
145
|
Promise.resolve(oBinding.setExternalValue(oInnerControl.getValue()))
|
|
175
146
|
.catch(Function.prototype)
|
|
176
147
|
.finally(fnOnFieldChange);
|
|
@@ -181,69 +152,123 @@ sap.ui.define([
|
|
|
181
152
|
});
|
|
182
153
|
}
|
|
183
154
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
* - Only shown for editable fields to display the current OP value for comparison
|
|
187
|
-
* - Bound to the original ObjectPage context
|
|
188
|
-
*/
|
|
189
|
-
var oSmartFieldPrev = new SmartField({
|
|
190
|
-
value: "{" + sKey + "}",
|
|
191
|
-
editable: false,
|
|
192
|
-
enabled: false,
|
|
193
|
-
contextEditable: false,
|
|
194
|
-
showLabel: false,
|
|
195
|
-
layoutData: new ColumnElementData({
|
|
196
|
-
cellsSmall: 9,
|
|
197
|
-
cellsLarge: 9
|
|
198
|
-
}),
|
|
199
|
-
editableChanged: function(oEvent) {
|
|
200
|
-
// Always keep the "previously" field read-only
|
|
201
|
-
if (oEvent.getParameter("editable") !== false) {
|
|
202
|
-
oEvent.getSource().setEditable(false);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
});
|
|
155
|
+
// Hoist vAIValue so it can be reused when seeding the transient context below
|
|
156
|
+
var vAIValue = oLLMData[sKey];
|
|
206
157
|
|
|
207
158
|
if (oTransientContextForEasyFill) {
|
|
208
|
-
// Primary field always uses transient context to show AI-proposed value.
|
|
209
|
-
// Field editability is controlled by bIsEditable.
|
|
210
159
|
oSmartField.setBindingContext(oTransientContextForEasyFill);
|
|
211
|
-
|
|
212
|
-
// Only seed the transient context with the AI-suggested value on the first
|
|
213
|
-
// population. On subsequent calls (e.g. mode switch), the transient context
|
|
214
|
-
// already holds the current value — overwriting it would discard user edits.
|
|
215
160
|
if (oTransientContextForEasyFill.getProperty(sKey) === undefined) {
|
|
216
|
-
oTransientContextForEasyFill.setProperty(sKey,
|
|
161
|
+
oTransientContextForEasyFill.setProperty(sKey, vAIValue);
|
|
217
162
|
}
|
|
218
163
|
} else {
|
|
219
|
-
// Fallback: without transient context, bind to original OP context.
|
|
220
164
|
oSmartField.setBindingContext(oObjectPageContext);
|
|
221
165
|
}
|
|
222
166
|
|
|
223
|
-
//
|
|
224
|
-
|
|
167
|
+
// Read the current (pre-AI) value as a plain string for display.
|
|
168
|
+
var vCurrentValue = (oObjectPageContext && typeof oObjectPageContext.getProperty === "function")
|
|
169
|
+
? oObjectPageContext.getProperty(sKey) : null;
|
|
170
|
+
var sCurrentValue;
|
|
171
|
+
if (vCurrentValue === null || vCurrentValue === undefined || vCurrentValue === "") {
|
|
172
|
+
sCurrentValue = "-";
|
|
173
|
+
} else if (vCurrentValue instanceof Date) {
|
|
174
|
+
sCurrentValue = vCurrentValue.toLocaleDateString();
|
|
175
|
+
} else if (typeof vCurrentValue === "object") {
|
|
176
|
+
sCurrentValue = "-";
|
|
177
|
+
} else {
|
|
178
|
+
sCurrentValue = String(vCurrentValue);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
var oGroupElement = new GroupElement({ useHorizontalLayout: false });
|
|
182
|
+
oGroupElement.addElement(oSmartField);
|
|
183
|
+
|
|
184
|
+
// "Original Value:" text shown for all fields (editable and non-editable)
|
|
185
|
+
var oOriginalValueText = new Text({
|
|
186
|
+
text: sOriginalValueLabel + " " + sCurrentValue,
|
|
187
|
+
wrapping: false
|
|
188
|
+
}).addStyleClass("sapEasyFillPreviouslyLabel");
|
|
189
|
+
oGroupElement.addElement(oOriginalValueText);
|
|
225
190
|
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
191
|
+
// Toggle controls (revert button + proposed value link) only for editable fields
|
|
192
|
+
if (bIsEditable) {
|
|
193
|
+
var bReverted = false;
|
|
194
|
+
|
|
195
|
+
var oRevertButton = new Button({
|
|
196
|
+
icon: "sap-icon://undo",
|
|
197
|
+
type: "Transparent",
|
|
198
|
+
tooltip: sRevertTooltip
|
|
199
|
+
}).addStyleClass("sapEasyFillRevertButton");
|
|
200
|
+
|
|
201
|
+
// State 2 row: "Proposed Value: <aiValue>" clickable link — hidden until user reverts
|
|
202
|
+
var sAIDisplayValue;
|
|
203
|
+
if (vAIValue === null || vAIValue === undefined || vAIValue === "") {
|
|
204
|
+
sAIDisplayValue = "-";
|
|
205
|
+
} else if (vAIValue instanceof Date) {
|
|
206
|
+
sAIDisplayValue = vAIValue.toLocaleDateString();
|
|
207
|
+
} else if (typeof vAIValue === "object") {
|
|
208
|
+
sAIDisplayValue = "-";
|
|
209
|
+
} else {
|
|
210
|
+
sAIDisplayValue = String(vAIValue);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
var oProposedValueLink = new Link({
|
|
214
|
+
text: sProposedValueLabel + " " + sAIDisplayValue,
|
|
215
|
+
wrapping: false,
|
|
216
|
+
visible: false,
|
|
217
|
+
icon: "sap-icon://ai"
|
|
218
|
+
}).addStyleClass("sapEasyFillProposedValueLink");
|
|
219
|
+
|
|
220
|
+
// Revert button: State 1 → State 2
|
|
221
|
+
oRevertButton.attachPress(function() {
|
|
222
|
+
if (bReverted) { return; }
|
|
223
|
+
bReverted = true;
|
|
224
|
+
if (oTransientContextForEasyFill) {
|
|
225
|
+
oTransientContextForEasyFill.setProperty(sKey, vCurrentValue);
|
|
226
|
+
}
|
|
227
|
+
oOriginalValueText.setVisible(false);
|
|
228
|
+
oRevertButton.setVisible(false);
|
|
229
|
+
oProposedValueLink.setVisible(true);
|
|
230
|
+
if (typeof fnOnFieldChange === "function") { fnOnFieldChange(); }
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Proposed Value link: State 2 → State 1
|
|
234
|
+
oProposedValueLink.attachPress(function() {
|
|
235
|
+
if (!bReverted) { return; }
|
|
236
|
+
bReverted = false;
|
|
237
|
+
if (oTransientContextForEasyFill) {
|
|
238
|
+
oTransientContextForEasyFill.setProperty(sKey, vAIValue);
|
|
239
|
+
}
|
|
240
|
+
oProposedValueLink.setVisible(false);
|
|
241
|
+
oOriginalValueText.setVisible(true);
|
|
242
|
+
oRevertButton.setVisible(true);
|
|
243
|
+
if (typeof fnOnFieldChange === "function") { fnOnFieldChange(); }
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
oGroupElement.addElement(oRevertButton);
|
|
247
|
+
oGroupElement.addElement(oProposedValueLink);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
oGroup.addGroupElement(oGroupElement);
|
|
237
251
|
});
|
|
238
252
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
oLogger.debug("populateSmartFields: populated " + aFields.length + " fields for group '" + sId + "'");
|
|
244
|
-
}, 0);
|
|
253
|
+
if (typeof fnOnFieldChange === "function") { fnOnFieldChange(); }
|
|
254
|
+
oLogger.debug("populateGroupFields: " + aFields.length + " fields in group '" + sGroupId + "'");
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
245
257
|
|
|
246
|
-
|
|
258
|
+
// If the group control exists already (e.g. mode switch on existing sections),
|
|
259
|
+
// inject immediately. Otherwise the sections= binding hasn't created the group
|
|
260
|
+
// control yet — attach a one-shot afterRendering on the OPL to retry once
|
|
261
|
+
// the new sections are in the DOM.
|
|
262
|
+
if (!tryInject()) {
|
|
263
|
+
if (!oObjectPageLayout) { return; }
|
|
264
|
+
var oDelegate = {
|
|
265
|
+
onAfterRendering: function() {
|
|
266
|
+
oObjectPageLayout.removeEventDelegate(oDelegate);
|
|
267
|
+
tryInject();
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
oObjectPageLayout.addEventDelegate(oDelegate);
|
|
271
|
+
}
|
|
247
272
|
},
|
|
248
273
|
|
|
249
274
|
/**
|