@sapui5/sap.suite.ui.commons 1.136.12 → 1.136.13

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.
Files changed (68) hide show
  1. package/package.json +1 -1
  2. package/src/sap/suite/ui/commons/.library +1 -1
  3. package/src/sap/suite/ui/commons/AriaProperties.js +1 -1
  4. package/src/sap/suite/ui/commons/CalculationBuilder.js +1 -1
  5. package/src/sap/suite/ui/commons/CalculationBuilderExpression.js +1 -1
  6. package/src/sap/suite/ui/commons/CalculationBuilderFunction.js +1 -1
  7. package/src/sap/suite/ui/commons/CalculationBuilderGroup.js +1 -1
  8. package/src/sap/suite/ui/commons/CalculationBuilderItem.js +1 -1
  9. package/src/sap/suite/ui/commons/CalculationBuilderValidationResult.js +1 -1
  10. package/src/sap/suite/ui/commons/CalculationBuilderVariable.js +1 -1
  11. package/src/sap/suite/ui/commons/CloudFilePicker.js +1 -1
  12. package/src/sap/suite/ui/commons/MicroProcessFlow.js +1 -1
  13. package/src/sap/suite/ui/commons/MicroProcessFlowItem.js +1 -1
  14. package/src/sap/suite/ui/commons/TimelineRenderManager.js +8 -4
  15. package/src/sap/suite/ui/commons/flexibility/changeHandler/PropertyChangeMapper.js +1 -1
  16. package/src/sap/suite/ui/commons/imageeditor/CropCustomShapeHistoryItem.js +1 -1
  17. package/src/sap/suite/ui/commons/imageeditor/CropEllipseHistoryItem.js +1 -1
  18. package/src/sap/suite/ui/commons/imageeditor/CropRectangleHistoryItem.js +1 -1
  19. package/src/sap/suite/ui/commons/imageeditor/CustomSizeItem.js +1 -1
  20. package/src/sap/suite/ui/commons/imageeditor/FilterHistoryItem.js +1 -1
  21. package/src/sap/suite/ui/commons/imageeditor/FlipHistoryItem.js +1 -1
  22. package/src/sap/suite/ui/commons/imageeditor/HistoryItem.js +1 -1
  23. package/src/sap/suite/ui/commons/imageeditor/ImageEditor.js +1 -1
  24. package/src/sap/suite/ui/commons/imageeditor/ImageEditorContainer.js +1 -1
  25. package/src/sap/suite/ui/commons/imageeditor/ImageEditorResponsiveContainer.js +1 -1
  26. package/src/sap/suite/ui/commons/imageeditor/ResizeHistoryItem.js +1 -1
  27. package/src/sap/suite/ui/commons/imageeditor/RotateHistoryItem.js +1 -1
  28. package/src/sap/suite/ui/commons/library.js +100 -3
  29. package/src/sap/suite/ui/commons/messagebundle.properties +73 -12
  30. package/src/sap/suite/ui/commons/messagebundle_en_US_saprigi.properties +39 -5
  31. package/src/sap/suite/ui/commons/messagebundle_fr_CA.properties +1 -1
  32. package/src/sap/suite/ui/commons/networkgraph/ElementBase.js +19 -1
  33. package/src/sap/suite/ui/commons/networkgraph/Graph.js +554 -45
  34. package/src/sap/suite/ui/commons/networkgraph/GraphMap.js +25 -3
  35. package/src/sap/suite/ui/commons/networkgraph/GraphRenderer.js +19 -8
  36. package/src/sap/suite/ui/commons/networkgraph/KeyboardNavigator.js +367 -12
  37. package/src/sap/suite/ui/commons/networkgraph/Line.js +814 -22
  38. package/src/sap/suite/ui/commons/networkgraph/Node.js +573 -79
  39. package/src/sap/suite/ui/commons/networkgraph/Tooltip.js +4 -0
  40. package/src/sap/suite/ui/commons/networkgraph/Utils.js +249 -10
  41. package/src/sap/suite/ui/commons/networkgraph/layout/NoopLayout.js +77 -7
  42. package/src/sap/suite/ui/commons/networkgraph/util/ConnectionPathUtils.js +1174 -0
  43. package/src/sap/suite/ui/commons/networkgraph/util/CreateConnectionPopover.js +374 -0
  44. package/src/sap/suite/ui/commons/networkgraph/util/DependencyLayoutHelper.js +1017 -0
  45. package/src/sap/suite/ui/commons/networkgraph/util/DragDropManager.js +721 -0
  46. package/src/sap/suite/ui/commons/networkgraph/util/PortManager.js +582 -0
  47. package/src/sap/suite/ui/commons/statusindicator/Circle.js +1 -1
  48. package/src/sap/suite/ui/commons/statusindicator/CustomShape.js +1 -1
  49. package/src/sap/suite/ui/commons/statusindicator/DiscreteThreshold.js +1 -1
  50. package/src/sap/suite/ui/commons/statusindicator/FillingOption.js +1 -1
  51. package/src/sap/suite/ui/commons/statusindicator/LibraryShape.js +1 -1
  52. package/src/sap/suite/ui/commons/statusindicator/Path.js +1 -1
  53. package/src/sap/suite/ui/commons/statusindicator/PropertyThreshold.js +1 -1
  54. package/src/sap/suite/ui/commons/statusindicator/Rectangle.js +1 -1
  55. package/src/sap/suite/ui/commons/statusindicator/Shape.js +1 -1
  56. package/src/sap/suite/ui/commons/statusindicator/ShapeGroup.js +1 -1
  57. package/src/sap/suite/ui/commons/statusindicator/SimpleShape.js +1 -1
  58. package/src/sap/suite/ui/commons/statusindicator/StatusIndicator.js +1 -1
  59. package/src/sap/suite/ui/commons/taccount/TAccount.js +1 -1
  60. package/src/sap/suite/ui/commons/taccount/TAccountGroup.js +1 -1
  61. package/src/sap/suite/ui/commons/taccount/TAccountItem.js +1 -1
  62. package/src/sap/suite/ui/commons/taccount/TAccountItemProperty.js +1 -1
  63. package/src/sap/suite/ui/commons/taccount/TAccountPanel.js +1 -1
  64. package/src/sap/suite/ui/commons/themes/base/NetworkGraph.less +26 -13
  65. package/src/sap/suite/ui/commons/themes/base/NetworkGroup.less +4 -0
  66. package/src/sap/suite/ui/commons/themes/base/NetworkLine.less +58 -13
  67. package/src/sap/suite/ui/commons/themes/base/NetworkNode.less +251 -47
  68. package/src/sap/suite/ui/commons/themes/base/SemanticColorMixins.less +55 -0
@@ -0,0 +1,582 @@
1
+ /*!
2
+ *
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
4
+ (c) Copyright 2009-2015 SAP SE. All rights reserved
5
+
6
+ */
7
+ sap.ui.define([
8
+ "sap/ui/thirdparty/jquery",
9
+ "sap/suite/ui/commons/library",
10
+ "sap/suite/ui/commons/networkgraph/Utils"
11
+ ], function (jQuery, Library, Utils) {
12
+ "use strict";
13
+ /**
14
+ * PortManager class for managing network graph ports.
15
+ * Implements singleton pattern to ensure only one instance exists.
16
+ */
17
+ class PortManager {
18
+ constructor() {
19
+ /**
20
+ * Set of node keys that currently have trigger ports.
21
+ * Used to track which nodes are acting as trigger nodes for port connections.
22
+ * @type {Set<string>}
23
+ * @private
24
+ */
25
+ this._triggerPortNodeKeys = new Set();
26
+ /**
27
+ * Reference to the current graph instance.
28
+ * Used for accessing graph properties and nodes for port operations.
29
+ * @type {sap.suite.ui.commons.networkgraph.Graph|null}
30
+ * @private
31
+ */
32
+ this._graphInstance = null;
33
+ /**
34
+ * Key of the node that currently has trigger ports active.
35
+ * Used for port restoration after graph rerendering and toggle behavior.
36
+ * @type {string|null}
37
+ * @private
38
+ */
39
+ this._currentTriggerNodeKey = null;
40
+ /**
41
+ * Flag indicating whether port restoration mechanism has been set up.
42
+ * Prevents duplicate event listeners for graph ready events.
43
+ * @type {boolean}
44
+ * @private
45
+ */
46
+ this._restorationSetup = false;
47
+ }
48
+
49
+ /**
50
+ * Reference to the ConnectionType enum for efficient access
51
+ * @type {Object}
52
+ * @private
53
+ */
54
+ static _oConnectionType = Library.networkgraph.ConnectionType;
55
+
56
+ getGraphInstance() {
57
+ return this._graphInstance;
58
+ }
59
+ setGraphInstance(oGraph) {
60
+ this._graphInstance = oGraph;
61
+ // Set up automatic port restoration after rerendering
62
+ if (oGraph) {
63
+ this.setupPortRestoration();
64
+ }
65
+ }
66
+ /**
67
+ * Adds ports to the given node instance based on the graph's nodePorts property.
68
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
69
+ * @param {boolean} bTriggerNode - Whether the node is a trigger node.
70
+ */
71
+ addPortsToNode(oNode, bTriggerNode) {
72
+ var sNodePorts = oNode._getNodePorts();
73
+ // Remove existing ports first
74
+ this.removePortsFromNode(oNode);
75
+ if (sNodePorts === "None") {
76
+ return;
77
+ }
78
+ var $node = oNode.$();
79
+ // Add ports based on the nodePorts setting
80
+ switch (sNodePorts) {
81
+ case "All":
82
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "left", bTriggerNode: bTriggerNode });
83
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "right", bTriggerNode: bTriggerNode });
84
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "top", bTriggerNode: bTriggerNode });
85
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "bottom", bTriggerNode: bTriggerNode });
86
+ break;
87
+ case "LeftRight":
88
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "left", bTriggerNode: bTriggerNode });
89
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "right", bTriggerNode: bTriggerNode });
90
+ break;
91
+ case "TopBottom":
92
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "top", bTriggerNode: bTriggerNode });
93
+ this._addPortToSide({ $node: $node, oNode: oNode, sSide: "bottom", bTriggerNode: bTriggerNode });
94
+ break;
95
+ default:
96
+ // No ports to add
97
+ break;
98
+ }
99
+ if (bTriggerNode) {
100
+ this._triggerPortNodeKeys.add(oNode.getKey());
101
+ this._currentTriggerNodeKey = oNode.getKey();
102
+ }
103
+ }
104
+ /**
105
+ * Adds a port to a specific side of the node.
106
+ * @param {Object} oConfig - Configuration object for port creation.
107
+ * @param {jQuery} oConfig.$node - The node DOM element.
108
+ * @param {sap.suite.ui.commons.networkgraph.Node} oConfig.oNode - The node instance.
109
+ * @param {string} oConfig.sSide - The side to add the port to ("left", "right", "top", "bottom").
110
+ * @param {boolean} oConfig.bTriggerNode - Whether this is a trigger node.
111
+ */
112
+ _addPortToSide(oConfig) {
113
+ var $node = oConfig.$node;
114
+ var oNode = oConfig.oNode;
115
+ var sSide = oConfig.sSide;
116
+ var bTriggerNode = oConfig.bTriggerNode;
117
+ var sPortType = bTriggerNode ? "trigger" : "inlet";
118
+ var sCapitalizedSide = sSide.charAt(0).toUpperCase() + sSide.slice(1);
119
+ // Build the CSS classes based on port type and position
120
+ var aClasses = ["sapSuiteUiCommonsNetworkNodePort"];
121
+ // Add port type specific class
122
+ aClasses.push("sapSuiteUiCommonsNetworkNode" + (bTriggerNode ? "TriggerPort" : "InletPort"));
123
+ // Add position-specific class (matching the CSS class names)
124
+ aClasses.push("sapSuiteUi" + sCapitalizedSide + (bTriggerNode ? "TriggerPort" : "InletPort"));
125
+ var sPortClass = aClasses.join(" ");
126
+ var $port = this._createPort({
127
+ className: sPortClass,
128
+ isAccessible: bTriggerNode, // Only trigger ports are accessible
129
+ ariaLabel: bTriggerNode ? ("Connection port on " + sSide + " side of " + (oNode.getTitle() || "node")) : null,
130
+ attributes: {
131
+ "data-node-key": oNode.getKey(),
132
+ "data-port-type": sPortType,
133
+ "data-port-side": sSide
134
+ }
135
+ });
136
+ $node.append($port);
137
+ if (bTriggerNode) {
138
+ this._setupPortEvents($port, oNode);
139
+ }
140
+ }
141
+ /**
142
+ * Removes all ports from the given node instance.
143
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
144
+ */
145
+ removePortsFromNode(oNode) {
146
+ oNode.$().find(".sapSuiteUiCommonsNetworkNodePort").remove();
147
+ this._triggerPortNodeKeys.delete(oNode.getKey());
148
+ if (this._currentTriggerNodeKey === oNode.getKey()) {
149
+ this._currentTriggerNodeKey = null;
150
+ }
151
+ }
152
+ /**
153
+ * Removes all ports from all nodes and clears tracking.
154
+ */
155
+ removeAllPorts() {
156
+ this._removeAlltriggerPorts();
157
+ this.removeInletPortsFromOtherNodes();
158
+ this.clearTriggerNodeTracking();
159
+ }
160
+ /**
161
+ * Gets the current trigger node key.
162
+ * @returns {string|null} The key of the current trigger node or null if none.
163
+ */
164
+ getCurrentTriggerNodeKey() {
165
+ return this._currentTriggerNodeKey;
166
+ }
167
+ /**
168
+ * Restores trigger ports to the previously active trigger node after rerendering.
169
+ * This should be called after graph rerendering to maintain port state.
170
+ */
171
+ restoreTriggerPorts() {
172
+ if (this._currentTriggerNodeKey && this._graphInstance) {
173
+ var oTriggerNode = this._graphInstance.getNodeByKey(this._currentTriggerNodeKey);
174
+ if (oTriggerNode) {
175
+ // Small delay to ensure DOM is ready after rerendering
176
+ setTimeout(function () {
177
+ this.addPortsToNode(oTriggerNode, true);
178
+ }.bind(this));
179
+ }
180
+ }
181
+ }
182
+ /**
183
+ * Sets up automatic restoration of trigger ports after graph rerendering.
184
+ * This method should be called once to set up the restoration mechanism.
185
+ */
186
+ setupPortRestoration() {
187
+ if (!this._graphInstance || this._restorationSetup) {
188
+ return;
189
+ }
190
+ // Listen for graph ready event to restore ports after rerendering
191
+ this._graphInstance.attachGraphReady(function () {
192
+ this.restoreTriggerPorts();
193
+ }.bind(this));
194
+ // Mark as setup to prevent duplicate handlers
195
+ this._restorationSetup = true;
196
+ }
197
+ /**
198
+ * Adds inlet ports to all nodes in the graph except the node with trigger ports.
199
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
200
+ */
201
+ addInletPortsToOtherNodes(oNode) {
202
+ var oGraph = oNode.getParent();
203
+ var sNodePorts = oNode._getNodePorts();
204
+ // Don't add inlet ports if nodePorts is "None"
205
+ if (sNodePorts === "None") {
206
+ return;
207
+ }
208
+ oGraph.getNodes().forEach(function (oOtherNode) {
209
+ const sKey = oOtherNode.getKey();
210
+ var $otherNode = oOtherNode.$();
211
+ // Skip the trigger node (node that was clicked to trigger port addition)
212
+ if (sKey === this._currentTriggerNodeKey) {
213
+ return;
214
+ }
215
+ // Skip if inlet ports already exist
216
+ if ($otherNode.find(".sapSuiteUiCommonsNetworkNodeInletPort").length > 0) {
217
+ return;
218
+ }
219
+ // Add inlet ports based on the nodePorts setting
220
+ switch (sNodePorts) {
221
+ case "All":
222
+ this._addInletPortToSide({ $node: $otherNode, sSide: "left", sKey: sKey });
223
+ this._addInletPortToSide({ $node: $otherNode, sSide: "right", sKey: sKey });
224
+ this._addInletPortToSide({ $node: $otherNode, sSide: "top", sKey: sKey });
225
+ this._addInletPortToSide({ $node: $otherNode, sSide: "bottom", sKey: sKey });
226
+ break;
227
+ case "LeftRight":
228
+ this._addInletPortToSide({ $node: $otherNode, sSide: "left", sKey: sKey });
229
+ this._addInletPortToSide({ $node: $otherNode, sSide: "right", sKey: sKey });
230
+ break;
231
+ case "TopBottom":
232
+ this._addInletPortToSide({ $node: $otherNode, sSide: "top", sKey: sKey });
233
+ this._addInletPortToSide({ $node: $otherNode, sSide: "bottom", sKey: sKey });
234
+ break;
235
+ default:
236
+ // No inlet ports to add
237
+ break;
238
+ }
239
+ }.bind(this));
240
+ }
241
+ /**
242
+ * Adds an inlet port to a specific side of the node.
243
+ * @param {Object} oConfig - Configuration object for inlet port creation.
244
+ * @param {jQuery} oConfig.$node - The node DOM element.
245
+ * @param {string} oConfig.sSide - The side to add the port to ("left", "right", "top", "bottom").
246
+ * @param {string} oConfig.sKey - The node key.
247
+ */
248
+ _addInletPortToSide(oConfig) {
249
+ var $node = oConfig.$node;
250
+ var sSide = oConfig.sSide;
251
+ var sKey = oConfig.sKey;
252
+ var sCapitalizedSide = sSide.charAt(0).toUpperCase() + sSide.slice(1);
253
+ // Build the CSS classes for inlet port
254
+ var aClasses = ["sapSuiteUiCommonsNetworkNodePort"];
255
+ aClasses.push("sapSuiteUiCommonsNetworkNodeInletPort");
256
+ aClasses.push("sapSuiteUi" + sCapitalizedSide + "InletPort");
257
+ var sPortClass = aClasses.join(" ");
258
+ var $port = this._createPort({
259
+ className: sPortClass,
260
+ attributes: {
261
+ "data-node-key": sKey,
262
+ "data-port-type": "inlet",
263
+ "data-port-side": sSide
264
+ }
265
+ });
266
+ $node.append($port);
267
+ }
268
+ /**
269
+ * Removes all inlet ports from the graph.
270
+ */
271
+ removeInletPortsFromOtherNodes() {
272
+ jQuery(".sapSuiteUiCommonsNetworkNodeInletPort").remove();
273
+ }
274
+ /**
275
+ * Removes trigger ports from the given node instance.
276
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
277
+ */
278
+ removeTriggerPortsFromNode(oNode) {
279
+ oNode.$().find(".sapSuiteUiCommonsNetworkNodeLeftTriggerPort, .sapSuiteUiCommonsNetworkNodeRightTriggerPort").remove();
280
+ this._triggerPortNodeKeys.delete(oNode.getKey());
281
+ }
282
+ /**
283
+ * Creates a port element.
284
+ * @param {Object} options - Configuration options for the port.
285
+ * @returns {jQuery} - The created port element.
286
+ */
287
+ _createPort(options) {
288
+ // Prepare accessibility attributes for trigger ports
289
+ var mAttributes = options?.attributes || {};
290
+ if (options.isAccessible) {
291
+ mAttributes.tabindex = "0";
292
+ mAttributes.role = "button";
293
+ mAttributes["aria-label"] = options.ariaLabel || ("Port on " + options.position + " side");
294
+ mAttributes["aria-describedby"] = options.ariaDescribedBy || null;
295
+ }
296
+ return jQuery("<div></div>", {
297
+ "class": options.className,
298
+ ...mAttributes
299
+ });
300
+ }
301
+ /**
302
+ * Sets up events for the given port.
303
+ * @param {jQuery} $port - The port element.
304
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
305
+ */
306
+ _setupPortEvents($port, oNode) {
307
+ $port.on("mousedown", this._onPortMouseDown.bind(this, $port, oNode));
308
+ $port.on("keydown", this._onPortKeyDown.bind(this, $port, oNode));
309
+ $port.on("focus", this._onPortFocus.bind(this, $port, oNode));
310
+ $port.on("blur", this._onPortBlur.bind(this, $port, oNode));
311
+ }
312
+ /**
313
+ * Handles keydown events on ports for accessibility navigation.
314
+ * @param {jQuery} $port - The port element.
315
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
316
+ * @param {Event} oEvent - The keydown event.
317
+ */
318
+ _onPortKeyDown($port, oNode, oEvent) {
319
+ var iKeyCode = oEvent.keyCode || oEvent.which;
320
+ // Shift+Tab key - Return focus to node (standard backward navigation)
321
+ if (iKeyCode === 9 && oEvent.shiftKey) { // Tab key with Shift
322
+ oEvent.preventDefault();
323
+ oEvent.stopPropagation();
324
+ this._returnFocusToNode(oNode);
325
+ return;
326
+ }
327
+ // Enter key - Log port click
328
+ if (iKeyCode === 13) { // KeyCodes.ENTER
329
+ oEvent.preventDefault();
330
+ oEvent.stopPropagation();
331
+ // Get port information
332
+ var sSide = $port.attr("data-port-side");
333
+ var sNodeKey = $port.attr("data-node-key");
334
+ var sPortType = $port.attr("data-port-type");
335
+ // Use the Graph's accessibility system to announce port details
336
+ var oGraph = oNode.getParent();
337
+ if (oGraph && oGraph._setAccessibilityTitle) {
338
+ var sNodeLabel = oNode._getAccessibilityLabel(oGraph);
339
+ var sPortInfo = sNodeLabel + " " + sPortType + " port on " + sSide + " side. Node key: " + sNodeKey + ".";
340
+ oGraph._setAccessibilityTitle(sPortInfo);
341
+ }
342
+ return;
343
+ }
344
+ }
345
+ /**
346
+ * Handles focus events on ports.
347
+ * @param {jQuery} $port - The port element.
348
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
349
+ * @param {Event} oEvent - The focus event.
350
+ */
351
+ _onPortFocus($port, oNode, oEvent) {
352
+ // Add visual focus indicator using SAP standard focus class
353
+ $port.addClass("sapMFocused");
354
+ // Use the Graph's accessibility system instead of our own announcements
355
+ var oGraph = oNode.getParent();
356
+ if (oGraph && oGraph._setAccessibilityTitle) {
357
+ var sNodeLabel = oNode._getAccessibilityLabel(oGraph);
358
+ var sSide = $port.attr("data-port-side");
359
+ var sPortLabel = sNodeLabel + " " + sSide + " port focused. Press Enter for details, Space for connection, Shift+Tab to return to node.";
360
+ oGraph._setAccessibilityTitle(sPortLabel);
361
+ }
362
+ }
363
+ /**
364
+ * Handles blur events on ports.
365
+ * @param {jQuery} $port - The port element.
366
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
367
+ * @param {Event} oEvent - The blur event.
368
+ */
369
+ _onPortBlur($port, oNode, oEvent) {
370
+ // Remove visual focus indicator
371
+ $port.removeClass("sapMFocused");
372
+ }
373
+ /**
374
+ * Returns focus to the node from a port.
375
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
376
+ */
377
+ _returnFocusToNode(oNode) {
378
+ // First, remove focus from any currently focused port
379
+ var $currentPort = jQuery(document.activeElement);
380
+ if ($currentPort.hasClass("sapSuiteUiCommonsNetworkNodePort")) {
381
+ $currentPort.blur();
382
+ $currentPort.removeClass("sapMFocused");
383
+ }
384
+ // Restore the Graph's focus state to the node (like Tab key behavior)
385
+ var oGraph = oNode.getParent();
386
+ if (oGraph) {
387
+ oGraph.setFocus({
388
+ item: oNode,
389
+ button: null
390
+ });
391
+ // Use the Graph's accessibility system to announce the return
392
+ if (oGraph._setAccessibilityTitle) {
393
+ var sNodeLabel = oNode._getAccessibilityLabel(oGraph);
394
+ var sReturnLabel = sNodeLabel + " Use Shift+Arrow keys to navigate to ports.";
395
+ oGraph._setAccessibilityTitle(sReturnLabel);
396
+ }
397
+ }
398
+ // Focus the node wrapper or node itself
399
+ var $focusTarget = oNode.$("wrapper");
400
+ if (!$focusTarget || $focusTarget.length === 0) {
401
+ $focusTarget = oNode.$();
402
+ }
403
+ if ($focusTarget && $focusTarget.length > 0) {
404
+ $focusTarget.focus();
405
+ }
406
+ }
407
+ /**
408
+ * Handles the mousedown event for a port.
409
+ * @param {jQuery} $port - The port element.
410
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
411
+ * @param {Event} e - The event object.
412
+ */
413
+ _onPortMouseDown($port, oNode, e) {
414
+ e.stopPropagation();
415
+ e.preventDefault();
416
+ // Create ghost port using CSS classes
417
+ var $ghostPort = jQuery("<div></div>", {
418
+ "class": "sapSuiteUiCommonsNetworkNodeGhostArrow",
419
+ "style": "position: absolute; width: 13px; height: 19px;"
420
+ });
421
+ jQuery("body").append($ghostPort);
422
+ // Create ghost line using CSS classes
423
+ var $ghostLine = jQuery("<div></div>", {
424
+ "class": "sapSuiteUiCommonsNetworkNodeGhostLine"
425
+ });
426
+ jQuery("body").append($ghostLine);
427
+ var startRect = $port[0].getBoundingClientRect();
428
+ var startX = startRect.left + startRect.width / 2;
429
+ var startY = startRect.top + startRect.height / 2;
430
+ $ghostPort.css({ left: startX + "px", top: startY + "px" });
431
+ // Bind mousemove and mouseup events
432
+ var onMouseMove = this._onPortMouseMove.bind(this, $ghostPort, $ghostLine, startX, startY, oNode);
433
+ var onMouseUp = this._onPortMouseUp.bind(this, $ghostPort, $ghostLine, $port, oNode);
434
+ jQuery(document).on("mousemove", onMouseMove);
435
+ jQuery(document).on("mouseup", onMouseUp);
436
+ }
437
+ /**
438
+ * Handles the mousemove event for a port.
439
+ * @param {jQuery} $ghostPort - The ghost port element.
440
+ * @param {jQuery} $ghostLine - The ghost line element.
441
+ * @param {number} startX - The starting X coordinate.
442
+ * @param {number} startY - The starting Y coordinate.
443
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
444
+ * @param {Event} moveEvent - The event object.
445
+ */
446
+ _onPortMouseMove($ghostPort, $ghostLine, startX, startY, oNode, moveEvent) {
447
+ // Center the ghost port on the cursor by offsetting by half its dimensions
448
+ var ghostPortWidth = 10; // Default port width
449
+ var ghostPortHeight = 10; // Default port height
450
+ $ghostPort.css({
451
+ left: (moveEvent.clientX - ghostPortWidth / 2) + "px",
452
+ top: (moveEvent.clientY - ghostPortHeight / 2) + "px"
453
+ });
454
+ var length = Math.sqrt(Math.pow(moveEvent.clientX - startX, 2) + Math.pow(moveEvent.clientY - startY, 2));
455
+ var angle = Math.atan2(moveEvent.clientY - startY, moveEvent.clientX - startX) * 180 / Math.PI;
456
+ $ghostLine.css({
457
+ width: length + "px",
458
+ left: startX + "px",
459
+ top: startY + "px",
460
+ transform: `rotate(${angle}deg)`,
461
+ transformOrigin: "0 0"
462
+ });
463
+ // Add inlet ports to other nodes
464
+ this.addInletPortsToOtherNodes(oNode);
465
+ }
466
+ /**
467
+ * Handles the mouseup event for a port.
468
+ * @param {jQuery} $ghostPort - The ghost port element.
469
+ * @param {jQuery} $ghostLine - The ghost line element.
470
+ * @param {jQuery} $port - The port element.
471
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
472
+ * @param {Event} mouseUpEvent - The event object.
473
+ */
474
+ _onPortMouseUp($ghostPort, $ghostLine, $port, oNode, mouseUpEvent) {
475
+ jQuery(document).off("mousemove");
476
+ jQuery(document).off("mouseup");
477
+ $ghostPort.remove();
478
+ $ghostLine.remove();
479
+ const target = mouseUpEvent?.target?.closest('.sapSuiteUiCommonsNetworkNodeInletPort');
480
+ if (target) {
481
+ // get the source node and target node
482
+ const sourceNode = oNode;
483
+ const targetNode = sourceNode?.getParent()?.getNodeByKey(target.dataset.nodeKey);
484
+ // Get the source and target port sides
485
+ const sourcePortSide = $port.data("portSide");
486
+ const targetPortSide = target.dataset.portSide;
487
+ // Check if the target node is valid
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;
494
+ const mParameters = {
495
+ from: sourceNode.getKey(),
496
+ to: targetNode.getKey(),
497
+ connectionType: this._getConnectionType(sourcePortSide, targetPortSide),
498
+ fromNode: sourceNode,
499
+ toNode: targetNode
500
+ };
501
+ // Fire the connectionCreated event
502
+ oGraph.fireConnectionCreated(mParameters);
503
+
504
+ // Preserve scroll position after event
505
+ Utils.preserveScrollPosition(oGraph, currentScrollLeft, currentScrollTop, 0);
506
+ }
507
+ }
508
+ // Remove inlet ports from other nodes
509
+ this.removeInletPortsFromOtherNodes();
510
+ }
511
+ /**
512
+ * Navigates to a port based on direction when Space + Arrow is pressed on a node.
513
+ * @param {sap.suite.ui.commons.networkgraph.Node} oNode - The node instance.
514
+ * @param {string} sDirection - The direction (left, right, up, down).
515
+ * @returns {boolean} True if navigation was successful, false otherwise.
516
+ */
517
+ navigateToPortFromNode(oNode, sDirection) {
518
+ // Check if this node has trigger ports
519
+ if (this._currentTriggerNodeKey !== oNode.getKey()) {
520
+ return false;
521
+ }
522
+ // Map direction to port side
523
+ var sPortSide;
524
+ switch (sDirection) {
525
+ case "left":
526
+ sPortSide = "left";
527
+ break;
528
+ case "right":
529
+ sPortSide = "right";
530
+ break;
531
+ case "up":
532
+ sPortSide = "top";
533
+ break;
534
+ case "down":
535
+ sPortSide = "bottom";
536
+ break;
537
+ default:
538
+ return false;
539
+ }
540
+ // Find the port element
541
+ var $port = oNode.$().find('.sapSuiteUiCommonsNetworkNodeTriggerPort[data-port-side="' + sPortSide + '"]');
542
+ if ($port.length === 0) {
543
+ return false;
544
+ }
545
+ // Focus the port (Graph focus already cleared by KeyboardNavigator)
546
+ $port.focus();
547
+ return true;
548
+ }
549
+ /**
550
+ * Clears the current trigger node tracking.
551
+ * This can be called when ports should no longer be restored.
552
+ */
553
+ clearTriggerNodeTracking() {
554
+ this._currentTriggerNodeKey = null;
555
+ }
556
+
557
+ _getConnectionType(sSourcePortSide, sTargetPortSide) {
558
+ if (sSourcePortSide === "left" && sTargetPortSide === "right") {
559
+ return PortManager._oConnectionType.LeftToRight;
560
+ } else if (sSourcePortSide === "right" && sTargetPortSide === "left") {
561
+ return PortManager._oConnectionType.RightToLeft;
562
+ } else if (sSourcePortSide === "left" && sTargetPortSide === "left") {
563
+ return PortManager._oConnectionType.LeftToLeft;
564
+ } else if (sSourcePortSide === "right" && sTargetPortSide === "right") {
565
+ return PortManager._oConnectionType.RightToRight;
566
+ }
567
+ return PortManager._oConnectionType.RightToLeft; // Default case
568
+ }
569
+
570
+ _removeAlltriggerPorts() {
571
+ jQuery(".sapSuiteUiCommonsNetworkNodePort").remove();
572
+ this._triggerPortNodeKeys.clear();
573
+ this.clearTriggerNodeTracking();
574
+ }
575
+ }
576
+ // Singleton instance
577
+ let portManagerInstance = null;
578
+ if (!portManagerInstance) {
579
+ portManagerInstance = new PortManager();
580
+ }
581
+ return portManagerInstance;
582
+ });
@@ -30,7 +30,7 @@ sap.ui.define([
30
30
  * @extends sap.suite.ui.commons.statusindicator.SimpleShape
31
31
  *
32
32
  * @author SAP SE
33
- * @version 1.136.12
33
+ * @version 1.136.13
34
34
  * @since 1.50
35
35
  *
36
36
  * @constructor
@@ -36,7 +36,7 @@ sap.ui.define([
36
36
  * @extends sap.suite.ui.commons.statusindicator.Shape
37
37
  *
38
38
  * @author SAP SE
39
- * @version 1.136.12
39
+ * @version 1.136.13
40
40
  * @since 1.50
41
41
  *
42
42
  * @constructor
@@ -21,7 +21,7 @@ sap.ui.define([
21
21
  * @extends sap.ui.core.Control
22
22
  *
23
23
  * @author SAP SE
24
- * @version 1.136.12
24
+ * @version 1.136.13
25
25
  * @since 1.50
26
26
  *
27
27
  * @constructor
@@ -23,7 +23,7 @@ sap.ui.define([
23
23
  * @extends sap.ui.core.Control
24
24
  *
25
25
  * @author SAP SE
26
- * @version 1.136.12
26
+ * @version 1.136.13
27
27
  * @since 1.50
28
28
  *
29
29
  * @constructor
@@ -23,7 +23,7 @@ sap.ui.define([
23
23
  * @extends sap.suite.ui.commons.statusindicator.CustomShape
24
24
  *
25
25
  * @author SAP SE
26
- * @version 1.136.12
26
+ * @version 1.136.13
27
27
  * @since 1.60.0
28
28
  *
29
29
  * @constructor
@@ -29,7 +29,7 @@ sap.ui.define([
29
29
  * @extends sap.suite.ui.commons.statusindicator.SimpleShape
30
30
  *
31
31
  * @author SAP SE
32
- * @version 1.136.12
32
+ * @version 1.136.13
33
33
  * @since 1.50
34
34
  *
35
35
  * @constructor
@@ -28,7 +28,7 @@ sap.ui.define([
28
28
  * @extends sap.ui.core.Control
29
29
  *
30
30
  * @author SAP SE
31
- * @version 1.136.12
31
+ * @version 1.136.13
32
32
  * @since 1.50
33
33
  *
34
34
  * @constructor
@@ -29,7 +29,7 @@ sap.ui.define(
29
29
  * @extends sap.suite.ui.commons.statusindicator.SimpleShape
30
30
  *
31
31
  * @author SAP SE
32
- * @version 1.136.12
32
+ * @version 1.136.13
33
33
  * @since 1.50
34
34
  *
35
35
  * @constructor
@@ -42,7 +42,7 @@ sap.ui.define([
42
42
  * @extends sap.ui.core.Control
43
43
  *
44
44
  * @author SAP SE
45
- * @version 1.136.12
45
+ * @version 1.136.13
46
46
  * @since 1.50
47
47
  *
48
48
  * @constructor
@@ -30,7 +30,7 @@ sap.ui.define([
30
30
  * @extends sap.ui.core.Control
31
31
  *
32
32
  * @author SAP SE
33
- * @version 1.136.12
33
+ * @version 1.136.13
34
34
  * @since 1.50
35
35
  *
36
36
  * @constructor