'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** * Licensed Materials - Property of IBM * IBM Cognos Products: Dashboard * (C) Copyright IBM Corp. 2018, 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /** * @class Visualization * @hideconstructor */ define(['underscore', './VisualizationAPISpec', '../../lib/@waca/dashboard-common/dist/core/APIFactory', '../deprecated/VisualizationAPI', '../internal/VisualizationAPI', '../VisualizationAPI', '../cleanup/VisualizationAPI', './LocalFilters', './Slots', './SavedPrompts', './serviceability/ServiceabilityDataInfo', '../../widgets/livewidget/modelapis/modelmanagers/VisModelManager', '../../widgets/livewidget/visapi/support/VisFilterSupport', '../../widgets/livewidget/visapi/support/VisPropertySupport', './model/DataModel', '../../widgets/livewidget/nls/StringResources'], function (_, VisualizationAPISpec, APIFactory, DeprecatedVisualizationAPI, InternalVisualizationAPI, VisualizationAPI, CleanUpVisualizationAPI, LocalFilters, Slots, SavedPrompts, ServiceabilityDataInfo, VisModelManager, VisFilterSupport, VisPropertySupport, DataModel, StringResources) { // Used to indicate which fields are supported in the "compare" api // Each field can have an exclude list to exclude certain attributes from the comparison var widgetMatchingConfig = { visId: { getValue: function getValue(visModel) { return visModel.visId; }, exclude: [] }, localFilters: { getValue: function getValue(visModel) { var filters = visModel.localFilters; return filters ? filters.toJSON() : {}; }, exclude: ['binsLabel', 'id', 'readOnly', 'isMissing'] } }; var Visualization = function (_VisualizationAPISpec) { _inherits(Visualization, _VisualizationAPISpec); function Visualization(options) { _classCallCheck(this, Visualization); var _this = _possibleConstructorReturn(this, _VisualizationAPISpec.call(this)); _this.doNotRegisterDataSourceUsage = options.doNotRegisterDataSourceUsage; _this.state = options.features['state.internal']; _this.widgetModel = options.features['Models.internal'].getWidgetModel(); _this.dashboardAPI = options.features['Dashboard.API']; _this.logger = options.features['Dashboard.Logger']; _this.content = options.content; _this.colors = options.features['Dashboard.Colors']; _this.transaction = options.features['Dashboard.Transaction']; _this.dataSources = options.features['Dashboard.DataSources']; _this.boardModel = options.features['Dashboard.internal'].getBoardModel(); _this.visDefinitions = options.features['Dashboard.VisDefinitions']; _this.serviceability = options.features['Serviceability']; _this.internalVisDefinitions = options.features['Dashboard.VisDefinitions.internal']; _this.notification = options.features['Dashboard.Notification']; _this._isPreview = options.spec && options.spec.isPreview; // TODO - should be its own dashboard feature _this.userProfile = _this.dashboardAPI.getGlassCoreSvc('.UserProfile'); if (!_this.widgetModel.data) { _this.widgetModel.data = {}; } _this.dataModel = new DataModel(_this.widgetModel.data); _this.visDefinitions.on('refresh', _this.refreshSlotsAfterChanges, _this); _this._dataSource = {}; return _this; } Visualization.prototype.refreshSlotsAfterChanges = function refreshSlotsAfterChanges() { var isEmpty = this.internalVisDefinitions.getRawDefinition(this.getDefinition().getId()).empty; if (!this.getDefinition().getState().getError() && !isEmpty) { this.slotsImpl.setDefinition(this.getDefinition()); this.slotsImpl._initializeDataItems(); } }; Visualization.prototype.destroy = function destroy() { if (this.destroyed) { // TODO livewidget_cleanup -- remove the viz from the live widget feature // so that we don't need this.. // Because we temporary register this as a lvie widget feature and content feature, // the destroy will be called twice.. don't bother the second time // This code can go away once one move to the content feature return; } var dataSource = this.getDataSource(); if (dataSource && !this.doNotRegisterDataSourceUsage) { dataSource.deregisterUsage(this.widgetModel.id); } this.visDefinitions.off('refresh:definition', this.refreshSlotsAfterChanges, this); this.widgetModel = null; this.dashboardAPI = null; this.logger = null; this.widget = null; this.content = null; this.colors = null; this.transaction = null; this.dataSources = null; this.boardModel = null; this.visDefinitions = null; this.internalVisDefinitions = null; this.userProfile = null; this.localFiltersImpl.destroy(); this.localFiltersImpl = null; this.savedPromptsImpl.destroy(); this.savedPromptsImpl = null; this.slotsImpl.destroy(); this.slotsImpl = null; this.destroyed = true; }; Visualization.prototype._createLegacyManagers = function _createLegacyManagers() { var visModelManager = new VisModelManager({ logger: this.logger, localFilters: this.widgetModel.localFilters, searchFilters: this.widgetModel.searchFilters, visDefinitions: this.internalVisDefinitions, widgetModel: this.widgetModel, dashboardApi: this.dashboardAPI, boardModel: this.boardModel, colors: this.colors, content: this.content, visualizationFeature: this.getAPI() }); var pageContextModel = this.boardModel.get('pageContext'); var pageContext = pageContextModel && pageContextModel.getAPI(); var visFilterSupport = new VisFilterSupport({ visModelManager: visModelManager, pageContext: pageContext, logger: this.logger, dashboardApi: this.dashboardAPI, content: this.content, contentId: this.widgetModel.id, visualization: this.getAPI() }); var visPropertySupport = new VisPropertySupport({ properties: this.widgetModel.properties, visModelManager: visModelManager, dashboardApi: this.dashboardAPI, content: this.content }); visModelManager.initialize({ propertySupport: visPropertySupport, filterSupport: visFilterSupport //, }); this.legacyManagers = { visModelManager: visModelManager, visFilterSupport: visFilterSupport, visPropertySupport: visPropertySupport, dataModel: this.dataModel // TODO livewidget_cleanup -- remove this.. it is here temporary for the visCOnditionSupport }; }; Visualization.prototype.getLegacyManagers = function getLegacyManagers() { return this.legacyManagers; }; Visualization.prototype.getAPI = function getAPI(type) { if (type === 'legacy') { return { getLegacyManagers: this.getLegacyManagers.bind(this) }; } if (type === 'internal') { if (!this.internal) { this.internal = APIFactory.createAPIFromSpec([{ implementation: this, interface: VisualizationAPI }, { implementation: this, interface: InternalVisualizationAPI }, { implementation: this, interface: DeprecatedVisualizationAPI, options: { // Set true to enable deprecated logging isDeprecated: false } }]); } return this.internal; } if (type === 'cleanup') { if (!this.cleanup) { this.cleanup = APIFactory.createAPIFromSpec([{ implementation: this, interface: CleanUpVisualizationAPI }]); } return this.cleanup; } if (!this._apiInstance) { this._apiInstance = APIFactory.createAPIFromSpec([{ implementation: this, interface: VisualizationAPI }, { implementation: this, interface: DeprecatedVisualizationAPI, options: { // Set true to enable deprecated logging isDeprecated: false } }]); } return this._apiInstance; }; /** * @param {object} options * @description one of the task this method will do is to set data mapping * infomation to its associated contentInfo object. We put a try...catch... * here because of we don't want to block creating a widget on a place which * is not a canvas, like a conversation panel. */ Visualization.prototype.initialize = function initialize() { var _this2 = this; var dataSource = this.getDataSource(); var whenMetadataLoaded = null; if (dataSource) { if (!this.doNotRegisterDataSourceUsage) { dataSource.registerUsage(this.widgetModel.id); } whenMetadataLoaded = dataSource.loadMetadata(); } else { whenMetadataLoaded = Promise.resolve(); } // todo livewidget_cleanup - Should we load the metadata here or have a separate feature (metadataLoader) // I should be able to create the visualization without having to load the metadata. return whenMetadataLoaded.catch(function (e) { _this2.logger.log('An error occured while loading the metadata for content with id ' + _this2.content.getId()); _this2.logger.log(e); _this2.state.setError({ msg: 'dwErrorMissingDataset', params: { datasetName: e.sourceInfo && e.sourceInfo.name ? e.sourceInfo.name : dataSource.getAssetId() } }); }).finally(function () { _this2._createLegacyManagers(); _this2._createSubAPIs(); _this2._getFilterSupport().validateFilters(); // We don't support two cases where the following error will be thrown: // 1. live widgets on the conversation panel and, // 2. live widgets on the starting point page of an Exploration if (_this2.serviceability) { _this2._initializeServiceability(_this2.serviceability); } _this2._initializePropsAndThemes(); }); }; Visualization.prototype._initializePropsAndThemes = function _initializePropsAndThemes() { if (this.getType()) { var definition = this.getDefinition(); var propertySupport = this._getPropertySupport(); propertySupport.buildProperties(definition.getProperty('properties') || definition.getProperty('propertyList'), this.boardModel.getLanguageModelOptions()); // TODO: livewidget_cleanup - the updateThemeMapping should move to the VisDefinitions feature and we can register them in the Colors feature directly // This cannot be done until the color feature is a proper feature and created after the boardModel this.colors.updateThemeMapping(definition.getProperty('themeMapping')); } }; Visualization.prototype._initializeServiceability = function _initializeServiceability(serviceability) { var _this3 = this; if (serviceability !== undefined) { var s12yInfo = serviceability.getContentInfo(); s12yInfo.setData('dataInfo', new ServiceabilityDataInfo(this)); var generalInfo = s12yInfo.getData('generalInfo'); generalInfo.getLabel = function () { return _this3.getDefinition().getLabel(); }; s12yInfo.setData('generalInfo', generalInfo); } else { this.logger.warn('Cannot set serviceability information for this widget'); } }; Visualization.prototype.selectData = function selectData(selection, options) { return this._getFilterSupport().select(selection, options); }; Visualization.prototype._createSubAPIs = function _createSubAPIs() { this.localFiltersImpl = new LocalFilters({ filterSupport: this._getFilterSupport(), visualization: this.getAPI('internal'), dataModel: this.dataModel }); APIFactory.setParentChildRelation(this, this.localFiltersImpl); this.savedPromptsImpl = new SavedPrompts(this.widgetModel); APIFactory.setParentChildRelation(this, this.savedPromptsImpl); this.slotsImpl = new Slots(this.widgetModel, this.dataModel, this, this.transaction, this.userProfile.preferences.contentLocale, this.legacyManagers.visFilterSupport); APIFactory.setParentChildRelation(this, this.slotsImpl); }; Visualization.prototype.matches = function matches(spec) { return this._matches(spec); }; /** * Return true if the widget match the content provided in the parameter * We currently only support match visId and localFilter. Anything else will cause an error. * * @param {Object} widgetContent - content to match. */ Visualization.prototype._matches = function _matches(widgetContent) { var _this4 = this; var widgetContentAsString = ''; var currentAsString = ''; Object.keys(widgetContent).forEach(function (key) { var matchingConfig = widgetMatchingConfig[key]; if (!matchingConfig) { // Not supported throw 'the matches API does not support matching the property "' + key + '"'; } widgetContentAsString += _this4._getCompareString(widgetContent[key], matchingConfig.exclude); var currentValueToCompare = matchingConfig.getValue(_this4.widgetModel); currentAsString += _this4._getCompareString(currentValueToCompare, matchingConfig.exclude); }); return widgetContentAsString === currentAsString; }; /** * Build a unique string that represents a given object. * This string can be used to compare with another object * Certain props can be excluded from the string like ids. * */ Visualization.prototype._getCompareString = function _getCompareString(object, excludeAttributes) { var _this5 = this; var compareString = ''; if ((typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object') { var compareValues = []; if (Array.isArray(object)) { object.forEach(function (value) { compareValues.push(_this5._getCompareString(value, excludeAttributes)); }); } else { var name = void 0; for (name in object) { if (excludeAttributes.indexOf(name) === -1) { compareValues.push(name + '_' + this._getCompareString(object[name], excludeAttributes)); } } } compareValues.sort(); compareValues.forEach(function (value) { compareString += value; }); } else { compareString += object; } return compareString; }; Visualization.prototype.getType = function getType() { var type = null; var definition = this.getDefinition(); if (definition) { type = definition.getType(); } return type; }; Visualization.prototype.setType = function setType(type) { if (type && type !== this.getType()) { var newDefinition = this.visDefinitions.getByType(type); if (newDefinition) { this.widgetModel.visId = newDefinition.getId(); this.slotsImpl.setDefinition(newDefinition); this._initializePropsAndThemes(); this.refreshSlotsAfterChanges(); } else { throw new Error('Invalid type'); } } }; Visualization.prototype.isTypeLocked = function isTypeLocked() { var isLocked = this.widgetModel.get('visTypeLocked'); return !!isLocked; }; Visualization.prototype.lockType = function lockType() { this.widgetModel.visTypeLocked = true; }; Visualization.prototype.unlockType = function unlockType() { this.widgetModel.visTypeLocked = false; }; Visualization.prototype.getDefinition = function getDefinition() { var definition = this.visDefinitions.getById(this.widgetModel.visId); return definition; }; Visualization.prototype.getDataSource = function getDataSource() { var dataSource = null; var dataView = this.dataModel.getDataView(); if (dataView && dataView.modelRef) { if (!this._dataSource[dataView.modelRef]) { this._dataSource[dataView.modelRef] = this.dataSources.getDataSource(dataView.modelRef); } dataSource = this._dataSource[dataView.modelRef]; } return dataSource; }; Visualization.prototype.setDataSource = function setDataSource(sourceId) { var currentDataSource = this.getDataSource(); var currentId = currentDataSource && currentDataSource.getId(); var visDef = this.getDefinition(); if (currentId !== sourceId) { if (currentId !== null && (this.slotsImpl.getMappedSlotList().length > 0 || this.getLocalFilters().getFilterList().length > 0)) { throw 'Cannot change dataSource while the visualiation contains dataItems or filters from another source'; } var dataSource = this.dataSources.getDataSource(sourceId); if (dataSource) { if (dataSource.isOlapPackage() && visDef && visDef.getProperty('supportsOLAP') === false) { // todo livewidget_cleanup - add notification to dependencies in perspective file in the server this.dashboardAPI.getFeature('Notification').setMessage(StringResources.get('visualizationDoesNotSupportOLAP')); return false; } if (!this.doNotRegisterDataSourceUsage) { dataSource.registerUsage(this.widgetModel.id); } } if (currentDataSource && !this.doNotRegisterDataSourceUsage) { currentDataSource.deregisterUsage(this.widgetModel.id); } this.dataModel.setModelRefInAllViews(sourceId); return true; } return false; }; /** * @description Get an array of MetadataColumnAPI objects which are being used in the visualization * @return {MetadataColumnAPI[]} */ Visualization.prototype.getUsedMetadataColumnList = function getUsedMetadataColumnList() {}; Visualization.prototype.getSlots = function getSlots() { return this.slotsImpl.getAPI(); }; Visualization.prototype.getSavedPrompts = function getSavedPrompts() { return this.savedPromptsImpl.getAPI(); }; Visualization.prototype.getLocalFilters = function getLocalFilters() { return this.localFiltersImpl.getAPI(); }; Visualization.prototype.getSearchFilterList = function getSearchFilterList() { return this._getVisModelManager().searchFilters.toJSON(); }; // /** // * @description Returns the decorator object that can be used to decorate the data in the visualization. // * If the visualizatoin support multiple datasets and no view id is provided, then the decorator for the first dataset is returned // * // * @param {String} [viewId] Data view id. If not provided, the decorator for the first data view is returned. // * // * @return {DecoratorAPI} decorator object // * // */ // getDecorator(/* dataViewId */) { } // /** // * @description Return a list of decorator object that can be used to decorate the data in the visualization. // * Each dataset will have its own decorator object. // * // * // * @return {DecoratorAPI[]} decorator object // * // */ // getDecoratorList() { // if (!this.decorators) { // this.decorators = []; // const oldAPIs = this.widget.getDecoratorAPIs(); // if (oldAPIs) { // oldAPIs.forEach(oldAPI => { // this.decorators.push(new Decorator(oldAPI).getAPI()); // }); // } // } // return this.decorators; // } /** * @description Returns true if the visualization references a column that is no longer available * * @returns {Boolean} */ Visualization.prototype.hasUnavailableMetadataColumns = function hasUnavailableMetadataColumns() { var slotWithUnavailableColumns = this.getSlots().getSlotList().find(function (slot) { return slot.hasUnavailableMetadataColumns(); }); return !!slotWithUnavailableColumns; }; Visualization.prototype._convertTransactionTokenToLegacyOptions = function _convertTransactionTokenToLegacyOptions(transactionToken) { var oldOptions = {}; if (transactionToken) { oldOptions.payloadData = { transactionToken: transactionToken }; if (transactionToken.transactionId) { oldOptions.payloadData.undoRedoTransactionId = transactionToken.transactionId; } } return oldOptions; }; Visualization.prototype.isPreview = function isPreview() { return !!this._isPreview; }; Visualization.prototype._getFilterSupport = function _getFilterSupport() { return this.legacyManagers.visFilterSupport; }; Visualization.prototype._getVisModelManager = function _getVisModelManager() { return this.legacyManagers.visModelManager; }; Visualization.prototype._getPropertySupport = function _getPropertySupport() { return this.legacyManagers.visPropertySupport; }; Visualization.prototype.refreshSlotsCache = function refreshSlotsCache() { this.slotsImpl.invalidateCache(); }; return Visualization; }(VisualizationAPISpec); return Visualization; }); //# sourceMappingURL=Visualization.js.map