@sapui5/sap.suite.ui.generic.template 1.147.2 → 1.148.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/sap/suite/ui/generic/template/.library +1 -1
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/controller/ControllerImplementation.js +5 -3
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_bg.properties +3 -3
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_da.properties +3 -3
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_fr_CA.properties +2 -2
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/i18n/i18n_id.properties +2 -2
- 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/controller/ControllerImplementation.js +32 -3
- package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_fr.properties +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_id.properties +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_uk.properties +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/Component.js +4 -0
- package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +57 -25
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n.properties +6 -0
- package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en_US_saprigi.properties +4 -0
- package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +6 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/templateSpecificPreparationHelper.js +35 -19
- package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/Actions.fragment.xml +13 -13
- package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/Footer.fragment.xml +103 -42
- 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/fragments/EasyFilter.fragment.xml +3 -0
- package/src/sap/suite/ui/generic/template/genericUtilities/controlHelper.js +30 -29
- package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartFilterBarWrapper.js +15 -0
- package/src/sap/suite/ui/generic/template/lib/AppComponent.js +1 -1
- package/src/sap/suite/ui/generic/template/lib/CRUDHelper.js +93 -55
- package/src/sap/suite/ui/generic/template/lib/CRUDManager.js +7 -0
- package/src/sap/suite/ui/generic/template/lib/CommonEventHandlers.js +76 -19
- package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +4 -1
- package/src/sap/suite/ui/generic/template/lib/ComponentUtils.js +17 -7
- package/src/sap/suite/ui/generic/template/lib/StableIdDefinition.js +35 -34
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator.js +185 -0
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler.js +476 -0
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillDialogController.js +311 -0
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector.js +669 -0
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFormRenderer.js +217 -0
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +348 -422
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer.js +491 -0
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +142 -72
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +409 -22
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n.properties +32 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ar.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_bg.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ca.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cnr.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cs.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cy.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_da.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_de.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_el.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_GB.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saprigi.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es_MX.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_et.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr.properties +15 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr_CA.properties +15 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hi.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hr.properties +15 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hu.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_id.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_it.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_iw.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ja.properties +20 -6
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_kk.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ko.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lt.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lv.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_mk.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ms.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_nl.properties +15 -1
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_no.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pl.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt_PT.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ro.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ru.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sh.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sk.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sr.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sv.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_th.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_tr.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_uk.properties +17 -3
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_vi.properties +14 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_CN.properties +20 -6
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_TW.properties +20 -6
- package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +1 -1
- package/src/sap/suite/ui/generic/template/library.js +25 -2
- package/src/sap/suite/ui/generic/template/themes/base/ObjectPage.less +22 -3
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillNonUpdatableSmartForm.fragment.xml +0 -18
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillUpdatebleSmartForm.fragment.xml +0 -15
|
@@ -1,482 +1,408 @@
|
|
|
1
1
|
sap.ui.define([
|
|
2
2
|
"sap/ui/base/Object",
|
|
3
3
|
"sap/base/util/extend",
|
|
4
|
-
"sap/ui/
|
|
5
|
-
"sap/ui/
|
|
6
|
-
"sap/ui/
|
|
7
|
-
"sap/ui/
|
|
8
|
-
"sap/
|
|
9
|
-
"sap/ui/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
4
|
+
"sap/suite/ui/generic/template/library",
|
|
5
|
+
"sap/suite/ui/generic/template/genericUtilities/FeError",
|
|
6
|
+
"sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector",
|
|
7
|
+
"sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator",
|
|
8
|
+
"sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFormRenderer",
|
|
9
|
+
"sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer",
|
|
10
|
+
"sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler",
|
|
11
|
+
"sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillDialogController",
|
|
12
|
+
"sap/suite/ui/generic/template/js/AnnotationHelper"
|
|
13
|
+
], function(
|
|
14
|
+
BaseObject,
|
|
15
|
+
extend,
|
|
16
|
+
Library,
|
|
17
|
+
FeError,
|
|
18
|
+
EasyFillFieldCollector,
|
|
19
|
+
EasyFillAIOrchestrator,
|
|
20
|
+
EasyFillFormRenderer,
|
|
21
|
+
EasyFillTableRenderer,
|
|
22
|
+
EasyFillApplyHandler,
|
|
23
|
+
EasyFillDialogController,
|
|
24
|
+
GenericAnnotationHelper
|
|
25
|
+
) {
|
|
26
|
+
"use strict";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* EasyFillHandler
|
|
19
30
|
*
|
|
31
|
+
* Thin orchestrator for the EasyFill AI feature on the ObjectPage.
|
|
32
|
+
*
|
|
33
|
+
* This class wires all EasyFill sub-modules together and exposes a single public
|
|
34
|
+
* entry point (onEasyFillButtonClick) to the ObjectPage ControllerImplementation.
|
|
35
|
+
*
|
|
36
|
+
* Sub-module responsibilities:
|
|
37
|
+
* EasyFillFieldCollector — OData metadata field/section extraction
|
|
38
|
+
* EasyFillAIOrchestrator — AI service call and response post-processing
|
|
39
|
+
* EasyFillFormRenderer — SmartForm/GroupElement/SmartField population
|
|
40
|
+
* EasyFillTableRenderer — SmartTable collection preview rendering
|
|
41
|
+
* EasyFillApplyHandler — Confirm/save, validation, reset logic
|
|
42
|
+
* EasyFillDialogController — Dialog lifecycle, formatters, UI event handlers
|
|
43
|
+
*
|
|
44
|
+
* Shared mutable state lives here and is passed by reference into sub-modules.
|
|
45
|
+
* Sub-modules are stateless — they never store state themselves.
|
|
20
46
|
*/
|
|
21
47
|
function getMethods(oState, oController, oTemplateUtils, oObjectPage) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
48
|
+
var EasyFillLayoutMode = Library.EasyFillLayoutMode;
|
|
49
|
+
|
|
50
|
+
// ─── Shared Mutable State ────────────────────────────────────────────────
|
|
51
|
+
// All state is declared here and passed into sub-modules as needed.
|
|
52
|
+
// Sub-modules must not cache these values — always use the latest reference.
|
|
53
|
+
|
|
54
|
+
var oTransientContextForEasyFill = null; // Transient OData context for staged AI scalar values
|
|
55
|
+
var oObjectPageContext = null; // Live ObjectPage binding context
|
|
56
|
+
var oObjectPageModel = null; // OData model of the ObjectPage
|
|
57
|
+
var mUpdatableLookupMap = {}; // { fieldName: value } for updatable fields only
|
|
58
|
+
var oRb = null; // i18n resource bundle
|
|
59
|
+
var oAIPopoverRef = { popover: null }; // Mutable ref for lazy-loaded AINotice popover
|
|
60
|
+
|
|
61
|
+
// Collection state — tracks OData row contexts and property metadata for SmartTable collections
|
|
62
|
+
var mCollectionState = {
|
|
63
|
+
mCollectionRowContexts: Object.create(null),
|
|
64
|
+
mCollectionRowContextsByPath: Object.create(null),
|
|
65
|
+
mCollectionProperties: Object.create(null),
|
|
66
|
+
mCollectionEntityTypes: Object.create(null)
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
var mCollectionUpdates = Object.create(null); // { navProperty: [ rowUpdate ] } from AI response
|
|
70
|
+
var oTableStagingState = {
|
|
71
|
+
mStagedRows: Object.create(null)
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// ─── Internal Helpers ────────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Opens the EasyFill dialog for the given ObjectPage context.
|
|
78
|
+
* Initializes the dialog model on first open, then loads and opens the dialog fragment
|
|
79
|
+
* with all event handlers and formatters bound.
|
|
80
|
+
*
|
|
81
|
+
* @param {sap.ui.base.Event} oEvent - the button click event
|
|
82
|
+
* @param {sap.ui.model.Context} [oContext] - optional context override (used when OP just entered edit mode)
|
|
83
|
+
*/
|
|
84
|
+
async function openEasyFillDialog(oEvent, oContext) {
|
|
32
85
|
oRb = oController.getView().getModel("i18n").getResourceBundle();
|
|
33
|
-
const bIsModelCreated = !!oController.getView().getModel("easyFillDialogModel");
|
|
34
86
|
oObjectPageModel = oObjectPage.getModel();
|
|
35
|
-
if (!bIsModelCreated) {
|
|
36
|
-
const aDeferredGroups = oObjectPageModel.getDeferredGroups();
|
|
37
|
-
//Adding a defferred group will make sure that no batch call would get triggered to backend until submitChanges() is invoked
|
|
38
|
-
aDeferredGroups.push("EasyFillFETransientChanges");
|
|
39
|
-
oObjectPageModel.setDeferredGroups(aDeferredGroups);
|
|
40
|
-
|
|
41
|
-
//Creating a JSON model for the dialog
|
|
42
|
-
|
|
43
|
-
const oData = {
|
|
44
|
-
isBusy: false,
|
|
45
|
-
isUpdatableVisible: false,
|
|
46
|
-
isNonUpdatableVisible: false,
|
|
47
|
-
isIllustrationVisible: true,
|
|
48
|
-
isSaveEnabled: false,
|
|
49
|
-
stateType: "Initial",
|
|
50
|
-
feedbackEnabled: true,
|
|
51
|
-
feedbackPressedUp: false,
|
|
52
|
-
feedbackPressedDown: false,
|
|
53
|
-
isEasyFillButtonEnabled: false
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
let oModel = new JSONModel(oData);
|
|
57
|
-
oController.getView().setModel(oModel, "easyFillDialogModel");
|
|
58
|
-
}
|
|
59
87
|
|
|
60
|
-
|
|
88
|
+
// Initialize dialog model and deferred group once per view lifetime
|
|
89
|
+
EasyFillDialogController.initDialogModel(oController, oObjectPageModel, EasyFillLayoutMode);
|
|
61
90
|
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_TITLE_INITIAL");
|
|
86
|
-
case "NoEntries":
|
|
87
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_TITLE_NO_ENTRIES");
|
|
88
|
-
case "Error":
|
|
89
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_TITLE_ERROR");
|
|
90
|
-
default:
|
|
91
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_TITLE_INITIAL");
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
formatIllustrationDescription: function (sState) {
|
|
95
|
-
switch (sState) {
|
|
96
|
-
case "Initial":
|
|
97
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_DESCRIPTION_INITIAL");
|
|
98
|
-
case "NoEntries":
|
|
99
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_DESCRIPTION_NO_ENTRIES");
|
|
100
|
-
case "Error":
|
|
101
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_DESCRIPTION_ERROR");
|
|
102
|
-
default:
|
|
103
|
-
return oRb.getText("EASY_FILL_ILLUSTRATION_DESCRIPTION_INITIAL");
|
|
104
|
-
}
|
|
91
|
+
// Use the provided context override or fall back to the current OP binding context
|
|
92
|
+
oObjectPageContext = oContext || oObjectPage.getBindingContext();
|
|
93
|
+
|
|
94
|
+
// Build the handler/formatter map that the dialog fragment binds to
|
|
95
|
+
var oHandlers = _buildDialogHandlers();
|
|
96
|
+
|
|
97
|
+
await EasyFillDialogController.openDialog(oController, oTemplateUtils, oHandlers);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Builds the event handler and formatter map passed to the EasyFillDialog fragment.
|
|
102
|
+
* Each entry corresponds to a function called from the fragment via event binding or formatter.
|
|
103
|
+
*
|
|
104
|
+
* @returns {object} handler/formatter map
|
|
105
|
+
*/
|
|
106
|
+
function _buildDialogHandlers() {
|
|
107
|
+
return {
|
|
108
|
+
// ── Layout mode toggle (Condensed ↔ ObjectPage view) ──────────────
|
|
109
|
+
onSelectionChange: function(oEvent) {
|
|
110
|
+
EasyFillDialogController.onSelectionChange(
|
|
111
|
+
oEvent, oController, oTemplateUtils, oRb,
|
|
112
|
+
EasyFillFieldCollector, EasyFillLayoutMode
|
|
113
|
+
);
|
|
105
114
|
},
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
oObjectPageContext.setProperty(oProp, oTransientObject[oProp]);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
activateSideEffects();
|
|
114
|
-
resetEasyFill(true);
|
|
115
|
-
oEasyFillDialog?.close();
|
|
115
|
+
|
|
116
|
+
// ── Feedback thumbs-up/down ───────────────────────────────────────
|
|
117
|
+
onFeedbackPress: function() {
|
|
118
|
+
EasyFillDialogController.onFeedbackPress(oController, oRb);
|
|
116
119
|
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
|
|
121
|
+
// ── Section title formatter (resolves i18n patterns) ──────────────
|
|
122
|
+
formatSectionTitle: function(sTitle) {
|
|
123
|
+
return EasyFillDialogController.formatSectionTitle(sTitle, oController);
|
|
120
124
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
|
|
126
|
+
// ── IllustratedMessage state formatters ───────────────────────────
|
|
127
|
+
formatIllustrationType: function(sState) {
|
|
128
|
+
return EasyFillDialogController.formatIllustrationType(sState);
|
|
124
129
|
},
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
easyFillDialogModel.setProperty("/isBusy",true);
|
|
128
|
-
let mFieldMapping = getEntitySetMapForLLM();
|
|
129
|
-
let aiCallResult = await oTemplateUtils.oServices.oFioriAIHandler.fioriaiLib.EasyFill.extractFieldValuesFromText(oController.byId("EasyFillInputTextArea").getValue(), mFieldMapping);
|
|
130
|
-
resetEasyFill();
|
|
131
|
-
aEditableFields = [];
|
|
132
|
-
easyFillDialogModel.setProperty("/isBusy",false);
|
|
133
|
-
formatDateValues(aiCallResult,mFieldMapping);
|
|
134
|
-
if (aiCallResult.success) {
|
|
135
|
-
const {updatableFields,nonUpdatableFields} = getUpdatableAndNonUpdatableFields(aiCallResult.data);
|
|
136
|
-
mUpdatableLookupMap = updatableFields;
|
|
137
|
-
if (Object.keys(updatableFields).length + Object.keys(nonUpdatableFields).length === 0) {
|
|
138
|
-
easyFillDialogModel.setProperty("/stateType","NoEntries");
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
easyFillDialogModel.setProperty("/isIllustrationVisible",false);
|
|
142
|
-
//Fillable Fields
|
|
143
|
-
makeTransientContext();
|
|
144
|
-
easyFillDialogModel.setProperty("/isUpdatableVisible",Object.keys(updatableFields).length > 0);
|
|
145
|
-
if (Object.keys(updatableFields).length > 0) {
|
|
146
|
-
const oAIResponseReviewRegionSmartFormForUpdatableFields = oController.byId("EasyFillUpdatebleForm");
|
|
147
|
-
|
|
148
|
-
const oOldGroup = getGroupForSmartForm(updatableFields,false,oObjectPage.getBindingContext(),false);
|
|
149
|
-
const oNewGroup = getGroupForSmartForm(updatableFields,true,oTransientContextForEasyFill,true);
|
|
150
|
-
oAIResponseReviewRegionSmartFormForUpdatableFields.addGroup(oOldGroup);
|
|
151
|
-
oAIResponseReviewRegionSmartFormForUpdatableFields.addGroup(oNewGroup);
|
|
152
|
-
validateSmartForm();
|
|
153
|
-
}
|
|
154
|
-
//Non-Fillable Fields
|
|
155
|
-
easyFillDialogModel.setProperty("/isNonUpdatableVisible",Object.keys(nonUpdatableFields).length > 0);
|
|
156
|
-
if (Object.keys(nonUpdatableFields).length > 0) {
|
|
157
|
-
const oAIResponseReviewRegionSmartFormForNonUpdatableFields = oController.byId("EasyFillNonUpdatebleForm");
|
|
158
|
-
const oOldGroup = getGroupForSmartForm(nonUpdatableFields,false,oObjectPage.getBindingContext(),false);
|
|
159
|
-
const oNewGroup = getGroupForSmartForm(nonUpdatableFields,false,oTransientContextForEasyFill,true);
|
|
160
|
-
oAIResponseReviewRegionSmartFormForNonUpdatableFields.addGroup(oOldGroup);
|
|
161
|
-
oAIResponseReviewRegionSmartFormForNonUpdatableFields.addGroup(oNewGroup);
|
|
162
|
-
}
|
|
163
|
-
} else {
|
|
164
|
-
easyFillDialogModel.setProperty("/stateType","Error");
|
|
165
|
-
}
|
|
130
|
+
formatIllustrationTitle: function(sState) {
|
|
131
|
+
return EasyFillDialogController.formatIllustrationTitle(sState, oRb);
|
|
166
132
|
},
|
|
167
|
-
|
|
168
|
-
|
|
133
|
+
formatIllustrationDescription: function(sState) {
|
|
134
|
+
return EasyFillDialogController.formatIllustrationDescription(sState, oRb);
|
|
169
135
|
},
|
|
170
|
-
onLinkPress: async function(oEvent) {
|
|
171
|
-
if (!oAIPopover) {
|
|
172
|
-
oAIPopover = await getAIPopover();
|
|
173
|
-
}
|
|
174
|
-
oAIPopover.openBy(oEvent.getSource());
|
|
175
|
-
}
|
|
176
|
-
}, "easyFillPopup",undefined,true,true).then(function (oPopup) {
|
|
177
|
-
oEasyFillDialog = oPopup;
|
|
178
|
-
oPopup?.open();
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function activateSideEffects() {
|
|
183
|
-
//Making a set so that , duplicate field group ids are not passed
|
|
184
|
-
const aFieldGroupIdSet = new Set();
|
|
185
|
-
aEditableFields.forEach((oSmartField)=>{
|
|
186
|
-
//SideEffect would be invoked only for the editable controls inside the SmartField
|
|
187
|
-
const aEditableInnerFields = oSmartField.getInnerControls().filter((oControl)=>oControl.getEditable());
|
|
188
|
-
aEditableInnerFields.forEach((oControl)=>{
|
|
189
|
-
const aControlFieldGroupId = oControl.getFieldGroupIds();
|
|
190
|
-
if (aControlFieldGroupId.length > 0) {
|
|
191
|
-
aControlFieldGroupId.forEach((sFieldGroupId)=>{
|
|
192
|
-
aFieldGroupIdSet.add(sFieldGroupId);
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
136
|
|
|
197
|
-
|
|
137
|
+
// ── Confirm: apply AI values to the live OP context ───────────────
|
|
138
|
+
onSaveFromEasyFillDialog: async function() {
|
|
139
|
+
EasyFillApplyHandler.applyAndSave(
|
|
140
|
+
oTransientContextForEasyFill,
|
|
141
|
+
oObjectPageContext,
|
|
142
|
+
mUpdatableLookupMap,
|
|
143
|
+
oTableStagingState,
|
|
144
|
+
mCollectionState
|
|
145
|
+
);
|
|
146
|
+
_resetEasyFill(true);
|
|
147
|
+
EasyFillDialogController.closeDialog(oController);
|
|
148
|
+
},
|
|
198
149
|
|
|
199
|
-
|
|
150
|
+
// ── Text area live change: enable/disable submit button ───────────
|
|
151
|
+
onLiveChange: function(oEvent) {
|
|
152
|
+
EasyFillDialogController.onLiveChange(oEvent, oController);
|
|
153
|
+
},
|
|
200
154
|
|
|
201
|
-
|
|
202
|
-
|
|
155
|
+
// ── Cancel: revert staged values and close dialog ─────────────────
|
|
156
|
+
onCancelEasyFillDialog: function() {
|
|
157
|
+
_resetEasyFill(true);
|
|
158
|
+
EasyFillDialogController.closeDialog(oController);
|
|
159
|
+
},
|
|
203
160
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
* However, we need to use the original OP context so that side effects are triggered
|
|
209
|
-
* on the original OP context when the user saves data from the EasyFill dialog back to OP.
|
|
210
|
-
*
|
|
211
|
-
* Therefore, we update the "context" and "contextObject" to reference the original OP context.
|
|
212
|
-
*/
|
|
161
|
+
// ── Field value formatter (binding expression builder) ────────────
|
|
162
|
+
formatFieldValue: function(sFieldName) {
|
|
163
|
+
return "{" + sFieldName + "}";
|
|
164
|
+
},
|
|
213
165
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
//To make sure that all the fields sideeffect would be triggered
|
|
220
|
-
const sSideEffectQualifier = oTemplateUtils.oServices.oApplicationController._getSideEffectsQualifier(oID.name);
|
|
221
|
-
oTemplateUtils.oServices.oApplicationController.registerGroupChange(sSideEffectQualifier);
|
|
222
|
-
});
|
|
166
|
+
// ── Submit user text to AI ────────────────────────────────────────
|
|
167
|
+
onEasyFillSubmitInputToAI: async function() {
|
|
168
|
+
await _handleAISubmit();
|
|
169
|
+
},
|
|
223
170
|
|
|
171
|
+
// ── Clear all (reset without closing) ────────────────────────────
|
|
172
|
+
onEasyFillClearAll: function() {
|
|
173
|
+
_resetEasyFill(true);
|
|
174
|
+
},
|
|
224
175
|
|
|
225
|
-
|
|
226
|
-
|
|
176
|
+
// ── SmartForm group population formatter ──────────────────────────
|
|
177
|
+
populateSmartFields: function(sId, aFields, sEasyFillMode) {
|
|
178
|
+
return EasyFillFormRenderer.populateSmartFields(
|
|
179
|
+
sId, aFields, sEasyFillMode,
|
|
180
|
+
oController,
|
|
181
|
+
oTransientContextForEasyFill,
|
|
182
|
+
oObjectPageContext,
|
|
183
|
+
mUpdatableLookupMap,
|
|
184
|
+
oDialogModel().getProperty("/llmData")
|
|
185
|
+
);
|
|
186
|
+
},
|
|
227
187
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
onCloseAiPopover: function() {
|
|
233
|
-
oAIPopover.close();
|
|
234
|
-
}
|
|
235
|
-
},"aiPopover",undefined,true);
|
|
236
|
-
resolve(oPopover);
|
|
237
|
-
});
|
|
238
|
-
}
|
|
188
|
+
// ── Fullscreen toggle ─────────────────────────────────────────────
|
|
189
|
+
onToggleFullScreen: function() {
|
|
190
|
+
EasyFillDialogController.onToggleFullScreen(oController);
|
|
191
|
+
},
|
|
239
192
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
oEntityType.property.forEach((oProperty)=>{
|
|
244
|
-
if (isVisible(oProperty)) {
|
|
245
|
-
mPropertyMap[oProperty.name] = {
|
|
246
|
-
description: getLabel(oProperty),
|
|
247
|
-
dataType: oProperty.type
|
|
248
|
-
};
|
|
193
|
+
// ── AI Notice popover ─────────────────────────────────────────────
|
|
194
|
+
onLinkPress: async function(oEvent) {
|
|
195
|
+
await EasyFillDialogController.onLinkPress(oEvent, oTemplateUtils, oAIPopoverRef);
|
|
249
196
|
}
|
|
250
|
-
}
|
|
251
|
-
return mPropertyMap;
|
|
197
|
+
};
|
|
252
198
|
}
|
|
253
199
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Handles the full AI submission flow:
|
|
202
|
+
* 1. Build field mapping
|
|
203
|
+
* 2. Call AI service
|
|
204
|
+
* 3. Post-process response (dates, split)
|
|
205
|
+
* 4. Update dialog model
|
|
206
|
+
* 5. Populate SmartForms and table previews
|
|
207
|
+
*/
|
|
208
|
+
async function _handleAISubmit() {
|
|
209
|
+
var oModel = oDialogModel();
|
|
210
|
+
oModel.setProperty("/isBusy", true);
|
|
211
|
+
|
|
212
|
+
// Build complete LLM field mapping (entity fields + collection fields)
|
|
213
|
+
var mFieldMapping = EasyFillAIOrchestrator.buildFieldMapping(
|
|
214
|
+
oTemplateUtils, oController, oObjectPage, oObjectPageModel,
|
|
215
|
+
oObjectPageContext, EasyFillFieldCollector, mCollectionState
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
// Submit to AI
|
|
219
|
+
var aiCallResult = await EasyFillAIOrchestrator.submitToAI(
|
|
220
|
+
oController.byId("EasyFillInputTextArea").getValue(),
|
|
221
|
+
mFieldMapping,
|
|
222
|
+
oTemplateUtils
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Reset editable fields tracker for fresh population
|
|
226
|
+
oModel.setProperty("/isBusy", false);
|
|
227
|
+
|
|
228
|
+
// Convert date strings in AI response to JS Date objects
|
|
229
|
+
EasyFillAIOrchestrator.formatDateValues(aiCallResult, mFieldMapping);
|
|
230
|
+
|
|
231
|
+
var sSelectedKey = oModel.getProperty("/easyFillMode") || EasyFillLayoutMode.CondensedMode;
|
|
232
|
+
oModel.setProperty("/easyFillMode", sSelectedKey);
|
|
257
233
|
|
|
258
|
-
function formatDateValues(aiCallResult,mFieldMapping) {
|
|
259
234
|
if (aiCallResult.success) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
235
|
+
// Split AI response into simple fields (SmartForm) and collection rows (SmartTable)
|
|
236
|
+
var oSplitResult = EasyFillAIOrchestrator.splitAIResultByCollection(
|
|
237
|
+
aiCallResult.data, mFieldMapping, EasyFillFieldCollector, oObjectPage
|
|
238
|
+
);
|
|
239
|
+
var simpleFields = oSplitResult.simpleFields;
|
|
240
|
+
var collectionFields = oSplitResult.collectionFields;
|
|
241
|
+
|
|
242
|
+
// Separate updatable from non-updatable fields
|
|
243
|
+
var oEntityType = oTemplateUtils.oCommonUtils.getMetaModelEntityType(
|
|
244
|
+
oController.getOwnerComponent().getEntitySet()
|
|
245
|
+
);
|
|
246
|
+
var oSplit = EasyFillFieldCollector.getUpdatableAndNonUpdatableFields(
|
|
247
|
+
simpleFields, oEntityType, oObjectPageContext
|
|
248
|
+
);
|
|
249
|
+
mUpdatableLookupMap = oSplit.updatableFields;
|
|
250
|
+
|
|
251
|
+
// Build section tree for selected view mode
|
|
252
|
+
var aData = (sSelectedKey === EasyFillLayoutMode.CondensedMode)
|
|
253
|
+
? EasyFillFieldCollector.getSectionsForCondensedView(simpleFields)
|
|
254
|
+
: EasyFillFieldCollector.getSectionsForObjectPageView(oEntityType, simpleFields, oRb);
|
|
255
|
+
|
|
256
|
+
// Reset form (destroy previous SmartForm content + revert table staging)
|
|
257
|
+
// then create a fresh transient context for the new AI result
|
|
258
|
+
_resetEasyFill();
|
|
259
|
+
oTransientContextForEasyFill = EasyFillFormRenderer.makeTransientContext(
|
|
260
|
+
null, oObjectPageModel, oController
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
// Update dialog model with section data and AI result
|
|
264
|
+
oModel.setProperty("/sections", aData);
|
|
265
|
+
oModel.setProperty("/llmData", simpleFields);
|
|
266
|
+
|
|
267
|
+
// Process collection/table updates
|
|
268
|
+
mCollectionUpdates = collectionFields;
|
|
269
|
+
var bHasTableUpdates = Object.keys(mCollectionUpdates).length > 0;
|
|
270
|
+
oModel.setProperty("/hasTableUpdates", bHasTableUpdates);
|
|
271
|
+
|
|
272
|
+
// Render collection previews into the table preview container
|
|
273
|
+
EasyFillTableRenderer.renderCollectionPreviews(
|
|
274
|
+
mCollectionUpdates,
|
|
275
|
+
mFieldMapping,
|
|
276
|
+
[],
|
|
277
|
+
oController,
|
|
278
|
+
oRb,
|
|
279
|
+
mCollectionState,
|
|
280
|
+
oTableStagingState,
|
|
281
|
+
oObjectPageModel,
|
|
282
|
+
function() {
|
|
283
|
+
_refreshTableValidationAndSaveState().catch(Function.prototype);
|
|
264
284
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
await _refreshTableValidationAndSaveState();
|
|
268
288
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const oAIResponseReviewRegionSmartFormForUpdatableFields = oController.byId("EasyFillUpdatebleForm");
|
|
274
|
-
const aIds = await oAIResponseReviewRegionSmartFormForUpdatableFields.check();
|
|
275
|
-
easyFillDialogModel.setProperty("/isSaveEnabled",aIds.length === 0);
|
|
276
|
-
} catch (error) {
|
|
277
|
-
easyFillDialogModel.setProperty("/isSaveEnabled",false);
|
|
289
|
+
var iTotalFields = Object.keys(oSplit.updatableFields).length + Object.keys(oSplit.nonUpdatableFields).length;
|
|
290
|
+
if (iTotalFields === 0 && !bHasTableUpdates) {
|
|
291
|
+
oModel.setProperty("/stateType", "NoEntries");
|
|
292
|
+
return;
|
|
278
293
|
}
|
|
279
|
-
}, 0);
|
|
280
|
-
}
|
|
281
294
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
resetTransientContext();
|
|
289
|
-
easyFillDialogModel.setProperty("/isUpdatableVisible",false);
|
|
290
|
-
easyFillDialogModel.setProperty("/isNonUpdatableVisible",false);
|
|
291
|
-
easyFillDialogModel.setProperty("/isIllustrationVisible",true);
|
|
292
|
-
easyFillDialogModel.setProperty("/isSaveEnabled",false);
|
|
293
|
-
easyFillDialogModel.setProperty("/stateType","Initial");
|
|
294
|
-
easyFillDialogModel.setProperty("/feedbackEnabled",true);
|
|
295
|
-
easyFillDialogModel.setProperty("/feedbackPressedUp",false);
|
|
296
|
-
easyFillDialogModel.setProperty("/feedbackPressedDown",false);
|
|
297
|
-
if (bRemoveTextAreaValue) {
|
|
298
|
-
oController.byId("EasyFillInputTextArea").setValue("");
|
|
299
|
-
easyFillDialogModel.setProperty("/isEasyFillButtonEnabled",false);
|
|
295
|
+
oModel.setProperty("/isIllustrationVisible", false);
|
|
296
|
+
oModel.setProperty("/isFormVisible", iTotalFields > 0);
|
|
297
|
+
} else {
|
|
298
|
+
// AI call failed — show error illustration
|
|
299
|
+
EasyFillApplyHandler.applyTableValidationState([], oModel, oRb);
|
|
300
|
+
oModel.setProperty("/stateType", "Error");
|
|
300
301
|
}
|
|
301
302
|
}
|
|
302
303
|
|
|
303
|
-
function
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
304
|
+
async function _refreshTableValidationAndSaveState() {
|
|
305
|
+
var oModel = oDialogModel();
|
|
306
|
+
var mStagedCollectionUpdates = EasyFillApplyHandler.buildStagedCollectionUpdates(
|
|
307
|
+
oTableStagingState,
|
|
308
|
+
mCollectionState
|
|
309
|
+
);
|
|
310
|
+
var aTableValidationErrors = await EasyFillApplyHandler.validateCollectionUpdatesAgainstValueHelp(
|
|
311
|
+
mStagedCollectionUpdates,
|
|
312
|
+
mCollectionState,
|
|
313
|
+
oObjectPageModel,
|
|
314
|
+
oRb,
|
|
315
|
+
EasyFillFieldCollector,
|
|
316
|
+
GenericAnnotationHelper
|
|
317
|
+
);
|
|
318
|
+
EasyFillApplyHandler.applyTableValidationState(aTableValidationErrors, oModel, oRb);
|
|
319
|
+
|
|
320
|
+
var bHasScalarChanges = Object.keys(mUpdatableLookupMap || {}).length > 0;
|
|
321
|
+
var bHasTableChanges = EasyFillApplyHandler.hasStagedCollectionChanges(
|
|
322
|
+
oTableStagingState,
|
|
323
|
+
mCollectionState
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
oModel.setProperty(
|
|
327
|
+
"/isSaveEnabled",
|
|
328
|
+
bHasScalarChanges || (bHasTableChanges && aTableValidationErrors.length === 0)
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
return aTableValidationErrors;
|
|
318
332
|
}
|
|
319
333
|
|
|
320
|
-
//Checks if the field is editable or not
|
|
321
|
-
|
|
322
|
-
// It can be set in 2 ways using field-control, it would be present when sap:updatable attribute is not present
|
|
323
|
-
// 1. By attaching to an existing metadata property, sap:field-control-> path for the property
|
|
324
|
-
//Below are the values by which the editable state would be defined
|
|
325
|
-
|
|
326
334
|
/**
|
|
327
|
-
*
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
//Check for "com.sap.vocabularies.Common.v1.FieldControl"
|
|
348
|
-
const oAnnotation = oProperty["com.sap.vocabularies.Common.v1.FieldControl"];
|
|
349
|
-
|
|
350
|
-
if (oAnnotation && oAnnotation["EnumMember"]) {
|
|
351
|
-
const enumNumberType = oAnnotation["EnumMember"];
|
|
352
|
-
return enumNumberType === 'com.sap.vocabularies.Common.v1.FieldControlType/ReadOnly' ? false : true;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
//Check for "sap:field-control"
|
|
357
|
-
const sFieldControl = oProperty["sap:field-control"];
|
|
358
|
-
|
|
359
|
-
if (sFieldControl) {
|
|
360
|
-
const iFieldControlValue = oObjectPageContext.getObject()[sFieldControl];
|
|
361
|
-
return iFieldControlValue === 1 ? false : true;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
//If no restriction is present then by default all fields are editable
|
|
365
|
-
return true;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function isVisible(oProperty) {
|
|
369
|
-
|
|
370
|
-
//Check for "com.sap.vocabularies.Common.v1.FieldControl"
|
|
371
|
-
const oAnnotation = oProperty["com.sap.vocabularies.Common.v1.FieldControl"];
|
|
372
|
-
|
|
373
|
-
if (oAnnotation && oAnnotation["EnumMember"]) {
|
|
374
|
-
const enumNumberType = oAnnotation["EnumMember"];
|
|
375
|
-
return enumNumberType === 'com.sap.vocabularies.Common.v1.FieldControlType/Hidden' ? false : true;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
//Check for Hidden annotation i.e com.sap.vocabularies.UI.v1.Hidden
|
|
379
|
-
const oHiddenAnnotation = oProperty["com.sap.vocabularies.UI.v1.Hidden"];
|
|
380
|
-
if (oHiddenAnnotation) {
|
|
381
|
-
let bIsVisible = false; // <Annotation Term="UI.Hidden"/>
|
|
382
|
-
if (oHiddenAnnotation["Bool"]) {
|
|
383
|
-
bIsVisible = (oHiddenAnnotation["Bool"] === "true") ? false : true;
|
|
384
|
-
} else if (oHiddenAnnotation["Path"]) {
|
|
385
|
-
bIsVisible = !oObjectPageContext.getObject()[oHiddenAnnotation["Path"]];
|
|
335
|
+
* Resets the EasyFill dialog to its initial state.
|
|
336
|
+
* Delegates to EasyFillApplyHandler.resetEasyFill with the current state references.
|
|
337
|
+
*
|
|
338
|
+
* @param {boolean} [bRemoveTextAreaValue=false] - if true, also clears the text area input
|
|
339
|
+
*/
|
|
340
|
+
function _resetEasyFill(bRemoveTextAreaValue) {
|
|
341
|
+
EasyFillApplyHandler.resetEasyFill(
|
|
342
|
+
!!bRemoveTextAreaValue,
|
|
343
|
+
oDialogModel(),
|
|
344
|
+
oController,
|
|
345
|
+
mCollectionUpdates,
|
|
346
|
+
EasyFillLayoutMode,
|
|
347
|
+
function() {
|
|
348
|
+
EasyFillTableRenderer.resetStagedCollectionContexts(oTableStagingState, oObjectPageModel);
|
|
349
|
+
},
|
|
350
|
+
function() {
|
|
351
|
+
EasyFillFormRenderer.resetTransientContext(oTransientContextForEasyFill, oObjectPageModel);
|
|
352
|
+
oTransientContextForEasyFill = null;
|
|
386
353
|
}
|
|
387
|
-
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
//Check for "sap:field-control"
|
|
391
|
-
const sFieldControl = oProperty["sap:field-control"];
|
|
392
|
-
|
|
393
|
-
if (sFieldControl) {
|
|
394
|
-
const iFieldControlValue = oObjectPageContext.getObject()[sFieldControl];
|
|
395
|
-
return iFieldControlValue === 0 ? false : true;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
//If no restriction is present then by default all fields are visible
|
|
399
|
-
return true;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
function resetTransientContext() {
|
|
403
|
-
if (oTransientContextForEasyFill) {
|
|
404
|
-
oObjectPageModel.resetChanges([oTransientContextForEasyFill.getPath()],false,true);
|
|
405
|
-
oTransientContextForEasyFill = null;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
function makeTransientContext() {
|
|
410
|
-
if (oTransientContextForEasyFill) {
|
|
411
|
-
resetTransientContext();
|
|
412
|
-
}
|
|
413
|
-
oTransientContextForEasyFill = oObjectPageModel.createEntry("/" + oController.getOwnerComponent().getEntitySet(), {
|
|
414
|
-
"groupId" : "EasyFillFETransientChanges",
|
|
415
|
-
"changeSetId":"EasyFillFETransientChanges"
|
|
416
|
-
});
|
|
354
|
+
);
|
|
417
355
|
}
|
|
418
356
|
|
|
419
|
-
|
|
420
|
-
|
|
357
|
+
/**
|
|
358
|
+
* Convenience accessor for the easyFillDialogModel JSONModel.
|
|
359
|
+
* @returns {sap.ui.model.json.JSONModel}
|
|
360
|
+
*/
|
|
361
|
+
function oDialogModel() {
|
|
362
|
+
return oController.getView().getModel("easyFillDialogModel");
|
|
421
363
|
}
|
|
422
364
|
|
|
423
|
-
|
|
424
|
-
var oGroup = new Group({
|
|
425
|
-
title: (isTransient) ? oRb.getText("EASY_FILL_PROPOSED_VALUES") : oRb.getText("EASY_FILL_PREVIOUS_VALUES")
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
for (const key of Object.keys(oDataFromLLM)) {
|
|
429
|
-
const oGroupElement = new GroupElement();
|
|
430
|
-
const oSmartField = new SmartField({
|
|
431
|
-
value: "{" + key + "}",
|
|
432
|
-
editable: isEditable,
|
|
433
|
-
enabled: isEditable,
|
|
434
|
-
contextEditable: isEditable,
|
|
435
|
-
change: onSmartFieldChange.bind(this),
|
|
436
|
-
editableChanged: (oEvent)=>{
|
|
437
|
-
//SmartField changes the editable state of inner controls based on various factors, so to make sure that the editable state remains as per our requirement we are forcing it here
|
|
438
|
-
if (oEvent.getParameter("editable") !== isEditable) {
|
|
439
|
-
oEvent.getSource().setEditable(isEditable);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
if (isEditable) {
|
|
444
|
-
aEditableFields.push(oSmartField);
|
|
445
|
-
}
|
|
446
|
-
const oSmartLabel = new SmartLabel();
|
|
447
|
-
oSmartLabel.setLabelFor(oSmartField);
|
|
448
|
-
oGroupElement.addElement(oSmartField);
|
|
449
|
-
//Update the field only if its transient
|
|
450
|
-
if (isTransient) {
|
|
451
|
-
oContext.setProperty(key,oDataFromLLM[key]);
|
|
452
|
-
}
|
|
453
|
-
oGroup.addGroupElement(oGroupElement);
|
|
454
|
-
}
|
|
455
|
-
oGroup.setBindingContext(oContext);
|
|
456
|
-
return oGroup;
|
|
457
|
-
}
|
|
365
|
+
// ─── Public API ──────────────────────────────────────────────────────────
|
|
458
366
|
|
|
459
367
|
return {
|
|
368
|
+
/**
|
|
369
|
+
* Entry point called by the ObjectPage ControllerImplementation when the
|
|
370
|
+
* EasyFill button is pressed.
|
|
371
|
+
*
|
|
372
|
+
* If the ObjectPage is already in edit mode, the dialog opens immediately.
|
|
373
|
+
* If not, the page is transitioned to edit mode first and the resulting
|
|
374
|
+
* edit context is passed into the dialog.
|
|
375
|
+
*
|
|
376
|
+
* @param {sap.ui.base.Event} oEvent - the button click event
|
|
377
|
+
*/
|
|
460
378
|
onEasyFillButtonClick: function(oEvent) {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
const isEditable = oController.getView().getModel("ui").getProperty("/editable");
|
|
464
|
-
if (isEditable) {
|
|
379
|
+
var bIsEditable = oController.getView().getModel("ui").getProperty("/editable");
|
|
380
|
+
if (bIsEditable) {
|
|
465
381
|
openEasyFillDialog(oEvent);
|
|
466
382
|
} else {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
383
|
+
// Trigger the OP edit flow and wait for the new edit context before opening
|
|
384
|
+
oController._templateEventHandlers.onEditByEasyFill()
|
|
385
|
+
.then(function(oContext) {
|
|
386
|
+
oObjectPageContext = oContext;
|
|
387
|
+
openEasyFillDialog(oEvent, oContext);
|
|
388
|
+
})
|
|
389
|
+
.catch(Function.prototype);
|
|
471
390
|
}
|
|
472
391
|
}
|
|
473
392
|
};
|
|
474
393
|
}
|
|
475
394
|
|
|
476
395
|
return BaseObject.extend("sap.suite.ui.generic.template.lib.ai.EasyFill.EasyFillHandler", {
|
|
477
|
-
|
|
396
|
+
/**
|
|
397
|
+
* Constructor — wires all helpers and exposes the public API via getMethods.
|
|
398
|
+
*
|
|
399
|
+
* @param {object} oState - shared template state (passed from ControllerImplementation)
|
|
400
|
+
* @param {object} oController - MVC controller instance
|
|
401
|
+
* @param {object} oTemplateUtils - FE template utilities (services, common utils, etc.)
|
|
402
|
+
* @param {object} oObjectPage - the ObjectPage control instance
|
|
403
|
+
*/
|
|
404
|
+
constructor: function(oState, oController, oTemplateUtils, oObjectPage) {
|
|
478
405
|
extend(this, getMethods(oState, oController, oTemplateUtils, oObjectPage));
|
|
479
406
|
}
|
|
480
407
|
});
|
|
481
|
-
|
|
482
408
|
});
|