@sapui5/sap.suite.ui.commons 1.145.0 → 1.146.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/commons/.library +1 -1
- package/src/sap/suite/ui/commons/AriaProperties.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilder.js +28 -3
- package/src/sap/suite/ui/commons/CalculationBuilderExpression.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderFunction.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderGroup.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderInput.js +11 -0
- package/src/sap/suite/ui/commons/CalculationBuilderItem.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderValidationResult.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderVariable.js +1 -1
- package/src/sap/suite/ui/commons/CloudFilePicker.js +1 -1
- package/src/sap/suite/ui/commons/ControlProxy.js +7 -4
- package/src/sap/suite/ui/commons/MicroProcessFlow.js +1 -1
- package/src/sap/suite/ui/commons/MicroProcessFlowItem.js +1 -1
- package/src/sap/suite/ui/commons/ProcessFlow.js +79 -75
- package/src/sap/suite/ui/commons/ProcessFlowRenderer.js +3 -0
- package/src/sap/suite/ui/commons/collaboration/ContactHelper.js +5 -1
- package/src/sap/suite/ui/commons/collaboration/ContactPopover.fragment.xml +3 -3
- package/src/sap/suite/ui/commons/collaboration/MinimalContactPopover.fragment.xml +8 -6
- package/src/sap/suite/ui/commons/collaboration/ServiceContainer.js +12 -2
- package/src/sap/suite/ui/commons/flexibility/changeHandler/PropertyChangeMapper.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CropCustomShapeHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CropEllipseHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CropRectangleHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CustomSizeItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/FilterHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/FlipHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/HistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/ImageEditor.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/ImageEditorContainer.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/ImageEditorResponsiveContainer.js +9 -6
- package/src/sap/suite/ui/commons/imageeditor/ResizeHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/RotateHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/library.js +1 -1
- package/src/sap/suite/ui/commons/messagebundle.properties +4 -0
- package/src/sap/suite/ui/commons/messagebundle_ar.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_bg.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_ca.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_cnr.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_cs.properties +7 -1
- package/src/sap/suite/ui/commons/messagebundle_cy.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_da.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_de.properties +8 -2
- package/src/sap/suite/ui/commons/messagebundle_el.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_en.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_en_GB.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_en_US_saprigi.properties +9 -5
- package/src/sap/suite/ui/commons/messagebundle_es.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_es_MX.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_et.properties +6 -0
- package/src/sap/suite/ui/commons/messagebundle_fi.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_fr.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_fr_CA.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_hi.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_hr.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_hu.properties +9 -3
- package/src/sap/suite/ui/commons/messagebundle_id.properties +12 -6
- package/src/sap/suite/ui/commons/messagebundle_it.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_iw.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_ja.properties +9 -3
- package/src/sap/suite/ui/commons/messagebundle_kk.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_ko.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_lt.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_lv.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_mk.properties +8 -2
- package/src/sap/suite/ui/commons/messagebundle_ms.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_nl.properties +8 -2
- package/src/sap/suite/ui/commons/messagebundle_no.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_pl.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_pt.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_pt_PT.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_ro.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_ru.properties +12 -6
- package/src/sap/suite/ui/commons/messagebundle_sh.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_sk.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_sl.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_sr.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_sv.properties +10 -4
- package/src/sap/suite/ui/commons/messagebundle_th.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_tr.properties +8 -2
- package/src/sap/suite/ui/commons/messagebundle_uk.properties +14 -8
- package/src/sap/suite/ui/commons/messagebundle_vi.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_zh_CN.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_zh_TW.properties +11 -5
- package/src/sap/suite/ui/commons/networkgraph/Graph.js +11 -13
- package/src/sap/suite/ui/commons/networkgraph/Line.js +105 -11
- package/src/sap/suite/ui/commons/networkgraph/Utils.js +239 -10
- package/src/sap/suite/ui/commons/networkgraph/layout/NoopLayout.js +55 -8
- package/src/sap/suite/ui/commons/networkgraph/util/DependencyLayoutHelper.js +18 -9
- package/src/sap/suite/ui/commons/networkgraph/util/DragDropManager.js +52 -50
- package/src/sap/suite/ui/commons/networkgraph/util/PortManager.js +12 -3
- package/src/sap/suite/ui/commons/statusindicator/Circle.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/CustomShape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/DiscreteThreshold.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/FillingOption.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/LibraryShape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/Path.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/PropertyThreshold.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/Rectangle.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/Shape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/ShapeGroup.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/SimpleShape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/StatusIndicator.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccount.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountGroup.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountItem.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountItemProperty.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountPanel.js +1 -1
- package/src/sap/suite/ui/commons/windowmessages/CollaborationMessageConsumer.js +3 -3
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
sap.ui.define([], function () {
|
|
8
|
+
sap.ui.define(["sap/base/Log"], function (Log) {
|
|
9
9
|
"use strict";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -73,15 +73,244 @@ sap.ui.define([], function () {
|
|
|
73
73
|
* @returns {function} throttled function.
|
|
74
74
|
*/
|
|
75
75
|
Utils.throttle = (mainFunction, delay) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
return (...args) => {
|
|
77
|
+
if (timeFlag === null) {
|
|
78
|
+
mainFunction(...args);
|
|
79
|
+
timeFlag = setTimeout(() => {
|
|
80
|
+
timeFlag = null;
|
|
81
|
+
}, delay);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Helper function to convert CSS outline to border for drag image elements.
|
|
88
|
+
* This is needed because some browsers don't capture outline in drag images.
|
|
89
|
+
*
|
|
90
|
+
* @param {HTMLElement} oElement - The DOM element to apply border to
|
|
91
|
+
* @param {CSSStyleDeclaration} oComputedStyle - The computed style of the element
|
|
92
|
+
* @param {string} [sBorderProperty="border"] - The CSS border property to set ("border", "borderBottom", etc.)
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
var _applyOutlineAsBorder = function (oElement, oComputedStyle, sBorderProperty) {
|
|
96
|
+
var sOutlineWidth = oComputedStyle.outlineWidth;
|
|
97
|
+
if (sOutlineWidth && sOutlineWidth !== "0px") {
|
|
98
|
+
var sBorderValue = sOutlineWidth + " " + oComputedStyle.outlineStyle + " " + oComputedStyle.outlineColor;
|
|
99
|
+
oElement.style[sBorderProperty || "border"] = sBorderValue;
|
|
100
|
+
oElement.style.outline = "none";
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Clones the inner div element and applies basic styles for drag image.
|
|
106
|
+
*
|
|
107
|
+
* @param {HTMLElement} oInnerDiv - Inner div element to clone
|
|
108
|
+
* @returns {HTMLElement} The cloned and styled node
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
var _cloneAndStyleNode = function (oInnerDiv) {
|
|
112
|
+
var oClonedNode = oInnerDiv.cloneNode(true);
|
|
113
|
+
var oComputedStyle = window.getComputedStyle(oInnerDiv);
|
|
114
|
+
|
|
115
|
+
// Apply computed styles to ensure the clone looks identical
|
|
116
|
+
oClonedNode.style.width = oComputedStyle.width;
|
|
117
|
+
oClonedNode.style.height = oComputedStyle.height;
|
|
118
|
+
oClonedNode.style.position = "absolute";
|
|
119
|
+
oClonedNode.style.top = "-9999px";
|
|
120
|
+
oClonedNode.style.left = "-9999px";
|
|
121
|
+
oClonedNode.style.pointerEvents = "none";
|
|
122
|
+
|
|
123
|
+
// Convert outline to border for the drag image
|
|
124
|
+
_applyOutlineAsBorder(oClonedNode, oComputedStyle);
|
|
125
|
+
|
|
126
|
+
// Retain border-radius for rounded corners
|
|
127
|
+
var sBorderRadius = oComputedStyle.borderRadius;
|
|
128
|
+
if (sBorderRadius && sBorderRadius !== "0px") {
|
|
129
|
+
oClonedNode.style.borderRadius = sBorderRadius;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Retain background color
|
|
133
|
+
var sBackgroundColor = oComputedStyle.backgroundColor;
|
|
134
|
+
if (sBackgroundColor) {
|
|
135
|
+
oClonedNode.style.backgroundColor = sBackgroundColor;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return oClonedNode;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Processes header element styling in the cloned node.
|
|
143
|
+
*
|
|
144
|
+
* @param {HTMLElement} oClonedNode - The cloned node to process
|
|
145
|
+
* @param {HTMLElement} oInnerDiv - Original inner div element
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
var _processHeaderElement = function (oClonedNode, oInnerDiv) {
|
|
149
|
+
var oOriginalHeader = oInnerDiv.querySelector(".sapSuiteUiCommonsNetworkGraphDivHeader");
|
|
150
|
+
if (!oOriginalHeader) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
var oHeaderComputedStyle = window.getComputedStyle(oOriginalHeader);
|
|
155
|
+
var oHeaderElement = oClonedNode.querySelector(".sapSuiteUiCommonsNetworkGraphDivHeader");
|
|
156
|
+
|
|
157
|
+
if (!oHeaderElement) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Retain header background color
|
|
162
|
+
if (oHeaderComputedStyle.backgroundColor) {
|
|
163
|
+
oHeaderElement.style.backgroundColor = oHeaderComputedStyle.backgroundColor;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Convert header outline to border
|
|
167
|
+
_applyOutlineAsBorder(oHeaderElement, oHeaderComputedStyle, "borderBottom");
|
|
168
|
+
|
|
169
|
+
// Process separate header color wrapper if it exists (skip if combined class)
|
|
170
|
+
if (!oHeaderElement.classList.contains("sapSuiteUiCommonsNetworkGraphDivHeaderColor")) {
|
|
171
|
+
var oOriginalHeaderColor = oInnerDiv.querySelector(".sapSuiteUiCommonsNetworkGraphDivHeaderColor");
|
|
172
|
+
if (oOriginalHeaderColor) {
|
|
173
|
+
var oHeaderColorComputedStyle = window.getComputedStyle(oOriginalHeaderColor);
|
|
174
|
+
var oHeaderColorElement = oHeaderElement.querySelector(".sapSuiteUiCommonsNetworkGraphDivHeaderColor");
|
|
175
|
+
|
|
176
|
+
if (oHeaderColorElement) {
|
|
177
|
+
// Retain border
|
|
178
|
+
if (oHeaderColorComputedStyle.border && oHeaderColorComputedStyle.border !== "0px none rgb(0, 0, 0)") {
|
|
179
|
+
oHeaderColorElement.style.border = oHeaderColorComputedStyle.border;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Retain border-radius
|
|
183
|
+
if (oHeaderColorComputedStyle.borderRadius && oHeaderColorComputedStyle.borderRadius !== "0px") {
|
|
184
|
+
oHeaderColorElement.style.borderRadius = oHeaderColorComputedStyle.borderRadius;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Retain background color
|
|
188
|
+
if (oHeaderColorComputedStyle.backgroundColor) {
|
|
189
|
+
oHeaderColorElement.style.backgroundColor = oHeaderColorComputedStyle.backgroundColor;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Retain color
|
|
193
|
+
if (oHeaderColorComputedStyle.color) {
|
|
194
|
+
oHeaderColorElement.style.color = oHeaderColorComputedStyle.color;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Creates a custom drag image for the node that includes borders, border-radius, and background colors.
|
|
203
|
+
* This is necessary because the default browser drag image doesn't capture CSS outline properties for few browsers e.g. Chrome.
|
|
204
|
+
*
|
|
205
|
+
* @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node being dragged
|
|
206
|
+
* @param {Event} oBrowserEvent - The native browser drag event
|
|
207
|
+
* @returns {HTMLElement|null} The cloned node attached to DOM, or null if creation failed. Caller is responsible for cleanup.
|
|
208
|
+
*/
|
|
209
|
+
Utils.createCustomDragImage = function (oNode, oBrowserEvent) {
|
|
210
|
+
if (!oNode || !oBrowserEvent || !oBrowserEvent.dataTransfer) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Get the graph instance to check the ghost image mode
|
|
215
|
+
var oGraph = oNode.getParent();
|
|
216
|
+
if (!oGraph) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
var oDomRef = oNode.getDomRef();
|
|
222
|
+
if (!oDomRef) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
var oInnerDiv = oDomRef.querySelector(".sapSuiteUiCommonsNetworkGraphDivInner");
|
|
227
|
+
if (!oInnerDiv) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Clone and apply basic styles
|
|
232
|
+
var oClonedNode = _cloneAndStyleNode(oInnerDiv);
|
|
233
|
+
|
|
234
|
+
// Process header element styling
|
|
235
|
+
_processHeaderElement(oClonedNode, oInnerDiv);
|
|
236
|
+
|
|
237
|
+
// Attach to DOM temporarily
|
|
238
|
+
document.body.appendChild(oClonedNode);
|
|
239
|
+
|
|
240
|
+
// Set drag image with correct offset
|
|
241
|
+
var oRect = oInnerDiv.getBoundingClientRect();
|
|
242
|
+
var iOffsetX = oBrowserEvent.clientX - oRect.left;
|
|
243
|
+
var iOffsetY = oBrowserEvent.clientY - oRect.top;
|
|
244
|
+
oBrowserEvent.dataTransfer.setDragImage(oClonedNode, iOffsetX, iOffsetY);
|
|
245
|
+
|
|
246
|
+
// Return the cloned node for cleanup by caller
|
|
247
|
+
return oClonedNode;
|
|
248
|
+
} catch (oError) {
|
|
249
|
+
Log.warning("Utils: Failed to create custom drag image", oError);
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Retains the scroll position of the graph after DOM operations.
|
|
256
|
+
* This method ensures that the viewport remains stable after operations like
|
|
257
|
+
* drag-drop, connection creation, or other DOM manipulations.
|
|
258
|
+
*
|
|
259
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
260
|
+
* @param {number} scrollLeft - The horizontal scroll position to maintain
|
|
261
|
+
* @param {number} scrollTop - The vertical scroll position to maintain
|
|
262
|
+
*/
|
|
263
|
+
Utils.retainScrollPosition = function (oGraph, scrollLeft, scrollTop) {
|
|
264
|
+
if (!oGraph || !oGraph.$scroller || !oGraph.$scroller[0]) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const scrollerElement = oGraph.$scroller[0];
|
|
269
|
+
|
|
270
|
+
// Use requestAnimationFrame for better performance and timing
|
|
271
|
+
requestAnimationFrame(() => {
|
|
272
|
+
try {
|
|
273
|
+
scrollerElement.scrollLeft = scrollLeft;
|
|
274
|
+
scrollerElement.scrollTop = scrollTop;
|
|
275
|
+
|
|
276
|
+
// Fallback verification - ensure the scroll position was actually set
|
|
277
|
+
if (Math.abs(scrollerElement.scrollLeft - scrollLeft) > 1 ||
|
|
278
|
+
Math.abs(scrollerElement.scrollTop - scrollTop) > 1) {
|
|
279
|
+
|
|
280
|
+
// If the scroll position wasn't set correctly, try again after DOM updates
|
|
281
|
+
setTimeout(() => {
|
|
282
|
+
scrollerElement.scrollLeft = scrollLeft;
|
|
283
|
+
scrollerElement.scrollTop = scrollTop;
|
|
284
|
+
}, 10);
|
|
285
|
+
}
|
|
286
|
+
} catch (error) {
|
|
287
|
+
Log.error("retainScrollPosition: Error setting scroll position - " + error.message, "sap.suite.ui.commons.networkgraph.Utils");
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Preserves the scroll position of the graph by scheduling restoration after DOM updates.
|
|
294
|
+
* This is a convenience wrapper that handles the setTimeout + restoration logic.
|
|
295
|
+
*
|
|
296
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
297
|
+
* @param {number} scrollLeft - The horizontal scroll position to restore
|
|
298
|
+
* @param {number} scrollTop - The vertical scroll position to restore
|
|
299
|
+
* @param {number} [iDelay=0] - Delay in milliseconds before restoring scroll position
|
|
300
|
+
* @public
|
|
301
|
+
*/
|
|
302
|
+
Utils.preserveScrollPosition = function (oGraph, scrollLeft, scrollTop, iDelay) {
|
|
303
|
+
if (!oGraph || !oGraph.$scroller || !oGraph.$scroller[0]) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const delay = typeof iDelay === "number" ? iDelay : 0;
|
|
308
|
+
|
|
309
|
+
// Schedule restoration after DOM updates
|
|
310
|
+
setTimeout(() => {
|
|
311
|
+
Utils.retainScrollPosition(oGraph, scrollLeft, scrollTop);
|
|
312
|
+
}, delay);
|
|
313
|
+
};
|
|
85
314
|
|
|
86
315
|
return Utils;
|
|
87
316
|
}, true);
|
|
@@ -9,11 +9,13 @@ sap.ui.define([
|
|
|
9
9
|
"sap/suite/ui/commons/library",
|
|
10
10
|
"./LayoutAlgorithm",
|
|
11
11
|
"./LayoutTask",
|
|
12
|
-
"../util/ConnectionPathUtils"
|
|
13
|
-
|
|
12
|
+
"../util/ConnectionPathUtils",
|
|
13
|
+
"../util/DependencyLayoutHelper"
|
|
14
|
+
], function (library, LayoutAlgorithm, LayoutTask, ConnectionPathUtils, DependencyLayoutHelper) {
|
|
14
15
|
"use strict";
|
|
15
16
|
|
|
16
|
-
var
|
|
17
|
+
var oLayoutRenderType = library.networkgraph.LayoutRenderType,
|
|
18
|
+
oComponentArrangement = library.networkgraph.ComponentArrangement;
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Constructor for a new NoopLayout.
|
|
@@ -37,9 +39,17 @@ sap.ui.define([
|
|
|
37
39
|
* Enables advanced line routing algorithm that creates orthogonal bends along the pathfinding process for line creation.
|
|
38
40
|
*
|
|
39
41
|
* @public
|
|
40
|
-
* @since 1.144
|
|
41
42
|
*/
|
|
42
|
-
enableOptimizedLineAlgorithm: { type: "boolean", group: "Behavior", defaultValue: false }
|
|
43
|
+
enableOptimizedLineAlgorithm: { type: "boolean", group: "Behavior", defaultValue: false },
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Defines how separate connected components should be arranged in the graph.
|
|
47
|
+
* Components can be arranged either horizontally (side-by-side) or vertically (stacked).
|
|
48
|
+
*
|
|
49
|
+
* @since 1.146
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
componentArrangement: { type: "sap.suite.ui.commons.networkgraph.ComponentArrangement", group: "Behavior", defaultValue: oComponentArrangement.Horizontal }
|
|
43
53
|
}
|
|
44
54
|
}
|
|
45
55
|
});
|
|
@@ -54,11 +64,14 @@ sap.ui.define([
|
|
|
54
64
|
* @public
|
|
55
65
|
*/
|
|
56
66
|
NoopLayout.prototype.getLayoutRenderType = function () {
|
|
57
|
-
return
|
|
67
|
+
return oLayoutRenderType.LayeredWithGroups;
|
|
58
68
|
};
|
|
59
69
|
|
|
60
70
|
/**
|
|
61
71
|
* Executes the layout algorithm.
|
|
72
|
+
* Automatically calculates initial positions for unpositioned nodes using DependencyLayoutHelper,
|
|
73
|
+
* then normalizes line coordinates.
|
|
74
|
+
*
|
|
62
75
|
* @returns {sap.suite.ui.commons.networkgraph.layout.LayoutTask} Task to get the layout calculated.
|
|
63
76
|
* @public
|
|
64
77
|
*/
|
|
@@ -76,6 +89,19 @@ sap.ui.define([
|
|
|
76
89
|
return;
|
|
77
90
|
}
|
|
78
91
|
|
|
92
|
+
// Check if positioning should be calculated
|
|
93
|
+
// Note: DependencyLayoutHelper only repositions nodes without valid coordinates
|
|
94
|
+
if (this._shouldCalculatePositions(oGraph)) {
|
|
95
|
+
DependencyLayoutHelper.calculatePositions(oGraph, {
|
|
96
|
+
componentArrangement: this.getComponentArrangement()
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Reset flag after calculation
|
|
100
|
+
if (oGraph._bTriggerLayoutCalculation) {
|
|
101
|
+
oGraph._bTriggerLayoutCalculation = false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
79
105
|
if (this.getEnableOptimizedLineAlgorithm()) {
|
|
80
106
|
// Use the ConnectionPathUtils utility to normalize lines
|
|
81
107
|
ConnectionPathUtils.normalizeLines(oGraph, {
|
|
@@ -86,11 +112,32 @@ sap.ui.define([
|
|
|
86
112
|
this._normalizeLines();
|
|
87
113
|
}
|
|
88
114
|
|
|
89
|
-
|
|
90
|
-
|
|
91
115
|
fnResolve();
|
|
92
116
|
}.bind(this));
|
|
93
117
|
};
|
|
94
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Determines if initial positions should be calculated.
|
|
121
|
+
* Only returns true if there are unpositioned nodes or if explicitly triggered.
|
|
122
|
+
*
|
|
123
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph instance
|
|
124
|
+
* @returns {boolean} True if positions should be calculated
|
|
125
|
+
* @private
|
|
126
|
+
*/
|
|
127
|
+
NoopLayout.prototype._shouldCalculatePositions = function (oGraph) {
|
|
128
|
+
// Check if explicit trigger flag is set
|
|
129
|
+
// Even when triggered, DependencyLayoutHelper only affects unpositioned nodes
|
|
130
|
+
if (oGraph._bTriggerLayoutCalculation) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Auto-detect unpositioned nodes (coordinates 0,0 or undefined)
|
|
135
|
+
return oGraph.getNodes().some(function (oNode) {
|
|
136
|
+
var fX = oNode.getX();
|
|
137
|
+
var fY = oNode.getY();
|
|
138
|
+
return (fX === 0 || fX === undefined) && (fY === 0 || fY === undefined);
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
|
|
95
142
|
return NoopLayout;
|
|
96
143
|
});
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (library, Log) {
|
|
8
8
|
"use strict";
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const oConnectionType = library.networkgraph.ConnectionType,
|
|
11
|
+
oComponentArrangement = library.networkgraph.ComponentArrangement;
|
|
12
12
|
const DEFAULT_HORIZONTAL_SPACING = 240;
|
|
13
13
|
const DEFAULT_VERTICAL_SPACING = 100;
|
|
14
14
|
|
|
@@ -32,12 +32,14 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
32
32
|
* Calculates and sets positions for nodes without coordinates based on their dependency relationships.
|
|
33
33
|
* Uses topological sorting (Kahn's algorithm) and DFS-based cycle detection to arrange nodes
|
|
34
34
|
* in layers from left to right, ensuring no overlaps and minimal line crossings.
|
|
35
|
+
* Note: Drag and drop functionality is only available for nodes. Groups cannot be dragged and dropped, even when NoopLayout is used and enableDragAndDrop is set to true.
|
|
35
36
|
*
|
|
36
|
-
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The
|
|
37
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph instance
|
|
37
38
|
* @param {object} [mConfig] - Configuration object
|
|
38
39
|
* @param {number} [mConfig.horizontalSpacing=240] - Horizontal spacing between layers
|
|
39
40
|
* @param {number} [mConfig.verticalSpacing=100] - Vertical spacing between nodes
|
|
40
41
|
* @param {sap.suite.ui.commons.networkgraph.ComponentArrangement} [mConfig.componentArrangement=Horizontal] - Component arrangement: "Horizontal" or "Vertical"
|
|
42
|
+
* @param {boolean} [mConfig.clearCache=false] - Clear the position cache to force recalculation of all nodes
|
|
41
43
|
* @public
|
|
42
44
|
*/
|
|
43
45
|
calculatePositions: function (oGraph, mConfig) {
|
|
@@ -49,10 +51,17 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
49
51
|
{
|
|
50
52
|
horizontalSpacing: DEFAULT_HORIZONTAL_SPACING,
|
|
51
53
|
verticalSpacing: DEFAULT_VERTICAL_SPACING,
|
|
52
|
-
componentArrangement:
|
|
54
|
+
componentArrangement: oComponentArrangement.Horizontal,
|
|
55
|
+
clearCache: false
|
|
53
56
|
},
|
|
54
57
|
mConfig || {}
|
|
55
58
|
);
|
|
59
|
+
|
|
60
|
+
// Clear cache if requested (e.g., when changing arrangement)
|
|
61
|
+
if (config.clearCache) {
|
|
62
|
+
this._lastCalculated = new WeakMap();
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
try {
|
|
57
66
|
this._detectUserChanges(oGraph);
|
|
58
67
|
this._buildDependencyGraph(oGraph);
|
|
@@ -129,13 +138,13 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
129
138
|
this._lineMap.get(sFromKey).set(sToKey, oLine);
|
|
130
139
|
|
|
131
140
|
switch (sConnectionType) {
|
|
132
|
-
case
|
|
133
|
-
case
|
|
141
|
+
case oConnectionType.RightToRight:
|
|
142
|
+
case oConnectionType.LeftToLeft:
|
|
134
143
|
oFromNode._layoutData.parallelNodes.push(oToNode);
|
|
135
144
|
oToNode._layoutData.parallelNodes.push(oFromNode);
|
|
136
145
|
break;
|
|
137
|
-
case
|
|
138
|
-
case
|
|
146
|
+
case oConnectionType.RightToLeft:
|
|
147
|
+
case oConnectionType.LeftToRight:
|
|
139
148
|
default:
|
|
140
149
|
oFromNode._layoutData.outgoing.push(oToNode);
|
|
141
150
|
oToNode._layoutData.incoming.push(oFromNode);
|
|
@@ -279,7 +288,7 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
279
288
|
aConnectedComponents.push(aComponentNodes);
|
|
280
289
|
}
|
|
281
290
|
});
|
|
282
|
-
const bSideBySide = componentArrangement !==
|
|
291
|
+
const bSideBySide = componentArrangement !== oComponentArrangement.Vertical;
|
|
283
292
|
let iMaxVerticalPosition = 0;
|
|
284
293
|
let iMaxLayerAcrossAll = 0;
|
|
285
294
|
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
sap.ui.define([
|
|
8
8
|
"sap/ui/core/dnd/DragInfo",
|
|
9
9
|
"sap/ui/core/dnd/DropInfo",
|
|
10
|
-
"sap/base/Log"
|
|
11
|
-
|
|
10
|
+
"sap/base/Log",
|
|
11
|
+
"sap/suite/ui/commons/networkgraph/Utils"
|
|
12
|
+
], function (DragInfo, DropInfo, Log, Utils) {
|
|
12
13
|
"use strict";
|
|
13
14
|
|
|
14
15
|
// constants
|
|
@@ -22,12 +23,32 @@ sap.ui.define([
|
|
|
22
23
|
AUTO_SCROLL_SPEED: 10, // Pixels to scroll per frame (16ms)
|
|
23
24
|
};
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Minimum position offsets to ensure action buttons remain visible.
|
|
28
|
+
* LEFT: 60px accounts for line and port
|
|
29
|
+
* TOP: 40px accounts for top action buttons (-2.25rem ≈ 36px) plus margin
|
|
30
|
+
*/
|
|
31
|
+
const POSITION_CLAMP_OFFSET = {
|
|
32
|
+
LEFT: 60,
|
|
33
|
+
TOP: 40
|
|
34
|
+
};
|
|
35
|
+
|
|
25
36
|
// Instance object: Only one will exist
|
|
26
37
|
var instance = null;
|
|
27
38
|
var sDragSessionKey = "networkGraphDragSession";
|
|
28
39
|
var oUtilityFunctions = {
|
|
29
40
|
diff: function (a, b) {
|
|
30
41
|
return Math.abs(a - b);
|
|
42
|
+
},
|
|
43
|
+
clampPosition: function (x, y) {
|
|
44
|
+
/**
|
|
45
|
+
* Clamps position coordinates to minimum thresholds.
|
|
46
|
+
* Prevents nodes from being positioned where action buttons would be off-screen.
|
|
47
|
+
*/
|
|
48
|
+
return {
|
|
49
|
+
x: Math.max(POSITION_CLAMP_OFFSET.LEFT, x),
|
|
50
|
+
y: Math.max(POSITION_CLAMP_OFFSET.TOP, y)
|
|
51
|
+
};
|
|
31
52
|
}
|
|
32
53
|
};
|
|
33
54
|
|
|
@@ -276,45 +297,6 @@ sap.ui.define([
|
|
|
276
297
|
oControl.isA("sap.suite.ui.commons.networkgraph.Node");
|
|
277
298
|
}
|
|
278
299
|
|
|
279
|
-
/**
|
|
280
|
-
* Retains the scroll position of the graph after node drop.
|
|
281
|
-
* This method ensures that the viewport remains stable after drag and drop operations.
|
|
282
|
-
*
|
|
283
|
-
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
284
|
-
* @param {number} scrollLeft - The horizontal scroll position to maintain
|
|
285
|
-
* @param {number} scrollTop - The vertical scroll position to maintain
|
|
286
|
-
* @private
|
|
287
|
-
*/
|
|
288
|
-
DragDropManager.prototype._retainScrollPosition = function (oGraph, scrollLeft, scrollTop) {
|
|
289
|
-
if (!oGraph || !oGraph.$scroller || !oGraph.$scroller[0]) {
|
|
290
|
-
Log.warning("DragDropManager: Invalid graph or scroller element for scroll position retention.");
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const scrollerElement = oGraph.$scroller[0];
|
|
295
|
-
|
|
296
|
-
// Use requestAnimationFrame for better performance and timing
|
|
297
|
-
this._iRequestAnimationFrameId = requestAnimationFrame(() => {
|
|
298
|
-
try {
|
|
299
|
-
scrollerElement.scrollLeft = scrollLeft;
|
|
300
|
-
scrollerElement.scrollTop = scrollTop;
|
|
301
|
-
|
|
302
|
-
// Fallback verification - ensure the scroll position was actually set
|
|
303
|
-
if (Math.abs(scrollerElement.scrollLeft - scrollLeft) > 1 ||
|
|
304
|
-
Math.abs(scrollerElement.scrollTop - scrollTop) > 1) {
|
|
305
|
-
|
|
306
|
-
// If the scroll position wasn't set correctly, try again after DOM updates
|
|
307
|
-
setTimeout(() => {
|
|
308
|
-
scrollerElement.scrollLeft = scrollLeft;
|
|
309
|
-
scrollerElement.scrollTop = scrollTop;
|
|
310
|
-
}, 10);
|
|
311
|
-
}
|
|
312
|
-
} catch (error) {
|
|
313
|
-
Log.error("DragDropManager: Failed to retain scroll position", error);
|
|
314
|
-
}
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
|
|
318
300
|
/**
|
|
319
301
|
* Handles the drag start event for nodes.
|
|
320
302
|
*
|
|
@@ -325,6 +307,7 @@ sap.ui.define([
|
|
|
325
307
|
let dragSession = oEvent.getParameter("dragSession");
|
|
326
308
|
let browserEvent = oEvent.getParameter("browserEvent");
|
|
327
309
|
let oGraph = oEvent.getParameter("target")?.getParent();
|
|
310
|
+
let oNode = oEvent.getParameter("target");
|
|
328
311
|
let boundingRectScroller = oGraph?.$scroller?.[0]?.getBoundingClientRect() || { x: 0, y: 0 };
|
|
329
312
|
let boundingRectInnerScroller = oGraph?._$innerscroller?.[0]?.getBoundingClientRect() || { x: 0, y: 0 };
|
|
330
313
|
|
|
@@ -336,6 +319,9 @@ sap.ui.define([
|
|
|
336
319
|
// Stop any existing auto-scroll from previous drag operations
|
|
337
320
|
this._stopAutoScroll();
|
|
338
321
|
|
|
322
|
+
// Create custom drag image that includes the border
|
|
323
|
+
this._oDragImageNode = Utils.createCustomDragImage(oNode, browserEvent);
|
|
324
|
+
|
|
339
325
|
dragSession.setComplexData(sDragSessionKey, {
|
|
340
326
|
// Mouse cursor position when drag starts (in viewport coordinates)
|
|
341
327
|
cursorX: browserEvent.clientX,
|
|
@@ -369,6 +355,12 @@ sap.ui.define([
|
|
|
369
355
|
|
|
370
356
|
// Stop auto-scrolling when drag ends
|
|
371
357
|
this._stopAutoScroll();
|
|
358
|
+
|
|
359
|
+
// Clean up the drag image node
|
|
360
|
+
if (this._oDragImageNode && this._oDragImageNode.parentNode) {
|
|
361
|
+
this._oDragImageNode.parentNode.removeChild(this._oDragImageNode);
|
|
362
|
+
this._oDragImageNode = null;
|
|
363
|
+
}
|
|
372
364
|
};
|
|
373
365
|
|
|
374
366
|
/**
|
|
@@ -543,6 +535,9 @@ sap.ui.define([
|
|
|
543
535
|
let newX = dropData.draggedControl.getX() + deltaX + (deltaSignatureX * deltaInnerScrollerX),
|
|
544
536
|
newY = dropData.draggedControl.getY() + deltaY + (deltaSignatureY * deltaInnerScrollerY);
|
|
545
537
|
|
|
538
|
+
// Clamp position to prevent nodes from going off-screen (especially for action buttons)
|
|
539
|
+
var oClampedPosition = oUtilityFunctions.clampPosition(newX, newY);
|
|
540
|
+
|
|
546
541
|
// Store current scroll position before any DOM changes
|
|
547
542
|
let currentScrollLeft = oGraph?.$scroller?.[0]?.scrollLeft || 0;
|
|
548
543
|
let currentScrollTop = oGraph?.$scroller?.[0]?.scrollTop || 0;
|
|
@@ -550,14 +545,11 @@ sap.ui.define([
|
|
|
550
545
|
oGraph.fireEvent("nodeDropped", {
|
|
551
546
|
...oEvent.getParameters(),
|
|
552
547
|
node: dropData.draggedControl,
|
|
553
|
-
newX:
|
|
554
|
-
newY:
|
|
548
|
+
newX: oClampedPosition.x,
|
|
549
|
+
newY: oClampedPosition.y
|
|
555
550
|
});
|
|
556
|
-
//
|
|
557
|
-
|
|
558
|
-
setTimeout(() => {
|
|
559
|
-
this._retainScrollPosition(oGraph, currentScrollLeft, currentScrollTop);
|
|
560
|
-
}, 0);
|
|
551
|
+
// Preserve scroll position after event
|
|
552
|
+
Utils.preserveScrollPosition(oGraph, currentScrollLeft, currentScrollTop, 0);
|
|
561
553
|
};
|
|
562
554
|
|
|
563
555
|
/**
|
|
@@ -574,12 +566,22 @@ sap.ui.define([
|
|
|
574
566
|
x = dropData.clientX - boundingRect.left,
|
|
575
567
|
y = dropData.clientY - boundingRect.top;
|
|
576
568
|
|
|
569
|
+
// Clamp position to prevent nodes from going off-screen (especially for action buttons)
|
|
570
|
+
var oClampedPosition = oUtilityFunctions.clampPosition(x, y);
|
|
571
|
+
|
|
572
|
+
// Store current scroll position before any DOM changes
|
|
573
|
+
let currentScrollLeft = oGraph?.$scroller?.[0]?.scrollLeft || 0;
|
|
574
|
+
let currentScrollTop = oGraph?.$scroller?.[0]?.scrollTop || 0;
|
|
575
|
+
|
|
577
576
|
oGraph.fireEvent("nodeDropped", {
|
|
578
577
|
...oEvent.getParameters(),
|
|
579
578
|
node: dropData.draggedControl,
|
|
580
|
-
newX: x,
|
|
581
|
-
newY: y
|
|
579
|
+
newX: oClampedPosition.x,
|
|
580
|
+
newY: oClampedPosition.y
|
|
582
581
|
});
|
|
582
|
+
|
|
583
|
+
// Preserve scroll position after event
|
|
584
|
+
Utils.preserveScrollPosition(oGraph, currentScrollLeft, currentScrollTop, 0);
|
|
583
585
|
};
|
|
584
586
|
|
|
585
587
|
/**
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
sap.ui.define([
|
|
8
8
|
"sap/ui/thirdparty/jquery",
|
|
9
|
-
"sap/suite/ui/commons/library"
|
|
10
|
-
|
|
9
|
+
"sap/suite/ui/commons/library",
|
|
10
|
+
"sap/suite/ui/commons/networkgraph/Utils"
|
|
11
|
+
], function (jQuery, Library, Utils) {
|
|
11
12
|
"use strict";
|
|
12
13
|
/**
|
|
13
14
|
* PortManager class for managing network graph ports.
|
|
@@ -485,6 +486,11 @@ sap.ui.define([
|
|
|
485
486
|
const targetPortSide = target.dataset.portSide;
|
|
486
487
|
// Check if the target node is valid
|
|
487
488
|
if (targetNode) {
|
|
489
|
+
const oGraph = sourceNode.getParent();
|
|
490
|
+
// Capture current scroll position before firing event
|
|
491
|
+
const scrollerElement = oGraph.$scroller[0];
|
|
492
|
+
const currentScrollLeft = scrollerElement.scrollLeft || 0;
|
|
493
|
+
const currentScrollTop = scrollerElement.scrollTop || 0;
|
|
488
494
|
const mParameters = {
|
|
489
495
|
from: sourceNode.getKey(),
|
|
490
496
|
to: targetNode.getKey(),
|
|
@@ -493,7 +499,10 @@ sap.ui.define([
|
|
|
493
499
|
toNode: targetNode
|
|
494
500
|
};
|
|
495
501
|
// Fire the connectionCreated event
|
|
496
|
-
|
|
502
|
+
oGraph.fireConnectionCreated(mParameters);
|
|
503
|
+
|
|
504
|
+
// Preserve scroll position after event
|
|
505
|
+
Utils.preserveScrollPosition(oGraph, currentScrollLeft, currentScrollTop, 0);
|
|
497
506
|
}
|
|
498
507
|
}
|
|
499
508
|
// Remove inlet ports from other nodes
|