@sapui5/sap.suite.ui.commons 1.146.0 → 1.147.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 +56 -2
- package/src/sap/suite/ui/commons/CalculationBuilderExpression.js +87 -14
- 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/CalculationBuilderItem.js +16 -3
- 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/MicroProcessFlow.js +1 -1
- package/src/sap/suite/ui/commons/MicroProcessFlowItem.js +1 -1
- package/src/sap/suite/ui/commons/collaboration/ContactPopover.fragment.xml +8 -8
- package/src/sap/suite/ui/commons/collaboration/MinimalContactPopover.fragment.xml +5 -5
- 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 +1 -1
- 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 +4 -4
- package/src/sap/suite/ui/commons/messagebundle.properties +12 -8
- package/src/sap/suite/ui/commons/messagebundle_mk.properties +1 -1
- package/src/sap/suite/ui/commons/networkgraph/Graph.js +138 -27
- package/src/sap/suite/ui/commons/networkgraph/GraphMap.js +25 -3
- package/src/sap/suite/ui/commons/networkgraph/KeyboardNavigator.js +332 -13
- package/src/sap/suite/ui/commons/networkgraph/Line.js +5 -1
- package/src/sap/suite/ui/commons/networkgraph/Node.js +67 -5
- package/src/sap/suite/ui/commons/networkgraph/Utils.js +10 -0
- package/src/sap/suite/ui/commons/networkgraph/util/ConnectionPathUtils.js +34 -4
- package/src/sap/suite/ui/commons/networkgraph/util/DependencyLayoutHelper.js +213 -74
- 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/BusinessCard.less +5 -4
- package/src/sap/suite/ui/commons/themes/base/CalculationBuilder.less +33 -24
- package/src/sap/suite/ui/commons/themes/base/CalculationBuilderExpression.less +40 -31
- package/src/sap/suite/ui/commons/themes/base/CalculationBuilderInput.less +26 -10
- package/src/sap/suite/ui/commons/themes/base/CalculationBuilderItem.less +76 -63
- package/src/sap/suite/ui/commons/themes/base/ChartContainer.less +8 -11
- package/src/sap/suite/ui/commons/themes/base/ChartTile.less +5 -8
- package/src/sap/suite/ui/commons/themes/base/CollaborationPopover.less +116 -106
- package/src/sap/suite/ui/commons/themes/base/DateRangeScroller.less +5 -5
- package/src/sap/suite/ui/commons/themes/base/DateRangeSliderInternal.less +9 -10
- package/src/sap/suite/ui/commons/themes/base/FacetOverview.less +9 -10
- package/src/sap/suite/ui/commons/themes/base/FeedItemHeader.less +9 -12
- package/src/sap/suite/ui/commons/themes/base/FeedTile.less +23 -27
- package/src/sap/suite/ui/commons/themes/base/GenericTile2X2.less +15 -15
- package/src/sap/suite/ui/commons/themes/base/HeaderCell.less +7 -6
- package/src/sap/suite/ui/commons/themes/base/HeaderContainer.less +35 -37
- package/src/sap/suite/ui/commons/themes/base/ImageEditor.less +28 -10
- package/src/sap/suite/ui/commons/themes/base/ImageEditorContainer.less +29 -22
- package/src/sap/suite/ui/commons/themes/base/InfoTile.less +10 -4
- package/src/sap/suite/ui/commons/themes/base/InfoTileSize.less +5 -4
- package/src/sap/suite/ui/commons/themes/base/KpiTile.less +10 -11
- package/src/sap/suite/ui/commons/themes/base/LaunchTile.less +9 -8
- package/src/sap/suite/ui/commons/themes/base/LinkActionSheet.less +14 -43
- package/src/sap/suite/ui/commons/themes/base/MicroProcessFlow.less +51 -47
- package/src/sap/suite/ui/commons/themes/base/MonitoringContent.less +5 -5
- package/src/sap/suite/ui/commons/themes/base/NetworkGraph.less +57 -62
- package/src/sap/suite/ui/commons/themes/base/NetworkGroup.less +61 -65
- package/src/sap/suite/ui/commons/themes/base/NetworkLine.less +58 -55
- package/src/sap/suite/ui/commons/themes/base/NetworkNode.less +3 -0
- package/src/sap/suite/ui/commons/themes/base/NetworkTooltip.less +21 -25
- package/src/sap/suite/ui/commons/themes/base/NoteTaker.less +13 -18
- package/src/sap/suite/ui/commons/themes/base/NoteTakerCard.less +26 -27
- package/src/sap/suite/ui/commons/themes/base/NoteTakerFeeder.less +22 -44
- package/src/sap/suite/ui/commons/themes/base/NumericTile.less +7 -5
- package/src/sap/suite/ui/commons/themes/base/PictureZoomIn.less +6 -5
- package/src/sap/suite/ui/commons/themes/base/ProcessFlow.less +57 -76
- package/src/sap/suite/ui/commons/themes/base/ProcessFlowConnection.less +71 -17
- package/src/sap/suite/ui/commons/themes/base/ProcessFlowConnectionLabel.less +9 -13
- package/src/sap/suite/ui/commons/themes/base/ProcessFlowLaneHeader.less +37 -96
- package/src/sap/suite/ui/commons/themes/base/ProcessFlowNode.less +219 -238
- package/src/sap/suite/ui/commons/themes/base/SemanticColorMixins.less +55 -0
- package/src/sap/suite/ui/commons/themes/base/SplitButton.less +7 -20
- package/src/sap/suite/ui/commons/themes/base/StatusIndicator.less +10 -9
- package/src/sap/suite/ui/commons/themes/base/TAccount.less +78 -73
- package/src/sap/suite/ui/commons/themes/base/TargetFilter.less +50 -58
- package/src/sap/suite/ui/commons/themes/base/ThingCollection.less +18 -13
- package/src/sap/suite/ui/commons/themes/base/ThreePanelThingViewer.less +14 -14
- package/src/sap/suite/ui/commons/themes/base/TileContent2X2.less +9 -13
- package/src/sap/suite/ui/commons/themes/base/Timeline.less +16 -19
- package/src/sap/suite/ui/commons/themes/base/TimelineItem.less +95 -103
- package/src/sap/suite/ui/commons/themes/base/UnifiedThingGroup.less +7 -9
- package/src/sap/suite/ui/commons/themes/base/UnifiedThingInspector.less +12 -9
- package/src/sap/suite/ui/commons/themes/base/VerticalNavigationBar.less +10 -15
- package/src/sap/suite/ui/commons/themes/base/ViewRepeater.less +8 -9
- package/src/sap/suite/ui/commons/themes/base/library.source.less +0 -2
- package/src/sap/suite/ui/commons/themes/sap_fiori_3/MicroProcessFlow.less +9 -3
- package/src/sap/suite/ui/commons/themes/sap_fiori_3/ProcessFlowConnection.less +14 -7
- package/src/sap/suite/ui/commons/themes/sap_fiori_3/ProcessFlowConnectionLabel.less +38 -35
- package/src/sap/suite/ui/commons/themes/sap_fiori_3/ProcessFlowLaneHeader.less +29 -30
- package/src/sap/suite/ui/commons/themes/sap_fiori_3/ProcessFlowNode.less +158 -102
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_dark/MicroProcessFlow.less +9 -3
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_dark/ProcessFlowConnection.less +14 -7
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_dark/ProcessFlowConnectionLabel.less +38 -35
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_dark/ProcessFlowLaneHeader.less +30 -31
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_dark/ProcessFlowNode.less +157 -101
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcb/ProcessFlowConnection.less +14 -7
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcb/ProcessFlowConnectionLabel.less +38 -35
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcb/ProcessFlowLaneHeader.less +30 -31
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcb/ProcessFlowNode.less +147 -101
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcw/ProcessFlowConnection.less +14 -7
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcw/ProcessFlowConnectionLabel.less +38 -35
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcw/ProcessFlowLaneHeader.less +30 -31
- package/src/sap/suite/ui/commons/themes/sap_fiori_3_hcw/ProcessFlowNode.less +158 -102
- package/src/sap/suite/ui/commons/themes/sap_horizon/MicroProcessFlow.less +5 -0
- package/src/sap/suite/ui/commons/themes/sap_horizon/NetworkLine.less +12 -8
- package/src/sap/suite/ui/commons/themes/sap_horizon/ProcessFlowConnection.less +17 -10
- package/src/sap/suite/ui/commons/themes/sap_horizon/ProcessFlowConnectionLabel.less +154 -133
- package/src/sap/suite/ui/commons/themes/sap_horizon/ProcessFlowLaneHeader.less +30 -32
- package/src/sap/suite/ui/commons/themes/sap_horizon/ProcessFlowNode.less +113 -214
- package/src/sap/suite/ui/commons/themes/sap_horizon/TimelineItem.less +43 -39
- package/src/sap/suite/ui/commons/themes/sap_horizon_dark/MicroProcessFlow.less +5 -0
- package/src/sap/suite/ui/commons/themes/sap_horizon_dark/NetworkLine.less +12 -12
- package/src/sap/suite/ui/commons/themes/sap_horizon_dark/ProcessFlowConnection.less +17 -10
- package/src/sap/suite/ui/commons/themes/sap_horizon_dark/ProcessFlowConnectionLabel.less +154 -133
- package/src/sap/suite/ui/commons/themes/sap_horizon_dark/ProcessFlowLaneHeader.less +30 -31
- package/src/sap/suite/ui/commons/themes/sap_horizon_dark/ProcessFlowNode.less +114 -216
- package/src/sap/suite/ui/commons/themes/sap_horizon_dark/TimelineItem.less +41 -39
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcb/MicroProcessFlow.less +4 -4
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcb/ProcessFlowConnection.less +17 -10
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcb/ProcessFlowConnectionLabel.less +153 -131
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcb/ProcessFlowLaneHeader.less +29 -30
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcb/ProcessFlowNode.less +159 -103
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcb/TimelineItem.less +41 -39
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcw/MicroProcessFlow.less +4 -4
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcw/ProcessFlowConnection.less +16 -9
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcw/ProcessFlowConnectionLabel.less +153 -131
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcw/ProcessFlowLaneHeader.less +29 -30
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcw/ProcessFlowNode.less +157 -101
- package/src/sap/suite/ui/commons/themes/sap_horizon_hcw/TimelineItem.less +41 -39
- package/src/sap/suite/ui/commons/themes/base/DateRangeSlider.less +0 -3
- package/src/sap/suite/ui/commons/themes/base/MonitoringTile.less +0 -3
|
@@ -11,12 +11,32 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
11
11
|
oComponentArrangement = library.networkgraph.ComponentArrangement;
|
|
12
12
|
const DEFAULT_HORIZONTAL_SPACING = 240;
|
|
13
13
|
const DEFAULT_VERTICAL_SPACING = 100;
|
|
14
|
+
const DRAG_DETECTION_THRESHOLD = 10;
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Utility class for calculating node positions based on dependency relationships.
|
|
17
18
|
* This utility arranges nodes based on their dependency relationships using topological sorting,
|
|
18
19
|
* cycle detection, and layer-based positioning.
|
|
19
20
|
*
|
|
21
|
+
* Why a node may be positioned incorrectly after recalculation:
|
|
22
|
+
* After each run, node positions are cached with a flag indicating whether the user moved
|
|
23
|
+
* them (<code>bIsUserPositioned</code>). On the next call, nodes flagged as user-positioned
|
|
24
|
+
* are preserved as-is, and the algorithm-placed nodes are recalculated. A node appears in the
|
|
25
|
+
* wrong place if it is unexpectedly treated as user-positioned, most commonly because
|
|
26
|
+
* <code>clearCache: true</code> was passed. It wipes the cache, but leaves the coordinates intact.
|
|
27
|
+
* So every node with non-zero coordinates is immediately re-classified as user-positioned
|
|
28
|
+
* and freezes, rather than being recalculated.
|
|
29
|
+
*
|
|
30
|
+
* Drag and drop recalculation - correct pattern:
|
|
31
|
+
* Call <code>resetNode(oNode)</code> for each dragged node, then call
|
|
32
|
+
* <code>calculatePositions</code> without <code>clearCache</code> (default <code>false</code>).
|
|
33
|
+
* <code>resetNode</code> evicts the node from the cache and zeros its coordinates, so only
|
|
34
|
+
* that node is repositioned; all the other nodes remain stable.
|
|
35
|
+
*
|
|
36
|
+
* Sentinel value:
|
|
37
|
+
* Coordinates <code>(0, 0)</code> mean "unpositioned". To place a node at the canvas origin,
|
|
38
|
+
* use <code>(0.1, 0.1)</code> or <code>(1, 1)</code> instead.
|
|
39
|
+
*
|
|
20
40
|
* @namespace sap.suite.ui.commons.networkgraph.util.DependencyLayoutHelper
|
|
21
41
|
* @public
|
|
22
42
|
* @since 1.144
|
|
@@ -28,6 +48,26 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
28
48
|
*/
|
|
29
49
|
_lastCalculated: new WeakMap(),
|
|
30
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Evicts one or more nodes from the position cache and zeros their coordinates so the next
|
|
53
|
+
* <code>calculatePositions</code> call repositions them while all other nodes remain stable.
|
|
54
|
+
* To understand the use for drag and drop recalculation, see the class-level JSDoc for the full pattern.
|
|
55
|
+
*
|
|
56
|
+
* @param {sap.suite.ui.commons.networkgraph.Node|sap.suite.ui.commons.networkgraph.Node[]} vNode - A single node or an array of nodes to reset
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
resetNode: function (vNode) {
|
|
60
|
+
const aNodes = Array.isArray(vNode) ? vNode : [vNode];
|
|
61
|
+
aNodes.forEach((oNode) => {
|
|
62
|
+
if (!oNode || !oNode.setX || !oNode.setY) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this._lastCalculated.delete(oNode);
|
|
66
|
+
oNode.setX(0);
|
|
67
|
+
oNode.setY(0);
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
|
|
31
71
|
/**
|
|
32
72
|
* Calculates and sets positions for nodes without coordinates based on their dependency relationships.
|
|
33
73
|
* Uses topological sorting (Kahn's algorithm) and DFS-based cycle detection to arrange nodes
|
|
@@ -39,7 +79,10 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
39
79
|
* @param {number} [mConfig.horizontalSpacing=240] - Horizontal spacing between layers
|
|
40
80
|
* @param {number} [mConfig.verticalSpacing=100] - Vertical spacing between nodes
|
|
41
81
|
* @param {sap.suite.ui.commons.networkgraph.ComponentArrangement} [mConfig.componentArrangement=Horizontal] - Component arrangement: "Horizontal" or "Vertical"
|
|
42
|
-
* @param {boolean} [mConfig.clearCache=false] -
|
|
82
|
+
* @param {boolean} [mConfig.clearCache=false] - Wipes the position cache; node coordinates are not modified.
|
|
83
|
+
* <code>_detectUserChanges</code> then re-classifies every non-zero node as user-positioned and freezes it.
|
|
84
|
+
* Use only to discard all layout history (e.g. switching <code>componentArrangement</code>).
|
|
85
|
+
* For drag and drop recalculation, use <code>resetNode()</code> with the default <code>clearCache: false</code>.
|
|
43
86
|
* @public
|
|
44
87
|
*/
|
|
45
88
|
calculatePositions: function (oGraph, mConfig) {
|
|
@@ -63,14 +106,17 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
63
106
|
}
|
|
64
107
|
|
|
65
108
|
try {
|
|
66
|
-
this._detectUserChanges(oGraph);
|
|
109
|
+
this._detectUserChanges(oGraph, config.horizontalSpacing);
|
|
67
110
|
this._buildDependencyGraph(oGraph);
|
|
68
111
|
const aComponents = this._identifyComponents(oGraph);
|
|
69
112
|
this._processComponents(aComponents, config);
|
|
70
113
|
this._calculateCoordinates(oGraph, config);
|
|
71
114
|
this._adjustHorizontalSpacingForNodeWidths(oGraph, config);
|
|
72
115
|
this._adjustVerticalSpacingForNodeHeights(oGraph, config);
|
|
73
|
-
|
|
116
|
+
if (oGraph._bIsRtl) {
|
|
117
|
+
this._horizontalMirror(oGraph, config.horizontalSpacing);
|
|
118
|
+
}
|
|
119
|
+
this._storeFinalPositions(oGraph, config.horizontalSpacing);
|
|
74
120
|
} catch (e) {
|
|
75
121
|
Log.error("DependencyLayoutHelper error: " + e.message, e);
|
|
76
122
|
throw new Error("DependencyLayoutHelper error: " + e.message);
|
|
@@ -96,11 +142,6 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
96
142
|
|
|
97
143
|
aNodes.forEach((oNode) => {
|
|
98
144
|
mNodeMap.set(oNode.getKey(), oNode);
|
|
99
|
-
const fX = oNode.getX();
|
|
100
|
-
const fY = oNode.getY();
|
|
101
|
-
const oLastPos = this._lastCalculated.get(oNode);
|
|
102
|
-
// Only preserve coordinates if they were original or user-dragged
|
|
103
|
-
const bShouldPreserve = oLastPos?.bIsUserPositioned;
|
|
104
145
|
|
|
105
146
|
oNode._layoutData = {
|
|
106
147
|
layer: -1,
|
|
@@ -110,10 +151,7 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
110
151
|
parallelNodes: [],
|
|
111
152
|
backwardEdges: [],
|
|
112
153
|
backwardEdgeLines: [],
|
|
113
|
-
isBackwardSource: false
|
|
114
|
-
bShouldPreserve,
|
|
115
|
-
userX: fX,
|
|
116
|
-
userY: fY
|
|
154
|
+
isBackwardSource: false
|
|
117
155
|
};
|
|
118
156
|
});
|
|
119
157
|
|
|
@@ -279,8 +317,7 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
279
317
|
const bIsIsolated =
|
|
280
318
|
aComponentNodes.length === 1 &&
|
|
281
319
|
aComponentNodes[0]._layoutData.incoming.length === 0 &&
|
|
282
|
-
aComponentNodes[0]._layoutData.outgoing.length === 0
|
|
283
|
-
!aComponentNodes[0]._layoutData.bShouldPreserve;
|
|
320
|
+
aComponentNodes[0]._layoutData.outgoing.length === 0;
|
|
284
321
|
|
|
285
322
|
if (bIsIsolated) {
|
|
286
323
|
aIsolatedNodes.push(aComponentNodes[0]);
|
|
@@ -335,18 +372,17 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
335
372
|
});
|
|
336
373
|
|
|
337
374
|
if (aIsolatedNodes.length > 0) {
|
|
338
|
-
const iRightSideOffset = iMaxLayerAcrossAll + 1;
|
|
339
|
-
|
|
340
|
-
aIsolatedNodes.forEach((oNode
|
|
341
|
-
if (
|
|
342
|
-
|
|
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;
|
|
375
|
+
const iRightSideOffset = bSideBySide ? iMaxLayerAcrossAll : iMaxLayerAcrossAll + 1;
|
|
376
|
+
let iIsolatedIdx = 0;
|
|
377
|
+
aIsolatedNodes.forEach((oNode) => {
|
|
378
|
+
if (this._lastCalculated.get(oNode)?.bIsUserPositioned) {
|
|
379
|
+
return;
|
|
349
380
|
}
|
|
381
|
+
const idx = iIsolatedIdx++;
|
|
382
|
+
|
|
383
|
+
oNode._layoutData.layer = Math.floor(idx / 2);
|
|
384
|
+
oNode._layoutData.position = idx % 2;
|
|
385
|
+
oNode._layoutData.componentOffset = iRightSideOffset;
|
|
350
386
|
});
|
|
351
387
|
}
|
|
352
388
|
},
|
|
@@ -711,10 +747,10 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
711
747
|
});
|
|
712
748
|
|
|
713
749
|
aNodes.forEach((oNode) => {
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
oNode.setX(
|
|
717
|
-
oNode.setY(
|
|
750
|
+
const oLastPos = this._lastCalculated.get(oNode);
|
|
751
|
+
if (oLastPos?.bIsUserPositioned) {
|
|
752
|
+
oNode.setX(oLastPos.x);
|
|
753
|
+
oNode.setY(oLastPos.y);
|
|
718
754
|
}
|
|
719
755
|
});
|
|
720
756
|
},
|
|
@@ -731,16 +767,16 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
731
767
|
let iMaxLayer = -1;
|
|
732
768
|
|
|
733
769
|
aNodes.forEach((oNode) => {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
770
|
+
const iLayer =
|
|
771
|
+
oNode._layoutData.layer + (oNode._layoutData.componentOffset || 0);
|
|
772
|
+
// Skip nodes with unassigned layout
|
|
773
|
+
if (iLayer < 0) return;
|
|
774
|
+
iMaxLayer = Math.max(iMaxLayer, iLayer);
|
|
775
|
+
|
|
776
|
+
if (oNode._iWidth) {
|
|
777
|
+
const iWidth = oNode._iWidth;
|
|
778
|
+
if (!mLayerWidths[iLayer] || mLayerWidths[iLayer] < iWidth) {
|
|
779
|
+
mLayerWidths[iLayer] = iWidth;
|
|
744
780
|
}
|
|
745
781
|
}
|
|
746
782
|
});
|
|
@@ -757,7 +793,7 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
757
793
|
}
|
|
758
794
|
|
|
759
795
|
aNodes.forEach((oNode) => {
|
|
760
|
-
if (!
|
|
796
|
+
if (!this._lastCalculated.get(oNode)?.bIsUserPositioned) {
|
|
761
797
|
const iLayer =
|
|
762
798
|
oNode._layoutData.layer + (oNode._layoutData.componentOffset || 0);
|
|
763
799
|
const iOffset = mLayerOffsets[iLayer] || 0;
|
|
@@ -778,18 +814,18 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
778
814
|
const mAllPositions = {};
|
|
779
815
|
|
|
780
816
|
aNodes.forEach((oNode) => {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
817
|
+
const iPosition = oNode._layoutData.position;
|
|
818
|
+
// Skip nodes with unassigned layout
|
|
819
|
+
if (iPosition < 0) return;
|
|
820
|
+
mAllPositions[iPosition] = true;
|
|
784
821
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
}
|
|
822
|
+
if (oNode._iHeight) {
|
|
823
|
+
const iHeight = oNode._iHeight;
|
|
824
|
+
if (
|
|
825
|
+
!mPositionHeights[iPosition] ||
|
|
826
|
+
mPositionHeights[iPosition] < iHeight
|
|
827
|
+
) {
|
|
828
|
+
mPositionHeights[iPosition] = iHeight;
|
|
793
829
|
}
|
|
794
830
|
}
|
|
795
831
|
});
|
|
@@ -809,7 +845,7 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
809
845
|
});
|
|
810
846
|
|
|
811
847
|
aNodes.forEach((oNode) => {
|
|
812
|
-
if (!
|
|
848
|
+
if (!this._lastCalculated.get(oNode)?.bIsUserPositioned) {
|
|
813
849
|
const iPosition = oNode._layoutData.position;
|
|
814
850
|
const iOffset = mPositionOffsets[iPosition] || 0;
|
|
815
851
|
oNode.setY(oNode.getY() + iOffset);
|
|
@@ -822,19 +858,38 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
822
858
|
* Only stores positions for nodes that were calculated (not original/dragged).
|
|
823
859
|
*
|
|
824
860
|
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
861
|
+
* @param {number} iHSpacing - Horizontal spacing used as RTL mirror offset
|
|
825
862
|
* @private
|
|
826
863
|
*/
|
|
827
|
-
_storeFinalPositions: function (oGraph) {
|
|
864
|
+
_storeFinalPositions: function (oGraph, iHSpacing) {
|
|
828
865
|
const aNodes = oGraph.getNodes();
|
|
866
|
+
const bIsRtl = oGraph._bIsRtl || false;
|
|
867
|
+
|
|
868
|
+
// Reuse fMaxX from _horizontalMirror to ensure consistent mirror/unmirror
|
|
869
|
+
let fMaxX = 0;
|
|
870
|
+
if (bIsRtl) {
|
|
871
|
+
fMaxX = oGraph._rtlMirrorMaxX || 0;
|
|
872
|
+
}
|
|
829
873
|
|
|
830
874
|
aNodes.forEach((oNode) => {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
875
|
+
const fCurrentX = oNode.getX();
|
|
876
|
+
const fCurrentY = oNode.getY();
|
|
877
|
+
|
|
878
|
+
// Always store in LTR space
|
|
879
|
+
let fLtrX = fCurrentX;
|
|
880
|
+
if (bIsRtl) {
|
|
881
|
+
const fNodeWidth = oNode._iWidth || 0;
|
|
882
|
+
fLtrX = fMaxX - fCurrentX - fNodeWidth + iHSpacing;
|
|
837
883
|
}
|
|
884
|
+
|
|
885
|
+
const bIsUserPositioned = this._lastCalculated.get(oNode)?.bIsUserPositioned ?? false;
|
|
886
|
+
|
|
887
|
+
this._lastCalculated.set(oNode, {
|
|
888
|
+
x: fLtrX,
|
|
889
|
+
y: fCurrentY,
|
|
890
|
+
lastRtl: bIsRtl,
|
|
891
|
+
bIsUserPositioned
|
|
892
|
+
});
|
|
838
893
|
});
|
|
839
894
|
},
|
|
840
895
|
|
|
@@ -843,36 +898,120 @@ sap.ui.define(["sap/suite/ui/commons/library", "sap/base/Log"], function (librar
|
|
|
843
898
|
* Marks nodes with original coordinates and tracks drag operations.
|
|
844
899
|
*
|
|
845
900
|
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
901
|
+
* @param {number} iHSpacing - Horizontal spacing used as RTL mirror offset
|
|
846
902
|
* @private
|
|
847
903
|
*/
|
|
848
|
-
_detectUserChanges: function (oGraph) {
|
|
904
|
+
_detectUserChanges: function (oGraph, iHSpacing) {
|
|
849
905
|
const aNodes = oGraph.getNodes();
|
|
906
|
+
const bIsRtl = oGraph._bIsRtl || false;
|
|
907
|
+
|
|
908
|
+
// Use stored fMaxX from previous mirror operation if available, otherwise calculate.
|
|
909
|
+
// We need it both when in RTL mode AND when switching RTL→LTR (to detect pre-switch drags).
|
|
910
|
+
let fMaxX = oGraph._rtlMirrorMaxX || 0;
|
|
911
|
+
if (bIsRtl && !fMaxX) {
|
|
912
|
+
aNodes.forEach((n) => {
|
|
913
|
+
const fRight = n.getX() + (n._iWidth || 0);
|
|
914
|
+
if (fRight > fMaxX) fMaxX = fRight;
|
|
915
|
+
});
|
|
916
|
+
}
|
|
850
917
|
|
|
851
918
|
aNodes.forEach((oNode) => {
|
|
852
|
-
const
|
|
853
|
-
const
|
|
854
|
-
//
|
|
855
|
-
//
|
|
856
|
-
|
|
919
|
+
const fCurrentX = oNode.getX();
|
|
920
|
+
const fCurrentY = oNode.getY();
|
|
921
|
+
// (0,0) is the sentinel for "unpositioned": resetNode() sets coordinates to (0,0)
|
|
922
|
+
// so the algorithm treats the node as if it were never placed.
|
|
923
|
+
// To legitimately position a node at the canvas origin, use (0.1, 0.1) or (1, 1).
|
|
924
|
+
const bHasCoordinates = fCurrentX !== undefined && fCurrentY !== undefined && (fCurrentX !== 0 || fCurrentY !== 0);
|
|
857
925
|
const oLastPos = this._lastCalculated.get(oNode);
|
|
858
926
|
|
|
859
|
-
|
|
860
|
-
|
|
927
|
+
// Convert current position to LTR coordinates for comparison
|
|
928
|
+
let fLtrX = fCurrentX;
|
|
929
|
+
if (bIsRtl) {
|
|
930
|
+
const fNodeWidth = oNode._iWidth || 0;
|
|
931
|
+
fLtrX = fMaxX - fCurrentX - fNodeWidth + iHSpacing;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (oLastPos && !bHasCoordinates) {
|
|
935
|
+
// Coordinates were cleared (sentinel value 0,0) — evict cache so the algorithm
|
|
936
|
+
// repositions this node on the next layout pass.
|
|
937
|
+
this._lastCalculated.delete(oNode);
|
|
938
|
+
} else if (!oLastPos && bHasCoordinates) {
|
|
939
|
+
// No cache entry + non-zero coords: node has model-provided position (first call).
|
|
940
|
+
// Treated as user-positioned → preserved. Use resetNode() to opt a node out.
|
|
861
941
|
this._lastCalculated.set(oNode, {
|
|
862
|
-
x:
|
|
863
|
-
y:
|
|
942
|
+
x: fLtrX,
|
|
943
|
+
y: fCurrentY,
|
|
944
|
+
lastRtl: bIsRtl,
|
|
864
945
|
bIsUserPositioned: true
|
|
865
946
|
});
|
|
866
947
|
} else if (oLastPos) {
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
948
|
+
const bModeChanged = (oLastPos.lastRtl !== bIsRtl);
|
|
949
|
+
|
|
950
|
+
if (bModeChanged) {
|
|
951
|
+
const bPrevRtl = oLastPos.lastRtl;
|
|
952
|
+
let fLtrXBeforeSwitch;
|
|
953
|
+
|
|
954
|
+
if (bPrevRtl) {
|
|
955
|
+
const fNodeWidth = oNode._iWidth || 0;
|
|
956
|
+
fLtrXBeforeSwitch = fMaxX - fCurrentX - fNodeWidth + iHSpacing;
|
|
957
|
+
} else {
|
|
958
|
+
fLtrXBeforeSwitch = fCurrentX;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
const fDeltaX = Math.abs(fLtrXBeforeSwitch - oLastPos.x);
|
|
962
|
+
const fDeltaY = Math.abs(fCurrentY - oLastPos.y);
|
|
963
|
+
|
|
964
|
+
if (fDeltaX > DRAG_DETECTION_THRESHOLD || fDeltaY > DRAG_DETECTION_THRESHOLD) {
|
|
965
|
+
oLastPos.x = fLtrXBeforeSwitch;
|
|
966
|
+
oLastPos.y = fCurrentY;
|
|
967
|
+
oLastPos.bIsUserPositioned = true;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
oLastPos.lastRtl = bIsRtl;
|
|
971
|
+
} else {
|
|
972
|
+
const fDeltaX = Math.abs(fLtrX - oLastPos.x);
|
|
973
|
+
const fDeltaY = Math.abs(fCurrentY - oLastPos.y);
|
|
974
|
+
|
|
975
|
+
if (fDeltaX > DRAG_DETECTION_THRESHOLD || fDeltaY > DRAG_DETECTION_THRESHOLD) {
|
|
976
|
+
oLastPos.x = fLtrX;
|
|
977
|
+
oLastPos.y = fCurrentY;
|
|
978
|
+
oLastPos.bIsUserPositioned = true;
|
|
979
|
+
}
|
|
872
980
|
}
|
|
873
981
|
}
|
|
874
982
|
});
|
|
875
983
|
},
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Mirrors all node X positions horizontally for RTL layout.
|
|
987
|
+
*
|
|
988
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The network graph instance
|
|
989
|
+
* @param {number} iHSpacing - Horizontal spacing used as left-side padding offset after mirroring
|
|
990
|
+
* @private
|
|
991
|
+
*/
|
|
992
|
+
_horizontalMirror: function (oGraph, iHSpacing) {
|
|
993
|
+
const aNodes = oGraph.getNodes();
|
|
994
|
+
|
|
995
|
+
// Find the rightmost edge of all nodes
|
|
996
|
+
let fMaxX = 0;
|
|
997
|
+
aNodes.forEach((oNode) => {
|
|
998
|
+
const fX = oNode.getX();
|
|
999
|
+
const fWidth = oNode._iWidth || 0;
|
|
1000
|
+
const fRightEdge = fX + fWidth;
|
|
1001
|
+
if (fRightEdge > fMaxX) {
|
|
1002
|
+
fMaxX = fRightEdge;
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
oGraph._rtlMirrorMaxX = fMaxX;
|
|
1007
|
+
|
|
1008
|
+
aNodes.forEach((oNode) => {
|
|
1009
|
+
const fCurrentX = oNode.getX();
|
|
1010
|
+
const fWidth = oNode._iWidth || 0;
|
|
1011
|
+
const fMirroredX = fMaxX - fCurrentX - fWidth + iHSpacing;
|
|
1012
|
+
oNode.setX(fMirroredX);
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
876
1015
|
};
|
|
877
1016
|
|
|
878
1017
|
return DependencyLayoutHelper;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
/*
|
|
2
|
-
/* CSS for control sap.suite.ui.commons/BusinessCard
|
|
3
|
-
/*
|
|
1
|
+
/* ================================================== */
|
|
2
|
+
/* CSS for control sap.suite.ui.commons/BusinessCard */
|
|
3
|
+
/* Base theme */
|
|
4
|
+
/* ================================================== */
|
|
4
5
|
|
|
5
6
|
.suiteUiCard {
|
|
6
7
|
border: solid @sapUiLightBorder 1px;
|
|
@@ -50,4 +51,4 @@
|
|
|
50
51
|
|
|
51
52
|
.suiteUiCardDesc {
|
|
52
53
|
width: 100%;
|
|
53
|
-
}
|
|
54
|
+
}
|