'use strict'; /** * Licensed Materials - Property of IBM * IBM Cognos Products: Dashboard * (C) Copyright IBM Corp. 2013, 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * * VisModelManager * INTENT: VisModelManager object is a top-level manager for the LiveWidgetModel and its sub-managers. * It has an api for use by external callers and the renderer. * TODO: The functionality in this class should be investigated and moved into more focused sub-objects. * * The VisModelManager owns VisDataSlots and VisProperties that the renderer pieces render, * interactivity modifies and save persists. * * It also has utilities to ease access for Visualization items to data-oriented actions * (like querying/filtering). */ define(['underscore', './VisModelManagerWrappedAPI', './VisMetadataManager', '../../../../data/models/VisPropertyCollection', '../../../../filters/Filters', '../../../../lib/@waca/core-client/js/core-client/ui/core/Events', '../../../../data/models/Conditions'], function (_, VisModelManagerWrappedAPI, VisMetadataManager, VisPropertyCollection, FilterCollection, Events, ConditionsModel) { 'use strict'; var VisModelManager = null; // class declaration VisModelManager = Events.extend([VisModelManagerWrappedAPI], { CHANCE_MAPPING_TYPES: { TRANSITION_NORMAL_MAPPING: 0, TRANSITION_INCOMPLETE_MAPPING: 1, TRANSITION_COMPLETE_MAPPING: 2, TRANSITION_UNDO_MAPPING_COMPLETE: 3, TRANSITION_REPLACE_NORMAL_MAPPING: 4 }, init: function init(options) { VisModelManager.inherited('init', this, arguments); this.localFilters = options.localFilters; this.searchFilters = options.searchFilters; this.logger = options.logger; this.visDefinitions = options.visDefinitions; this.widgetModel = options.widgetModel; this.dashboardApi = options.dashboardApi; this.transaction = this.dashboardApi.getFeature('Transaction'); this.boardModel = options.boardModel; this.colors = options.colors; this.content = options.content; this.visMetadataManager = new VisMetadataManager({ widgetModel: this.widgetModel, dashboardApi: this.dashboardApi, visualizationFeature: options.visualizationFeature }); }, initialize: function initialize(options) { options = options || {}; this.propertySupport = options.propertySupport; this.filterSupport = options.filterSupport; this.displayTypeManager = options.displayTypeManager; this._pendingFiltersActive = false; this._suppressViewAnimations = false; }, isFilterEditable: function isFilterEditable(filterEntry) { return this.filterSupport.isFilterEditable(filterEntry); }, _convertTransactionTokenToLegacyOptions: function _convertTransactionTokenToLegacyOptions(transactionToken) { var oldOptions = {}; if (transactionToken) { oldOptions.payloadData = { transactionToken: transactionToken }; if (transactionToken.transactionId) { oldOptions.payloadData.undoRedoTransactionId = transactionToken.transactionId; } } return oldOptions; }, /** *Swap data items between the two slots that are identified by their IDs *the operation should be one transaction * *@param {String} sourceSlotId the ID of the source slot *@param {String} targetSlotID the ID of the target slot **/ swapSlots: function swapSlots(sourceSlotId, targetSlotId, transactionToken) { var subTransaction = this.transaction.startTransaction(transactionToken); var options = this._convertTransactionTokenToLegacyOptions(subTransaction); var targetSlotAPI = this.getDataSlotById(targetSlotId); var sourceSlotAPI = this.getDataSlotById(sourceSlotId); var aSourceDataItemRefs = _.clone(sourceSlotAPI.getDataItemRefs()); var aTargetDataItemRefs = _.clone(targetSlotAPI.getDataItemRefs()); targetSlotAPI.assignItemsToSlot(aSourceDataItemRefs, options); sourceSlotAPI.assignItemsToSlot(aTargetDataItemRefs, options); this.transaction.endTransaction(subTransaction); }, // TODO livewidget_cleanup -- move this to the widget model getConditions: function getConditions(createNew) { var conditions = this.widgetModel.get('conditions'); if (!conditions && createNew) { //@todo Not ideal fix until a new ConditionalFormatAPI is imlemented conditions = new ConditionsModel({ palette: { colors: [] } }); this.widgetModel.set({ 'conditions': conditions }, { silent: true }); } return conditions; }, getPossibleKeyDrivers: function getPossibleKeyDrivers() { var possibleKeyDrivers = this.widgetModel.get('possibleKeyDrivers'); //If possibleKeyDrivers, clone them so the undo/redo manager stack can access changes return possibleKeyDrivers ? JSON.parse(JSON.stringify(possibleKeyDrivers)) : {}; }, setPossibleKeyDrivers: function setPossibleKeyDrivers(drivers, options) { this.widgetModel.set({ 'possibleKeyDrivers': drivers }, options); }, getTitle: function getTitle() { return this.widgetModel.get('name') || null; }, setTitle: function setTitle(title, titleHtml, options) { this.widgetModel.set({ 'name': title, 'titleHtml': titleHtml }, options); }, getShowTitle: function getShowTitle() { var titleMode = this.widgetModel.get('titleMode'); if (titleMode) { return titleMode !== 'noTitle'; } else { return this.widgetModel.get('showTitle') || null; } }, getAnnotations: function getAnnotations() { return this.widgetModel.get('annotations') || {}; }, setAnnotations: function setAnnotations(annotations, options) { this.widgetModel.set({ 'annotations': annotations }, options); }, getDefinition: function getDefinition() { try { return this.visDefinitions.getRawDefinition(this.getVisId()); } catch (error) { // Show error should be handled in other places. this.logger.error(error); } }, //TODO: It should be possible for a model manager to manager multiple modules. getMetadataAPI: function getMetadataAPI() { return this.visMetadataManager; }, changeAggregationType: function changeAggregationType() { this.logger.error('ENDOR: VisModelManager: ChangeAggregationType is not yet implemented for live widget.'); }, //======================================================================================================== /** * @returns the visId as is in the current definition. * The exception is during display type changes, this would be the visId 'post-change'. */ getVisId: function getVisId() { return this.widgetModel.get('visId'); }, supportsSortAction: function supportsSortAction() { return this.getDefinition() && this.getDefinition().supportsSortAction; }, supportsFormatAction: function supportsFormatAction() { return this.getDefinition() && this.getDefinition().supportsFormatAction; }, supportsBinAction: function supportsBinAction() { return this.getDefinition() && this.getDefinition().canApplyBinning; }, supportsCustomGroupAction: function supportsCustomGroupAction() { return this.getDefinition() && this.getDefinition().supportsCustomGroupAction; }, /** * @returns {boolean} `true` iff vis supports maintainAxisScale */ supportsMaintainAxisScale: function supportsMaintainAxisScale() { return !!(this.getDefinition() && this.getDefinition().supportsMaintainAxisScale); }, /** * @returns {array} listenForPropChanges specified in the vizdef.An array of string for prop names. */ getListenForPropChangesFromDefinition: function getListenForPropChangesFromDefinition() { return this.getDefinition() && this.getDefinition().listenForPropChanges; }, /** * @return {boolean} `true` iff vis type is locked */ isVisLocked: function isVisLocked() { var isLocked = this.widgetModel.get('visTypeLocked'); return !!isLocked; }, getPreferredSize: function getPreferredSize() { return this.getDefinition().preferredSize; }, /** * Allocate a new filter collection...for test purposes. * @returns {FilterCollection} */ _makeFilterCollection: function _makeFilterCollection() { return new FilterCollection(); }, /** * Set a visDataSlot to a new mapping * (eg: map slot XAxis to column { name: REVENUE, type: 'fact', ... }) * @param propId The property ID (as defined in VisDefinitions) * (see: smart-viz/ws/src/main/webapp/WEB-INF/localGallery) * @param value The new value. */ setDataSlotMapping: function setDataSlotMapping(slotId, mapping) { var slot = this.getDataSlotById(slotId); if (slot) { slot.setMapping(mapping); } }, clearModelInvalid: function clearModelInvalid() { this._invalidReason = null; }, setInvalidReason: function setInvalidReason(oError) { this._invalidReason = oError; }, getInvalidReason: function getInvalidReason() { return this._invalidReason; }, /** * @returns a specification for this particular visualization subtype * as a path to a template file. * (In the case of RAVE, this would be the RAVE template specification for the * specific visualization...eg: bubblechart.json or bars.json) */ getSpecification: function getSpecification() { return this.getDefinition() ? this.getDefinition().specification : null; }, /** * @returns the renderer for this VisModelManager as a path and name as defined in vis definitions. * (see: smart-viz/ws/src/main/webapp/WEB-INF/localGallery) */ getRenderer: function getRenderer() { return this.getDefinition() ? this.getDefinition().renderer : null; }, /** * @params moduleRef (optional) - a reference to a module. If not specified, the default module associated with this model is returned. * @returns a module with the specified moduleRef (or the default module if no moduleRef is specified) */ getModule: function getModule(moduleRef) { return this.visMetadataManager ? this.visMetadataManager.getModule(moduleRef) : this.getCanvas().getDataSource(); }, getMetadataManager: function getMetadataManager() { return this.visMetadataManager; }, getMetadataColumn: function getMetadataColumn(columnId, moduleRef) { return this.visMetadataManager ? this.visMetadataManager.getMetadataColumn(columnId, moduleRef) : null; }, /** * @return array of metadata columns which are being used in the model */ getUsedMetadataColumns: function getUsedMetadataColumns() { return this.visMetadataManager ? this.visMetadataManager.getMetadataColumns() : null; }, /** * @returns the module id for this VisModelManager. */ getModuleId: function getModuleId() { // TODO currently only one data view is supported. When we support multiple dataViews, dataItemId should be used to get correct module Id. return this.getModule() ? this.getModule().getSourceId() : null; }, /** * TEMPORARY METHOD: The VisCanvas is being deprecated but is still created in the original board. * Until the canvas is completely removed, callers can call getCanvas() as normal * and will either return * 1) the canvas object (if a VisCanvas has been created) * 2) a temporary object with a getDataSource() method that returns the module member of visModel. */ getCanvas: function getCanvas() { if (this.canvas) { return this.canvas; } return { module: this.getModule(), getDataSource: function getDataSource() { return this.getModule(); } }; }, getLocalFilters: function getLocalFilters() { return this.localFilters; }, setSuppressViewAnimations: function setSuppressViewAnimations(suppress) { this._suppressViewAnimations = suppress; }, getSuppressViewAnimations: function getSuppressViewAnimations() { return this._suppressViewAnimations; }, doLocalSort: function doLocalSort() { return this.getDefinition() && this.getDefinition().clientSort; }, hasBinnedDataItems: function hasBinnedDataItems() { return this.mappingAPI.hasBinnedDataItems(); }, getMetaDataValue: function getMetaDataValue(name) { var definition = this.getDefinition(); if (definition && definition.metaDataEntries) { var foundEntry = _.find(definition.metaDataEntries, function (metaDataEntry) { return metaDataEntry.name === name; }); return foundEntry ? foundEntry.value : null; } return null; }, cleanUpMissingFilters: function cleanUpMissingFilters() { this.localFilters.cleanUpMissingFilterEntries(this.visMetadataManager); }, isIgnoreDefaultSlotSort: function isIgnoreDefaultSlotSort(dataItem) { return this.mappingAPI.isIgnoreDefaultSlotSort(dataItem); } }); return VisModelManager; }); //# sourceMappingURL=VisModelManager.js.map