'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; }; /* *+------------------------------------------------------------------------+ *| Licensed Materials - Property of IBM *| IBM Cognos Products: Content Explorer *| (C) Copyright IBM Corp. 2015, 2020 *| *| US Government Users Restricted Rights - Use, duplication or disclosure *| restricted by GSA ADP Schedule Contract with IBM Corp. *+------------------------------------------------------------------------+ */ /** * * Override this class to provide localized labels,description for vis properties and slots. * */ define(['underscore', '../../lib/@waca/core-client/js/core-client/ui/core/Class', '../../lib/@waca/dashboard-common/dist/api/Error', './VisDefinitions', '../../DynamicFileLoader', 'dashboard-analytics/widgets/livewidget/nls/StringResources', '../../widgets/livewidget/util/VisUtil', '../vipr/VIPRLibraries'], function (_, Class, APIError, VisDefinitions, DynamicFileLoader, StringResources, VisUtil, VIPRLibraries) { // List of providers managed by the visDefinitionManager var PROVIDERS = ['dashboard-analytics/visualizations/definitions/providers/VIPR3Provider', 'dashboard-analytics/visualizations/definitions/providers/LocalProvider']; var WILDCARD_KEY = '*'; var VisDefinitionManager = Class.extend({ initialAllPromise: null, extensionsPromise: null, initializeProvidersPromise: null, /** * This class is singleton, do not cache dashboard api. * @param params - expects a dashboardApi to access the dashboard API */ init: function init(params) { this.logger = params.dashboardApi.getGlassCoreSvc('.Logger'); if (params.visDefinitions) { this.visDefinitions = new VisDefinitions({ jsonDefinitions: params.visDefinitions }); } this.ajaxSvc = params.dashboardApi.getGlassCoreSvc('.Ajax'); this.initialAllPromise = null; // initialize all visDefinition providers this.initializeProviders = this._initProviders(params); }, _getExtensions: function _getExtensions(dashboardApi) { if (!this.extensionsPromise) { var visualizationExtensionConfig = dashboardApi.getCollectionConfig('visualizationExtension'); if (visualizationExtensionConfig) { var collectionId = visualizationExtensionConfig.id; // load the collection this.extensionsPromise = new Promise(function (resolve, reject) { dashboardApi.findGlassCollection(collectionId).then(function (extensions) { // convert visualization extensions array to a map (id as key) var extentionsMap = _.object(_.map(extensions, function (ext) { // ids that are not fully qualified will be prefixed by the feature id var prefix = 'com.ibm.bi.dashboard.'; var idParts = ext.id && ext.id.split(prefix); var id = idParts.length === 1 ? idParts[0] : idParts[1]; return [id, ext]; })); // @todo temporary code to temporarily enable a visualization only on dev mode // edit the extension entry from perspectives/dashboard/contrib/visualizationExtensionCA.json var enabledList = ['com.ibm.vis.comet']; if (dashboardApi.isDevInstall()) { _.each(enabledList, function (visId) { if (_.isObject(extentionsMap[visId])) { extentionsMap[visId].active = true; } }); } resolve(extentionsMap); }).catch(reject); }); } else { // no extensions available... move on... this.extensionsPromise = Promise.resolve({}); } } return this.extensionsPromise; }, /** * Load all providers defined on the provider list */ _initProviders: function _initProviders(params) { if (!this.initializeProvidersPromise) { var providers = []; this.initializeProvidersPromise = DynamicFileLoader.load(params.providers ? params.providers : PROVIDERS).then(function (modules) { _.each(modules, function (Cls) { providers.push(new (Function.prototype.bind.call(Cls, null, params))()); }); return providers; }); } return this.initializeProvidersPromise; }, /** * Clear the known vis definitions so they can be refreshed. */ clearDefinitions: function clearDefinitions() { this.visDefinitions = null; this.initialAllPromise = null; this.initializeProviders.then(function (providers) { _.each(providers, function (provider) { provider.clear(); }); }); }, /** * Loads all vis definitions from the server */ _loadAllDefinitions: function _loadAllDefinitions(dashboardApi) { var _this = this; var visDefinitions = this._getVisDefinitions(); this.initialAllPromise = this.initializeProviders.then(function (providers) { return Promise.all(_.map(providers, function (provider) { return provider.getDefinitions(); })).then(function (definitions) { return _this._extendDefinitions([].concat.apply([], definitions), dashboardApi); }).then(function (extendDefinitions) { visDefinitions.jsonDefinitions = _.sortBy(extendDefinitions, 'label'); return visDefinitions; }); }); return this.initialAllPromise; }, /** * Recurrsively deep extend the target definition with the source definition along * with a wildcard source which applies to all objects when a specific source is not defined. * The source should take precedence over the wildcard. * { // Example 1: Disable multiMeasure on column chart 'com.ibm.vis.rave2bundlecolumn': { 'dataSlots': { 'values': { 'multiMeasure': false } } }, // Example 2: Disable multiMeasure on all visualizations '*': { 'dataSlots': { 'values': { 'multiMeasure': false } } }, // Example 3: Only allow 1 mapping for all slots and mutliMeasure is disabled on all visualizations '*': { 'dataSlots': { 'values': { 'multiMeasure': false }, '*': { 'maxItems': 1 } } } } * @param {Object} target target defiinition object to override * @param {Object} source source definition object to override with * @param {Object} wildcard wildcard definition object to override with against all objects */ _extendDefinitionObject: function _extendDefinitionObject(target, source, wildcard) { var extended = target; // Attempt to extend the object only if at least one canidates exists if (source || wildcard) { var sourceKeys = source ? Object.keys(source) : []; var wildcardKeys = wildcard ? Object.keys(wildcard) : []; var allKeys = [].concat(Object.keys(target), sourceKeys, wildcardKeys); // Ensure we are not extending the original definition, original definition may also be frozen extended = _.clone(target); for (var _iterator = allKeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var key = _ref; // wildcard should not exist in the target if (key === WILDCARD_KEY) { continue; } var extKey = Array.isArray(target) ? target[key].id : key; // NOTE. `typeof null` is also 'object' if (target[key] && _typeof(target[key]) === 'object') { // deep extend with extension and wildcard // source takes precedence over the wildcard var childSource = source && source[extKey] || wildcard && wildcard[extKey]; var childWildcard = source && source[WILDCARD_KEY] || wildcard && wildcard[WILDCARD_KEY]; extended[key] = this._extendDefinitionObject(target[key], childSource, childWildcard); } else if (key !== 'id') { // shallow extend all attrubutes giving precedence to the source over the wildecard if (source && source.hasOwnProperty(extKey)) { extended[key] = source[extKey]; } else if (wildcard && wildcard.hasOwnProperty(extKey)) { extended[key] = wildcard[extKey]; } } } } return extended; }, _extendDefinitions: function _extendDefinitions(definitions, dashboardApi) { var _this2 = this; // fetch the visualization extensions return this._getExtensions(dashboardApi).then(function (extensions) { // exclude all inactive definitions var activeDefs = _.filter(definitions, function (definition) { var ext = extensions[definition.id] || { active: true }; return ext.active !== false; }); var extendedDefs = _.map(activeDefs, function (definition) { return _this2._extendDefinitionObject(definition, extensions[definition.id], extensions[WILDCARD_KEY]); }); return extendedDefs; }).catch(function () { return definitions; }); }, getBundles: function getBundles() { return this.getAll().then(function (all) { return all.jsonDefinitions; }); }, /** * Load the VisDefinitions list from server. * Returns a cached copy if this operation is already done. * @returns a promise */ getAll: function getAll(dashboardApi) { if (!dashboardApi) { //The only time there should be no dashboard API is when running unit tests, //and in that case, visDefinitions should be provided in the constructor. return Promise.resolve(this.visDefinitions); } if (!this.initialAllPromise) { return this._loadAllDefinitions(dashboardApi); } return this.initialAllPromise; }, findProvider: function findProvider(id) { return this.initializeProviders.then(function (providers) { var promises = _.map(providers, function (provider) { // resolve the promise with the provider (if contains) or undefined (if doesn't contain) return provider.contains(id).then(function (contains) { return contains ? provider : undefined; }).catch(function () { return undefined; }); }); return Promise.all(promises).then(function (results) { // see if there was promise that resolved with a provider var provider = _.find(results, function (result) { return !!result; }); if (provider) { return provider; } else { throw new Error('Invalid provider'); } }); }); }, /** * Loads a single vis definition from the server */ _loadDefinition: function _loadDefinition(id) { var visDefinitions = this._getVisDefinitions(); return this.findProvider(id).then(function (provider) { return provider.getDefinition(id).then(function (data) { visDefinitions.mapDefinitionsById[id] = data; return data; }); }).catch(function () { throw VisUtil.createVisDefinitionLoadingError(id); }); }, /** * Load VisDefinition for specified id * Updates map in this.visDefinitions on getting the spec * Returns a cached version if this operation is already done * @returns a promise */ get: function get(id) { var data = this.visDefinitions && this.visDefinitions.mapDefinitionsById[id]; if (!data) { return this._loadDefinition(id); } return Promise.resolve(data); }, refreshProviders: function refreshProviders(dashboardApi) { var _this3 = this; var visDefinitions = this._getVisDefinitions(); return this.initializeProviders.then(function () { var providers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return Promise.all(_.map(providers, function (provider) { return provider.refreshProvider(dashboardApi); })).then(function (definitions) { return _this3._extendDefinitions([].concat.apply([], definitions), dashboardApi); }).then(function (extendDefinitions) { visDefinitions.jsonDefinitions = _.sortBy(extendDefinitions, 'label'); //Remove cached visDefinitions.mapDefinitionsById that are no longer valid (i.e. got deleted from CM for custom vis) visDefinitions.removeObsoleteCachedVisDefinitions(); return visDefinitions; }); }); }, refresh: function refresh(visId) { var _this4 = this; return this.findProvider(visId).then(function (provider) { if (provider) { return provider.refresh(visId).then(function (newDef) { //update cache if (newDef.renderer) { _this4.visDefinitions.mapDefinitionsById[visId] = newDef; } return newDef; }); } }).catch(function () { var msg = StringResources.get('loadVisDefinitionError', { id: visId }); throw new APIError({ msg: msg, params: { errorInfo: { id: visId, errorCode: VIPRLibraries.LOAD_DEFINITION_ERROR, errorMessage: msg } } }); }); }, _getVisDefinitions: function _getVisDefinitions() { if (!this.visDefinitions) { this.visDefinitions = new VisDefinitions(); } return this.visDefinitions; } }); var mgr = null; return function (params) { if (!mgr || params.providers) { mgr = new VisDefinitionManager(params); } return mgr; }; }); //# sourceMappingURL=VisDefinitionManager.js.map