@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
|
@@ -14,11 +14,12 @@ sap.ui.define([
|
|
|
14
14
|
"sap/ui/events/KeyCodes",
|
|
15
15
|
"sap/ui/dom/containsOrEquals",
|
|
16
16
|
"sap/base/Log",
|
|
17
|
-
"sap/ui/core/Lib"
|
|
18
|
-
|
|
19
|
-
], function (jQuery, BaseObject, Group, Node, Line, KeyCodes, containsOrEquals, Log, CoreLib, Element) {
|
|
17
|
+
"sap/ui/core/Lib"
|
|
18
|
+
], function (jQuery, BaseObject, Group, Node, Line, KeyCodes, containsOrEquals, Log, CoreLib) {
|
|
20
19
|
"use strict";
|
|
21
20
|
|
|
21
|
+
const oResourceBundle = CoreLib.getResourceBundleFor("sap.suite.ui.commons");
|
|
22
|
+
|
|
22
23
|
var mDirections = {
|
|
23
24
|
LEFT: "left",
|
|
24
25
|
RIGHT: "right",
|
|
@@ -74,6 +75,13 @@ sap.ui.define([
|
|
|
74
75
|
this._oFocusPosition = null;
|
|
75
76
|
this._oWrapperDom = null;
|
|
76
77
|
this.isFromFullscreen = null;
|
|
78
|
+
this._oAltNode = null;
|
|
79
|
+
this._oAltConnectors = null;
|
|
80
|
+
this._oAltAnnouncement = null;
|
|
81
|
+
this._oAssociatedControl = null;
|
|
82
|
+
this._oAssociatedContainer = null;
|
|
83
|
+
this._oAssociatedDelegate = null;
|
|
84
|
+
this._bCtrlAltDown = false;
|
|
77
85
|
}
|
|
78
86
|
});
|
|
79
87
|
|
|
@@ -124,6 +132,14 @@ sap.ui.define([
|
|
|
124
132
|
this._iColumns = aRow.length;
|
|
125
133
|
}
|
|
126
134
|
}, this);
|
|
135
|
+
|
|
136
|
+
const oControl = this._oGraph.getAssociatedControl();
|
|
137
|
+
if (oControl !== this._oAssociatedControl) {
|
|
138
|
+
this._updateAssociatedDelegate(oControl);
|
|
139
|
+
}
|
|
140
|
+
this._oAltNode = null;
|
|
141
|
+
this._oAltConnectors = null;
|
|
142
|
+
this._oAltAnnouncement = null;
|
|
127
143
|
};
|
|
128
144
|
|
|
129
145
|
KeyboardNavigator.prototype.setWrapperDom = function (oDom) {
|
|
@@ -229,6 +245,12 @@ sap.ui.define([
|
|
|
229
245
|
KeyboardNavigator.prototype.onkeydown = function (oEvent) {
|
|
230
246
|
var oItem, oBtn,
|
|
231
247
|
oFocus = this.getFocus();
|
|
248
|
+
|
|
249
|
+
// On Windows, Ctrl+Alt = AltGr — browsers strip ctrlKey/altKey from the character keydown.
|
|
250
|
+
if (oEvent.keyCode === KeyCodes.ALT && oEvent.ctrlKey) {
|
|
251
|
+
this._bCtrlAltDown = true;
|
|
252
|
+
}
|
|
253
|
+
|
|
232
254
|
if (!oFocus) {
|
|
233
255
|
return;
|
|
234
256
|
}
|
|
@@ -256,11 +278,7 @@ sap.ui.define([
|
|
|
256
278
|
}
|
|
257
279
|
oEvent.stopPropagation();
|
|
258
280
|
} else if (oEvent.keyCode === KeyCodes.F6) {
|
|
259
|
-
|
|
260
|
-
oFocus.button = null;
|
|
261
|
-
this._oGraph.setFocus(oFocus);
|
|
262
|
-
}
|
|
263
|
-
this._handleArrow(oEvent, oEvent.shiftKey ? mDirections.LEFT : mDirections.RIGHT);
|
|
281
|
+
this._handleF6(oEvent);
|
|
264
282
|
} else if (oEvent.keyCode === KeyCodes.F7 && !oEvent.shiftKey) {
|
|
265
283
|
if (oItem && oBtn) {
|
|
266
284
|
oFocus.button = null;
|
|
@@ -272,12 +290,24 @@ sap.ui.define([
|
|
|
272
290
|
this._onCtrlPlus(oEvent);
|
|
273
291
|
} else if (oEvent.ctrlKey && (oEvent.keyCode === KeyCodes.SLASH || oEvent.keyCode === KeyCodes.NUMPAD_MINUS)) {
|
|
274
292
|
this._onCtrlMinus(oEvent);
|
|
275
|
-
} else if(
|
|
276
|
-
|
|
293
|
+
} else if (this._bCtrlAltDown && oEvent.keyCode === KeyCodes.P) {
|
|
294
|
+
this._bCtrlAltDown = false;
|
|
295
|
+
const oAssociatedControl = this._oGraph.getAssociatedControl();
|
|
277
296
|
if (oAssociatedControl) {
|
|
278
297
|
oAssociatedControl.focus();
|
|
279
298
|
oItem._setFocus(false);
|
|
280
299
|
}
|
|
300
|
+
oEvent.preventDefault();
|
|
301
|
+
oEvent.stopPropagation();
|
|
302
|
+
} else if (oEvent.altKey && !oEvent.ctrlKey && !oEvent.shiftKey && oItem instanceof Node) {
|
|
303
|
+
if (oEvent.keyCode === KeyCodes.PLUS || oEvent.keyCode === KeyCodes.NUMPAD_PLUS) {
|
|
304
|
+
this._handleAltAnnounce(oEvent, oItem);
|
|
305
|
+
} else {
|
|
306
|
+
const iDigitIndex = this._getAltDigitIndex(oEvent.keyCode);
|
|
307
|
+
if (iDigitIndex >= 0) {
|
|
308
|
+
this._handleAltConnectorNavigation(oEvent, oItem, iDigitIndex);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
281
311
|
}
|
|
282
312
|
};
|
|
283
313
|
|
|
@@ -285,6 +315,59 @@ sap.ui.define([
|
|
|
285
315
|
/* Private methods */
|
|
286
316
|
/* =========================================================== */
|
|
287
317
|
|
|
318
|
+
KeyboardNavigator.prototype._getAltDigitIndex = function (iKeyCode) {
|
|
319
|
+
if (iKeyCode >= KeyCodes.DIGIT_1 && iKeyCode <= KeyCodes.DIGIT_9) {
|
|
320
|
+
return iKeyCode - KeyCodes.DIGIT_1;
|
|
321
|
+
}
|
|
322
|
+
if (iKeyCode >= KeyCodes.NUMPAD_1 && iKeyCode <= KeyCodes.NUMPAD_9) {
|
|
323
|
+
return iKeyCode - KeyCodes.NUMPAD_1;
|
|
324
|
+
}
|
|
325
|
+
return -1;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Handles F6 / Shift+F6 — skip to next/previous visible group regardless of what is focused.
|
|
330
|
+
* @private
|
|
331
|
+
*/
|
|
332
|
+
KeyboardNavigator.prototype._handleF6 = function (oEvent) {
|
|
333
|
+
const bBackward = oEvent.shiftKey,
|
|
334
|
+
oFocus = this.getFocus(),
|
|
335
|
+
oItem = oFocus ? oFocus.item : null,
|
|
336
|
+
bIsRtl = this._oGraph._bIsRtl,
|
|
337
|
+
aGroups = this._oGraph.getGroups().filter(function (oGroup) {
|
|
338
|
+
return !oGroup.isHidden() && oGroup.getVisible();
|
|
339
|
+
}).sort(function (oA, oB) {
|
|
340
|
+
// Top-to-bottom, then by reading direction (RTL: descending x, LTR: ascending x)
|
|
341
|
+
const iDeltaY = oA.getY() - oB.getY();
|
|
342
|
+
if (iDeltaY !== 0) { return iDeltaY; }
|
|
343
|
+
const iDeltaX = oA.getX() - oB.getX();
|
|
344
|
+
return bIsRtl ? -iDeltaX : iDeltaX;
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
if (aGroups.length === 0) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
let iCurrentIndex = -1;
|
|
352
|
+
if (oItem instanceof Group) {
|
|
353
|
+
iCurrentIndex = aGroups.indexOf(oItem);
|
|
354
|
+
} else if (oItem instanceof Node && oItem._oGroup) {
|
|
355
|
+
iCurrentIndex = aGroups.indexOf(oItem._oGroup);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const iTargetIndex = bBackward
|
|
359
|
+
? (iCurrentIndex > 0 ? iCurrentIndex - 1 : aGroups.length - 1)
|
|
360
|
+
: (iCurrentIndex < aGroups.length - 1 ? iCurrentIndex + 1 : 0);
|
|
361
|
+
|
|
362
|
+
// Ensure setFocus lands on the group header, not the menu button
|
|
363
|
+
if (this._oGraph._oFocus) {
|
|
364
|
+
this._oGraph._oFocus.groupInFocused = false;
|
|
365
|
+
}
|
|
366
|
+
this._oGraph.setFocus({ item: aGroups[iTargetIndex], button: null });
|
|
367
|
+
oEvent.preventDefault();
|
|
368
|
+
oEvent.stopPropagation();
|
|
369
|
+
};
|
|
370
|
+
|
|
288
371
|
KeyboardNavigator.prototype._handleEnter = function () {
|
|
289
372
|
var oItem, oBtn,
|
|
290
373
|
oFocus = this.getFocus();
|
|
@@ -372,9 +455,32 @@ sap.ui.define([
|
|
|
372
455
|
}
|
|
373
456
|
};
|
|
374
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Fires the nodeAdded event and shifts focus to the newly added node after re-render.
|
|
460
|
+
* Only active when DnD is enabled.
|
|
461
|
+
* @private
|
|
462
|
+
*/
|
|
463
|
+
KeyboardNavigator.prototype._handleAddNode = function (oEvent) {
|
|
464
|
+
if (!this._oGraph._isDnDEnabled()) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
this._oGraph.fireEvent("nodeAdded", {}, false);
|
|
468
|
+
const fnFocus = () => {
|
|
469
|
+
this._oGraph.detachGraphReady(fnFocus);
|
|
470
|
+
const aNodes = this._oGraph.getNodes();
|
|
471
|
+
if (aNodes.length) {
|
|
472
|
+
this._oGraph.setFocus({ item: aNodes.at(-1), button: null });
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
this._oGraph.attachGraphReady(fnFocus);
|
|
476
|
+
oEvent.preventDefault();
|
|
477
|
+
oEvent.stopPropagation();
|
|
478
|
+
};
|
|
479
|
+
|
|
375
480
|
KeyboardNavigator.prototype._handleTab = function (oEvent, sDirection) {
|
|
376
|
-
|
|
377
|
-
|
|
481
|
+
const oFocus = this.getFocus(),
|
|
482
|
+
bBackward = sDirection === mDirections.LEFT;
|
|
483
|
+
this._oWrapperDom.setAttribute("aria-live", "assertive");
|
|
378
484
|
this._oGraph._setAriaLabelForWrapper(oResourceBundle.getText("NETWORK_GRAPH_ACCESSIBILITY_LABEL"));
|
|
379
485
|
if (this._ignoreEvent(oEvent)) {
|
|
380
486
|
this._oWrapperDom.setAttribute("aria-live","off");
|
|
@@ -386,6 +492,12 @@ sap.ui.define([
|
|
|
386
492
|
}
|
|
387
493
|
return;
|
|
388
494
|
} else {
|
|
495
|
+
if (sDirection === mDirections.LEFT && this._bWrapperHighlighted && !this.getFocus()) {
|
|
496
|
+
this._oWrapperDom.classList.add("sapSuiteUiCommonsNetworkGraphContentFocusHidden");
|
|
497
|
+
this._bWrapperHighlighted = false;
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
this._bWrapperHighlighted = false;
|
|
389
501
|
this._oWrapperDom.classList.add("sapSuiteUiCommonsNetworkGraphContentFocusHidden");
|
|
390
502
|
}
|
|
391
503
|
|
|
@@ -396,7 +508,118 @@ sap.ui.define([
|
|
|
396
508
|
return;
|
|
397
509
|
}
|
|
398
510
|
|
|
399
|
-
|
|
511
|
+
if (oFocus?.item instanceof Node) {
|
|
512
|
+
const bMoved = this._navigateFromNode(oFocus.item, bBackward);
|
|
513
|
+
if (!bMoved && bBackward) {
|
|
514
|
+
const oGroup = oFocus.item._oGroup;
|
|
515
|
+
if (oGroup) {
|
|
516
|
+
this._oGraph.setFocus({ item: oGroup, button: Group.BUTTONS.COLLAPSE });
|
|
517
|
+
oEvent.preventDefault();
|
|
518
|
+
oEvent.stopPropagation();
|
|
519
|
+
} else {
|
|
520
|
+
this._moveItemFocus(oEvent, mDirections.LEFT);
|
|
521
|
+
}
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
} else if (oFocus?.item instanceof Line) {
|
|
525
|
+
this._navigateFromConnector(oFocus.item, bBackward);
|
|
526
|
+
} else {
|
|
527
|
+
this._moveItemFocus(oEvent, sDirection);
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
oEvent.preventDefault();
|
|
532
|
+
oEvent.stopPropagation();
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Navigate from a node to its first connector.
|
|
537
|
+
* @returns {boolean} True if focus moved to a connector, false otherwise
|
|
538
|
+
* @private
|
|
539
|
+
*/
|
|
540
|
+
KeyboardNavigator.prototype._navigateFromNode = function (oNode, bBackward) {
|
|
541
|
+
const aLines = bBackward ? oNode.getParentLines() : oNode.getChildLines();
|
|
542
|
+
const aVisibleLines = this._getVisibleLines(aLines, bBackward);
|
|
543
|
+
|
|
544
|
+
if (aVisibleLines.length > 0) {
|
|
545
|
+
this._oGraph.setFocus({
|
|
546
|
+
item: aVisibleLines[0],
|
|
547
|
+
button: null
|
|
548
|
+
});
|
|
549
|
+
return true;
|
|
550
|
+
}
|
|
551
|
+
return false;
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Navigate from a connector to its connected node
|
|
556
|
+
* @param {Line} oLine - The connector to navigate from
|
|
557
|
+
* @param {boolean} bBackward - True for source node, false for target node
|
|
558
|
+
* @private
|
|
559
|
+
*/
|
|
560
|
+
KeyboardNavigator.prototype._navigateFromConnector = function (oLine, bBackward) {
|
|
561
|
+
const oNode = bBackward ? oLine.getFromNode() : oLine.getToNode();
|
|
562
|
+
|
|
563
|
+
if (oNode && !oNode.isHidden()) {
|
|
564
|
+
this._oGraph.setFocus({
|
|
565
|
+
item: oNode,
|
|
566
|
+
button: null
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Returns visible lines sorted top-to-bottom.
|
|
573
|
+
* @param {Array} aLines - Array of lines to filter and sort
|
|
574
|
+
* @param {boolean} bSortBySource - If true, sort by source node Y position; otherwise by target node
|
|
575
|
+
* @private
|
|
576
|
+
*/
|
|
577
|
+
KeyboardNavigator.prototype._getVisibleLines = function (aLines, bSortBySource) {
|
|
578
|
+
if (!aLines || aLines.length === 0) {
|
|
579
|
+
return [];
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
const aVisibleLines = aLines.filter(function (oLine) {
|
|
583
|
+
return !oLine.isHidden() && !oLine._isIgnored() && oLine.getVisible();
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
const fnGetSortY = (oLine) => {
|
|
587
|
+
const oNode = bSortBySource ? oLine.getFromNode() : oLine.getToNode();
|
|
588
|
+
if (oNode && !oNode.isHidden()) {
|
|
589
|
+
return oNode.getY();
|
|
590
|
+
}
|
|
591
|
+
const aCoords = oLine.getCoordinates();
|
|
592
|
+
return (aCoords && aCoords.length > 0) ? aCoords[0].getY() : 0;
|
|
593
|
+
};
|
|
594
|
+
return aVisibleLines.sort((oLine1, oLine2) => fnGetSortY(oLine1) - fnGetSortY(oLine2));
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
KeyboardNavigator.prototype._handleAltAnnounce = function (oEvent, oNode) {
|
|
598
|
+
if (this._oAltNode !== oNode) {
|
|
599
|
+
this._oAltNode = oNode;
|
|
600
|
+
this._oAltConnectors = oNode._getAltNavigationConnectors();
|
|
601
|
+
const { aIncomingConnectors, aOutgoingConnectors, aConnectors } = this._oAltConnectors;
|
|
602
|
+
this._oAltAnnouncement = (aIncomingConnectors.length >= 2 || aOutgoingConnectors.length >= 2)
|
|
603
|
+
? oNode._getAltConnectorsAnnouncement(aConnectors)
|
|
604
|
+
: null;
|
|
605
|
+
}
|
|
606
|
+
if (!this._oAltAnnouncement) { return; }
|
|
607
|
+
this._oGraph._setAccessibilityTitle(this._oAltAnnouncement);
|
|
608
|
+
oEvent.preventDefault();
|
|
609
|
+
oEvent.stopPropagation();
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
KeyboardNavigator.prototype._handleAltConnectorNavigation = function (oEvent, oNode, iIndex) {
|
|
613
|
+
if (this._oAltNode !== oNode || !this._oAltConnectors) {
|
|
614
|
+
this._oAltNode = oNode;
|
|
615
|
+
this._oAltConnectors = oNode._getAltNavigationConnectors();
|
|
616
|
+
}
|
|
617
|
+
const { aConnectors } = this._oAltConnectors;
|
|
618
|
+
if (iIndex < aConnectors.length) {
|
|
619
|
+
this._oGraph.setFocus({ item: aConnectors[iIndex].line, button: null });
|
|
620
|
+
oEvent.preventDefault();
|
|
621
|
+
oEvent.stopPropagation();
|
|
622
|
+
}
|
|
400
623
|
};
|
|
401
624
|
|
|
402
625
|
KeyboardNavigator.prototype._handleTabOverLinesWithButtons = function (oEvent, sDirection) {
|
|
@@ -624,12 +847,64 @@ sap.ui.define([
|
|
|
624
847
|
return;
|
|
625
848
|
}
|
|
626
849
|
|
|
850
|
+
const oFocus = this.getFocus();
|
|
851
|
+
const oItem = oFocus.item;
|
|
852
|
+
if (oItem instanceof Line) {
|
|
853
|
+
if (sDirection === mDirections.UP || sDirection === mDirections.DOWN) {
|
|
854
|
+
this._navigateBetweenConnectors(oEvent, sDirection);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// For all other cases, use default behavior
|
|
627
860
|
this._moveItemFocus(oEvent, sDirection, true);
|
|
628
861
|
};
|
|
629
862
|
|
|
863
|
+
/**
|
|
864
|
+
* Navigate between multiple connectors from the same source node
|
|
865
|
+
* @private
|
|
866
|
+
*/
|
|
867
|
+
KeyboardNavigator.prototype._navigateBetweenConnectors = function (oEvent, sDirection) {
|
|
868
|
+
const oFocus = this.getFocus(),
|
|
869
|
+
oLine = oFocus.item;
|
|
870
|
+
|
|
871
|
+
if (!(oLine instanceof Line)) {
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// ↑/↓ navigates among the outgoing connectors of this line's source node,
|
|
876
|
+
// giving a consistent vertical ordering regardless of which connector is focused.
|
|
877
|
+
const oSourceNode = oLine.getFromNode();
|
|
878
|
+
if (!oSourceNode) {
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
const aVisibleLines = this._getVisibleLines(oSourceNode.getChildLines());
|
|
883
|
+
if (aVisibleLines.length <= 1) {
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
const iCurrentIndex = aVisibleLines.indexOf(oLine);
|
|
888
|
+
if (iCurrentIndex === -1) {
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
const iTargetIndex = sDirection === mDirections.DOWN ? iCurrentIndex + 1 : iCurrentIndex - 1;
|
|
893
|
+
if (iTargetIndex >= 0 && iTargetIndex < aVisibleLines.length) {
|
|
894
|
+
this._oGraph.setFocus({
|
|
895
|
+
item: aVisibleLines[iTargetIndex],
|
|
896
|
+
button: null
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
oEvent.preventDefault();
|
|
901
|
+
oEvent.stopPropagation();
|
|
902
|
+
};
|
|
903
|
+
|
|
630
904
|
KeyboardNavigator.prototype._moveItemFocus = function (oEvent, sDirection, bStopOnLast) {
|
|
631
905
|
var oFocus,
|
|
632
906
|
bBackTab = (sDirection === mDirections.LEFT && oEvent.key === "Tab"),
|
|
907
|
+
bHadFocus = !!this.getFocus(),
|
|
633
908
|
oPosition,
|
|
634
909
|
oNewItem,
|
|
635
910
|
aBtns;
|
|
@@ -667,6 +942,11 @@ sap.ui.define([
|
|
|
667
942
|
if (oEvent && oNewItem) {
|
|
668
943
|
oEvent.preventDefault();
|
|
669
944
|
oEvent.stopPropagation();
|
|
945
|
+
} else if (bBackTab && !oNewItem && bHadFocus) {
|
|
946
|
+
this._oWrapperDom.classList.remove("sapSuiteUiCommonsNetworkGraphContentFocusHidden");
|
|
947
|
+
this._bWrapperHighlighted = true;
|
|
948
|
+
oEvent.preventDefault();
|
|
949
|
+
oEvent.stopPropagation();
|
|
670
950
|
}
|
|
671
951
|
};
|
|
672
952
|
|
|
@@ -815,6 +1095,45 @@ sap.ui.define([
|
|
|
815
1095
|
oEvent.stopPropagation();
|
|
816
1096
|
};
|
|
817
1097
|
|
|
1098
|
+
KeyboardNavigator.prototype._updateAssociatedDelegate = function (oControl) {
|
|
1099
|
+
if (this._oAssociatedContainer) {
|
|
1100
|
+
this._oAssociatedContainer.removeEventDelegate(this._oAssociatedDelegate);
|
|
1101
|
+
this._oAssociatedContainer = null;
|
|
1102
|
+
this._oAssociatedDelegate = null;
|
|
1103
|
+
}
|
|
1104
|
+
const oContainer = oControl && oControl.getParent();
|
|
1105
|
+
if (oContainer) {
|
|
1106
|
+
this._oAssociatedDelegate = {
|
|
1107
|
+
onkeydown: (oEvent) => {
|
|
1108
|
+
if (oEvent.keyCode === KeyCodes.ALT && oEvent.ctrlKey) {
|
|
1109
|
+
this._bCtrlAltDown = true;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
if (oEvent.shiftKey && oEvent.keyCode === KeyCodes.F10) {
|
|
1113
|
+
this._oGraph._restoreFocusToGraph();
|
|
1114
|
+
oEvent.preventDefault();
|
|
1115
|
+
oEvent.stopPropagation();
|
|
1116
|
+
} else if (oEvent.keyCode === KeyCodes.INSERT || (this._bCtrlAltDown && oEvent.keyCode === KeyCodes.N)) {
|
|
1117
|
+
this._bCtrlAltDown = false;
|
|
1118
|
+
this._handleAddNode(oEvent);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
this._oAssociatedContainer = oContainer;
|
|
1123
|
+
oContainer.addEventDelegate(this._oAssociatedDelegate);
|
|
1124
|
+
}
|
|
1125
|
+
this._oAssociatedControl = oControl;
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1128
|
+
KeyboardNavigator.prototype.destroy = function () {
|
|
1129
|
+
if (this._oAssociatedContainer) {
|
|
1130
|
+
this._oAssociatedContainer.removeEventDelegate(this._oAssociatedDelegate);
|
|
1131
|
+
this._oAssociatedContainer = null;
|
|
1132
|
+
this._oAssociatedDelegate = null;
|
|
1133
|
+
}
|
|
1134
|
+
BaseObject.prototype.destroy.apply(this, arguments);
|
|
1135
|
+
};
|
|
1136
|
+
|
|
818
1137
|
KeyboardNavigator.prototype._ignoreEvent = function (oEvent) {
|
|
819
1138
|
return !containsOrEquals(this._oWrapperDom, oEvent.target);
|
|
820
1139
|
};
|
|
@@ -883,7 +883,11 @@ sap.ui.define([
|
|
|
883
883
|
Line.prototype._getAccessibilityLabel = function (oGraph) {
|
|
884
884
|
const aSentenceParts = [];
|
|
885
885
|
const sConnectionType = this.getConnectionType();
|
|
886
|
-
const
|
|
886
|
+
const oMapping = oGraph.getConnectionTypeMapping();
|
|
887
|
+
// In RTL mode, left and right sides of nodes are semantically swapped
|
|
888
|
+
const bRTL = this.getParent()._bIsRtl;
|
|
889
|
+
const sResolvedType = bRTL ? (Utils.mRTLSwap[sConnectionType] || sConnectionType) : sConnectionType;
|
|
890
|
+
const sConnectionTypeText = oMapping[sResolvedType];
|
|
887
891
|
const sFromNodeTitle = this.getFromNode().getTitle();
|
|
888
892
|
const sFromNodeText = sFromNodeTitle ? sFromNodeTitle : this.getFromNode().getAltText();
|
|
889
893
|
const sToNodeTitle = this.getToNode().getTitle();
|
|
@@ -1001,10 +1001,10 @@ sap.ui.define([
|
|
|
1001
1001
|
}, false);
|
|
1002
1002
|
|
|
1003
1003
|
let { style: sBorderColor, class: sBorderClass } = this._getStatusStyle({
|
|
1004
|
-
"
|
|
1004
|
+
"outline-color": ElementBase.ColorType.Border,
|
|
1005
1005
|
"background-color": this.getSelected() ? ElementBase.ColorType.SelectedBackground : "",
|
|
1006
|
-
"
|
|
1007
|
-
"
|
|
1006
|
+
"outline-width": ElementBase.ColorType.BorderWidth,
|
|
1007
|
+
"outline-style": ElementBase.ColorType.BorderStyle
|
|
1008
1008
|
}, false);
|
|
1009
1009
|
|
|
1010
1010
|
mOptions.renderManager.openStart("div", sId + "-wrapperwithbuttons");
|
|
@@ -2754,9 +2754,71 @@ sap.ui.define([
|
|
|
2754
2754
|
aSentenceParts.push(oResourceBundle.getText("NETWORK_GRAPH_NAVIGATION_SHIFT_TAB_TO_INCOMING"));
|
|
2755
2755
|
}
|
|
2756
2756
|
|
|
2757
|
+
const { aIncomingConnectors, aOutgoingConnectors } = this._getAltNavigationConnectors();
|
|
2758
|
+
if (aIncomingConnectors.length >= 2 || aOutgoingConnectors.length >= 2) {
|
|
2759
|
+
aSentenceParts.push(oResourceBundle.getText("NETWORK_GRAPH_NAVIGATION_ALT_CONNECTORS"));
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2757
2762
|
return `${sLabel}. ${aSentenceParts.join(". ")}.`;
|
|
2758
2763
|
};
|
|
2759
2764
|
|
|
2765
|
+
Node.prototype._getAltNavigationConnectors = function () {
|
|
2766
|
+
const iThisX = this.getX();
|
|
2767
|
+
const fnDir = (oNode) => oNode?.getX() < iThisX ? "left" : "right";
|
|
2768
|
+
const fnActive = (oLine) => oLine.getVisible() && !oLine.isHidden() && !oLine._isIgnored();
|
|
2769
|
+
|
|
2770
|
+
// Incoming: all valid lines, sorted top-to-bottom by source node Y, then by node key for stability
|
|
2771
|
+
const aIncomingConnectors = this.getParentLines()
|
|
2772
|
+
.filter((oLine) => fnActive(oLine) && oLine.getFromNode())
|
|
2773
|
+
.sort((a, b) => {
|
|
2774
|
+
const iY = a.getFromNode().getY() - b.getFromNode().getY();
|
|
2775
|
+
return iY !== 0 ? iY : a.getFromNode().getKey().localeCompare(b.getFromNode().getKey());
|
|
2776
|
+
})
|
|
2777
|
+
.map((oLine) => ({ line: oLine, type: "incoming", direction: fnDir(oLine.getFromNode()) }));
|
|
2778
|
+
|
|
2779
|
+
// Outgoing: all valid lines, sorted top-to-bottom by target node Y, then by node key for stability
|
|
2780
|
+
const aOutgoingConnectors = this.getChildLines()
|
|
2781
|
+
.filter((oLine) => fnActive(oLine) && oLine.getToNode())
|
|
2782
|
+
.sort((a, b) => {
|
|
2783
|
+
const iY = a.getToNode().getY() - b.getToNode().getY();
|
|
2784
|
+
return iY !== 0 ? iY : a.getToNode().getKey().localeCompare(b.getToNode().getKey());
|
|
2785
|
+
})
|
|
2786
|
+
.map((oLine) => ({ line: oLine, type: "outgoing", direction: fnDir(oLine.getToNode()) }));
|
|
2787
|
+
|
|
2788
|
+
const aConnectors = ["left", "right"].flatMap((sDir) => [
|
|
2789
|
+
...aIncomingConnectors.filter((o) => o.direction === sDir),
|
|
2790
|
+
...aOutgoingConnectors.filter((o) => o.direction === sDir)
|
|
2791
|
+
]);
|
|
2792
|
+
|
|
2793
|
+
return { aIncomingConnectors, aOutgoingConnectors, aConnectors };
|
|
2794
|
+
};
|
|
2795
|
+
|
|
2796
|
+
Node.prototype._getAltConnectorsAnnouncement = function (aConnectors) {
|
|
2797
|
+
const oGraph = this.getParent();
|
|
2798
|
+
const oMapping = oGraph.getConnectionTypeMapping();
|
|
2799
|
+
const bRTL = oGraph._bIsRtl;
|
|
2800
|
+
return aConnectors.map((oConnector, i) => {
|
|
2801
|
+
const oLine = oConnector.line;
|
|
2802
|
+
const sConnectionType = oLine.getConnectionType();
|
|
2803
|
+
const sResolvedType = bRTL ? (Utils.mRTLSwap[sConnectionType] || sConnectionType) : sConnectionType;
|
|
2804
|
+
const sConnectionTypeText = oMapping[sResolvedType] || sResolvedType;
|
|
2805
|
+
const sFromNodeTitle = oLine.getFromNode().getTitle() || oLine.getFromNode().getAltText();
|
|
2806
|
+
const sToNodeTitle = oLine.getToNode().getTitle() || oLine.getToNode().getAltText();
|
|
2807
|
+
// Determine the physical port side from connection type (Left key = left port, Right key = right port)
|
|
2808
|
+
const sSide = oConnector.type === "outgoing"
|
|
2809
|
+
? (sResolvedType.startsWith("Left") ? "left" : "right")
|
|
2810
|
+
: (sResolvedType.endsWith("Left") ? "left" : "right");
|
|
2811
|
+
return oResourceBundle.getText("NETWORK_GRAPH_NAVIGATION_ALT_CONNECTOR_ANNOUNCE", [
|
|
2812
|
+
oConnector.type,
|
|
2813
|
+
sSide,
|
|
2814
|
+
sConnectionTypeText,
|
|
2815
|
+
sFromNodeTitle,
|
|
2816
|
+
sToNodeTitle,
|
|
2817
|
+
i + 1
|
|
2818
|
+
]);
|
|
2819
|
+
}).join(". ");
|
|
2820
|
+
};
|
|
2821
|
+
|
|
2760
2822
|
Node.prototype._setStatusColors = function(sType) {
|
|
2761
2823
|
var fnSetAttrColor = function(item, sStatus) {
|
|
2762
2824
|
if (sStatus && item) {
|
|
@@ -2818,10 +2880,10 @@ sap.ui.define([
|
|
|
2818
2880
|
$titleText = this.$().find(".sapSuiteUiCommonsNetworkGraphDivNodeTitleText");
|
|
2819
2881
|
|
|
2820
2882
|
if(SemanticColorType.hasOwnProperty(sBackgroundColor)){
|
|
2821
|
-
$wrapper.addClass(Utils.SEMANTIC_CLASS_NAME.
|
|
2883
|
+
$wrapper.addClass(Utils.SEMANTIC_CLASS_NAME.OUTLINE + sBackgroundColor);
|
|
2822
2884
|
} else {
|
|
2823
2885
|
/** @deprecated As of 1.120 */
|
|
2824
|
-
$wrapper.css("
|
|
2886
|
+
$wrapper.css("outline-color", sBorderColor);
|
|
2825
2887
|
}
|
|
2826
2888
|
|
|
2827
2889
|
let sFocusColor = this._getColor(ElementBase.ColorType[sType + "Focus"])
|
|
@@ -24,6 +24,8 @@ sap.ui.define(["sap/base/Log"], function (Log) {
|
|
|
24
24
|
'BACKGROUND-COLOR': 'backgroundSemanticColor',
|
|
25
25
|
BORDER: 'borderSemanticColor',
|
|
26
26
|
'BORDER-COLOR': 'borderSemanticColor',
|
|
27
|
+
OUTLINE: 'outlineSemanticColor',
|
|
28
|
+
'OUTLINE-COLOR': 'outlineSemanticColor',
|
|
27
29
|
TEXT: 'textSemanticColor',
|
|
28
30
|
FILL: 'fillSemanticColor',
|
|
29
31
|
STROKE: 'strokeSemanticColor',
|
|
@@ -312,5 +314,13 @@ sap.ui.define(["sap/base/Log"], function (Log) {
|
|
|
312
314
|
}, delay);
|
|
313
315
|
};
|
|
314
316
|
|
|
317
|
+
// RTL swap map for connection types: mirrors Left↔Right side labels.
|
|
318
|
+
Utils.mRTLSwap = {
|
|
319
|
+
"LeftToLeft": "RightToRight",
|
|
320
|
+
"LeftToRight": "RightToLeft",
|
|
321
|
+
"RightToLeft": "LeftToRight",
|
|
322
|
+
"RightToRight": "LeftToLeft"
|
|
323
|
+
};
|
|
324
|
+
|
|
315
325
|
return Utils;
|
|
316
326
|
}, true);
|
|
@@ -21,6 +21,31 @@ sap.ui.define([
|
|
|
21
21
|
* @since 1.144
|
|
22
22
|
*/
|
|
23
23
|
var ConnectionPathUtils = {
|
|
24
|
+
/**
|
|
25
|
+
* Gets the effective connection type for path calculation based on RTL mode.
|
|
26
|
+
* In RTL mode, semantic directions are reversed since nodes are already mirrored.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} sConnectionType - The configured connection type
|
|
29
|
+
* @param {boolean} bIsRTL - Whether RTL mode is enabled
|
|
30
|
+
* @returns {string} The effective connection type to use for calculations
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
_getEffectiveConnectionType: function (sConnectionType, bIsRTL) {
|
|
34
|
+
if (!bIsRTL) {
|
|
35
|
+
return sConnectionType;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// In RTL mode, semantic directions are reversed (nodes are already mirrored)
|
|
39
|
+
const rtlMapping = {
|
|
40
|
+
[ConnectionType.RightToLeft]: ConnectionType.LeftToRight,
|
|
41
|
+
[ConnectionType.LeftToRight]: ConnectionType.RightToLeft,
|
|
42
|
+
[ConnectionType.LeftToLeft]: ConnectionType.RightToRight,
|
|
43
|
+
[ConnectionType.RightToRight]: ConnectionType.LeftToLeft
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return rtlMapping[sConnectionType] || sConnectionType;
|
|
47
|
+
},
|
|
48
|
+
|
|
24
49
|
/**
|
|
25
50
|
* Normalizes lines in a network graph by calculating path coordinates
|
|
26
51
|
* between source and target nodes based on connection types.
|
|
@@ -40,20 +65,25 @@ sap.ui.define([
|
|
|
40
65
|
// Enable multiple directed arrows feature when using ConnectionPathUtils
|
|
41
66
|
oGraph._enableMultipleDirectedArrows = true;
|
|
42
67
|
|
|
68
|
+
// Detect RTL mode from graph
|
|
69
|
+
const bIsRTL = oGraph._bIsRtl || false;
|
|
70
|
+
|
|
43
71
|
// Iterate over all lines in the graph
|
|
44
72
|
oGraph.getLines().forEach((oLine) => {
|
|
45
|
-
const
|
|
73
|
+
const configuredConnectionType = oLine.getConnectionType(); // Get the connection type, if not configured at Line level then the default is Right to Left from source to target.
|
|
74
|
+
// In RTL mode, use effective connection type (semantically reversed)
|
|
75
|
+
const effectiveConnectionType = this._getEffectiveConnectionType(configuredConnectionType, bIsRTL);
|
|
46
76
|
const oSourceNode = oLine.getFromNode();
|
|
47
77
|
const oTargetNode = oLine.getToNode();
|
|
48
78
|
// Get anchor coordinates for source and target nodes, usually the center of the respective sides
|
|
49
|
-
const oSourceAnchor = this._getNodeAnchorCoordinates(oLine.getFromNode(),
|
|
50
|
-
const oTargetAnchor = this._getNodeAnchorCoordinates(oLine.getToNode(),
|
|
79
|
+
const oSourceAnchor = this._getNodeAnchorCoordinates(oLine.getFromNode(), effectiveConnectionType, "source");
|
|
80
|
+
const oTargetAnchor = this._getNodeAnchorCoordinates(oLine.getToNode(), effectiveConnectionType, "target");
|
|
51
81
|
const mParams = {
|
|
52
82
|
sourceAnchor: oSourceAnchor,
|
|
53
83
|
targetAnchor: oTargetAnchor,
|
|
54
84
|
sourceNode: oSourceNode,
|
|
55
85
|
targetNode: oTargetNode,
|
|
56
|
-
sConnectionType:
|
|
86
|
+
sConnectionType: effectiveConnectionType,
|
|
57
87
|
gridSize: config.gridSize,
|
|
58
88
|
minEdgeLength: config.minEdgeLength
|
|
59
89
|
};
|