123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- '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
|