@sapui5/sap.suite.ui.commons 1.136.11 → 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.
- 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 +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderExpression.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderFunction.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderGroup.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderItem.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderValidationResult.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderVariable.js +1 -1
- package/src/sap/suite/ui/commons/CloudFilePicker.js +1 -1
- package/src/sap/suite/ui/commons/MicroProcessFlow.js +1 -1
- package/src/sap/suite/ui/commons/MicroProcessFlowItem.js +1 -1
- package/src/sap/suite/ui/commons/TimelineRenderManager.js +8 -4
- 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 +100 -3
- package/src/sap/suite/ui/commons/messagebundle.properties +73 -12
- package/src/sap/suite/ui/commons/messagebundle_ar.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_en_US_saprigi.properties +39 -5
- package/src/sap/suite/ui/commons/messagebundle_fr_CA.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_hu.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_id.properties +2 -2
- package/src/sap/suite/ui/commons/messagebundle_it.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_pt.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_ru.properties +1 -1
- package/src/sap/suite/ui/commons/networkgraph/ElementBase.js +19 -1
- package/src/sap/suite/ui/commons/networkgraph/Graph.js +590 -48
- package/src/sap/suite/ui/commons/networkgraph/GraphMap.js +25 -3
- package/src/sap/suite/ui/commons/networkgraph/GraphRenderer.js +19 -8
- package/src/sap/suite/ui/commons/networkgraph/KeyboardNavigator.js +367 -12
- package/src/sap/suite/ui/commons/networkgraph/Line.js +814 -22
- package/src/sap/suite/ui/commons/networkgraph/Node.js +573 -79
- package/src/sap/suite/ui/commons/networkgraph/Tooltip.js +4 -0
- package/src/sap/suite/ui/commons/networkgraph/Utils.js +249 -10
- package/src/sap/suite/ui/commons/networkgraph/layout/NoopLayout.js +77 -7
- package/src/sap/suite/ui/commons/networkgraph/util/ConnectionPathUtils.js +1174 -0
- package/src/sap/suite/ui/commons/networkgraph/util/CreateConnectionPopover.js +374 -0
- package/src/sap/suite/ui/commons/networkgraph/util/DependencyLayoutHelper.js +1017 -0
- package/src/sap/suite/ui/commons/networkgraph/util/DragDropManager.js +721 -0
- package/src/sap/suite/ui/commons/networkgraph/util/PortManager.js +582 -0
- 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/NetworkGraph.less +26 -13
- package/src/sap/suite/ui/commons/themes/base/NetworkGroup.less +4 -0
- package/src/sap/suite/ui/commons/themes/base/NetworkLine.less +58 -13
- package/src/sap/suite/ui/commons/themes/base/NetworkNode.less +251 -47
- package/src/sap/suite/ui/commons/themes/base/SemanticColorMixins.less +55 -0
|
@@ -0,0 +1,721 @@
|
|
|
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/core/dnd/DragInfo",
|
|
9
|
+
"sap/ui/core/dnd/DropInfo",
|
|
10
|
+
"sap/base/Log",
|
|
11
|
+
"sap/suite/ui/commons/networkgraph/Utils"
|
|
12
|
+
], function (DragInfo, DropInfo, Log, Utils) {
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
15
|
+
// constants
|
|
16
|
+
const RESIZE_CONFIG = {
|
|
17
|
+
WIDTH_INCREMENT: 150,
|
|
18
|
+
HEIGHT_INCREMENT: 150,
|
|
19
|
+
PROXIMITY_THRESHOLD: 50, // TODO: update according to figma take node's width /height into consideration
|
|
20
|
+
RESIZE_DEBOUNCE_DELAY: 150,
|
|
21
|
+
// Auto-scroll configuration
|
|
22
|
+
AUTO_SCROLL_THRESHOLD: 50, // Distance from scroller edge to trigger auto-scroll
|
|
23
|
+
AUTO_SCROLL_SPEED: 10, // Pixels to scroll per frame (16ms)
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Minimum position offsets to ensure action buttons remain visible.
|
|
28
|
+
* LEFT: 60px accounts for line and port
|
|
29
|
+
* TOP: 40px accounts for top action buttons (-2.25rem ≈ 36px) plus margin
|
|
30
|
+
*/
|
|
31
|
+
const POSITION_CLAMP_OFFSET = {
|
|
32
|
+
LEFT: 60,
|
|
33
|
+
TOP: 40
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Instance object: Only one will exist
|
|
37
|
+
var instance = null;
|
|
38
|
+
var sDragSessionKey = "networkGraphDragSession";
|
|
39
|
+
var oUtilityFunctions = {
|
|
40
|
+
diff: function (a, b) {
|
|
41
|
+
return Math.abs(a - b);
|
|
42
|
+
},
|
|
43
|
+
clampPosition: function (x, y) {
|
|
44
|
+
/**
|
|
45
|
+
* Clamps position coordinates to minimum thresholds.
|
|
46
|
+
* Prevents nodes from being positioned where action buttons would be off-screen.
|
|
47
|
+
*/
|
|
48
|
+
return {
|
|
49
|
+
x: Math.max(POSITION_CLAMP_OFFSET.LEFT, x),
|
|
50
|
+
y: Math.max(POSITION_CLAMP_OFFSET.TOP, y)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Constructor for DragDropManager.
|
|
57
|
+
* This class is for internal use only
|
|
58
|
+
*
|
|
59
|
+
* @class
|
|
60
|
+
* Manages drag and drop functionality for network graph components.
|
|
61
|
+
* This class handles drag start, drag end, drag over, and drop events
|
|
62
|
+
* for both Graph and Node controls in the network graph library.
|
|
63
|
+
*
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
function DragDropManager() {
|
|
67
|
+
this.bIsDragging = false;
|
|
68
|
+
this._iWidthResizeDebounceTimeout = null;
|
|
69
|
+
this._iHeightResizeDebounceTimeout = null;
|
|
70
|
+
this._iRequestAnimationFrameId = null;
|
|
71
|
+
this._iLastWidthResizeTime = 0;
|
|
72
|
+
this._iLastHeightResizeTime = 0;
|
|
73
|
+
// Auto-scroll state
|
|
74
|
+
this._iAutoScrollIntervalId = null;
|
|
75
|
+
this._oAutoScrollDirection = { x: 0, y: 0 };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Debounced function to resize the inner scroller width when dragging near right edge.
|
|
80
|
+
* Uses debouncing to prevent excessive resize operations during drag operations.
|
|
81
|
+
*
|
|
82
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
83
|
+
* @param {number} incrementBy - The amount in pixels to increment the width
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
DragDropManager.prototype._resizeInnerScrollerWidth = function (oGraph, incrementBy) {
|
|
87
|
+
const currentTime = Date.now();
|
|
88
|
+
|
|
89
|
+
// Clear any existing timeout
|
|
90
|
+
if (this._iWidthResizeDebounceTimeout) {
|
|
91
|
+
clearTimeout(this._iWidthResizeDebounceTimeout);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// If enough time has passed since last resize, execute immediately
|
|
95
|
+
if (currentTime - this._iLastWidthResizeTime > RESIZE_CONFIG.RESIZE_DEBOUNCE_DELAY) {
|
|
96
|
+
this._executeWidthResize(oGraph, incrementBy);
|
|
97
|
+
this._iLastWidthResizeTime = currentTime;
|
|
98
|
+
} else {
|
|
99
|
+
// Otherwise, debounce the call
|
|
100
|
+
this._iWidthResizeDebounceTimeout = setTimeout(() => {
|
|
101
|
+
this._executeWidthResize(oGraph, incrementBy);
|
|
102
|
+
this._iLastWidthResizeTime = Date.now();
|
|
103
|
+
this._iWidthResizeDebounceTimeout = null;
|
|
104
|
+
}, RESIZE_CONFIG.RESIZE_DEBOUNCE_DELAY);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Executes the actual width resize in the DOM.
|
|
110
|
+
* Forces a reflow and updates the width-related CSS properties of the inner scroller.
|
|
111
|
+
*
|
|
112
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
113
|
+
* @param {number} incrementBy - The amount in pixels to increment the width
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
DragDropManager.prototype._executeWidthResize = function (oGraph, incrementBy) {
|
|
117
|
+
// Guard check: Ensure graph and css for innerscroller exist before proceeding
|
|
118
|
+
if (!oGraph || !oGraph._$innerscroller || !oGraph._$innerscroller.css) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Force a reflow to get the most current width
|
|
124
|
+
* When you read a calculated property like clientHeight, offsetWidth etc.,
|
|
125
|
+
* the browser has to pause the JavaScript code and reflow the page so it can return an accurate number.”
|
|
126
|
+
**/
|
|
127
|
+
oGraph._$innerscroller[0].offsetWidth;
|
|
128
|
+
|
|
129
|
+
const currentWidth = parseFloat(oGraph._$innerscroller.css("width")) ||
|
|
130
|
+
oGraph._$innerscroller[0].getBoundingClientRect().width;
|
|
131
|
+
const newWidth = currentWidth + incrementBy;
|
|
132
|
+
|
|
133
|
+
oGraph._$innerscroller[0].style.setProperty("width", newWidth + "px");
|
|
134
|
+
oGraph._$innerscroller[0].style.setProperty("min-width", newWidth + "px");
|
|
135
|
+
oGraph._$innerscroller[0].style.setProperty("max-width", "none");
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Debounced function to resize the inner scroller height when dragging near bottom edge.
|
|
140
|
+
* Uses debouncing to prevent excessive resize operations during drag operations.
|
|
141
|
+
*
|
|
142
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
143
|
+
* @param {number} incrementBy - The amount in pixels to increment the height
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
DragDropManager.prototype._resizeInnerScrollerHeight = function (oGraph, incrementBy) {
|
|
147
|
+
const currentTime = Date.now();
|
|
148
|
+
|
|
149
|
+
// Clear any existing timeout
|
|
150
|
+
if (this._iHeightResizeDebounceTimeout) {
|
|
151
|
+
clearTimeout(this._iHeightResizeDebounceTimeout);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// If enough time has passed since last resize, execute immediately
|
|
155
|
+
if (currentTime - this._iLastHeightResizeTime > RESIZE_CONFIG.RESIZE_DEBOUNCE_DELAY) {
|
|
156
|
+
this._executeHeightResize(oGraph, incrementBy);
|
|
157
|
+
this._iLastHeightResizeTime = currentTime;
|
|
158
|
+
} else {
|
|
159
|
+
// Otherwise, debounce the call
|
|
160
|
+
this._iHeightResizeDebounceTimeout = setTimeout(() => {
|
|
161
|
+
this._executeHeightResize(oGraph, incrementBy);
|
|
162
|
+
this._iLastHeightResizeTime = Date.now();
|
|
163
|
+
this._iHeightResizeDebounceTimeout = null;
|
|
164
|
+
}, RESIZE_CONFIG.RESIZE_DEBOUNCE_DELAY);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Executes the actual height resize in the DOM.
|
|
170
|
+
* Forces a reflow and updates the height-related CSS properties of the inner scroller.
|
|
171
|
+
*
|
|
172
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
173
|
+
* @param {number} incrementBy - The amount in pixels to increment the height
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
DragDropManager.prototype._executeHeightResize = function (oGraph, incrementBy) {
|
|
177
|
+
// Guard check: Ensure graph and css for innerscroller exist before proceeding
|
|
178
|
+
if (!oGraph || !oGraph._$innerscroller || !oGraph._$innerscroller.css) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Force a reflow to get the most current height
|
|
183
|
+
oGraph._$innerscroller[0].offsetHeight;
|
|
184
|
+
|
|
185
|
+
const currentHeight = parseFloat(oGraph._$innerscroller.css("height")) ||
|
|
186
|
+
oGraph._$innerscroller[0].getBoundingClientRect().height;
|
|
187
|
+
const newHeight = currentHeight + incrementBy;
|
|
188
|
+
|
|
189
|
+
oGraph._$innerscroller[0].style.setProperty("height", newHeight + "px");
|
|
190
|
+
oGraph._$innerscroller[0].style.setProperty("min-height", newHeight + "px");
|
|
191
|
+
oGraph._$innerscroller[0].style.setProperty("max-height", "none");
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Checks if the scroller can scroll in the given direction.
|
|
196
|
+
*
|
|
197
|
+
* @param {HTMLElement} scrollerElement - The scroller DOM element
|
|
198
|
+
* @param {string} direction - Direction to check: 'up', 'down', 'left', 'right'
|
|
199
|
+
* @returns {boolean} True if scrolling is possible in that direction
|
|
200
|
+
* @private
|
|
201
|
+
*/
|
|
202
|
+
DragDropManager.prototype._canScroll = function (scrollerElement, direction) {
|
|
203
|
+
if (!scrollerElement) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
switch (direction) {
|
|
208
|
+
case 'up':
|
|
209
|
+
return scrollerElement.scrollTop > 0;
|
|
210
|
+
case 'down':
|
|
211
|
+
return scrollerElement.scrollTop < (scrollerElement.scrollHeight - scrollerElement.clientHeight);
|
|
212
|
+
case 'left':
|
|
213
|
+
return scrollerElement.scrollLeft > 0;
|
|
214
|
+
case 'right':
|
|
215
|
+
return scrollerElement.scrollLeft < (scrollerElement.scrollWidth - scrollerElement.clientWidth);
|
|
216
|
+
default:
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Starts or updates auto-scrolling of the viewport.
|
|
223
|
+
*
|
|
224
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
225
|
+
* @param {number} scrollX - Horizontal scroll direction (-1: left, 0: none, 1: right)
|
|
226
|
+
* @param {number} scrollY - Vertical scroll direction (-1: up, 0: none, 1: down)
|
|
227
|
+
* @private
|
|
228
|
+
*/
|
|
229
|
+
DragDropManager.prototype._startAutoScroll = function (oGraph, scrollX, scrollY) {
|
|
230
|
+
// Update scroll direction
|
|
231
|
+
this._oAutoScrollDirection = { x: scrollX, y: scrollY };
|
|
232
|
+
|
|
233
|
+
// If already scrolling, direction is updated, no need to restart interval
|
|
234
|
+
if (this._iAutoScrollIntervalId) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Start auto-scroll loop at ~60fps
|
|
239
|
+
this._iAutoScrollIntervalId = setInterval(() => {
|
|
240
|
+
if (!this.bIsDragging) {
|
|
241
|
+
this._stopAutoScroll();
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const scrollerElement = oGraph.$scroller?.[0];
|
|
246
|
+
if (!scrollerElement) {
|
|
247
|
+
this._stopAutoScroll();
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Apply scrolling
|
|
252
|
+
if (this._oAutoScrollDirection.x !== 0) {
|
|
253
|
+
scrollerElement.scrollLeft += this._oAutoScrollDirection.x * RESIZE_CONFIG.AUTO_SCROLL_SPEED;
|
|
254
|
+
}
|
|
255
|
+
if (this._oAutoScrollDirection.y !== 0) {
|
|
256
|
+
scrollerElement.scrollTop += this._oAutoScrollDirection.y * RESIZE_CONFIG.AUTO_SCROLL_SPEED;
|
|
257
|
+
}
|
|
258
|
+
}, 16); // ~60fps
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Stops auto-scrolling.
|
|
263
|
+
* @private
|
|
264
|
+
*/
|
|
265
|
+
DragDropManager.prototype._stopAutoScroll = function () {
|
|
266
|
+
if (this._iAutoScrollIntervalId) {
|
|
267
|
+
clearInterval(this._iAutoScrollIntervalId);
|
|
268
|
+
this._iAutoScrollIntervalId = null;
|
|
269
|
+
}
|
|
270
|
+
this._oAutoScrollDirection = { x: 0, y: 0 };
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Validates if the given control is supported for drag and drop operations.
|
|
275
|
+
* Checks if the control is a valid Graph or Node instance.
|
|
276
|
+
*
|
|
277
|
+
* @param {object} oControl - The control to validate
|
|
278
|
+
* @returns {boolean} True if the control is eligible for drag and drop, otherwise false
|
|
279
|
+
* @private
|
|
280
|
+
*/
|
|
281
|
+
DragDropManager.prototype.isValidControl = function (oControl) {
|
|
282
|
+
if (!oControl || typeof oControl !== 'object') {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Check if it's an empty object
|
|
287
|
+
if (Object.keys(oControl).length === 0 && oControl.constructor === Object) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Check if it has the required isA method
|
|
292
|
+
if (typeof oControl.isA !== 'function') {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return oControl.isA("sap.suite.ui.commons.networkgraph.Graph") ||
|
|
297
|
+
oControl.isA("sap.suite.ui.commons.networkgraph.Node");
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Handles the drag start event for nodes.
|
|
302
|
+
*
|
|
303
|
+
* @param {sap.ui.base.Event} oEvent - The drag start event handler
|
|
304
|
+
* @private
|
|
305
|
+
*/
|
|
306
|
+
DragDropManager.prototype._handleDragStart = function (oEvent) {
|
|
307
|
+
let dragSession = oEvent.getParameter("dragSession");
|
|
308
|
+
let browserEvent = oEvent.getParameter("browserEvent");
|
|
309
|
+
let oGraph = oEvent.getParameter("target")?.getParent();
|
|
310
|
+
let oNode = oEvent.getParameter("target");
|
|
311
|
+
let boundingRectScroller = oGraph?.$scroller?.[0]?.getBoundingClientRect() || { x: 0, y: 0 };
|
|
312
|
+
let boundingRectInnerScroller = oGraph?._$innerscroller?.[0]?.getBoundingClientRect() || { x: 0, y: 0 };
|
|
313
|
+
|
|
314
|
+
// Capture initial scroll positions
|
|
315
|
+
let scrollLeft = oGraph?._$innerscroller?.[0]?.scrollLeft || 0;
|
|
316
|
+
let scrollTop = oGraph?._$innerscroller?.[0]?.scrollTop || 0;
|
|
317
|
+
this.bIsDragging = true;
|
|
318
|
+
|
|
319
|
+
// Stop any existing auto-scroll from previous drag operations
|
|
320
|
+
this._stopAutoScroll();
|
|
321
|
+
|
|
322
|
+
// Create custom drag image that includes the border
|
|
323
|
+
this._oDragImageNode = Utils.createCustomDragImage(oNode, browserEvent);
|
|
324
|
+
|
|
325
|
+
dragSession.setComplexData(sDragSessionKey, {
|
|
326
|
+
// Mouse cursor position when drag starts (in viewport coordinates)
|
|
327
|
+
cursorX: browserEvent.clientX,
|
|
328
|
+
cursorY: browserEvent.clientY,
|
|
329
|
+
// Position of the inner scroller container when drag starts (relative to viewport)
|
|
330
|
+
// This changes if the graph content is scrolled during drag
|
|
331
|
+
innerScrollerX: boundingRectInnerScroller.x,
|
|
332
|
+
innerScrollerY: boundingRectInnerScroller.y,
|
|
333
|
+
// Position of the outer scroller container when drag starts (relative to viewport)
|
|
334
|
+
// This is usually stable but included for completeness
|
|
335
|
+
scrollerX: boundingRectScroller.x,
|
|
336
|
+
scrollerY: boundingRectScroller.y,
|
|
337
|
+
// How much the graph content was already scrolled when drag starts
|
|
338
|
+
// Used to maintain scroll position after drop to prevent viewport jumping
|
|
339
|
+
initialScrollLeft: scrollLeft,
|
|
340
|
+
initialScrollTop: scrollTop
|
|
341
|
+
});
|
|
342
|
+
this._iRequestAnimationFrameId && cancelAnimationFrame(this._iRequestAnimationFrameId);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Handles the drag end event for nodes.
|
|
347
|
+
*
|
|
348
|
+
* @param {sap.ui.base.Event} oEvent - The drag End event handler
|
|
349
|
+
* @private
|
|
350
|
+
*/
|
|
351
|
+
DragDropManager.prototype._handleDragEnd = function (oEvent) {
|
|
352
|
+
if (!this._validateEvent(oEvent)) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Stop auto-scrolling when drag ends
|
|
357
|
+
this._stopAutoScroll();
|
|
358
|
+
|
|
359
|
+
// Clean up the drag image node
|
|
360
|
+
if (this._oDragImageNode && this._oDragImageNode.parentNode) {
|
|
361
|
+
this._oDragImageNode.parentNode.removeChild(this._oDragImageNode);
|
|
362
|
+
this._oDragImageNode = null;
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Handles the drag over event for nodes.
|
|
368
|
+
*
|
|
369
|
+
* @param {sap.ui.base.Event} oEvent - The drag over event handler
|
|
370
|
+
* @private
|
|
371
|
+
*/
|
|
372
|
+
DragDropManager.prototype._handleDragOver = function (oEvent) {
|
|
373
|
+
if (!this.bIsDragging) {
|
|
374
|
+
// not dragging - skip dragover handling
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (!this._validateEvent(oEvent)) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const oGraph = oEvent.getParameter("target");
|
|
382
|
+
const oBrowserEvent = oEvent.getParameter("browserEvent");
|
|
383
|
+
const oScrollerElement = oGraph?.$scroller?.[0];
|
|
384
|
+
const oInnerScrollerElement = oGraph?._$innerscroller?.[0];
|
|
385
|
+
|
|
386
|
+
if (!oScrollerElement || !oInnerScrollerElement) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Get cursor position
|
|
391
|
+
const iCursorX = oBrowserEvent?.clientX;
|
|
392
|
+
const iCursorY = oBrowserEvent?.clientY;
|
|
393
|
+
|
|
394
|
+
// Get scroller's bounding rect to know viewport edges
|
|
395
|
+
const oScrollerRect = oScrollerElement.getBoundingClientRect();
|
|
396
|
+
|
|
397
|
+
// ========================================
|
|
398
|
+
// AUTO-SCROLL LOGIC (Decision Tree)
|
|
399
|
+
// ========================================
|
|
400
|
+
|
|
401
|
+
let scrollX = 0;
|
|
402
|
+
let scrollY = 0;
|
|
403
|
+
|
|
404
|
+
// Check horizontal auto-scroll
|
|
405
|
+
const distanceFromScrollerLeft = iCursorX - oScrollerRect.left;
|
|
406
|
+
const distanceFromScrollerRight = oScrollerRect.right - iCursorX;
|
|
407
|
+
|
|
408
|
+
if (distanceFromScrollerRight <= RESIZE_CONFIG.AUTO_SCROLL_THRESHOLD &&
|
|
409
|
+
this._canScroll(oScrollerElement, 'right')) {
|
|
410
|
+
scrollX = 1; // Scroll right
|
|
411
|
+
} else if (distanceFromScrollerLeft <= RESIZE_CONFIG.AUTO_SCROLL_THRESHOLD &&
|
|
412
|
+
this._canScroll(oScrollerElement, 'left')) {
|
|
413
|
+
scrollX = -1; // Scroll left
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Check vertical auto-scroll
|
|
417
|
+
const distanceFromScrollerTop = iCursorY - oScrollerRect.top;
|
|
418
|
+
const distanceFromScrollerBottom = oScrollerRect.bottom - iCursorY;
|
|
419
|
+
|
|
420
|
+
if (distanceFromScrollerBottom <= RESIZE_CONFIG.AUTO_SCROLL_THRESHOLD &&
|
|
421
|
+
this._canScroll(oScrollerElement, 'down')) {
|
|
422
|
+
scrollY = 1; // Scroll down
|
|
423
|
+
} else if (distanceFromScrollerTop <= RESIZE_CONFIG.AUTO_SCROLL_THRESHOLD &&
|
|
424
|
+
this._canScroll(oScrollerElement, 'up')) {
|
|
425
|
+
scrollY = -1; // Scroll up
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Start/update/stop auto-scroll based on calculated direction
|
|
429
|
+
if (scrollX !== 0 || scrollY !== 0) {
|
|
430
|
+
this._startAutoScroll(oGraph, scrollX, scrollY);
|
|
431
|
+
} else {
|
|
432
|
+
this._stopAutoScroll();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Get dimensions and scroll positions
|
|
436
|
+
const iScrollerWidth = oScrollerElement.clientWidth;
|
|
437
|
+
const iScrollerHeight = oScrollerElement.clientHeight;
|
|
438
|
+
const iInnerScrollerWidth = oInnerScrollerElement.scrollWidth || oInnerScrollerElement.clientWidth;
|
|
439
|
+
const iInnerScrollerHeight = oInnerScrollerElement.scrollHeight || oInnerScrollerElement.clientHeight;
|
|
440
|
+
const iScrollLeft = oScrollerElement.scrollLeft;
|
|
441
|
+
const iScrollTop = oScrollerElement.scrollTop;
|
|
442
|
+
|
|
443
|
+
// Check proximity to right edge for width expansion
|
|
444
|
+
// TODO: Consider adding a maximum width/height limit to prevent excessive growth
|
|
445
|
+
// TODO: Consider adding factor of cursor position being at the end of the screen
|
|
446
|
+
const bShouldExpandWidth = this._shouldExpandDimension(
|
|
447
|
+
iInnerScrollerWidth,
|
|
448
|
+
iScrollerWidth,
|
|
449
|
+
iScrollLeft,
|
|
450
|
+
iCursorX - oScrollerRect.left, // Cursor X relative to scroller
|
|
451
|
+
RESIZE_CONFIG.PROXIMITY_THRESHOLD
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
if (bShouldExpandWidth) {
|
|
455
|
+
this._resizeInnerScrollerWidth(oGraph, RESIZE_CONFIG.WIDTH_INCREMENT);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Check proximity to bottom edge for height expansion
|
|
459
|
+
const bShouldExpandHeight = this._shouldExpandDimension(
|
|
460
|
+
iInnerScrollerHeight,
|
|
461
|
+
iScrollerHeight,
|
|
462
|
+
iScrollTop,
|
|
463
|
+
iCursorY - oScrollerRect.top, // Cursor Y relative to scroller
|
|
464
|
+
RESIZE_CONFIG.PROXIMITY_THRESHOLD
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
if (bShouldExpandHeight) {
|
|
468
|
+
this._resizeInnerScrollerHeight(oGraph, RESIZE_CONFIG.HEIGHT_INCREMENT);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Determines if the inner scroller dimension should be expanded based on cursor proximity to viewport edge
|
|
474
|
+
* and available content space.
|
|
475
|
+
* Handles two cases:
|
|
476
|
+
* Case 1: InnerScroller smaller than Scroller (not scrolled) - cursor must be near viewport edge AND near innerScroller's edge
|
|
477
|
+
* Case 2: InnerScroller larger than Scroller (scrolled) - cursor must be near viewport edge AND running out of content
|
|
478
|
+
*
|
|
479
|
+
* @param {number} iInnerDimension - The total dimension of inner scroller (width or height)
|
|
480
|
+
* @param {number} iScrollerDimension - The viewport dimension of scroller (width or height)
|
|
481
|
+
* @param {number} iScrollPosition - Current scroll position (scrollLeft or scrollTop)
|
|
482
|
+
* @param {number} iCursorPosition - Cursor position relative to scroller (clientX/Y - scrollerRect.left/top)
|
|
483
|
+
* @param {number} iProximityThreshold - Distance from edge to trigger expansion
|
|
484
|
+
* @returns {boolean} True if should expand, false otherwise
|
|
485
|
+
* @private
|
|
486
|
+
*/
|
|
487
|
+
DragDropManager.prototype._shouldExpandDimension = function (iInnerDimension, iScrollerDimension, iScrollPosition, iCursorPosition, iProximityThreshold) {
|
|
488
|
+
// Case 1: InnerScroller is smaller than or equal to Scroller (not scrollable or minimal scroll)
|
|
489
|
+
// In this case, cursor proximity is checked against innerScroller's edge, not viewport edge
|
|
490
|
+
if (iInnerDimension <= iScrollerDimension) {
|
|
491
|
+
// Check if cursor is near the innerScroller's content edge
|
|
492
|
+
const bCursorNearInnerScrollerEdge = iCursorPosition >= (iInnerDimension - iProximityThreshold);
|
|
493
|
+
return bCursorNearInnerScrollerEdge;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Case 2: InnerScroller is larger than Scroller (content is scrollable)
|
|
497
|
+
// Check if cursor is near viewport edge AND we're running out of content
|
|
498
|
+
const bCursorNearViewportEdge = iCursorPosition >= (iScrollerDimension - iProximityThreshold);
|
|
499
|
+
|
|
500
|
+
if (!bCursorNearViewportEdge) {
|
|
501
|
+
// Cursor is not near the viewport edge, no need to expand
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Cursor is near viewport edge, now check if we're running out of content
|
|
506
|
+
const iVisibleEdgePosition = iScrollPosition + iScrollerDimension;
|
|
507
|
+
const iContentEdgeThreshold = iInnerDimension - iProximityThreshold;
|
|
508
|
+
|
|
509
|
+
return iVisibleEdgePosition >= iContentEdgeThreshold;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Handles the drop event for node elements.
|
|
514
|
+
* Calculates the new position of the node based on cursor movement and scroll changes,
|
|
515
|
+
* then fires the nodeDropped event with the updated coordinates.
|
|
516
|
+
*
|
|
517
|
+
* @param {sap.ui.base.Event} oEvent - The drop event
|
|
518
|
+
* @param {object} dropData - The extracted drop data containing drag information
|
|
519
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
520
|
+
* @private
|
|
521
|
+
*/
|
|
522
|
+
DragDropManager.prototype._handleNodeDrop = function (oEvent, dropData, oGraph) {
|
|
523
|
+
let dragSessionComplexData = dropData.dragSessionComplexData,
|
|
524
|
+
deltaX = dropData.clientX - (dragSessionComplexData?.cursorX || 0), // Calculate the change in X position for the node being dragged in viewport
|
|
525
|
+
deltaY = dropData.clientY - (dragSessionComplexData?.cursorY || 0), // Calculate the change in Y position for the node being dragged in viewport
|
|
526
|
+
prevInnerScrollerX = dragSessionComplexData?.innerScrollerX || 0, // Previous X position of the inner scroller at drag start
|
|
527
|
+
prevInnerScrollerY = dragSessionComplexData?.innerScrollerY || 0; // Previous Y position of the inner scroller at drag start
|
|
528
|
+
|
|
529
|
+
let boundingRectInnerScroller = oGraph?._$innerscroller[0]?.getBoundingClientRect() || { x: 0, y: 0 },
|
|
530
|
+
deltaInnerScrollerX = oUtilityFunctions.diff(prevInnerScrollerX, boundingRectInnerScroller.x || 0), // Change in X position of the inner scroller during drag, to track scrolling
|
|
531
|
+
deltaInnerScrollerY = oUtilityFunctions.diff(prevInnerScrollerY, boundingRectInnerScroller.y || 0), // Change in Y position of the inner scroller during drag, to track scrolling
|
|
532
|
+
deltaSignatureX = prevInnerScrollerX >= boundingRectInnerScroller.x ? 1 : -1, // Determine scroll direction in X axis
|
|
533
|
+
deltaSignatureY = prevInnerScrollerY >= boundingRectInnerScroller.y ? 1 : -1; // Determine scroll direction in Y axis
|
|
534
|
+
|
|
535
|
+
let newX = dropData.draggedControl.getX() + deltaX + (deltaSignatureX * deltaInnerScrollerX),
|
|
536
|
+
newY = dropData.draggedControl.getY() + deltaY + (deltaSignatureY * deltaInnerScrollerY);
|
|
537
|
+
|
|
538
|
+
// Clamp position to prevent nodes from going off-screen (especially for action buttons)
|
|
539
|
+
var oClampedPosition = oUtilityFunctions.clampPosition(newX, newY);
|
|
540
|
+
|
|
541
|
+
// Store current scroll position before any DOM changes
|
|
542
|
+
let currentScrollLeft = oGraph?.$scroller?.[0]?.scrollLeft || 0;
|
|
543
|
+
let currentScrollTop = oGraph?.$scroller?.[0]?.scrollTop || 0;
|
|
544
|
+
|
|
545
|
+
oGraph.fireEvent("nodeDropped", {
|
|
546
|
+
...oEvent.getParameters(),
|
|
547
|
+
node: dropData.draggedControl,
|
|
548
|
+
newX: oClampedPosition.x,
|
|
549
|
+
newY: oClampedPosition.y
|
|
550
|
+
});
|
|
551
|
+
// Preserve scroll position after event
|
|
552
|
+
Utils.preserveScrollPosition(oGraph, currentScrollLeft, currentScrollTop, 0);
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Handles the drop event for external items (non-node elements).
|
|
557
|
+
* Calculates the drop position relative to the inner scroller and fires the nodeDropped event.
|
|
558
|
+
*
|
|
559
|
+
* @param {sap.ui.base.Event} oEvent - The drop event
|
|
560
|
+
* @param {object} dropData - The extracted drop data containing drag information
|
|
561
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
562
|
+
* @private
|
|
563
|
+
*/
|
|
564
|
+
DragDropManager.prototype._handleExternalItemDrop = function (oEvent, dropData, oGraph) {
|
|
565
|
+
let boundingRect = oGraph?._$innerscroller[0]?.getBoundingClientRect() || { left: 0, top: 0 },
|
|
566
|
+
x = dropData.clientX - boundingRect.left,
|
|
567
|
+
y = dropData.clientY - boundingRect.top;
|
|
568
|
+
|
|
569
|
+
// Clamp position to prevent nodes from going off-screen (especially for action buttons)
|
|
570
|
+
var oClampedPosition = oUtilityFunctions.clampPosition(x, y);
|
|
571
|
+
|
|
572
|
+
// Store current scroll position before any DOM changes
|
|
573
|
+
let currentScrollLeft = oGraph?.$scroller?.[0]?.scrollLeft || 0;
|
|
574
|
+
let currentScrollTop = oGraph?.$scroller?.[0]?.scrollTop || 0;
|
|
575
|
+
|
|
576
|
+
oGraph.fireEvent("nodeDropped", {
|
|
577
|
+
...oEvent.getParameters(),
|
|
578
|
+
node: dropData.draggedControl,
|
|
579
|
+
newX: oClampedPosition.x,
|
|
580
|
+
newY: oClampedPosition.y
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
// Preserve scroll position after event
|
|
584
|
+
Utils.preserveScrollPosition(oGraph, currentScrollLeft, currentScrollTop, 0);
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Validates if the event contains required browser event data and if DnD is enabled.
|
|
589
|
+
* Logs a warning if validation fails.
|
|
590
|
+
*
|
|
591
|
+
* @param {sap.ui.base.Event} oEvent - The event to validate
|
|
592
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} [oGraph] - Optional graph control to check if DnD is enabled
|
|
593
|
+
* @returns {boolean} True if the event is valid, false otherwise
|
|
594
|
+
* @private
|
|
595
|
+
*/
|
|
596
|
+
DragDropManager.prototype._validateEvent = function (oEvent, oGraph = undefined) {
|
|
597
|
+
let oBrowserEvent = oEvent.getParameter("browserEvent") || undefined;
|
|
598
|
+
if (!oBrowserEvent || (!!oGraph && !oGraph._isDnDEnabled())) {
|
|
599
|
+
Log.warning("No native browser event available in drop event.");
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
return true;
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Checks if the given control is a Node type.
|
|
607
|
+
*
|
|
608
|
+
* @param {object} [control={}] - The control to check
|
|
609
|
+
* @returns {boolean} True if the control is a Node, false otherwise
|
|
610
|
+
* @private
|
|
611
|
+
*/
|
|
612
|
+
DragDropManager.prototype._isTypeNode = function (control = {}) {
|
|
613
|
+
return control?.isA && control.isA("sap.suite.ui.commons.networkgraph.Node");
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Extracts and returns the relevant drop data from the event.
|
|
618
|
+
* Includes dragged control, cursor position, and drag session data.
|
|
619
|
+
*
|
|
620
|
+
* @param {sap.ui.base.Event} oEvent - The drop event
|
|
621
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
622
|
+
* @returns {object} Object containing draggedControl, clientX, clientY, and dragSessionComplexData
|
|
623
|
+
* @private
|
|
624
|
+
*/
|
|
625
|
+
DragDropManager.prototype._extractDropData = function (oEvent, oGraph) {
|
|
626
|
+
let oBrowserEvent = oEvent.getParameter("browserEvent") || {};
|
|
627
|
+
return {
|
|
628
|
+
draggedControl: oEvent.getParameter("draggedControl") || {},
|
|
629
|
+
clientX: oBrowserEvent.clientX || 0,
|
|
630
|
+
clientY: oBrowserEvent.clientY || 0,
|
|
631
|
+
dragSessionComplexData: oEvent.getParameter("dragSession")?.getComplexData(sDragSessionKey) || {},
|
|
632
|
+
};
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Handles the drop event.
|
|
637
|
+
*
|
|
638
|
+
* @param {sap.ui.base.Event} oEvent - The drop event
|
|
639
|
+
* @param {sap.suite.ui.commons.networkgraph.Graph} oGraph - The graph control
|
|
640
|
+
* @private
|
|
641
|
+
*/
|
|
642
|
+
DragDropManager.prototype._handleDrop = function (oEvent, oGraph) {
|
|
643
|
+
this.bIsDragging = false;
|
|
644
|
+
if (!this._validateEvent(oEvent, oGraph)) {
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
let dropData = this._extractDropData(oEvent, oGraph);
|
|
649
|
+
if (this._isTypeNode(dropData.draggedControl)) {
|
|
650
|
+
this._handleNodeDrop(oEvent, dropData, oGraph);
|
|
651
|
+
} else {
|
|
652
|
+
this._handleExternalItemDrop(oEvent, dropData, oGraph);
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Injects drag and drop configuration into the given control.
|
|
658
|
+
* Adds appropriate DragInfo and DropInfo based on control type (Graph or Node).
|
|
659
|
+
*
|
|
660
|
+
* @param {sap.ui.core.Control} oControl - The control to inject DnD functionality into
|
|
661
|
+
* @throws {Error} If the control is not valid or not supported for DnD
|
|
662
|
+
* @public
|
|
663
|
+
*/
|
|
664
|
+
DragDropManager.prototype.injectDnD = function (oControl) {
|
|
665
|
+
if (!this.isValidControl(oControl)) {
|
|
666
|
+
throw new Error("DragDropManager: Control is not valid for DnD");
|
|
667
|
+
}
|
|
668
|
+
var sControlType = oControl.getMetadata().getName();
|
|
669
|
+
switch (sControlType) {
|
|
670
|
+
case "sap.suite.ui.commons.networkgraph.Graph":
|
|
671
|
+
var dragInfo = new DragInfo({
|
|
672
|
+
sourceAggregation: "nodes",
|
|
673
|
+
dragEnd: this._handleDragEnd.bind(this)
|
|
674
|
+
});
|
|
675
|
+
var dropInfo = new DropInfo({
|
|
676
|
+
dropPosition: "On",
|
|
677
|
+
drop: function (oEvent) {
|
|
678
|
+
this._handleDrop(oEvent, oControl);
|
|
679
|
+
}.bind(this),
|
|
680
|
+
dragOver: this._handleDragOver.bind(this),
|
|
681
|
+
dragEnter: function (oEvent) {
|
|
682
|
+
oEvent.getParameter("dragSession").setIndicatorConfig({
|
|
683
|
+
display: "none"
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
oControl.addDragDropConfig(dragInfo);
|
|
689
|
+
oControl.addDragDropConfig(dropInfo);
|
|
690
|
+
break;
|
|
691
|
+
case "sap.suite.ui.commons.networkgraph.Node":
|
|
692
|
+
var dragInfo = new DragInfo({
|
|
693
|
+
dragStart: this._handleDragStart.bind(this),
|
|
694
|
+
});
|
|
695
|
+
oControl.addDragDropConfig(dragInfo);
|
|
696
|
+
break;
|
|
697
|
+
default:
|
|
698
|
+
throw new Error("DragDropManager: Control type " + sControlType + " is not supported");
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// Remove DnD config
|
|
703
|
+
DragDropManager.prototype.removeDnD = function (oControl) {
|
|
704
|
+
if (!this.isValidControl(oControl)) {
|
|
705
|
+
throw new Error("DragDropManager: Control is not valid for DnD");
|
|
706
|
+
}
|
|
707
|
+
// Check if control has any drag drop configurations
|
|
708
|
+
if (!oControl.getDragDropConfig || oControl.getDragDropConfig().length === 0) {
|
|
709
|
+
return true; // Not an error, just nothing to remove
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
oControl?.destroyDragDropConfig();
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
// Exported singleton object - instantiate on first access
|
|
716
|
+
if (!instance) {
|
|
717
|
+
instance = new DragDropManager();
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return instance;
|
|
721
|
+
}, /* bExport= */true);
|