@sapui5/sap.suite.ui.commons 1.144.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 +35 -6
- 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 -3
- 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/Timeline.js +9 -0
- package/src/sap/suite/ui/commons/TimelineNavigator.js +37 -5
- package/src/sap/suite/ui/commons/TimelineRenderer.js +3 -3
- package/src/sap/suite/ui/commons/collaboration/BaseHelperService.js +0 -1
- package/src/sap/suite/ui/commons/collaboration/CollaborationHelper.js +0 -3
- package/src/sap/suite/ui/commons/collaboration/CollaborationManagerService.js +0 -1
- package/src/sap/suite/ui/commons/collaboration/ContactHelper.js +12 -1
- package/src/sap/suite/ui/commons/collaboration/ContactPopover.fragment.xml +4 -1
- package/src/sap/suite/ui/commons/collaboration/MinimalContactPopover.fragment.xml +8 -5
- package/src/sap/suite/ui/commons/collaboration/ServiceContainer.js +12 -2
- package/src/sap/suite/ui/commons/collaboration/TeamsHelperService.js +0 -6
- package/src/sap/suite/ui/commons/collaboration/channels/MessageChannel.js +0 -2
- package/src/sap/suite/ui/commons/collaboration/flpplugins/msplugin/Component-preload.js +1 -1
- package/src/sap/suite/ui/commons/collaboration/flpplugins/msplugin/Component.js +1 -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 +25 -1
- package/src/sap/suite/ui/commons/messagebundle.properties +20 -9
- package/src/sap/suite/ui/commons/messagebundle_ar.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_bg.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_ca.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_cnr.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_cs.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_cy.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_da.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_de.properties +36 -15
- package/src/sap/suite/ui/commons/messagebundle_el.properties +25 -4
- package/src/sap/suite/ui/commons/messagebundle_en.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_en_GB.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_en_US_saprigi.properties +11 -5
- package/src/sap/suite/ui/commons/messagebundle_es.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_es_MX.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_et.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_fi.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_fr.properties +32 -11
- package/src/sap/suite/ui/commons/messagebundle_fr_CA.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_hi.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_hr.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_hu.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_id.properties +25 -4
- package/src/sap/suite/ui/commons/messagebundle_it.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_iw.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_ja.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_kk.properties +25 -4
- package/src/sap/suite/ui/commons/messagebundle_ko.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_lt.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_lv.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_mk.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_ms.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_nl.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_no.properties +25 -4
- package/src/sap/suite/ui/commons/messagebundle_pl.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_pt.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_pt_PT.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_ro.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_ru.properties +25 -4
- package/src/sap/suite/ui/commons/messagebundle_sh.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_sk.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_sl.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_sr.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_sv.properties +23 -2
- package/src/sap/suite/ui/commons/messagebundle_th.properties +25 -4
- package/src/sap/suite/ui/commons/messagebundle_tr.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_uk.properties +27 -6
- package/src/sap/suite/ui/commons/messagebundle_vi.properties +26 -5
- package/src/sap/suite/ui/commons/messagebundle_zh_CN.properties +24 -3
- package/src/sap/suite/ui/commons/messagebundle_zh_TW.properties +26 -5
- package/src/sap/suite/ui/commons/networkgraph/Graph.js +49 -22
- package/src/sap/suite/ui/commons/networkgraph/KeyboardNavigator.js +45 -4
- package/src/sap/suite/ui/commons/networkgraph/Line.js +157 -11
- package/src/sap/suite/ui/commons/networkgraph/Node.js +289 -86
- 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 +156 -74
- package/src/sap/suite/ui/commons/networkgraph/util/DragDropManager.js +52 -50
- package/src/sap/suite/ui/commons/networkgraph/util/PortManager.js +14 -6
- 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/themes/base/NetworkLine.less +26 -5
- package/src/sap/suite/ui/commons/windowmessages/CollaborationMessageConsumer.js +3 -3
|
@@ -7,7 +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
|
|
10
|
+
const oConnectionType = library.networkgraph.ConnectionType,
|
|
11
|
+
oComponentArrangement = library.networkgraph.ComponentArrangement;
|
|
11
12
|
const DEFAULT_HORIZONTAL_SPACING = 240;
|
|
12
13
|
const DEFAULT_VERTICAL_SPACING = 100;
|
|
13
14
|
|
|
@@ -21,15 +22,24 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
21
22
|
* @since 1.144
|
|
22
23
|
*/
|
|
23
24
|
const DependencyLayoutHelper = {
|
|
25
|
+
/**
|
|
26
|
+
* WeakMap to store last calculated positions and origin flag for automatic drag detection.
|
|
27
|
+
* Structure: {x: number, y: number, bIsUserPositioned: boolean}
|
|
28
|
+
*/
|
|
29
|
+
_lastCalculated: new WeakMap(),
|
|
30
|
+
|
|
24
31
|
/**
|
|
25
32
|
* Calculates and sets positions for nodes without coordinates based on their dependency relationships.
|
|
26
33
|
* Uses topological sorting (Kahn's algorithm) and DFS-based cycle detection to arrange nodes
|
|
27
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.
|
|
28
36
|
*
|
|
29
|
-
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The
|
|
37
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph instance
|
|
30
38
|
* @param {object} [mConfig] - Configuration object
|
|
31
39
|
* @param {number} [mConfig.horizontalSpacing=240] - Horizontal spacing between layers
|
|
32
40
|
* @param {number} [mConfig.verticalSpacing=100] - Vertical spacing between nodes
|
|
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
|
|
33
43
|
* @public
|
|
34
44
|
*/
|
|
35
45
|
calculatePositions: function (oGraph, mConfig) {
|
|
@@ -41,17 +51,26 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
41
51
|
{
|
|
42
52
|
horizontalSpacing: DEFAULT_HORIZONTAL_SPACING,
|
|
43
53
|
verticalSpacing: DEFAULT_VERTICAL_SPACING,
|
|
54
|
+
componentArrangement: oComponentArrangement.Horizontal,
|
|
55
|
+
clearCache: false
|
|
44
56
|
},
|
|
45
57
|
mConfig || {}
|
|
46
58
|
);
|
|
47
59
|
|
|
60
|
+
// Clear cache if requested (e.g., when changing arrangement)
|
|
61
|
+
if (config.clearCache) {
|
|
62
|
+
this._lastCalculated = new WeakMap();
|
|
63
|
+
}
|
|
64
|
+
|
|
48
65
|
try {
|
|
66
|
+
this._detectUserChanges(oGraph);
|
|
49
67
|
this._buildDependencyGraph(oGraph);
|
|
50
68
|
const aComponents = this._identifyComponents(oGraph);
|
|
51
|
-
this._processComponents(aComponents);
|
|
69
|
+
this._processComponents(aComponents, config);
|
|
52
70
|
this._calculateCoordinates(oGraph, config);
|
|
53
71
|
this._adjustHorizontalSpacingForNodeWidths(oGraph, config);
|
|
54
72
|
this._adjustVerticalSpacingForNodeHeights(oGraph, config);
|
|
73
|
+
this._storeFinalPositions(oGraph);
|
|
55
74
|
} catch (e) {
|
|
56
75
|
Log.error("DependencyLayoutHelper error: " + e.message, e);
|
|
57
76
|
throw new Error("DependencyLayoutHelper error: " + e.message);
|
|
@@ -64,8 +83,8 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
64
83
|
},
|
|
65
84
|
|
|
66
85
|
/**
|
|
67
|
-
* Builds the
|
|
68
|
-
* Initializes layout data for each node and categorizes connections
|
|
86
|
+
* Builds the dependency graph structure by analyzing node relationships.
|
|
87
|
+
* Initializes layout data for each node and categorizes connections.
|
|
69
88
|
*
|
|
70
89
|
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
71
90
|
* @private
|
|
@@ -79,9 +98,9 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
79
98
|
mNodeMap.set(oNode.getKey(), oNode);
|
|
80
99
|
const fX = oNode.getX();
|
|
81
100
|
const fY = oNode.getY();
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
const
|
|
101
|
+
const oLastPos = this._lastCalculated.get(oNode);
|
|
102
|
+
// Only preserve coordinates if they were original or user-dragged
|
|
103
|
+
const bShouldPreserve = oLastPos?.bIsUserPositioned;
|
|
85
104
|
|
|
86
105
|
oNode._layoutData = {
|
|
87
106
|
layer: -1,
|
|
@@ -91,9 +110,10 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
91
110
|
parallelNodes: [],
|
|
92
111
|
backwardEdges: [],
|
|
93
112
|
backwardEdgeLines: [],
|
|
94
|
-
|
|
113
|
+
isBackwardSource: false,
|
|
114
|
+
bShouldPreserve,
|
|
95
115
|
userX: fX,
|
|
96
|
-
userY: fY
|
|
116
|
+
userY: fY
|
|
97
117
|
};
|
|
98
118
|
});
|
|
99
119
|
|
|
@@ -118,13 +138,13 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
118
138
|
this._lineMap.get(sFromKey).set(sToKey, oLine);
|
|
119
139
|
|
|
120
140
|
switch (sConnectionType) {
|
|
121
|
-
case
|
|
122
|
-
case
|
|
141
|
+
case oConnectionType.RightToRight:
|
|
142
|
+
case oConnectionType.LeftToLeft:
|
|
123
143
|
oFromNode._layoutData.parallelNodes.push(oToNode);
|
|
124
144
|
oToNode._layoutData.parallelNodes.push(oFromNode);
|
|
125
145
|
break;
|
|
126
|
-
case
|
|
127
|
-
case
|
|
146
|
+
case oConnectionType.RightToLeft:
|
|
147
|
+
case oConnectionType.LeftToRight:
|
|
128
148
|
default:
|
|
129
149
|
oFromNode._layoutData.outgoing.push(oToNode);
|
|
130
150
|
oToNode._layoutData.incoming.push(oFromNode);
|
|
@@ -164,12 +184,9 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
164
184
|
oNode._layoutData.isBackwardSource = true;
|
|
165
185
|
oNode._layoutData.backwardEdges.push(oTargetNode);
|
|
166
186
|
|
|
167
|
-
const
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
if (oLine) {
|
|
171
|
-
oNode._layoutData.backwardEdgeLines.push(oLine);
|
|
172
|
-
}
|
|
187
|
+
const oLine = this._lineMap.get(sKey)?.get(sTargetKey);
|
|
188
|
+
if (oLine) {
|
|
189
|
+
oNode._layoutData.backwardEdgeLines.push(oLine);
|
|
173
190
|
}
|
|
174
191
|
|
|
175
192
|
const idx = oTargetNode._layoutData.incoming.indexOf(oNode);
|
|
@@ -251,9 +268,10 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
251
268
|
* Processes all components: separates isolated nodes and arranges connected components.
|
|
252
269
|
*
|
|
253
270
|
* @param {Array<sap.suite.ui.commons.networkgraph.Node[]>} aComponents - Array of components (groups of connected nodes)
|
|
271
|
+
* @param {object} config - Configuration object
|
|
254
272
|
* @private
|
|
255
273
|
*/
|
|
256
|
-
_processComponents: function (aComponents) {
|
|
274
|
+
_processComponents: function (aComponents, { componentArrangement }) {
|
|
257
275
|
const aIsolatedNodes = [];
|
|
258
276
|
const aConnectedComponents = [];
|
|
259
277
|
|
|
@@ -261,7 +279,8 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
261
279
|
const bIsIsolated =
|
|
262
280
|
aComponentNodes.length === 1 &&
|
|
263
281
|
aComponentNodes[0]._layoutData.incoming.length === 0 &&
|
|
264
|
-
aComponentNodes[0]._layoutData.outgoing.length === 0
|
|
282
|
+
aComponentNodes[0]._layoutData.outgoing.length === 0 &&
|
|
283
|
+
!aComponentNodes[0]._layoutData.bShouldPreserve;
|
|
265
284
|
|
|
266
285
|
if (bIsIsolated) {
|
|
267
286
|
aIsolatedNodes.push(aComponentNodes[0]);
|
|
@@ -269,7 +288,7 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
269
288
|
aConnectedComponents.push(aComponentNodes);
|
|
270
289
|
}
|
|
271
290
|
});
|
|
272
|
-
|
|
291
|
+
const bSideBySide = componentArrangement !== oComponentArrangement.Vertical;
|
|
273
292
|
let iMaxVerticalPosition = 0;
|
|
274
293
|
let iMaxLayerAcrossAll = 0;
|
|
275
294
|
|
|
@@ -278,35 +297,56 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
278
297
|
this._adjustParallelLayersForComponent(aComponentNodes);
|
|
279
298
|
this._assignVerticalPositionsForComponent(aComponentNodes);
|
|
280
299
|
|
|
281
|
-
|
|
282
|
-
oNode
|
|
283
|
-
|
|
284
|
-
|
|
300
|
+
if (bSideBySide) {
|
|
301
|
+
aComponentNodes.forEach((oNode) => {
|
|
302
|
+
oNode._layoutData.layer += iMaxLayerAcrossAll;
|
|
303
|
+
oNode._layoutData.componentOffset = 0;
|
|
304
|
+
});
|
|
285
305
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
306
|
+
let iComponentMaxLayer = -1;
|
|
307
|
+
aComponentNodes.forEach((n) => {
|
|
308
|
+
if (n._layoutData.layer > iComponentMaxLayer) {
|
|
309
|
+
iComponentMaxLayer = n._layoutData.layer;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
iMaxLayerAcrossAll = iComponentMaxLayer + 1;
|
|
313
|
+
} else {
|
|
314
|
+
aComponentNodes.forEach((oNode) => {
|
|
315
|
+
oNode._layoutData.position += iMaxVerticalPosition;
|
|
316
|
+
oNode._layoutData.componentOffset = 0;
|
|
317
|
+
});
|
|
293
318
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
319
|
+
let iComponentMaxPosition = -1;
|
|
320
|
+
aComponentNodes.forEach((n) => {
|
|
321
|
+
if (n._layoutData.position > iComponentMaxPosition) {
|
|
322
|
+
iComponentMaxPosition = n._layoutData.position;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
iMaxVerticalPosition = iComponentMaxPosition + 1;
|
|
326
|
+
|
|
327
|
+
let iComponentMaxLayer = -1;
|
|
328
|
+
aComponentNodes.forEach((n) => {
|
|
329
|
+
if (n._layoutData.layer > iComponentMaxLayer) {
|
|
330
|
+
iComponentMaxLayer = n._layoutData.layer;
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
iMaxLayerAcrossAll = Math.max(iMaxLayerAcrossAll, iComponentMaxLayer);
|
|
334
|
+
}
|
|
301
335
|
});
|
|
302
336
|
|
|
303
337
|
if (aIsolatedNodes.length > 0) {
|
|
304
338
|
const iRightSideOffset = iMaxLayerAcrossAll + 1;
|
|
305
339
|
|
|
306
340
|
aIsolatedNodes.forEach((oNode, idx) => {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
341
|
+
if (bSideBySide) {
|
|
342
|
+
oNode._layoutData.layer = Math.floor(idx / 2);
|
|
343
|
+
oNode._layoutData.position = idx % 2;
|
|
344
|
+
oNode._layoutData.componentOffset = iMaxLayerAcrossAll;
|
|
345
|
+
} else {
|
|
346
|
+
oNode._layoutData.layer = idx % 2;
|
|
347
|
+
oNode._layoutData.position = Math.floor(idx / 2);
|
|
348
|
+
oNode._layoutData.componentOffset = iRightSideOffset;
|
|
349
|
+
}
|
|
310
350
|
});
|
|
311
351
|
}
|
|
312
352
|
},
|
|
@@ -657,10 +697,10 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
657
697
|
* @param {object} config - Configuration with spacing values
|
|
658
698
|
* @private
|
|
659
699
|
*/
|
|
660
|
-
_calculateCoordinates: function (oGraph,
|
|
700
|
+
_calculateCoordinates: function (oGraph, { horizontalSpacing, verticalSpacing }) {
|
|
661
701
|
const aNodes = oGraph.getNodes();
|
|
662
|
-
const iHSpacing =
|
|
663
|
-
const iVSpacing =
|
|
702
|
+
const iHSpacing = horizontalSpacing;
|
|
703
|
+
const iVSpacing = verticalSpacing;
|
|
664
704
|
|
|
665
705
|
aNodes.forEach((oNode) => {
|
|
666
706
|
const iComponentOffset = oNode._layoutData.componentOffset || 0;
|
|
@@ -671,11 +711,10 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
671
711
|
});
|
|
672
712
|
|
|
673
713
|
aNodes.forEach((oNode) => {
|
|
674
|
-
if (oNode._layoutData.
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
oNode.
|
|
678
|
-
oNode.setY(fUserY);
|
|
714
|
+
if (oNode._layoutData.bShouldPreserve) {
|
|
715
|
+
const { userX, userY } = oNode._layoutData;
|
|
716
|
+
oNode.setX(userX);
|
|
717
|
+
oNode.setY(userY);
|
|
679
718
|
}
|
|
680
719
|
});
|
|
681
720
|
},
|
|
@@ -684,18 +723,15 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
684
723
|
* Adjusts horizontal spacing to accommodate nodes with varying widths.
|
|
685
724
|
*
|
|
686
725
|
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
687
|
-
* @param {object} config - Configuration with spacing values
|
|
688
726
|
* @private
|
|
689
727
|
*/
|
|
690
|
-
_adjustHorizontalSpacingForNodeWidths: function (oGraph
|
|
728
|
+
_adjustHorizontalSpacingForNodeWidths: function (oGraph) {
|
|
691
729
|
const aNodes = oGraph.getNodes();
|
|
692
|
-
const iDefaultSpacing = config.horizontalSpacing;
|
|
693
|
-
const iHGap = iDefaultSpacing;
|
|
694
730
|
const mLayerWidths = {};
|
|
695
731
|
let iMaxLayer = -1;
|
|
696
732
|
|
|
697
733
|
aNodes.forEach((oNode) => {
|
|
698
|
-
if (!oNode._layoutData.
|
|
734
|
+
if (!oNode._layoutData.bShouldPreserve) {
|
|
699
735
|
const iLayer =
|
|
700
736
|
oNode._layoutData.layer + (oNode._layoutData.componentOffset || 0);
|
|
701
737
|
iMaxLayer = Math.max(iMaxLayer, iLayer);
|
|
@@ -716,16 +752,12 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
716
752
|
mLayerOffsets[iLayer] = iCumulativeOffset;
|
|
717
753
|
const iActualWidth = mLayerWidths[iLayer];
|
|
718
754
|
if (iActualWidth) {
|
|
719
|
-
|
|
720
|
-
iCumulativeOffset += iActualWidth - iDefaultSpacing + iHGap;
|
|
721
|
-
} else {
|
|
722
|
-
iCumulativeOffset += iActualWidth;
|
|
723
|
-
}
|
|
755
|
+
iCumulativeOffset += iActualWidth;
|
|
724
756
|
}
|
|
725
757
|
}
|
|
726
758
|
|
|
727
759
|
aNodes.forEach((oNode) => {
|
|
728
|
-
if (!oNode._layoutData.
|
|
760
|
+
if (!oNode._layoutData.bShouldPreserve) {
|
|
729
761
|
const iLayer =
|
|
730
762
|
oNode._layoutData.layer + (oNode._layoutData.componentOffset || 0);
|
|
731
763
|
const iOffset = mLayerOffsets[iLayer] || 0;
|
|
@@ -738,18 +770,15 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
738
770
|
* Adjusts vertical spacing to accommodate nodes with varying heights.
|
|
739
771
|
*
|
|
740
772
|
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
741
|
-
* @param {object} config - Configuration with spacing values
|
|
742
773
|
* @private
|
|
743
774
|
*/
|
|
744
|
-
_adjustVerticalSpacingForNodeHeights: function (oGraph
|
|
775
|
+
_adjustVerticalSpacingForNodeHeights: function (oGraph) {
|
|
745
776
|
const aNodes = oGraph.getNodes();
|
|
746
|
-
const iDefaultSpacing = config.verticalSpacing;
|
|
747
|
-
const iVGap = iDefaultSpacing;
|
|
748
777
|
const mPositionHeights = {};
|
|
749
778
|
const mAllPositions = {};
|
|
750
779
|
|
|
751
780
|
aNodes.forEach((oNode) => {
|
|
752
|
-
if (!oNode._layoutData.
|
|
781
|
+
if (!oNode._layoutData.bShouldPreserve) {
|
|
753
782
|
const iPosition = oNode._layoutData.position;
|
|
754
783
|
mAllPositions[iPosition] = true;
|
|
755
784
|
|
|
@@ -775,22 +804,75 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
775
804
|
mPositionOffsets[iPosition] = iCumulativeOffset;
|
|
776
805
|
const iActualHeight = mPositionHeights[iPosition];
|
|
777
806
|
if (iActualHeight) {
|
|
778
|
-
|
|
779
|
-
iCumulativeOffset += iActualHeight - iDefaultSpacing + iVGap;
|
|
780
|
-
} else {
|
|
781
|
-
iCumulativeOffset += iActualHeight;
|
|
782
|
-
}
|
|
807
|
+
iCumulativeOffset += iActualHeight;
|
|
783
808
|
}
|
|
784
809
|
});
|
|
785
810
|
|
|
786
811
|
aNodes.forEach((oNode) => {
|
|
787
|
-
if (!oNode._layoutData.
|
|
812
|
+
if (!oNode._layoutData.bShouldPreserve) {
|
|
788
813
|
const iPosition = oNode._layoutData.position;
|
|
789
814
|
const iOffset = mPositionOffsets[iPosition] || 0;
|
|
790
815
|
oNode.setY(oNode.getY() + iOffset);
|
|
791
816
|
}
|
|
792
817
|
});
|
|
793
818
|
},
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Stores final calculated positions for automatic drag detection on next call.
|
|
822
|
+
* Only stores positions for nodes that were calculated (not original/dragged).
|
|
823
|
+
*
|
|
824
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
825
|
+
* @private
|
|
826
|
+
*/
|
|
827
|
+
_storeFinalPositions: function (oGraph) {
|
|
828
|
+
const aNodes = oGraph.getNodes();
|
|
829
|
+
|
|
830
|
+
aNodes.forEach((oNode) => {
|
|
831
|
+
if (!oNode._layoutData.bShouldPreserve) {
|
|
832
|
+
this._lastCalculated.set(oNode, {
|
|
833
|
+
x: oNode.getX(),
|
|
834
|
+
y: oNode.getY(),
|
|
835
|
+
bIsUserPositioned: false
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
},
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* Detects user-made position changes by comparing current positions with last calculated positions.
|
|
843
|
+
* Marks nodes with original coordinates and tracks drag operations.
|
|
844
|
+
*
|
|
845
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
846
|
+
* @private
|
|
847
|
+
*/
|
|
848
|
+
_detectUserChanges: function (oGraph) {
|
|
849
|
+
const aNodes = oGraph.getNodes();
|
|
850
|
+
|
|
851
|
+
aNodes.forEach((oNode) => {
|
|
852
|
+
const fX = oNode.getX();
|
|
853
|
+
const fY = oNode.getY();
|
|
854
|
+
// Constraint: Nodes with coordinates (0,0) or negative values are treated as unpositioned.
|
|
855
|
+
// For origin positioning, use (0.1, 0.1) or (1, 1).
|
|
856
|
+
const bHasCoordinates = fX !== undefined && fY !== undefined && (fX !== 0 || fY !== 0);
|
|
857
|
+
const oLastPos = this._lastCalculated.get(oNode);
|
|
858
|
+
|
|
859
|
+
if (!oLastPos && bHasCoordinates) {
|
|
860
|
+
// First time seeing this node with coordinates - mark as original
|
|
861
|
+
this._lastCalculated.set(oNode, {
|
|
862
|
+
x: fX,
|
|
863
|
+
y: fY,
|
|
864
|
+
bIsUserPositioned: true
|
|
865
|
+
});
|
|
866
|
+
} else if (oLastPos) {
|
|
867
|
+
// Check if user dragged it
|
|
868
|
+
if (fX !== oLastPos.x || fY !== oLastPos.y) {
|
|
869
|
+
oLastPos.x = fX;
|
|
870
|
+
oLastPos.y = fY;
|
|
871
|
+
oLastPos.bIsUserPositioned = true;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
},
|
|
794
876
|
};
|
|
795
877
|
|
|
796
878
|
return DependencyLayoutHelper;
|
|
@@ -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.
|
|
@@ -68,8 +69,7 @@ sap.ui.define([
|
|
|
68
69
|
* @param {boolean} bTriggerNode - Whether the node is a trigger node.
|
|
69
70
|
*/
|
|
70
71
|
addPortsToNode(oNode, bTriggerNode) {
|
|
71
|
-
var
|
|
72
|
-
var sNodePorts = oGraph.getNodePorts();
|
|
72
|
+
var sNodePorts = oNode._getNodePorts();
|
|
73
73
|
// Remove existing ports first
|
|
74
74
|
this.removePortsFromNode(oNode);
|
|
75
75
|
if (sNodePorts === "None") {
|
|
@@ -200,7 +200,7 @@ sap.ui.define([
|
|
|
200
200
|
*/
|
|
201
201
|
addInletPortsToOtherNodes(oNode) {
|
|
202
202
|
var oGraph = oNode.getParent();
|
|
203
|
-
var sNodePorts =
|
|
203
|
+
var sNodePorts = oNode._getNodePorts();
|
|
204
204
|
// Don't add inlet ports if nodePorts is "None"
|
|
205
205
|
if (sNodePorts === "None") {
|
|
206
206
|
return;
|
|
@@ -486,6 +486,11 @@ sap.ui.define([
|
|
|
486
486
|
const targetPortSide = target.dataset.portSide;
|
|
487
487
|
// Check if the target node is valid
|
|
488
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;
|
|
489
494
|
const mParameters = {
|
|
490
495
|
from: sourceNode.getKey(),
|
|
491
496
|
to: targetNode.getKey(),
|
|
@@ -494,7 +499,10 @@ sap.ui.define([
|
|
|
494
499
|
toNode: targetNode
|
|
495
500
|
};
|
|
496
501
|
// Fire the connectionCreated event
|
|
497
|
-
|
|
502
|
+
oGraph.fireConnectionCreated(mParameters);
|
|
503
|
+
|
|
504
|
+
// Preserve scroll position after event
|
|
505
|
+
Utils.preserveScrollPosition(oGraph, currentScrollLeft, currentScrollTop, 0);
|
|
498
506
|
}
|
|
499
507
|
}
|
|
500
508
|
// Remove inlet ports from other nodes
|