123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- 'use strict';
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- /*
- *+------------------------------------------------------------------------+
- *| Licensed Materials - Property of IBM
- *| IBM Cognos Products: Dashboard
- *| (C) Copyright IBM Corp. 2019, 2020
- *|
- *| US Government Users Restricted Rights - Use, duplication or disclosure
- *| restricted by GSA ADP Schedule Contract with IBM Corp.
- *+------------------------------------------------------------------------+
- */
- define(['./LiveWidget', '../../lib/@waca/core-client/js/core-client/ui/core/Events', '../../lib/@waca/core-client/js/core-client/utils/LoadCSSPromise', './nls/StringResources', 'underscore', 'dashboard-core/js/canvas/Content', 'dashboard-core/js/dashboard/model/LayoutModel', 'dashboard-core/js/features/content/InlineFeatures', './models/LiveWidgetModel'], function (LiveWidget, Events, LoadCSSPromise, StringResources, _, ContentImpl, LayoutModel, InlineFeatures, LiveWidgetModel) {
- var isCSSLoaded = false;
- var StandaloneLiveWidget = function () {
- /**
- * Create an instance of the live widget API
- *
- * @constructor
- * @param {Object} options.node Dom node where the live widget content will be created
- * @param {Object} options.glassContext Glass context that provide access to glass API
- * @param {Object} options.spec The live widget spec json.
- * @param {Object} options.inlineContentFeatures Content features to be loaded inline
- * @param {QueryResultsAPI} options.queryResults If provided, the LiveWidgetPreview will not issue a query for data and will use the queryResults instead
- * @example
- * let LiveWidget = new LiveWidgetAPI({
- * node: document.getElementById('containerDivId'),
- * glassContext: this.glassContext,
- * inlineContentFeatures: [{
- * "name": "QueryResultOverride",
- * "id": "com.ibm.bi.dashboard.live-features.queryResultOverride",
- * "class": "dashboard-analytics/features/widget/queryResultOverride/queryResultOverride"
- * }],
- * spec: {
- * "data": {
- * "dataViews": [
- * {
- * "model":{
- * "assetId": "iB3884FE9ACF64BD2B8F0879A8C34B978",
- * "type": "uploadedFile"
- * }
- * "dataItems": [
- * {
- * "itemId": "HollywoodMovies_xls.Year_",
- *
- * },
- * {
- * "itemId": "HollywoodMovies_xls.Rotten_Tomatoes"
- * }
- * ]
- * }
- * ]
- * }
- * }
- * });
- */
- function StandaloneLiveWidget(options) {
- _classCallCheck(this, StandaloneLiveWidget);
- this._destroyed = false;
- this.spec = JSON.parse(JSON.stringify(options.spec));
- this.spec.id = _.uniqueId('LW');
- this.spec.type = 'live';
- this.board = options.board;
- this.node = options.node;
- this._glassContext = options.glassContext;
- this.runtimeEnv = options.runtimeEnv;
- this.predictData = options.predictData;
- this.isPredictPreview = options.isPredictPreview;
- this._inlineContentFeatures = options.inlineContentFeatures || [];
- this._queryResults = options.queryResults;
- this._managesOwnQueries = options.managesOwnQueries;
- this._LayoutModelClass = options.layoutModelClass || LayoutModel;
- // TODO - temporary until explore starting sending the dashboard Api
- if (this.runtimeEnv && !this.runtimeEnv.dashboardApi) {
- this.runtimeEnv.dashboardApi = this._glassContext.appController.getCurrentContentView().getDashboardApi();
- }
- if (this.runtimeEnv && !this.runtimeEnv.dashboardFeatureLoader) {
- // Needed to be able to build a content API for the live widget preview
- this.runtimeEnv.dashboardFeatureLoader = this.runtimeEnv.dashboardApi.getFeature('DashboardFeatureLoader.internal');
- }
- this._defaultEventRouter = new Events();
- this.interactivitySettings = {
- isClickDisabled: !options.enableClick,
- isPanAndZoomDisabled: !options.enablePanAndZoom,
- isHoverDisabled: !options.enableHover,
- tabNavigation: options.tabNavigation
- };
- this.featureSet = options.featureSet;
- }
- StandaloneLiveWidget.prototype._createEnvironment = function _createEnvironment() {
- var _this = this;
- if (this.runtimeEnv) {
- return Promise.resolve();
- }
- return this._glassContext.getSvc('.DashboardRuntime').then(function (svc) {
- var options = {
- spec: svc.getDefaultSpec()
- };
- options.spec.widgets[_this.spec.id] = _this.spec;
- options.spec.name = _this.board && _this.board.name || options.spec.name;
- options.spec.version = _this.board && _this.board.version || options.spec.version;
- return svc.getRuntimeEnvironment(options).then(function (env) {
- // overwrite with the upgraded spec
- _this.spec = env.boardModel.widgets[_this.spec.id];
- var promises = [];
- _this.runtimeEnv = env;
- if (env.cssStyles && !isCSSLoaded) {
- isCSSLoaded = true;
- env.cssStyles.forEach(function (style) {
- promises.push(LoadCSSPromise.load(style, null, null, [{
- type: 'text/css'
- }]));
- });
- }
- return Promise.all(promises);
- });
- });
- };
- /**
- * Render the live widget instance. This method will execute the query, wait for it and render when the data is complete.
- * @function LiveWidgetAPI#render
- * @params {options} object that describes the live widget
- * @return {Promise} promise that will be resolved when the render is complete or reject in the case of an error
- * @example
- * liveWidget.render().then(()=>{
- * console.debug('render is complete');
- * }).catch(()=>{
- * console.debug('An error occured');
- * });
- */
- StandaloneLiveWidget.prototype.render = function render() {
- var _this2 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- return this._createEnvironment().then(function () {
- return _this2._updateModelIds();
- }).then(function () {
- return _this2._createContent(options.isPreview);
- }).then(function (content) {
- if (_this2._queryResults) {
- _this2._inlineContentFeatures = _this2._addQueryOverrideFeature();
- }
- return Promise.all([content, content.registerFeatures(_this2._inlineContentFeatures)]);
- }).then(function (_ref) {
- var content = _ref[0];
- if (_this2._queryResults) {
- content.getFeature('QueryResultOverride').setQueryResults(_this2._queryResults);
- }
- options.widgetModel = content.widgetModel;
- options.initialConfigJSON = content.widgetModel;
- options = _.extend(options, {
- dashboardApi: _this2.runtimeEnv.dashboardApi,
- eventRouter: _this2.runtimeEnv.eventRouter || _this2._defaultEventRouter,
- registry: _this2.runtimeEnv.dashboardApi.getWidgetRegistry ? _this2.runtimeEnv.dashboardApi.getWidgetRegistry().live : {},
- contentFeatureLoader: _this2._createContentFeatureLoader(content),
- content: content
- });
- var widgetReady = void 0;
- if (!_this2.widget) {
- _this2.contentNode = _this2.contentNode || options.el;
- _this2.node.appendChild(_this2.contentNode);
- // Mock ability for unit tests
- var LiveWidgetClass = _this2._liveWidgetClass || LiveWidget;
- _this2.widget = new LiveWidgetClass(options);
- widgetReady = _this2.widget.initialize();
- } else {
- widgetReady = Promise.resolve();
- }
- return widgetReady;
- }).then(function () {
- if (!_this2._destroyed) {
- return _this2.widget.onContainerReady({
- model: _this2.widget.model
- });
- }
- }).then(function () {
- if (!_this2._destroyed) {
- return _this2.widget.render(null /* renderOptions */, false /* isInteractive */);
- }
- }).then(function () {
- if (!_this2._destroyed) {
- return _this2.widget.whenRenderComplete();
- }
- }).catch(function (error) {
- var errorId = error && error.message;
- if (errorId === 'promptingIsDisabled') {
- // don't need to localize this internal error
- throw error;
- }
- var datasetName = error && error.datasetName;
- //catches the exceptions thrown from VisRenderSequence and localize it so that
- //the caller of liveWidgetPreview eg. vis-recommnder can render the exceptions;
- if (errorId && datasetName) {
- var errorMessage = StringResources.get(errorId, { datasetName: datasetName });
- throw new Error(errorMessage);
- } else {
- throw error;
- }
- });
- };
- // TODO: look at moving the content creation earlier in the object construction/initialization to provide a mechanism
- // for content feature providers to work with the content (getFeature().setXYZ())
- // Then we can move this inline feature and the _queryResults to the provider.
- StandaloneLiveWidget.prototype._addQueryOverrideFeature = function _addQueryOverrideFeature() {
- this._inlineContentFeatures.push({
- containerId: 'com.ibm.bi.dashboard.content-features',
- name: 'QueryResultOverride',
- id: 'com.ibm.bi.dashboard.content-features.queryResultOverride',
- class: 'dashboard-analytics/features/widget/queryResultOverride/QueryResultOverride',
- types: ['widget.live']
- });
- return this._inlineContentFeatures;
- };
- StandaloneLiveWidget.prototype._createContentFeatureLoader = function _createContentFeatureLoader(content) {
- var _this3 = this;
- return {
- whenContentReady: function whenContentReady() /* contentId */{
- return Promise.resolve();
- },
- registerFeatureCollection: function registerFeatureCollection(contentId, collectionName) {
- return _this3.runtimeEnv.dashboardApi.findGlassCollection(collectionName).then(function (collectionItems) {
- return content.registerFeatures(collectionItems || []);
- });
- },
- registerFeature: function registerFeature(contentId, featureId, featureInstance, featureSpec) {
- return content.registerFeature(featureId, featureInstance, featureSpec);
- },
- registerDeprecatedFeature: function registerDeprecatedFeature(contentId, featureId, featureInstance) {
- return content.registerFeature(featureId, featureInstance, {}, true);
- }
- };
- };
- StandaloneLiveWidget.prototype._createContent = function _createContent(isPreview) {
- var _this4 = this;
- var dashboard = this.runtimeEnv.dashboardApi;
- return dashboard.findGlassCollection('com.ibm.bi.dashboard.content-features').then(function (collectionItems) {
- var contentFeatureCollection = InlineFeatures.concat(collectionItems || []);
- var boardModel = dashboard.getFeature('internal').getBoardModel();
- var logger = dashboard.getFeature('Logger');
- var layoutModel = new _this4._LayoutModelClass({
- type: 'widget',
- content: {
- features: {
- Visualization: {
- isPreview: isPreview === true
- }
- }
- }
- }, boardModel, logger);
- _this4.content = new ContentImpl({
- contentFeatureCollection: contentFeatureCollection,
- dashboardFeatures: _this4.runtimeEnv.dashboardFeatureLoader,
- boardModel: boardModel,
- layoutModel: layoutModel,
- canvas: dashboard.getCanvas(),
- widgetModel: new LiveWidgetModel(_this4.spec)
- });
- return _this4.content.initialize().then(function () {
- return _this4.content;
- });
- });
- };
- /**
- * Get preview title
- *
- * @return {string} livewidget preview title
- */
- StandaloneLiveWidget.prototype.getTitle = function getTitle() {
- if (this._destroyed) {
- return;
- }
- return this.widget.getTitle();
- };
- /**
- * Resize the preview. If the container size has changed since the last render,
- * a re-render will occur without re-executing the data query.
- */
- StandaloneLiveWidget.prototype.resize = function resize() {
- if (this._destroyed) {
- return;
- }
- if (this.widget) {
- return this.widget.resize();
- }
- };
- /**
- * Destroy the live widget instance.
- * This should be called when the live widget is no longer needed to free up resources.
- * @function LiveWidgetAPI#destroy
- */
- StandaloneLiveWidget.prototype.destroy = function destroy() {
- if (this._destroyed) {
- return;
- }
- this._destroyed = true;
- if (this.content) {
- this.content.destroy();
- this.content = null;
- }
- if (this.widget) {
- this.widget.destroy();
- this.widget = null;
- }
- if (this.contentNode) {
- this.contentNode.parentNode && this.contentNode.parentNode.removeChild(this.contentNode);
- this.contentNode = null;
- }
- };
- /**
- * Return the live widget spec. This will be the full spec and not the spec that was provide as input.
- *
- * @function LiveWidgetAPI#toJSON
- */
- StandaloneLiveWidget.prototype.toJSON = function toJSON() {
- if (!this._destroyed) {
- return this.widget.model.toJSON();
- }
- };
- /*
- * Private methods
- */
- StandaloneLiveWidget.prototype._updateModelIds = function _updateModelIds() {
- var _this5 = this;
- var dashboardApi = this.runtimeEnv.dashboardApi;
- var dataSources = dashboardApi.getFeature('DataSources');
- var dataSourceList = dataSources.getDataSourceList() || [];
- var promises = [];
- if (this.spec.data && this.spec.data.dataViews) {
- this.spec.data.dataViews.forEach(function (dataView) {
- if (!dataView.modelRef && dataView.model) {
- var sourceIdList = _.chain(dataSourceList).filter(function (ds) {
- return ds.getAssetId() === dataView.model.assetId;
- }).map(function (ds) {
- return ds.getId();
- }).value();
- if (sourceIdList.length > 0) {
- dataView.modelRef = sourceIdList[0];
- delete dataView.model;
- } else {
- if (!dataView.model.type) {
- promises.push(_this5._getAssetType(dataView.model.assetId).then(function (type) {
- dataView.model.type = type;
- _this5._convertModelToModelRef(dataView, dataSources);
- }));
- } else {
- _this5._convertModelToModelRef(dataView, dataSources);
- }
- }
- } else {
- if (dataView.modelRef && !dataView.model) {
- // this block is hit when the stand alone live widget is not added in the spec (case of footer view of driver analysis) and this method make sure the modelRef if specified is the active data source (scenario remove data item and drop column from different source in the same slot)
- var activeDataSourceId = dashboardApi.getActiveDataSourceId();
- if (activeDataSourceId && activeDataSourceId !== dataView.modelRef) {
- dataView.modelRef = activeDataSourceId;
- }
- }
- }
- });
- }
- return Promise.all(promises);
- };
- StandaloneLiveWidget.prototype._convertModelToModelRef = function _convertModelToModelRef(dataView, dataSources) {
- dataView.modelRef = dataSources.addDataSource(dataView.model);
- delete dataView.model;
- };
- StandaloneLiveWidget.prototype._getAssetType = function _getAssetType(assetId) {
- return this.runtimeEnv.dashboardApi.getGlassCoreSvc('.Ajax').ajax({
- url: 'v1/objects/' + assetId + '?fields=userInterfaces,defaultName,searchPath',
- type: 'GET',
- headers: {
- 'Accept': 'application/json'
- }
- }).then(function (response) {
- if (response.data && response.data.data && response.data.data.length > 0) {
- return response.data.data[0].type;
- }
- });
- };
- return StandaloneLiveWidget;
- }();
- return StandaloneLiveWidget;
- });
- //# sourceMappingURL=StandaloneLiveWidget.js.map
|