'use strict'; /** * Licensed Materials - Property of IBM * IBM Cognos Products: Storytelling (C) Copyright IBM Corp. 2017, 2019 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['baglass/core-client/js/core-client/ui/core/Class', 'react-dom', '../util/WidgetHelper'], function (Class, ReactDOM, WidgetHelper) { var SceneLoader = Class.extend({ init: function init(options) { SceneLoader.inherited('init', this, arguments); this.logger = options.logger; this.dashboardApi = options.dashboardApi; this.layoutController = options.layoutController; this._loadTimeout = options.loadTimeout || 10000; this._sceneLoadPromises = {}; this._loadSequence = []; this._loadSequenceGeneration = 0; this.widgetHelper = new WidgetHelper({ dashboardApi: this.dashboardApi }); }, loadScene: function loadScene(scene, options) { var _this = this; var refreshData = options && options.refreshData; // might be a better way, but for now we peek in the scene to see if there is anything to load. if (scene.isOverview) { return Promise.resolve(); } if (!this._sceneLoadPromises[scene.id] || refreshData) { var view = scene.getLayoutView(); // here we depend on the default scene css being having the hidden class (display:none) // so we remove that and set the scale to 0 // calling render() will kick the render sequence of the widgets since they are now 'visible' scene.$el.addClass('hiddenBackgroundLoadingScene').removeClass('hiddenScene'); view.render(); this._sceneLoadPromises[scene.id] = Promise.resolve(this.layoutController.whenPageRenderComplete(view.model)).then(function () { if (refreshData) { return _this._refreshData(view.model); } }).then(function () { _this.logger.debug('SceneLoader:loadScene: done loading scene: ', scene.id); _this._doneSceneBackgroundLoad(scene); }); } return this._sceneLoadPromises[scene.id]; }, _doneSceneBackgroundLoad: function _doneSceneBackgroundLoad(scene) { scene.$el.removeClass('hiddenBackgroundLoadingScene'); // In StoryView.js#render we render the React CenterLoadingSpinner before anything else // Here we attempt to remove it (once a single scene is done loading) var $contentViewEl = this.dashboardApi.getCurrentContentView().$el; ReactDOM.unmountComponentAtNode($contentViewEl[0]); }, waitForSceneToLoad: function waitForSceneToLoad(scene, options) { var _this2 = this; var showLoadingTimeout; return Promise.try(function () { // if the view is not ready within 500ms we display a loading screen to give the user feedback. showLoadingTimeout = setTimeout(function () { _this2.layoutController.getTopLayoutView().setLoading(true); }, 500); if (options && options.refreshData) { return _this2.loadScene(scene, options); } return _this2.loadScene(scene, options).timeout(_this2._loadTimeout); }).catch(Promise.TimeoutError, function () { _this2.logger.warn('Scene taking more than ' + _this2._loadTimeout / 1000 + ' seconds to load, loading the rest in background.'); _this2._doneSceneBackgroundLoad(scene); }).catch(function (error) { _this2.logger.error('SceneLoader:waitForSceneToLoad: Error ocurred loading scene: ', error); _this2._doneSceneBackgroundLoad(scene); // if we don't rethrow the error the returned promise will be resolved.. this seems to be the gemini way for now. // at some point we should rethrow and have the caller do something. }).finally(function () { clearTimeout(showLoadingTimeout); _this2.layoutController.getTopLayoutView().setLoading(false); }); }, /** * Starts loading an array of scenes in the background. * returns a promise that resolves when the all the scenes are loaded * @param scenes array of scenes. */ startBackgroundLoad: function startBackgroundLoad(scenes, options) { this._loadSequence = scenes.slice(); this._loadSequenceGeneration += 1; return Promise.try(function () { return this._doSequentialLoad(this._loadSequenceGeneration, options); }.bind(this)).catch(function (error) { this.logger.error('SceneLoader:waitForSceneToLoad:Error occurred pre-loading scene: ', error); // if we don't rethrow the error the returned promise will be resolved.. this seems to be the gemini way for now. // at some point we should rethrow and have the caller do something. return null; }.bind(this)); }, stopBackgroundLoad: function stopBackgroundLoad() { // this stops the loop in _doSequentialLoad this._loadSequenceGeneration = -1; }, _doSequentialLoad: function _doSequentialLoad(loadSequenceGeneration, options) { // if startBackgroundLoad is called again we stop since the order might have changed. if (loadSequenceGeneration !== this._loadSequenceGeneration) { return null; } var scene = this._loadSequence.shift(); if (!scene) { return null; } return this.loadScene(scene, options).then(function () { return this._doSequentialLoad(loadSequenceGeneration, options); }.bind(this)); }, _refreshData: function _refreshData(layoutModel) { var _this3 = this; var renderPromises = []; var widgetLayouts = layoutModel.findDescendantsWithType('widget'); widgetLayouts.forEach(function (widgetLayout) { var widget = _this3.widgetHelper.getWidget(widgetLayout.id); if (widget.getType() === 'live') { renderPromises.push(widget.getVisApi().ownerWidget.reRender({ sender: 'realtimeRefresh' })); } }); return Promise.all(renderPromises); } }); return SceneLoader; }); //# sourceMappingURL=SceneLoader.js.map