GridDnDManager.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. /**
  4. * Licensed Materials - Property of IBM
  5. * IBM Cognos Products: Dashboard
  6. * (C) Copyright IBM Corp. 2020
  7. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. *
  9. * This manager is responsible for registering and handing drop events in the crosstab.
  10. */
  11. define(['underscore', '../../../dataSources/utils/ShapingConstants'], function (_, ShapingConstants) {
  12. var GRID_ROW_EDGE = 'row';
  13. var GRID_COLUMN_EDGE = 'column';
  14. var GRID_VALUES_EDGE = 'values';
  15. return function () {
  16. function GridDnDManager() {
  17. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  18. _classCallCheck(this, GridDnDManager);
  19. this.grid = options.grid;
  20. this.dashboardApi = options.dashboardApi;
  21. this.content = options.content;
  22. this.gridEdgeMappedToId = options.gridEdgeMappedToId;
  23. this.visualization = this.content.getFeature('Visualization');
  24. this.visDnDUtils = this.content.getFeature('VisDnD.utils');
  25. }
  26. /**
  27. *
  28. * @param {React Component} component
  29. */
  30. GridDnDManager.prototype.registerElement = function registerElement(component, domNode) {
  31. var DndManager = this.dashboardApi.getFeature('DashboardDnd.internal');
  32. DndManager.addDropTarget(domNode, {
  33. accepts: this.accepts.bind(this, component, domNode),
  34. onDrop: this.onDrop.bind(this, component),
  35. onDragEnter: this.onDragEnter.bind(this),
  36. onDragMove: this.onDragMove.bind(this, component),
  37. onDragLeave: this.onDragLeave.bind(this, component)
  38. });
  39. };
  40. GridDnDManager.prototype.deregisterElement = function deregisterElement(domNode) {
  41. var DndManager = this.dashboardApi.getFeature('DashboardDnd.internal');
  42. DndManager.removeDropTarget(domNode);
  43. };
  44. //DND callbacks
  45. GridDnDManager.prototype.accepts = function accepts(component, targetNode, dragObject) {
  46. if (!component || !component.props) {
  47. return false;
  48. }
  49. var acceptsOptions = { dropTarget: ShapingConstants.DROP_TARGET_OPTIONS.SLOT };
  50. if (targetNode) {
  51. acceptsOptions.targetNode = targetNode;
  52. }
  53. var content = this._getContent();
  54. var visualization = content.getFeature('Visualization');
  55. var dropAction = void 0;
  56. var expandCollapseFeatureFlag = !this.dashboardApi.getGlassCoreSvc('.FeatureChecker').checkValue('dashboard', 'expandCollapse', 'disabled');
  57. if (expandCollapseFeatureFlag && visualization.getType() === 'Crosstab') {
  58. dropAction = targetNode && this._getDropAction(component, dragObject, targetNode);
  59. if (dropAction) {
  60. dropAction.actionSpec.slot = this._findSlot(dropAction.actionSpec.gridEdge);
  61. acceptsOptions.dropAction = dropAction;
  62. }
  63. }
  64. var accept = this.visDnDUtils.accepts(dragObject, acceptsOptions);
  65. // check if the current activate dropZone is visible, if not visible, we are not going to accept it
  66. if (accept) {
  67. var gridDom = this.grid.$el[0];
  68. var gridDomRect = gridDom && gridDom.getBoundingClientRect();
  69. var componentDom = component.ref.current;
  70. var componentDomRect = componentDom && componentDom.getBoundingClientRect();
  71. // allow tolerance for 3px regarding to vertical scroll bar and the padding on the right
  72. var tolerance = 3;
  73. if (!gridDomRect || !componentDomRect || parseInt(gridDomRect.bottom) < parseInt(componentDomRect.bottom) || parseInt(gridDomRect.right) < parseInt(componentDomRect.right) && Math.abs(componentDomRect.right - gridDomRect.right) > tolerance) {
  74. accept = false;
  75. }
  76. }
  77. return accept;
  78. };
  79. GridDnDManager.prototype.onDragEnter = function onDragEnter() {};
  80. GridDnDManager.prototype._findSlot = function _findSlot(gridEdge) {
  81. var _this = this;
  82. var slots = this.visualization.getSlots();
  83. var slot = _.find(slots.getSlotList(), function (slot) {
  84. switch (gridEdge) {
  85. case GRID_ROW_EDGE:
  86. return slot.getId() === _this.gridEdgeMappedToId.row;
  87. case GRID_COLUMN_EDGE:
  88. return slot.getId() === _this.gridEdgeMappedToId.column;
  89. case GRID_VALUES_EDGE:
  90. return slot.getId() === _this.gridEdgeMappedToId.values;
  91. }
  92. });
  93. return slot;
  94. };
  95. GridDnDManager.prototype._insertDataItems = function _insertDataItems(_ref) {
  96. var gridEdge = _ref.gridEdge,
  97. droppedColumns = _ref.droppedColumns,
  98. position = _ref.position;
  99. var slot = this._findSlot(gridEdge);
  100. if (slot) {
  101. this.visDnDUtils.mapColumns(slot.getId(), droppedColumns, { position: position, bReplace: false });
  102. }
  103. };
  104. GridDnDManager.prototype._replaceDataItems = function _replaceDataItems(_ref2) {
  105. var gridEdge = _ref2.gridEdge,
  106. droppedColumns = _ref2.droppedColumns,
  107. position = _ref2.position;
  108. var slot = this._findSlot(gridEdge);
  109. if (slot) {
  110. var slotDataItemList = slot.getDataItemList();
  111. if (_.isEmpty(slotDataItemList)) {
  112. return;
  113. }
  114. this.visDnDUtils.mapColumns(slot.getId(), droppedColumns, { position: position, bReplace: true });
  115. }
  116. };
  117. GridDnDManager.prototype._findValuesSlotPosition = function _findValuesSlotPosition(component) {
  118. var slot = this._findSlot(GRID_VALUES_EDGE);
  119. var index = -1;
  120. if (slot) {
  121. var dataItemList = slot.getDataItemList();
  122. if (!_.isEmpty(dataItemList)) {
  123. index = dataItemList.findIndex(function (dataItem) {
  124. return dataItem.getLabel() === component.props.useValue;
  125. });
  126. }
  127. }
  128. return index;
  129. };
  130. GridDnDManager.prototype._getDropAction = function _getDropAction(component, dragObject, node) {
  131. var droppedColumns = dragObject.data.columns;
  132. var metadataColumns = _.pluck(droppedColumns, 'metadataColumn');
  133. if (metadataColumns.length > 0) {
  134. var _getDropZoneInfo2 = this._getDropZoneInfo(dragObject, node, component),
  135. action = _getDropZoneInfo2.action,
  136. idx = _getDropZoneInfo2.idx;
  137. switch (action) {
  138. case 'insertLeft':
  139. return this._getInsertLeftAction(component, droppedColumns, idx);
  140. case 'insertRight':
  141. return this._getInsertRightAction(component, droppedColumns, idx);
  142. case 'replaceRow':
  143. return this._getReplaceRowAction(component, droppedColumns, idx);
  144. case 'insertAbove':
  145. return this._getInsertAboveAction(droppedColumns, idx);
  146. case 'insertBelow':
  147. return this._getInsertBelowAction(droppedColumns, idx);
  148. case 'replaceCol':
  149. return this._getReplaceColumnAction(component, droppedColumns, idx);
  150. }
  151. }
  152. };
  153. GridDnDManager.prototype.onDrop = function onDrop(component, dragObject, node) {
  154. var dropAction = this._getDropAction(component, dragObject, node);
  155. this.grid.hideDropZones();
  156. return dropAction.action(dropAction.actionSpec);
  157. };
  158. GridDnDManager.prototype.onDragMove = function onDragMove(component, dragObject, node) {
  159. var _getDropZoneInfo3 = this._getDropZoneInfo(dragObject, node, component),
  160. action = _getDropZoneInfo3.action,
  161. idx = _getDropZoneInfo3.idx;
  162. switch (action) {
  163. case 'insertLeft':
  164. return this.grid.showLeftDropZone(idx);
  165. case 'insertRight':
  166. return this.grid.showRightDropZone(idx);
  167. case 'replaceRow':
  168. {
  169. if (component.props.isMeasure && component.props.cellType !== 'corner') {
  170. return this.grid.showReplaceDropZone(component.props.row, 'row', component.props.useValue);
  171. } else {
  172. return this.grid.showReplaceDropZone(idx, 'col');
  173. }
  174. }
  175. case 'insertAbove':
  176. return this.grid.showTopDropZone(idx);
  177. case 'insertBelow':
  178. return this.grid.showBottomDropZone(idx);
  179. case 'replaceCol':
  180. return this.grid.showReplaceDropZone(idx, 'row');
  181. }
  182. };
  183. GridDnDManager.prototype.onDragLeave = function onDragLeave() {
  184. this.grid.hideDropZones();
  185. };
  186. GridDnDManager.prototype._getInsertLeftAction = function _getInsertLeftAction(component, droppedColumns, position) {
  187. var actionSpec = void 0;
  188. if (component.props.cellType === 'corner') {
  189. actionSpec = {
  190. gridEdge: GRID_VALUES_EDGE,
  191. droppedColumns: droppedColumns,
  192. position: 0
  193. };
  194. } else if (component.props.isMeasure) {
  195. actionSpec = {
  196. gridEdge: GRID_VALUES_EDGE,
  197. droppedColumns: droppedColumns,
  198. position: this._findValuesSlotPosition(component)
  199. };
  200. } else {
  201. actionSpec = {
  202. gridEdge: GRID_ROW_EDGE,
  203. droppedColumns: droppedColumns,
  204. position: parseInt(position)
  205. };
  206. }
  207. actionSpec.replace = false;
  208. return {
  209. actionSpec: actionSpec,
  210. action: this._insertDataItems.bind(this)
  211. };
  212. };
  213. GridDnDManager.prototype._getInsertRightAction = function _getInsertRightAction(component, droppedColumns, position) {
  214. var actionSpec = void 0;
  215. if (component.props.cellType === 'corner') {
  216. actionSpec = {
  217. gridEdge: GRID_VALUES_EDGE,
  218. droppedColumns: droppedColumns,
  219. position: -1
  220. };
  221. } else if (component.props.isMeasure) {
  222. actionSpec = {
  223. gridEdge: GRID_VALUES_EDGE,
  224. droppedColumns: droppedColumns,
  225. position: this._findValuesSlotPosition(component) + 1
  226. };
  227. } else {
  228. actionSpec = {
  229. gridEdge: GRID_ROW_EDGE,
  230. droppedColumns: droppedColumns,
  231. position: parseInt(position) + 1
  232. };
  233. }
  234. actionSpec.replace = false;
  235. return {
  236. actionSpec: actionSpec,
  237. action: this._insertDataItems.bind(this)
  238. };
  239. };
  240. GridDnDManager.prototype._getReplaceRowAction = function _getReplaceRowAction(component, droppedColumns, position) {
  241. var actionSpec = void 0;
  242. if (component.props.cellType === 'corner') {
  243. actionSpec = {
  244. gridEdge: GRID_VALUES_EDGE,
  245. droppedColumns: droppedColumns,
  246. position: 0
  247. };
  248. } else if (component.props.isMeasure) {
  249. actionSpec = {
  250. gridEdge: GRID_VALUES_EDGE,
  251. droppedColumns: droppedColumns,
  252. position: this._findValuesSlotPosition(component)
  253. };
  254. } else {
  255. actionSpec = {
  256. gridEdge: GRID_ROW_EDGE,
  257. droppedColumns: droppedColumns,
  258. position: parseInt(position)
  259. };
  260. }
  261. actionSpec.replace = true;
  262. return {
  263. actionSpec: actionSpec,
  264. action: this._replaceDataItems.bind(this)
  265. };
  266. };
  267. GridDnDManager.prototype._getInsertAboveAction = function _getInsertAboveAction(droppedColumns, position) {
  268. var actionSpec = {
  269. gridEdge: GRID_COLUMN_EDGE,
  270. droppedColumns: droppedColumns,
  271. position: parseInt(position),
  272. replace: false
  273. };
  274. return {
  275. actionSpec: actionSpec,
  276. action: this._insertDataItems.bind(this)
  277. };
  278. };
  279. GridDnDManager.prototype._getInsertBelowAction = function _getInsertBelowAction(droppedColumns, position) {
  280. var actionSpec = {
  281. gridEdge: GRID_COLUMN_EDGE,
  282. droppedColumns: droppedColumns,
  283. position: parseInt(position) + 1
  284. };
  285. actionSpec.replace = false;
  286. return {
  287. actionSpec: actionSpec,
  288. action: this._insertDataItems.bind(this)
  289. };
  290. };
  291. GridDnDManager.prototype._getReplaceColumnAction = function _getReplaceColumnAction(component, droppedColumns, position) {
  292. var actionSpec = void 0;
  293. if (component.props.isMeasure) {
  294. actionSpec = {
  295. gridEdge: GRID_VALUES_EDGE,
  296. droppedColumns: droppedColumns,
  297. position: this._findValuesSlotPosition(component)
  298. };
  299. } else {
  300. actionSpec = {
  301. gridEdge: GRID_COLUMN_EDGE,
  302. droppedColumns: droppedColumns,
  303. position: parseInt(position)
  304. };
  305. }
  306. actionSpec.replace = true;
  307. return {
  308. actionSpec: actionSpec,
  309. action: this._replaceDataItems.bind(this)
  310. };
  311. };
  312. GridDnDManager.prototype._getDropZoneInfo = function _getDropZoneInfo(dragObject, node, component) {
  313. if (component.props.cellType === 'column') {
  314. return this._getColumnDropZoneInfo(dragObject, node, component);
  315. } else if (component.props.cellType === 'row') {
  316. return this._getRowDropZoneInfo(dragObject, node, component);
  317. } else if (component.props.cellType === 'corner') {
  318. return this._getCornerDropZoneInfo(dragObject, node, component);
  319. }
  320. };
  321. GridDnDManager.prototype._getColumnDropZoneInfo = function _getColumnDropZoneInfo(dragObject, node) {
  322. var clientRect = node.getBoundingClientRect();
  323. var col = node && node.getAttribute('col');
  324. var diff = dragObject.position.x - clientRect.left;
  325. var percent = 100 * (diff / clientRect.width);
  326. if (percent < 33) {
  327. return { action: 'insertLeft', idx: col };
  328. } else if (percent > 66) {
  329. return { action: 'insertRight', idx: col };
  330. } else {
  331. return { action: 'replaceRow', idx: col };
  332. }
  333. };
  334. GridDnDManager.prototype._getRowDropZoneInfo = function _getRowDropZoneInfo(dragObject, node, component) {
  335. var clientRect = node.getBoundingClientRect();
  336. if (component.props.isMeasure) {
  337. return this._getColumnDropZoneInfo(dragObject, node);
  338. } else {
  339. var row = node && node.getAttribute('row');
  340. var diff = dragObject.position.y - clientRect.top;
  341. var percent = 100 * (diff / clientRect.height);
  342. if (percent < 33) {
  343. return { action: 'insertAbove', idx: row };
  344. } else if (percent > 66) {
  345. return { action: 'insertBelow', idx: row };
  346. } else {
  347. return { action: 'replaceCol', idx: row };
  348. }
  349. }
  350. };
  351. GridDnDManager.prototype._getCornerDropZoneInfo = function _getCornerDropZoneInfo(dragObject, node) {
  352. var clientRect = node.getBoundingClientRect();
  353. var diff = dragObject.position.x - clientRect.left;
  354. var percent = 100 * (diff / clientRect.width);
  355. if (percent < 33) {
  356. return { action: 'insertLeft', idx: 'corner' };
  357. } else if (percent > 66) {
  358. return { action: 'insertRight', idx: 'corner' };
  359. } else {
  360. return { action: 'replaceRow', idx: 'corner' };
  361. }
  362. };
  363. GridDnDManager.prototype._getContent = function _getContent() {
  364. if (!this.content) {
  365. var view = this.grid.gridView || this.grid.crosstabView;
  366. this.content = this.dashboardApi.getCanvas() && this.dashboardApi.getCanvas().getContent(view.ownerWidget.getId());
  367. }
  368. return this.content;
  369. };
  370. return GridDnDManager;
  371. }();
  372. });
  373. //# sourceMappingURL=GridDnDManager.js.map