DashboardController.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. 'use strict';
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2017, 2020
  5. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  6. */
  7. define(['../../../lib/@waca/core-client/js/core-client/ui/core/Class', '../../../lib/@waca/dashboard-common/dist/utils/ObjectHelper', 'jquery'], function (Class, ObjectHelper, $) {
  8. var DashboardController = Class.extend({
  9. init: function init(options) {
  10. DashboardController.inherited('init', this, arguments);
  11. this.view = options.view;
  12. this.glassContext = options.glassContext;
  13. this.eventRouter = options.eventRouter;
  14. this.services = options.services;
  15. this.widgetRegistry = options.widgetRegistry;
  16. this.featuresOverride = options.featuresOverride || {};
  17. this.FrozenWidgetRegistry = null;
  18. var _ref = options.appSettings || {},
  19. _ref$options = _ref.options;
  20. _ref$options = _ref$options === undefined ? {} : _ref$options;
  21. var _ref$options$collecti = _ref$options.collections,
  22. collections = _ref$options$collecti === undefined ? {} : _ref$options$collecti,
  23. _ref$options$config = _ref$options.config,
  24. config = _ref$options$config === undefined ? {} : _ref$options$config;
  25. this.collectionsConfig = collections;
  26. this.config = config;
  27. },
  28. createContent: function createContent(boardModel) {
  29. var options = {
  30. featureLoader: this.featureLoader,
  31. dashboardFeatures: this.featureLoader,
  32. boardModel: boardModel,
  33. type: 'dashboard'
  34. };
  35. var contentFactory = this.featureLoader.getFeature('ContentFactory');
  36. this._dashboardContent = contentFactory.createContent(options);
  37. return this._dashboardContent.initialize();
  38. },
  39. getFeature: function getFeature(name) {
  40. var feature = void 0;
  41. if (this.featureLoader) {
  42. feature = this.featureLoader.getFeature(name);
  43. }
  44. if (!feature) {
  45. try {
  46. feature = this.getDashboardCoreSvc(name);
  47. } catch (e) {
  48. // Ignore if getDashboardCoreSvc threw a missing feature error. getFeature should never throw a fault.
  49. // and won't once we clean up the old service stuff
  50. }
  51. }
  52. return feature;
  53. },
  54. setDirty: function setDirty(dirty) {
  55. // Sync dirty state to undoredo controller
  56. if (this.view.boardController && this.view.boardController.undoRedoController) {
  57. this.view.boardController.undoRedoController.setDirty(dirty);
  58. }
  59. this.view.trigger('change:dirty', {
  60. value: dirty
  61. });
  62. this.view.eventRouter.trigger('change:dirty', {
  63. value: dirty
  64. });
  65. },
  66. setServices: function setServices(services) {
  67. this.services = services;
  68. },
  69. setFeatureLoader: function setFeatureLoader(featureLoader) {
  70. this.featureLoader = featureLoader;
  71. },
  72. /**
  73. * Return the current content view
  74. */
  75. getCurrentContentView: function getCurrentContentView() {
  76. return this.view;
  77. },
  78. /**
  79. * Return the canvas API. This method might retrun null if the canvas is not ready yet
  80. */
  81. getCanvas: function getCanvas() {
  82. // The deprecated canvas contains all the deprecated api + the proper public apis
  83. return this.view.getDeprecatedCanvas();
  84. },
  85. /**
  86. * Return a promise that will be resolved with the canvas API
  87. */
  88. getCanvasWhenReady: function getCanvasWhenReady() {
  89. // The deprecated canvas contains all the deprecated api + the proper public apis
  90. return this.view.getDeprecatedCanvasWhenReady();
  91. },
  92. isDevInstall: function isDevInstall() {
  93. return this.glassContext.isDevInstall();
  94. },
  95. /**
  96. * Add a new widget to the canvas or new content to selected widgets
  97. *
  98. * @param {object} - options containing the widget to be added
  99. */
  100. addContentToCanvas: function addContentToCanvas(options) {
  101. this.view.boardController.addDataItemsOrAddWidget(options);
  102. },
  103. /**
  104. * Return the application name
  105. */
  106. getApplicationName: function getApplicationName() {
  107. return this.glassContext.appController.getCurrentPerspective();
  108. },
  109. /**
  110. * Return the localized application name
  111. */
  112. getApplicationLabel: function getApplicationLabel() {
  113. return this.view.getApplicationLabel();
  114. },
  115. /**
  116. * Reload the dashboard using a give json specified
  117. * @param {object} JSONSpec An object that represents a dashboard spec
  118. * @param {object} extOptions extra options to use when re-initializing BaseBoardView
  119. * @returns {Promise} The resolved object is the new dashboardApi instance from the reinitialization of the dashboad from the given spec
  120. */
  121. reloadFromJSONSpec: function reloadFromJSONSpec(JSONspec, extOptions) {
  122. return this.view.reloadFromJSONSpec(JSONspec, extOptions);
  123. },
  124. /**
  125. * Return the CDN url
  126. */
  127. getCDNUrl: function getCDNUrl() {
  128. return this.view.getCDNUrl();
  129. },
  130. /**
  131. * Get layout
  132. *
  133. * @param {string} id - layout id
  134. *
  135. * @return {Layout} layout
  136. *
  137. * @deprecated Use getCanvas().getLayout instead
  138. */
  139. getLayout: function getLayout(id) {
  140. return this.view.boardController.layoutController.getView(id);
  141. },
  142. /**
  143. * Glassify the options a.k.a - make an options object ready to be passed to a glass dependant component
  144. *
  145. * @param {object} options to be glassified.
  146. *
  147. */
  148. prepareGlassOptions: function prepareGlassOptions(options) {
  149. options.glassContext = this.glassContext;
  150. },
  151. /**
  152. * Open a glass application view
  153. *
  154. * @param {string} name - application anme
  155. * @param {object} options - application options.
  156. *
  157. */
  158. openGlassApplication: function openGlassApplication(name, options) {
  159. return this.glassContext.appController.openAppView(name, options);
  160. },
  161. /**
  162. * Close a glass application view
  163. *
  164. * @param {string} name - application name
  165. * @param {object} id - id of the application being closed.
  166. * @param {object} options - application options.
  167. *
  168. */
  169. closeGlassApplication: function closeGlassApplication(name, id, options) {
  170. return this.glassContext.appController.closeAppView(name, id, options);
  171. },
  172. /**
  173. * Return a collection config specified through the perspective
  174. * @param {string} name collection name
  175. * @return {object} config value
  176. */
  177. getCollectionConfig: function getCollectionConfig(name) {
  178. return this.collectionsConfig[name];
  179. },
  180. /**
  181. * Return a config specified through the perspective
  182. * @param {string} config name
  183. * @return {object} config value
  184. */
  185. getAppConfig: function getAppConfig(name) {
  186. return this.config[name];
  187. },
  188. /**
  189. * Return a dashboard service
  190. * @param {string} name service name
  191. * @return {Promise} - resolved with the service object
  192. */
  193. getDashboardSvc: function getDashboardSvc(name) {
  194. return this.services.getSvc(name);
  195. },
  196. /**
  197. * Register a dashboard service
  198. * @param {string} name service name
  199. * @param {Object} service service object
  200. *
  201. */
  202. registerDashboardSvc: function registerDashboardSvc(name, service) {
  203. return this.services.register(name, service);
  204. },
  205. /**
  206. * Return a dashboard core service
  207. * @param {string} name service name
  208. * @return {Object} - Service object
  209. */
  210. getDashboardCoreSvc: function getDashboardCoreSvc(name) {
  211. return this.services.getSvcSync(name);
  212. },
  213. /**
  214. * Return a glass service
  215. * @param {string} name service name
  216. * @return {Promise} - resolved with the service object
  217. */
  218. getGlassSvc: function getGlassSvc(name) {
  219. return this.glassContext.getSvc(name);
  220. },
  221. /**
  222. * Return a glass core service
  223. * @param {string} name service name
  224. * @return {Object} - Service object
  225. */
  226. getGlassCoreSvc: function getGlassCoreSvc(name) {
  227. return this.glassContext.getCoreSvc(name);
  228. },
  229. /**
  230. * Show an error message
  231. * @param {string} message
  232. * @param {string} title
  233. */
  234. showErrorMessage: function showErrorMessage(message, title) {
  235. return this.glassContext.appController.showErrorMessage(message, title);
  236. },
  237. /**
  238. * Show a message in the UI
  239. * @param {string} message
  240. */
  241. showMessage: function showMessage(message) {
  242. return this.glassContext.appController.showMessage(message);
  243. },
  244. /**
  245. * Show a toast message in the UI
  246. * @param {string} message
  247. * @param {object} options - toast options
  248. */
  249. showToast: function showToast(message, options) {
  250. return this.glassContext.appController.showToast(message, options);
  251. },
  252. /**
  253. * Show a glass slideout
  254. * @param {object} options - slideout options
  255. */
  256. showSlideOut: function showSlideOut(options) {
  257. return this.glassContext.appController.showSlideOut(options);
  258. },
  259. /**
  260. * Show a glass context menu
  261. * @param {object} options - context menu options
  262. */
  263. showContextMenu: function showContextMenu(options) {
  264. return this.glassContext.appController.showContextMenu(options);
  265. },
  266. /**
  267. * Find a glass plugin
  268. * @param {string} name - plugin name
  269. * @return {object} glass plugin object
  270. */
  271. findGlassPlugin: function findGlassPlugin(name) {
  272. return this.glassContext.appController.findPlugin(name);
  273. },
  274. /**
  275. * Find a glass collection
  276. * @param {string} name - plugin name
  277. * @return {Promise} promise resolved with the collection
  278. */
  279. findGlassCollection: function findGlassCollection(name) {
  280. var _this = this;
  281. return this.glassContext.appController.findCollection(name).then(function () {
  282. var collection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  283. var featureOverride = _this.featuresOverride[name] || {};
  284. var excludes = featureOverride.excludes || [];
  285. return collection.filter(function (item) {
  286. return !(excludes.indexOf(item.name) !== -1);
  287. });
  288. });
  289. },
  290. /**
  291. * Open a glass app view
  292. * @param {string} name
  293. * @param {object} options
  294. */
  295. openAppView: function openAppView(name, options) {
  296. return this.glassContext.appController.openAppView(name, options);
  297. },
  298. /**
  299. * @deprecated Use getCanvas().getSelectedWidgets() instead
  300. */
  301. getSelectedWidgets: function getSelectedWidgets() {
  302. return this.view.getSelectedWidgets();
  303. },
  304. /**
  305. * Set the permissions on the dashboard
  306. * @param {object} permissions
  307. */
  308. setPermissions: function setPermissions(permissions) {
  309. this.view.setPermissions(permissions);
  310. },
  311. /**
  312. * Checks for write access to the dashboard
  313. */
  314. canAuthor: function canAuthor() {
  315. return this.view.canAuthor();
  316. },
  317. /**
  318. * Destroy the dashboard - clean up
  319. */
  320. destroy: function destroy() {
  321. DashboardController.inherited('init', this, arguments);
  322. if (this.services) {
  323. this.services.destroy();
  324. }
  325. if (this.featureLoader) {
  326. this.featureLoader.destroy();
  327. }
  328. if (this._dashboardContent) {
  329. this._dashboardContent.destroy();
  330. this._dashboardContent = null;
  331. }
  332. this.view = null;
  333. this.glassContext = null;
  334. this.eventRouter = null;
  335. this.services = null;
  336. this.collectionsConfig = null;
  337. this.config = null;
  338. this.widgetRegistry = null;
  339. this.services = null;
  340. this.featureLoader = null;
  341. },
  342. /**
  343. * Map between API event names and internal event names
  344. */
  345. eventMap: {
  346. dirty: 'change:dirty'
  347. },
  348. /**
  349. * Register an event handler for dashboard events
  350. * @param {string} eventName Name of the dashboard event
  351. * @param {function} handler Event handler to be called when the event occurrs
  352. */
  353. on: function on(eventName, callback, context) {
  354. if (!eventName) {
  355. return;
  356. }
  357. var name = this.eventMap[eventName] || eventName;
  358. return this.eventRouter.on(name, callback, context);
  359. },
  360. /**
  361. * Unregister an event handler for dashboard events
  362. * @param {string} eventName Name of the dashboard event
  363. * @param {function} handler Event handler to be called when the event occurrs
  364. */
  365. off: function off(eventName, callback, context) {
  366. if (!eventName) {
  367. return;
  368. }
  369. var name = this.eventMap[eventName] || eventName;
  370. this.eventRouter.off(name, callback, context);
  371. },
  372. /**
  373. * Trigger a dashboard event
  374. * @param {string} eventName Name of the dashboard event
  375. * @param {object} payload Event payload
  376. */
  377. triggerDashboardEvent: function triggerDashboardEvent(eventName, payload) {
  378. if (!eventName) {
  379. return;
  380. }
  381. var name = this.eventMap[eventName] || eventName;
  382. this.eventRouter.trigger(name, payload);
  383. },
  384. /**
  385. * Relink an existing source to a new module.
  386. * Widgets that reference this source will reload after the relink is finished.
  387. * @param {String} sourceInfo.id Id of the source to relink. This id is passed to the caller in the relink:clicked event
  388. * @param {String=} sourceInfo.cognosAssetId Cognos Content Story ID.
  389. * @param {String=} sourceInfo.module The module definition
  390. * @param {String=} sourceInfo.type The type of the source, only needed if using cognosAssetId and the type if the source is changing.
  391. * @param {String=} sourceInfo.name Name of the source, only needed if you wish to change the name.
  392. */
  393. relink: function relink() /*sourceInfo*/{
  394. // var dataSourcesSvc = this.services.getSvcSync('dataSources');
  395. // dataSourcesSvc.relink(this.oDataSource, oNewDataSourceObj);
  396. },
  397. /**
  398. * Change the mode between authoring, consumption and eventGroups
  399. * @param {string} mode
  400. */
  401. setMode: function setMode(mode) {
  402. var promise = void 0;
  403. var contentView = this.view;
  404. if (contentView) {
  405. if (mode === 'eventGroups' && !contentView.isEventGroupViewMode || mode !== 'eventGroups' && contentView.isEventGroupViewMode) {
  406. // toggle from/to 'eventGroup'
  407. promise = contentView.toggleEventGroupMode(mode);
  408. } else if (mode === 'authoring' && !contentView.isAuthoringMode || mode === 'consumption' && contentView.isAuthoringMode) {
  409. promise = contentView.toggleMode();
  410. }
  411. // Ensure the properties pane is closed in eventGroup or consumption mode
  412. if (contentView.isEventGroupViewMode || !contentView.isAuthoringMode) {
  413. this.toggleProperties(false);
  414. }
  415. }
  416. return promise || Promise.reject(new Error('Cannot set mode without a content view'));
  417. },
  418. getMode: function getMode() {
  419. var contentView = this.view;
  420. if (contentView) {
  421. return contentView.isEventGroupViewMode ? 'eventGroups' : contentView.isAuthoringMode ? 'authoring' : 'consumption';
  422. }
  423. },
  424. /**
  425. * Get the dashboard instance specification
  426. * @return {Object} dashboard spec
  427. */
  428. getSpec: function getSpec() {
  429. var contentView = this.view;
  430. if (contentView && contentView.getContent) {
  431. var content = contentView.getContent();
  432. return content.boardSpec;
  433. }
  434. },
  435. /**
  436. * Undo the last action performed on the dashboard
  437. */
  438. undo: function undo() {
  439. var contentView = this.view;
  440. if (contentView) {
  441. contentView.doUndo();
  442. }
  443. },
  444. /**
  445. * Reverse the last undo performed on the dashboard
  446. */
  447. redo: function redo() {
  448. var contentView = this.view;
  449. if (contentView) {
  450. contentView.doRedo();
  451. }
  452. },
  453. /**
  454. * Toggle the properties pane
  455. * @param {boolean} [toggle] if <tt>true</tt> display the properties pane, otherwise hide the properties pane.
  456. * @param {Object} [context] Optional context for toggling properties pane
  457. */
  458. toggleProperties: function toggleProperties(toggle, context) {
  459. var contentView = this.view;
  460. if (contentView) {
  461. var controller = contentView.boardController;
  462. var dashboardAuthoringToolsPane = contentView.dashboardApi.getFeature('InAppSlideoutState');
  463. var propertiesManager = controller.getExtension('propertiesManager');
  464. var selectTab = function selectTab() {
  465. propertiesManager.getPropertyControl('tabControl').selectTabByName(context.tabName);
  466. };
  467. // in case an invalid toggle state (non-boolean) is given, simply toggle the state
  468. if (typeof toggle !== 'boolean') {
  469. toggle = !propertiesManager.isSlideoutOpen();
  470. }
  471. // Properties pane is always off on event group and consumption mode
  472. toggle = contentView.isEventGroupViewMode || !contentView.isAuthoringMode ? false : toggle;
  473. context = context || {};
  474. // close the pane when in non authoring (consumption and fullscreen) and event group mode
  475. if (contentView.isEventGroupViewMode || !contentView.isAuthoringMode) {
  476. dashboardAuthoringToolsPane && dashboardAuthoringToolsPane.close();
  477. }
  478. //TODO: remove the following block when the focus mode epic is ready
  479. if (propertiesManager.isSlideoutOpen()) {
  480. if (!toggle) {
  481. propertiesManager.hide();
  482. } else if (context.tabName) {
  483. selectTab();
  484. }
  485. } else if (toggle && !propertiesManager.isSlideoutOpen()) {
  486. propertiesManager.show({
  487. 'context': context,
  488. 'onSetFocus': context.tabName ? selectTab : null
  489. });
  490. }
  491. }
  492. },
  493. /**
  494. * @returns an object containing dashboard information (isDirty, dashboard id and dashboard search path)
  495. */
  496. getDashboardInfo: function getDashboardInfo() {
  497. return this.view.getBoardInfo();
  498. },
  499. /**
  500. * Select widget
  501. *
  502. * @param {string} widgetId - widget id to select
  503. */
  504. selectWidget: function selectWidget(widgetId) {
  505. var _view$boardController = this.view.boardController;
  506. _view$boardController = _view$boardController === undefined ? {} : _view$boardController;
  507. var layoutController = _view$boardController.layoutController;
  508. if (layoutController) {
  509. return layoutController.getInteractionController().then(function (controller) {
  510. var widgetEl = $('#' + widgetId).get(0);
  511. controller.selectionHandler.selectNode(widgetEl);
  512. });
  513. }
  514. return Promise.reject(new Error('Unable to select widget. Canvas not fully initialized.'));
  515. },
  516. deselectAllWidgets: function deselectAllWidgets() {
  517. var _view$boardController2 = this.view.boardController;
  518. _view$boardController2 = _view$boardController2 === undefined ? {} : _view$boardController2;
  519. var layoutController = _view$boardController2.layoutController;
  520. if (layoutController) {
  521. return layoutController.getInteractionController().then(function (controller) {
  522. controller.selectionHandler.deselectAll();
  523. });
  524. }
  525. return Promise.resolve();
  526. },
  527. getToolbarActions: function getToolbarActions() {
  528. var toolbarItems = this.view.boardController && this.view.boardController.layoutController && this.view.boardController.layoutController.interactionController && this.view.boardController.layoutController.interactionController.toolbarItems;
  529. return toolbarItems;
  530. },
  531. /**
  532. * Waits till all widgets in input list are rendered
  533. *
  534. * @param {string[]} widgetIds
  535. * @param {Promise} number of widgets rendered
  536. */
  537. waitTillWidgetsRendered: function waitTillWidgetsRendered(widgetIds) {
  538. if (!widgetIds || widgetIds.length === 0) {
  539. return Promise.resolve(0);
  540. }
  541. return this.getCanvasWhenReady().then(function (canvas) {
  542. var promises = [];
  543. var renderCount = 0;
  544. widgetIds.forEach(function (widgetId) {
  545. var prom = canvas.getWidgetWhenReady(widgetId);
  546. promises.push(prom);
  547. });
  548. return Promise.all(promises).then(function (widgetApis) {
  549. var renderPromises = [];
  550. widgetApis.forEach(function (widgetApi) {
  551. var prom2 = widgetApi.whenRenderComplete().then(function () {
  552. renderCount++;
  553. });
  554. renderPromises.push(prom2);
  555. });
  556. return Promise.all(renderPromises).then(function () {
  557. return renderCount;
  558. });
  559. });
  560. });
  561. },
  562. /**
  563. * get live widget registry
  564. *
  565. * @return a copy of live widget registry
  566. */
  567. getWidgetRegistry: function getWidgetRegistry() {
  568. if (!this.FrozenWidgetRegistry) {
  569. this.FrozenWidgetRegistry = ObjectHelper.deepFreezeObject(JSON.parse(JSON.stringify(this.widgetRegistry)));
  570. }
  571. return this.FrozenWidgetRegistry;
  572. },
  573. /**
  574. * Copy the selected widget(s) on the dashboard
  575. */
  576. copy: function copy() {
  577. var contentView = this.view;
  578. if (contentView) {
  579. contentView.doCopy();
  580. }
  581. },
  582. /**
  583. * Paste the selected widget(s) on the dashboard
  584. */
  585. paste: function paste() {
  586. var contentView = this.view;
  587. if (contentView) {
  588. return contentView.doPaste();
  589. }
  590. return Promise.reject();
  591. },
  592. getContent: function getContent() {
  593. return this._dashboardContent && this._dashboardContent.getAPI();
  594. }
  595. });
  596. return DashboardController;
  597. });
  598. //# sourceMappingURL=DashboardController.js.map