VisualizationPanelView.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5. /**
  6. * Licensed Materials - Property of IBM
  7. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2019, 2020
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. */
  10. define(['../lib/@waca/core-client/js/core-client/ui/core/View', '../lib/@waca/core-client/js/core-client/ui/KeyCodes', '../widgets/livewidget/nls/StringResources', '../visualizations/vipr/VIPRConfig', '../visualizations/vipr/extendedVis/SchematicVis', '../util/VidaSdkUtil', 'text!./templates/LoadingIndicator.html', 'underscore', 'jquery', 'doT', 'react', 'react-dom', 'prop-types', 'ca-ui-toolkit', './components/VisualizationContentContainer', './components/custom/CustomPanelContainer', './components/util/CustomVisAction', 'hammerjs', 'jquery.hammer'], function (View, KeyCodes, StringResources, VIPRConfig, SchematicVis, VidaSdkUtil, LoadingIndicatorTemplate, _, $, dot, React, ReactDOM, PropTypes, UI_Toolkit, VisualizationContentContainer, CustomPanelContainer, CustomVisAction) {
  11. var Component = React.Component;
  12. var Container = UI_Toolkit.Container,
  13. ProgressIndicator = UI_Toolkit.ProgressIndicator;
  14. var Tabs = UI_Toolkit.Tabs,
  15. TabPanel = UI_Toolkit.TabPanel,
  16. VSpacer = UI_Toolkit.VSpacer,
  17. Label = UI_Toolkit.Label,
  18. FlexLayout = UI_Toolkit.FlexLayout,
  19. FlexItem = UI_Toolkit.FlexItem;
  20. var DEFAULT_SELECTED_TAB = 'System';
  21. var VisualizationTabs = function (_Component) {
  22. _inherits(VisualizationTabs, _Component);
  23. function VisualizationTabs() {
  24. _classCallCheck(this, VisualizationTabs);
  25. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  26. args[_key] = arguments[_key];
  27. }
  28. var _this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args)));
  29. _this.state = {
  30. selectedTab: _this.props.selectedTab,
  31. isRefreshing: false,
  32. deleteable: false,
  33. editable: false,
  34. addable: false,
  35. align: 'center',
  36. tabs: _this.props
  37. };
  38. return _this;
  39. }
  40. VisualizationTabs.prototype.render = function render() {
  41. var panels = this._renderTabPanels();
  42. var tabsClassNames = panels.length === 1 ? 'vis-panel-tabs hide-tabs' : 'vis-panel-tabs';
  43. return React.createElement(
  44. Container,
  45. { className: 'vis-panel-container' },
  46. React.createElement(VSpacer, { size: 2 }),
  47. React.createElement(Label, { className: 'vis-panel-banner', label: StringResources.get('visualizationSlideoutTitle') }),
  48. React.createElement(VSpacer, { size: 2 }),
  49. React.createElement(
  50. Tabs,
  51. { className: tabsClassNames,
  52. selected: this.state.selectedTab,
  53. onChange: this.onChange.bind(this)
  54. },
  55. panels
  56. )
  57. );
  58. };
  59. VisualizationTabs.prototype._renderTabPanels = function _renderTabPanels() {
  60. var panels = [];
  61. panels.push(React.createElement(
  62. TabPanel,
  63. {
  64. id: DEFAULT_SELECTED_TAB,
  65. label: StringResources.get('extVisSystem')
  66. },
  67. React.createElement(VisualizationContentContainer, {
  68. containerClass: 'vis-system-container',
  69. itemClass: 'prop-item',
  70. items: this.props.tabs.system.items,
  71. handlers: this.props.tabs.handlers
  72. })
  73. ));
  74. var customVisAction = this.props.customVisAction;
  75. if (customVisAction.isEnabled()) {
  76. panels.push(React.createElement(
  77. TabPanel,
  78. {
  79. id: 'Custom',
  80. label: StringResources.get('extVisCustom')
  81. },
  82. this._renderCustomPanelContainer()
  83. ));
  84. }
  85. return panels;
  86. };
  87. VisualizationTabs.prototype.onChange = function onChange(tabId) {
  88. var _this2 = this;
  89. var customVisAction = this.props.customVisAction;
  90. var isRefreshing = customVisAction.shouldRefreshCustomPanel() && tabId === 'Custom';
  91. this.setState({
  92. selectedTab: tabId,
  93. isRefreshing: isRefreshing
  94. });
  95. if (isRefreshing) {
  96. return customVisAction.refreshCustomVis(true).then(function () {
  97. var tabs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  98. _this2.setState({
  99. tabs: tabs,
  100. isRefreshing: false
  101. });
  102. });
  103. }
  104. };
  105. VisualizationTabs.prototype._renderProgressIndicator = function _renderProgressIndicator() {
  106. return React.createElement(
  107. FlexLayout,
  108. {
  109. fullHeight: true,
  110. direction: 'column',
  111. justifyContent: 'center',
  112. width: '100%',
  113. height: '100%'
  114. },
  115. React.createElement(
  116. FlexItem,
  117. { alignSelf: 'center' },
  118. React.createElement(ProgressIndicator, null)
  119. )
  120. );
  121. };
  122. VisualizationTabs.prototype._renderCustomPanelContainer = function _renderCustomPanelContainer() {
  123. var _props = this.props,
  124. dashboardApi = _props.dashboardApi,
  125. customVisAction = _props.customVisAction,
  126. tabs = _props.tabs;
  127. var isRefreshing = this.state.isRefreshing;
  128. return React.createElement(CustomPanelContainer, {
  129. custom: tabs.custom,
  130. handlers: tabs.handlers,
  131. dashboardApi: dashboardApi,
  132. customVisAction: customVisAction,
  133. isRefreshing: isRefreshing
  134. });
  135. };
  136. return VisualizationTabs;
  137. }(Component);
  138. VisualizationTabs.propTypes = {
  139. tabs: PropTypes.object.isRequired,
  140. dashboardApi: PropTypes.object.isRequired,
  141. selectedTab: PropTypes.string.isRequired,
  142. customVisAction: PropTypes.object.isRequired
  143. };
  144. VisualizationTabs.defaultProps = {
  145. selectedTab: DEFAULT_SELECTED_TAB,
  146. isRefreshing: false
  147. };
  148. var SKD_VIS_PREVIEW = 'visualizationPreview';
  149. var CUS_VIS_SCHEMATIC_PREVIEW = 'com.ibm.vis.schematicsPreview';
  150. var _geVisItemSelector = function _geVisItemSelector(classSelectors) {
  151. return _.chain(classSelectors).map(function (selector) {
  152. return '.' + selector;
  153. }).value().join(' ');
  154. };
  155. return function (_View) {
  156. _inherits(VisualizationPanelView, _View);
  157. function VisualizationPanelView() {
  158. _classCallCheck(this, VisualizationPanelView);
  159. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  160. args[_key2] = arguments[_key2];
  161. }
  162. var _this3 = _possibleConstructorReturn(this, _View.call.apply(_View, [this].concat(args)));
  163. var options = args[0];
  164. if (!options.getEntries) {
  165. var _ret;
  166. return _ret = Promise.reject('Invalid getEntries api provided'), _possibleConstructorReturn(_this3, _ret);
  167. }
  168. _this3.getEntries = options.getEntries;
  169. _this3.selectedTab = options.selectedTab || DEFAULT_SELECTED_TAB;
  170. _this3.dashboardApi = options.dashboardApi;
  171. _this3.dndManager = _this3.dashboardApi.getFeature('DashboardDnd.internal');
  172. _this3.loadingIndicatorTemplate = dot.template(LoadingIndicatorTemplate || '');
  173. _this3.customVisAction = new CustomVisAction({
  174. dashboardApi: _this3.dashboardApi,
  175. refreshCustomVis: _this3._refreshCustomVisDefinitions.bind(_this3)
  176. });
  177. _this3._createViewStates();
  178. return _this3;
  179. }
  180. VisualizationPanelView.prototype.init = function init() {
  181. var _View$prototype$init;
  182. this.events = {
  183. 'clicktap .vis-panel-container .prop-item:not(.is-disabled)': '_onItemClick',
  184. 'mousedown .vis-panel-container .prop-item:not(.is-disabled)': '_onItemMouseDownStartDrag',
  185. 'keydown .vis-panel-container .prop-item:not(.is-disabled)': '_onItemKeyDown'
  186. };
  187. for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  188. args[_key3] = arguments[_key3];
  189. }
  190. (_View$prototype$init = _View.prototype.init).call.apply(_View$prototype$init, [this].concat(args));
  191. };
  192. VisualizationPanelView.prototype.remove = function remove() {
  193. var _View$prototype$remov;
  194. if (this._dropZone) {
  195. this._dropZone.remove();
  196. this._dropZone = null;
  197. }
  198. this.dndManager = null;
  199. this.customVisAction.destroy();
  200. this.customVisAction = null;
  201. ReactDOM.unmountComponentAtNode(this.$el[0]);
  202. for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
  203. args[_key4] = arguments[_key4];
  204. }
  205. (_View$prototype$remov = _View.prototype.remove).call.apply(_View$prototype$remov, [this].concat(args));
  206. };
  207. VisualizationPanelView.prototype.render = function render() {
  208. var _this4 = this;
  209. this._showLoadingIndicator();
  210. return this.getEntries().then(function (data) {
  211. _this4.items = data.items;
  212. _this4.options = data.options;
  213. return _this4._separateVisBaseOnFunctionality(data.items);
  214. }).then(function () {
  215. _this4.viewState.handlers = {
  216. componentDidMountCallback: _this4._componentDidMountCallback.bind(_this4),
  217. componentWillUnmountCallback: _this4._componentWillUnmountCallback.bind(_this4),
  218. refreshCustomVisDefinitions: _this4._refreshCustomVisDefinitions.bind(_this4),
  219. isSchematicType: _this4.isSchematicType.bind(_this4),
  220. isSDKActive: _this4._isSDKActive.bind(_this4),
  221. isSchematicTypePreview: _this4.isSchematicTypePreview.bind(_this4)
  222. };
  223. ReactDOM.render(React.createElement(VisualizationTabs, {
  224. tabs: _this4.viewState,
  225. dashboardApi: _this4.dashboardApi,
  226. selectedTab: _this4.selectedTab,
  227. customVisAction: _this4.customVisAction
  228. }), _this4.$el[0]);
  229. }).finally(function () {
  230. _this4._hideLoadingIndicator();
  231. _this4._dropZone = _this4.dndManager.addDropTarget(_this4.$el[0], { accepts: _this4._accepts.bind(_this4) });
  232. });
  233. };
  234. VisualizationPanelView.prototype._createViewStates = function _createViewStates() {
  235. this.viewState = {
  236. system: {
  237. items: []
  238. },
  239. custom: {
  240. preview: {
  241. previewItems: []
  242. },
  243. visuals: {
  244. items: []
  245. }
  246. }
  247. };
  248. };
  249. VisualizationPanelView.prototype._showLoadingIndicator = function _showLoadingIndicator() {
  250. this.$el.append(this.loadingIndicatorTemplate({}));
  251. this.loadingIndicatorContainer = this.$el.find('.loadingIndicatorContainer');
  252. this.loadingIndicator = this.loadingIndicatorContainer.find('.loading_indicator');
  253. ReactDOM.render(React.createElement(ProgressIndicator, null), this.loadingIndicator.get(0));
  254. };
  255. VisualizationPanelView.prototype._hideLoadingIndicator = function _hideLoadingIndicator() {
  256. if (this.loadingIndicatorContainer) {
  257. this.loadingIndicatorContainer.remove();
  258. this.loadingIndicatorContainer = null;
  259. ReactDOM.unmountComponentAtNode(this.loadingIndicator.get(0));
  260. }
  261. };
  262. VisualizationPanelView.prototype._accepts = function _accepts() {
  263. return true;
  264. };
  265. VisualizationPanelView.prototype._componentDidMountCallback = function _componentDidMountCallback(containerSelector, visItemSelector, $node) {
  266. var _this5 = this;
  267. if ($node instanceof $) {
  268. $node.hammer();
  269. $node.on('hold', this._onItemHoldAndStartDrag.bind(this));
  270. } else {
  271. var selector = _geVisItemSelector([containerSelector, visItemSelector]);
  272. var $items = this.$el.find(selector);
  273. _.each($items, function (item) {
  274. var $item = $(item);
  275. $item.hammer();
  276. $item.on('hold', _this5._onItemHoldAndStartDrag.bind(_this5));
  277. });
  278. }
  279. };
  280. VisualizationPanelView.prototype._componentWillUnmountCallback = function _componentWillUnmountCallback(containerSelector, visItemSelector, $node) {
  281. var _this6 = this;
  282. if ($node instanceof $) {
  283. $node.off('hold', this._onItemHoldAndStartDrag.bind(this));
  284. } else {
  285. var selector = _geVisItemSelector([containerSelector, visItemSelector]);
  286. var $items = this.$el.find(selector);
  287. _.each($items, function (item) {
  288. var $item = $(item);
  289. $item.off('hold', _this6._onItemHoldAndStartDrag.bind(_this6));
  290. });
  291. }
  292. };
  293. VisualizationPanelView.prototype._refreshCustomVisDefinitions = function _refreshCustomVisDefinitions() {
  294. var _this7 = this;
  295. var freshAll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  296. if (!this.getEntries) {
  297. return Promise.reject('Invalid getEntries api provided');
  298. }
  299. var visDefinitionAPI = this.dashboardApi.getFeature('VisDefinitions');
  300. if (!this._refreshPromise) {
  301. this._refreshPromise = visDefinitionAPI.refresh().then(this.getEntries.bind(this)).then(function () {
  302. var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  303. var items = data.items || [];
  304. _this7.items = items;
  305. return _this7._separateVisBaseOnFunctionality(items);
  306. }).then(function () {
  307. _this7._refreshPromise = null;
  308. return freshAll ? _this7.viewState : _this7.viewState.custom.visuals.items;
  309. }).catch(function (err) {
  310. _this7._refreshPromise = null;
  311. throw err;
  312. });
  313. }
  314. return this._refreshPromise;
  315. };
  316. VisualizationPanelView.prototype._isSDKActive = function _isSDKActive() {
  317. var _this8 = this;
  318. if (!this._sdkPromise) {
  319. this._sdkPromise = VidaSdkUtil.isSDKActive(this.dashboardApi).then(function (sdkIsActive) {
  320. if (sdkIsActive) {
  321. if (_this8._refreshPromise) {
  322. // prevent multiple refreshes from happening at the same time.
  323. return _this8._refreshPromise.then(_this8._refreshCustomVisDefinitions.bind(_this8, true));
  324. } else {
  325. return _this8._refreshCustomVisDefinitions(true);
  326. }
  327. } else {
  328. throw new Error('SDK is not active');
  329. }
  330. }).then(function () {
  331. _this8._sdkPromise = null;
  332. return true;
  333. }).catch(function () {
  334. _this8._sdkPromise = null;
  335. return false;
  336. });
  337. }
  338. return this._sdkPromise;
  339. };
  340. VisualizationPanelView.prototype._separateVisBaseOnFunctionality = function _separateVisBaseOnFunctionality() {
  341. var _this9 = this;
  342. var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  343. var customPreviewVis = [];
  344. var customExtVis = [];
  345. var systemVis = this.viewState.system.items = [];
  346. var schematicBundles = [];
  347. var visPreview = void 0;
  348. var svgPreview = void 0;
  349. var CustomVisual_32 = this.dashboardApi.getFeature('Icons').getIcon('customVisual');
  350. items.forEach(function (item) {
  351. var bundle = VIPRConfig.getConfig(item.name);
  352. var isCustomVis = bundle && bundle.isCustomVis;
  353. var isSchematic = bundle && bundle.isSchematic;
  354. if (item.name === SKD_VIS_PREVIEW) {
  355. visPreview = item;
  356. } else if (item.name === CUS_VIS_SCHEMATIC_PREVIEW) {
  357. svgPreview = item;
  358. } else if (isCustomVis) {
  359. if (!item.icon) {
  360. //Default to generic icon
  361. item.icon = CustomVisual_32.id;
  362. }
  363. item.isCustomVis = isCustomVis;
  364. customExtVis.push(item);
  365. } else if (isSchematic) {
  366. item.isSchematic = isSchematic;
  367. schematicBundles.push({
  368. item: item,
  369. bundle: bundle
  370. });
  371. } else {
  372. systemVis.push(item);
  373. }
  374. });
  375. // Add visualizationPreview first
  376. if (visPreview) {
  377. customPreviewVis.push(visPreview);
  378. } else {
  379. //add a dummy visPreview just in case the user has develop permission but SDK is not running
  380. customPreviewVis.push({
  381. name: 'visualizationPreview',
  382. label: StringResources.get('customVisTestVisualization')
  383. });
  384. }
  385. //Add SVG preview second
  386. if (svgPreview) {
  387. customPreviewVis.push(svgPreview);
  388. }
  389. return this._getSchematicSVGContext(schematicBundles).then(function () {
  390. _this9.viewState.custom.preview.previewItems = customPreviewVis;
  391. var schematicItems = schematicBundles.map(function (bundle) {
  392. return bundle.item;
  393. });
  394. _this9.viewState.custom.visuals.items = _.sortBy([].concat(customExtVis, schematicItems), function (item) {
  395. return item.label;
  396. });
  397. });
  398. };
  399. VisualizationPanelView.prototype._getSchematicSVGContext = function _getSchematicSVGContext() {
  400. var _this10 = this;
  401. var schematicBundles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  402. var promises = [];
  403. schematicBundles.forEach(function (schematic) {
  404. var payload = {
  405. method: 'get',
  406. type: 'meta',
  407. library: schematic.bundle.id
  408. };
  409. promises.push(schematic.bundle.schematicVis.getSchematicContent(payload, _this10.dashboardApi));
  410. });
  411. return Promise.all(promises).then(function () {
  412. var responses = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  413. responses.forEach(function (response, idx) {
  414. var bundle = schematicBundles[idx];
  415. var metadata = JSON.parse(response) || {};
  416. var content = metadata.content || [];
  417. bundle.item.numSVGs = content.length;
  418. if (bundle.bundle.icon) {
  419. bundle.item.placeholderIcon = bundle.bundle.placeholderIcon + SchematicVis.cleanseFilename(bundle.bundle.icon);
  420. } else {
  421. var SchematicVisual_32 = _this10.dashboardApi.getFeature('Icons').getIcon('schematicVisual');
  422. bundle.item.icon = SchematicVisual_32.id;
  423. }
  424. });
  425. });
  426. };
  427. VisualizationPanelView.prototype._getEntry = function _getEntry(event) {
  428. var $node = $(event.target);
  429. var $target = $node.closest('.prop-item');
  430. var targetName = $target.data('name');
  431. var targetItem = this.items.find(function (item) {
  432. return item.name === targetName;
  433. });
  434. //The content contains the svg that only gets use for Drag and Drop
  435. return targetItem.content;
  436. };
  437. VisualizationPanelView.prototype._onItemKeyDown = function _onItemKeyDown(event) {
  438. if (event.keyCode === KeyCodes.ENTER || event.keyCode === KeyCodes.SPACE) {
  439. this._onItemClick(event);
  440. }
  441. };
  442. VisualizationPanelView.prototype._onItemClick = function _onItemClick(event) {
  443. var currentTarget = event.currentTarget;
  444. if ($.data(currentTarget, '_clickEventReceived') !== true) {
  445. // Guard against adding two widgets at once during a double click.
  446. $.data(currentTarget, '_clickEventReceived', true);
  447. setTimeout(function () {
  448. $.data(currentTarget, '_clickEventReceived', false);
  449. }, 500);
  450. if (this.options.onItemClick) {
  451. var entry = this._getEntry(event);
  452. this.options.onItemClick(entry, event);
  453. if (event && event.gesture) {
  454. event.gesture.preventDefault();
  455. }
  456. }
  457. }
  458. };
  459. VisualizationPanelView.prototype._onStartDrag = function _onStartDrag(event) {
  460. if (this.options.onItemStartDrag) {
  461. if (event.preventDefault) {
  462. // prevent default drag behavior
  463. event.preventDefault();
  464. }
  465. var entry = this._getEntry(event);
  466. this.options.onItemStartDrag(entry, event);
  467. }
  468. };
  469. VisualizationPanelView.prototype._onItemHoldAndStartDrag = function _onItemHoldAndStartDrag(event) {
  470. event.showAvatarImmediately = true;
  471. this._onStartDrag(event);
  472. };
  473. VisualizationPanelView.prototype._onItemMouseDownStartDrag = function _onItemMouseDownStartDrag(event) {
  474. this._onStartDrag(event);
  475. };
  476. VisualizationPanelView.prototype.isSchematicType = function isSchematicType() {
  477. var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  478. return item.name === CUS_VIS_SCHEMATIC_PREVIEW || item.isSchematic;
  479. };
  480. VisualizationPanelView.prototype.isSchematicTypePreview = function isSchematicTypePreview() {
  481. var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  482. return item.name === CUS_VIS_SCHEMATIC_PREVIEW;
  483. };
  484. return VisualizationPanelView;
  485. }(View);
  486. });
  487. //# sourceMappingURL=VisualizationPanelView.js.map