InAppSlideoutDOM.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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 Business Analytics (C) Copyright IBM Corp. 2019, 2020
  6. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  7. */
  8. /**
  9. * @class SlideoutDOM
  10. * @hideconstructor
  11. * @classdesc API class that is used to manage Slideout functionality
  12. * (including the corrsponding view) across API calls
  13. */
  14. define(['react', 'react-dom', '../../../lib/@waca/dashboard-common/dist/core/APIFactory', './InAppSlideoutDOMAPI', './InAppSlideoutContainer', 'jquery'], function (React, ReactDOM, APIFactory, InAppSlideoutDOMAPI, InAppSlideoutContainer, $) {
  15. var InAppSlideoutDOM = function () {
  16. function InAppSlideoutDOM(options) {
  17. _classCallCheck(this, InAppSlideoutDOM);
  18. this._slideout = options.features['InAppSlideoutState'];
  19. this._api = null;
  20. this._root = null;
  21. this._currentView = null;
  22. this._views = [];
  23. this._domListeners = [];
  24. this._features = options.features;
  25. }
  26. InAppSlideoutDOM.prototype.getAPI = function getAPI() {
  27. return this._api;
  28. };
  29. InAppSlideoutDOM.prototype.initialize = function initialize() {
  30. this._api = APIFactory.createAPI(this, [InAppSlideoutDOMAPI]);
  31. this._slideout.onStateChange(this._onSlideoutStateChange.bind(this));
  32. };
  33. InAppSlideoutDOM.prototype._onSlideoutStateChange = function _onSlideoutStateChange() {
  34. var _this = this;
  35. var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  36. var slideoutState = state.sidePanel;
  37. if (this._shouldRenderSlideout(state)) {
  38. this.render();
  39. } else if (!slideoutState.isOpen && slideoutState.current && this._root) {
  40. // _onSlideoutStateChange is being called twice, once for DashboardState:setSidePanelOpen with
  41. // state.sidePanel.isOpen and state.sidePanel.current to allow the panel to be identifiable and close down gracefully
  42. // The second call occur during the DashboardState.setSidePanelCurrentView(null) to clear the side panel
  43. // this time state.sidePanel.current is null
  44. // So check to make sure we have a valid sstate.sidePanel.current
  45. var _getView = this.getView(slideoutState.current),
  46. contribution = _getView.instance;
  47. if (contribution.close) {
  48. contribution.close();
  49. }
  50. // do animation - slide out, width will become 0px
  51. var slideOutStyle = {
  52. 'width': '0px'
  53. };
  54. return this._doAnimation(slideOutStyle, function () {
  55. _this._unmountContribution();
  56. _this._root && ReactDOM.unmountComponentAtNode(_this._root);
  57. _this._dashboardFrameRight && _this._root && _this._dashboardFrameRight.removeChild(_this._root);
  58. _this._root = null;
  59. _this._triggerResizeEvent();
  60. });
  61. }
  62. };
  63. InAppSlideoutDOM.prototype._doAnimation = function _doAnimation(animateToStyle, postAnimationCallback) {
  64. var $_root = $(this._root);
  65. return $_root.animate(animateToStyle, 'fast', postAnimationCallback);
  66. };
  67. InAppSlideoutDOM.prototype._unmountContribution = function _unmountContribution() {
  68. if (this._currentView && this._currentView.unmount) {
  69. if (this._currentView.unmount) {
  70. this._currentView.unmount();
  71. }
  72. if (this._currentView.close) {
  73. this._currentView.close();
  74. }
  75. }
  76. this._currentView = null;
  77. };
  78. InAppSlideoutDOM.prototype._triggerResizeEvent = function _triggerResizeEvent() {
  79. // Required to create the event like this for IE
  80. var resizeEvent = document.createEvent('HTMLEvents');
  81. resizeEvent.initEvent('resize', false, true);
  82. window.dispatchEvent(resizeEvent);
  83. };
  84. InAppSlideoutDOM.prototype.registerView = function registerView(id, instance) {
  85. var view = this.getView(id);
  86. if (view) {
  87. throw new Error('View with id "' + id + '" is already registered');
  88. }
  89. this._views.push({
  90. id: id,
  91. instance: instance
  92. });
  93. };
  94. InAppSlideoutDOM.prototype.removeView = function removeView(id) {
  95. var index = this._views.findIndex(function (item) {
  96. return item.id === id;
  97. });
  98. if (index === -1) {
  99. throw new Error('View with id "' + id + '" does not exist');
  100. }
  101. this._views.splice(index, 1);
  102. };
  103. InAppSlideoutDOM.prototype.getView = function getView(id) {
  104. return this._views.find(function (item) {
  105. return item.id === id;
  106. });
  107. };
  108. InAppSlideoutDOM.prototype.getViews = function getViews() {
  109. return this._views;
  110. };
  111. InAppSlideoutDOM.prototype._setupRenderNode = function _setupRenderNode() {
  112. var _this2 = this;
  113. if (!this._root || !this._dashboardFrameRight) {
  114. // TODO: get the canvas node from a feature. for now will do
  115. // RTC: 295170
  116. this._dashboardFrameRight = $('.dashboardFrameRight:visible')[0];
  117. if (this._dashboardFrameRight) {
  118. this._root = document.createElement('div');
  119. this._root.setAttribute('class', 'dashboardAuthoringToolsPane');
  120. // set initial width to 0px
  121. this._root.setAttribute('style', 'width: 0px;');
  122. // append the inAppSlideOut into dashboardFrameRight
  123. this._dashboardFrameRight.appendChild(this._root);
  124. // do animationm - slide in, width will become 320px
  125. var customPanelWidth = this._features['DashboardSettings'].get('panelWidth');
  126. var panelWidth = customPanelWidth ? customPanelWidth : '320px';
  127. var slideInStyle = {
  128. 'width': panelWidth
  129. };
  130. this._doAnimation(slideInStyle, function () {
  131. _this2._triggerResizeEvent();
  132. });
  133. }
  134. }
  135. };
  136. InAppSlideoutDOM.prototype.render = function render(options) {
  137. var _this3 = this;
  138. this._setupRenderNode();
  139. return new Promise(function (resolve, reject) {
  140. try {
  141. var _slideout$getCurrent = _this3._slideout.getCurrent(),
  142. id = _slideout$getCurrent.id;
  143. var _getView2 = _this3.getView(id),
  144. contribution = _getView2.instance;
  145. if (contribution) {
  146. _this3._currentView = contribution;
  147. ReactDOM.render(React.createElement(InAppSlideoutContainer, {
  148. active: _this3._slideout.isOpen(),
  149. contribution: contribution,
  150. options: options,
  151. onDomStateChange: _this3._onUiDomStateChange.bind(_this3)
  152. }), _this3._root, function () {
  153. return resolve();
  154. });
  155. } else {
  156. resolve();
  157. }
  158. } catch (error) {
  159. reject(error);
  160. }
  161. });
  162. };
  163. InAppSlideoutDOM.prototype.destroy = function destroy() {
  164. this._root && ReactDOM.unmountComponentAtNode(this._root);
  165. this._dashboardFrameRight && this._root && this._dashboardFrameRight.removeChild(this._root);
  166. this._root = null;
  167. this._api = null;
  168. this._currentView = null;
  169. this._domListeners.length = 0;
  170. };
  171. InAppSlideoutDOM.prototype.onDomStateChange = function onDomStateChange(fn) {
  172. var _this4 = this;
  173. var newLength = this._domListeners.push(fn);
  174. var elementIndex = newLength - 1;
  175. var removeFn = function removeFn() {
  176. _this4._domListeners.splice(elementIndex, 1);
  177. };
  178. return removeFn;
  179. };
  180. /**
  181. * Invoke registered views when the InAppSlideoutContainer component get mount/unmounted in the DOM
  182. *
  183. * @param {boolean} state.type - ['mounted' | 'unmounted']
  184. * @param {string} [state.current] - the current contribution id
  185. */
  186. InAppSlideoutDOM.prototype._onUiDomStateChange = function _onUiDomStateChange(state) {
  187. if (!this._domListeners) {
  188. return;
  189. }
  190. this._domListeners.forEach(function (fn) {
  191. return fn(state);
  192. });
  193. };
  194. /**
  195. * Returns a boolean indicating whether should render the slide out or not
  196. * @param {object} state - the state provided by the DashboardState object
  197. * @param {boolean} state.dirty - something changed in the dashboard marking this dashboard as dirty
  198. * @param {boolean} state.selectionProperties - flag set by TimelineSliderView.js:openAnimationProperties
  199. * @param {boolean} state.sidePanel.isOpen - flag use to open or close the panel
  200. *
  201. */
  202. InAppSlideoutDOM.prototype._shouldRenderSlideout = function _shouldRenderSlideout() {
  203. var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  204. var shouldRender = !this._currentView || this._currentView.getProviderId() !== state.sidePanel.current;
  205. return state.sidePanel.isOpen && (shouldRender || state.dirty || state.selectionProperties);
  206. };
  207. return InAppSlideoutDOM;
  208. }();
  209. return InAppSlideoutDOM;
  210. });
  211. //# sourceMappingURL=InAppSlideoutDOM.js.map