BoardLoader.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. 'use strict';
  2. /*
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 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', 'jquery', '../../canvas/CanvasFactory', './WidgetLoader', '../../lib/@waca/core-client/js/core-client/utils/ClassFactory', './DeploymentReferencesUtil', 'underscore', '../../extension/Extensions', './BoardLoaderHelper', '../../lib/@waca/core-client/js/core-client/utils/Deferred'], function (BaseClass, $, CanvasFactory, WidgetLoader, ClassFactory, DeploymentReferencesUtil, _, Extensions, BoardLoaderHelper, Deferred) {
  8. /**
  9. * The board loader's responsibility is to load a dashboard. The board loader will be used in two main scenarios:
  10. *
  11. * 1. Loading a board from within the Gemini app (e.g from the homepage)
  12. * 2. Loading a board directly from a URL
  13. *
  14. * @param options
  15. *
  16. * boardSpec The board specification if avaialble, otherwise the spec will be fetched using the board ID
  17. * boardId The board ID used to fetch the spec
  18. * isAuthoringMode Set to true if the board is being loaded in authoring mode
  19. * el The element to render the board layout to
  20. * isLayoutRendered Set to false if the board's layout hasn't already been rendered
  21. *
  22. */
  23. var BoardLoader = BaseClass.extend({
  24. init: function init(options) {
  25. BoardLoader.inherited('init', this, arguments);
  26. options = options || {};
  27. // start - to be removed after done the refactoring
  28. this.glassContext = options.glassContext;
  29. this.appSettings = options.appSettings || {};
  30. this.services = options.services;
  31. this.ajaxSvc = options.ajaxSvc;
  32. // end - to be removed after done the refactoring
  33. this.dashboardApi = options.dashboardApi;
  34. this.eventRouter = options.eventRouter;
  35. this.boardSpec = options.boardSpec;
  36. this.addOnSpec = options.addOnSpec;
  37. this.specUrl = options.specUrl;
  38. this.boardModel = options.boardModel;
  39. this.setDirty = this.boardModel.isUpgraded || false;
  40. this.pageViewContentNode = options.el;
  41. this.contentNode = null;
  42. this.$viewEl = options.$viewEl;
  43. this.isLayoutRendered = options.isLayoutRendered;
  44. this._registry = options.widgetRegistry;
  45. this.gatewayUrl = options.gatewayUrl || '';
  46. this.cdnUrl = options.cdnUrl || '';
  47. this.currentVersion = options.currentVersion;
  48. this.logger = this.dashboardApi.getGlassCoreSvc('.Logger');
  49. this.stringResources = this.dashboardApi.getDashboardCoreSvc('.StringResources');
  50. this.extensions = options.extensions;
  51. this.boardLoaderHelper = new BoardLoaderHelper(this.dashboardApi);
  52. this.boardModuleFactory = this.boardLoaderHelper.createBoardModuleFactory(options.boardModules);
  53. // loading dfds
  54. this._canvasControllerDfd = new Deferred();
  55. this.featureLoader = options.featureLoader;
  56. this._dashboardController = options.dashboardController;
  57. this._colorsService = this.dashboardApi.getFeature('Colors');
  58. },
  59. getCanvasController: function getCanvasController() {
  60. return this._canvasControllerDfd.promise;
  61. },
  62. _createCanvas: function _createCanvas() {
  63. var _this = this;
  64. var factory = new CanvasFactory({
  65. dashboardAPI: this.dashboardApi,
  66. services: this.services,
  67. extensions: this.extensions,
  68. glassContext: this.glassContext,
  69. eventRouter: this.eventRouter,
  70. appSettings: this.appSettings,
  71. logger: this.logger,
  72. widgetRegistry: this._registry,
  73. featureLoader: this.featureLoader,
  74. boardModel: this.boardModel,
  75. dashboardContent: this._dashboardController.getContent()
  76. });
  77. return factory.createCanvas().then(function (factoryResponse) {
  78. _this.canvas = factoryResponse.canvas;
  79. _this.internalCanvas = factoryResponse.internalCanvas;
  80. });
  81. },
  82. _createDashboardContent: function _createDashboardContent() {
  83. return this._dashboardController.createContent(this.boardModel);
  84. },
  85. /**
  86. * Load the board
  87. *
  88. * @returns Deferred which is resolved once the board is loaded
  89. */
  90. loadBoard: function loadBoard() {
  91. return this._preDashboardInitialize().then(this._createDashboardContent.bind(this)).then(this._createCanvas.bind(this)).then(this._registerServices.bind(this)).then(this._initializeTranslationService.bind(this)).then(this._renderLayoutHtml.bind(this)).then(this._initBoardController.bind(this)).then(this._postDashboardInitialize.bind(this));
  92. },
  93. getCanvas: function getCanvas() {
  94. return this.canvas;
  95. },
  96. _initializeTranslationService: function _initializeTranslationService() {
  97. return this.dashboardApi.getDashboardSvc('TranslationService').then(function (translationService) {
  98. return translationService.initialize({ boardModel: this.boardModel, view: this.$viewEl });
  99. }.bind(this));
  100. },
  101. _getDashboardFrameNode: function _getDashboardFrameNode() {
  102. var parentNode = this.pageViewContentNode;
  103. var dashboardFrame = parentNode.querySelector('.dashboardFrame');
  104. if (!dashboardFrame) {
  105. dashboardFrame = document.createElement('div');
  106. dashboardFrame.setAttribute('class', 'dashboardFrame');
  107. var dashboardFrameCentre = document.createElement('div');
  108. dashboardFrameCentre.setAttribute('class', 'dashboardFrameCentre');
  109. var dashboardFrameRight = document.createElement('div');
  110. dashboardFrameRight.setAttribute('class', 'dashboardFrameRight');
  111. dashboardFrame.appendChild(dashboardFrameCentre);
  112. dashboardFrame.appendChild(dashboardFrameRight);
  113. parentNode.appendChild(dashboardFrame);
  114. }
  115. return dashboardFrame;
  116. },
  117. _getDashboardFrameCentreNode: function _getDashboardFrameCentreNode() {
  118. var dashboardFrame = this._getDashboardFrameNode();
  119. return dashboardFrame.querySelector('.dashboardFrameCentre');
  120. },
  121. _setContentNode: function _setContentNode() {
  122. this.contentNode = this._getDashboardFrameCentreNode();
  123. },
  124. /**
  125. * Render the layout HTML into the board's DOM element
  126. *
  127. * TODO: This is a bit awkward, it'd be nice if we could just create the board and if the DOM elements don't exist that
  128. * we'd create them on the fly.
  129. *
  130. * @returns deferred which is resolved once the HTML is rendered
  131. */
  132. _renderLayoutHtml: function _renderLayoutHtml() {
  133. var _this2 = this;
  134. // first set the content node where we want to render the content
  135. this._setContentNode();
  136. return this.boardLoaderHelper.loadLayoutExtensions(this.extensions.getLayoutViewExtensions(), this.boardModuleFactory).then(function (layoutExtensions) {
  137. _this2.boardLoaderHelper.registerLayoutExtensions(layoutExtensions);
  138. var html = _this2.dashboardApi.getFeature('htmlTemplates').getHtml(_this2.boardModel.layout, _this2.boardModel.widgetInstances);
  139. if (!_this2.isLayoutRendered) {
  140. _this2.contentNode.innerHTML = html;
  141. }
  142. });
  143. },
  144. /**
  145. * Initialize the board controller
  146. */
  147. _initBoardController: function _initBoardController() {
  148. var _this3 = this;
  149. return ClassFactory.loadModule('dashboard-core/js/dashboard/CanvasController').then(function (CanvasController) {
  150. _this3.widgetLoader = new WidgetLoader({
  151. // TODO begin to be removed
  152. glassContext: _this3.glassContext,
  153. services: _this3.services,
  154. appSettings: _this3.appSettings,
  155. // end to be removed
  156. dashboardApi: _this3.dashboardApi,
  157. eventRouter: _this3.eventRouter,
  158. widgetRegistry: _this3._registry,
  159. loadedWidgets: {},
  160. boardModel: _this3.boardModel,
  161. contentFeatureLoader: _this3.internalCanvas,
  162. canvas: _this3.getCanvas()
  163. });
  164. _this3.canvasController = new CanvasController({
  165. //begin to be removed
  166. glassContext: _this3.glassContext,
  167. services: _this3.services,
  168. appSettings: _this3.appSettings,
  169. //end to be removed
  170. dashboardApi: _this3.dashboardApi,
  171. eventRouter: _this3.eventRouter,
  172. $el: _this3.$viewEl,
  173. boardModel: _this3.boardModel,
  174. boardModuleFactory: _this3.boardModuleFactory,
  175. widgetLoader: _this3.widgetLoader,
  176. layoutExtensions: _this3.extensions.getLayoutViewExtensions(),
  177. boardLoader: _this3,
  178. gatewayUrl: _this3.gatewayUrl,
  179. cdnUrl: _this3.cdnUrl,
  180. contentFeatureLoader: _this3.internalCanvas
  181. });
  182. // TODO - Explore and storyTelling are using this service
  183. // Should be removed
  184. _this3.dashboardApi.registerDashboardSvc('widgetLoader', {
  185. loadedWidgets: _this3.widgetLoader.loadedWidgets,
  186. loadingWidgets: _this3.widgetLoader.loadingWidgets,
  187. load: _this3.widgetLoader.loadWidget.bind(_this3.widgetLoader),
  188. unload: _this3.widgetLoader.unLoadWidget.bind(_this3.widgetLoader),
  189. isLoaded: _this3.widgetLoader.isLoaded.bind(_this3.widgetLoader),
  190. isLoading: _this3.widgetLoader.isLoading.bind(_this3.widgetLoader),
  191. getWidget: _this3.widgetLoader.getWidget.bind(_this3.widgetLoader)
  192. });
  193. return _this3.canvasController.initialize().then(function () {
  194. _this3._canvasControllerDfd.resolve(_this3.canvasController);
  195. });
  196. }).catch(function (err) {
  197. _this3.logger.error(err);
  198. // don't rethrow, recover
  199. // TODO: probably rethrowing is a good idea. if you're
  200. // brave enough and you know what you're doing, make it do that.
  201. });
  202. },
  203. _preDashboardInitialize: function _preDashboardInitialize() {
  204. return this.dashboardApi.getFeature('.LifeCycleManager').invokeLifeCycleHandlers('pre:dashboard.initialize');
  205. },
  206. _postDashboardInitialize: function _postDashboardInitialize() {
  207. return this.dashboardApi.getFeature('.LifeCycleManager').invokeLifeCycleHandlers('post:dashboard.initialize');
  208. },
  209. _registerServices: function _registerServices() {
  210. // TODO - these services must go away
  211. //Add the board loader services
  212. var services = this.boardLoaderHelper.createBoardServices({
  213. boardModel: this.boardModel,
  214. widgetRegistry: this._registry
  215. });
  216. this.smartNamingSvc = services.smartNamingSvc;
  217. },
  218. /**
  219. * Populate map of widgetId and containerPageId from given layout. populate recursively if layout has items
  220. * Widget can be determined by type of layout.
  221. */
  222. _mapContainerPageForWidgetsInLayout: function _mapContainerPageForWidgetsInLayout(layout, map, containerPageId) {
  223. map = map || {};
  224. if (layout.items) {
  225. for (var i = 0; i < layout.items.length; i++) {
  226. map = this._mapContainerPageForWidgetsInLayout(layout.items[i], map, containerPageId);
  227. }
  228. } else if (layout.type === 'widget') {
  229. map[layout.id] = containerPageId;
  230. }
  231. return map;
  232. },
  233. activate: function activate() {
  234. if (this._colorsService) {
  235. this._colorsService.enableTheme();
  236. }
  237. },
  238. deactivate: function deactivate() {
  239. if (this._colorsService) {
  240. this._colorsService.disableTheme();
  241. }
  242. },
  243. destroyViews: function destroyViews() {
  244. this.deactivate();
  245. // The canvasController and widget loader might not exist if we are loading an invalid dashboard( missing/invalid spec or no permissions)
  246. if (this.widgetLoader) {
  247. this.widgetLoader.cleanup();
  248. this.widgetLoader = null;
  249. }
  250. if (this.canvasController) {
  251. this.canvasController.destroy();
  252. this.canvasController = null;
  253. }
  254. },
  255. /**
  256. * Destroy the board loader
  257. */
  258. destroyCanvasAPI: function destroyCanvasAPI() {
  259. if (this.internalCanvas) {
  260. this.internalCanvas.destroy();
  261. this.internalCanvas = null;
  262. }
  263. },
  264. _hasPermission: function _hasPermission(permissions) {
  265. return _.indexOf(permissions, 'read') !== -1 && _.indexOf(permissions, 'execute') !== -1;
  266. }
  267. });
  268. return BoardLoader;
  269. });
  270. //# sourceMappingURL=BoardLoader.js.map