123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 |
- 'use strict';
- /*
- *+------------------------------------------------------------------------+
- *| Licensed Materials - Property of IBM
- *| IBM Cognos Products: BI Dashboard
- *| (C) Copyright IBM Corp. 2017, 2020
- *|
- *| US Government Users Restricted Rights - Use, duplication or disclosure
- *| restricted by GSA ADP Schedule Contract with IBM Corp.
- *+------------------------------------------------------------------------+
- */
- define(['underscore', '../../../lib/@waca/core-client/js/core-client/ui/core/Class', '../../../lib/@waca/upgrades/UpgradeBase',
- // Ughn - this file should not be in dashboard-core... with dependencies on livewidget...
- 'dashboard-analytics/dataSources/models/DataSourcesModel', 'dashboard-analytics/dataSources/services/DataSourcesService'], function (_, Class, UpgradeBase, DataSourcesModel, DataSourcesService) {
- //NOSONAR
- var UpgradeShaping = Class.extend([UpgradeBase], {
- init: function init() {
- this.VERSION = 1005;
- },
- ORIGIN_VISUALIZATION: 'visualization',
- ORIGIN_FILTER: 'filter',
- /**
- * Perform upgrade
- *
- * @param {object} spec - spec to perform upgrade on
- *
- * @return {Promise} Promise to be resolved when upgrade performed
- */
- up: function up(spec) {
- this._calcIdMap = {};
- this.dataSourcesService = null;
- this._eventGroupMap = {};
- this._assetIdMap = {};
- this.spec = spec;
- this.dataSourcesService = new DataSourcesService({
- features: {
- API: this.data.dashboardApi,
- Logger: this.data.logger
- }
- });
- this.spec.dataSources = new DataSourcesModel(this.spec.dataSources);
- var dataSetShapingsToUpgrade = _.filter(this.spec.datasetShaping, function (datasetShapingInst) {
- return datasetShapingInst.calculations.length;
- });
- this._buildEventGroupMap();
- return this._upgradeShaping(dataSetShapingsToUpgrade).then(this._upgradeFilters.bind(this)).then(this._upgradeShapingFilters.bind(this)).then(function () {
- this._updateWidgetCalculationReferences();
- // remove old shaping
- delete this.spec.datasetShaping;
- // For pin upgrade with need the JSON back, not the object
- if (this.data.pinUpgrade) {
- if (this.spec.dataSources.toJSON) {
- this.spec.dataSources = this.spec.dataSources.toJSON();
- }
- // Cleanup any temp modules that were created
- this.dataSourcesService.destroy();
- }
- Promise.resolve(this.spec);
- }.bind(this), function (failure) {
- if (this.data.pinUpgrade) {
- // Cleanup any temp modules that were created
- this.dataSourcesService.destroy();
- }
- throw failure;
- });
- },
- /**
- * @returns container Page id containing the layout id
- * @param widgetId
- */
- getContainerPageId: function getContainerPageId(id) {
- var topParent = this.findTopLevelParentItem(this.spec.layout, id);
- if (topParent) {
- return topParent.id;
- }
- return undefined;
- },
- /**
- * Given any layout item, find its top level parent item (the item in the layout’s root level item list that contains it).
- * @param layout - this is the layout specification in the board spec
- * @param id - the id of the model for a widget
- * @returns the parent object (ie tab) for this model id
- */
- findTopLevelParentItem: function findTopLevelParentItem(layout, id) {
- var itemFound = null;
- _.each(layout.items, function (item) {
- if (item.id === id) {
- itemFound = layout;
- } else if (this.findChildItem(item.items, id) !== null) {
- itemFound = item;
- }
- }.bind(this));
- return itemFound;
- },
- /**
- * Recursively search all layout items and their child items lists for an id which matches
- * the specified id
- * @param items - the items list whose subtree of items lists are to be searched
- * @param id - the id to search for.
- * @returns the item if found or null if this id does not exist in this items list or any child lists.
- */
- findChildItem: function findChildItem(items, id) {
- if (!items) {
- return null;
- }
- var result = null;
- for (var i = 0; i < items.length; ++i) {
- var item = items[i];
- if (item.id === id) {
- // found it!
- result = item;
- break;
- } else if (item.items) {
- item = this.findChildItem(item.items, id);
- if (item) {
- // found it!
- result = item;
- break;
- }
- // otherwise continue with the remaining siblings
- }
- }
- return result;
- },
- _buildEventGroupMap: function _buildEventGroupMap() {
- _.each(this.spec.eventGroups, function (eg) {
- _.each(eg.widgetIds, function (wIds) {
- this._eventGroupMap[wIds] = eg.id;
- }.bind(this));
- }.bind(this));
- },
- _upgradeFilters: function _upgradeFilters() {
- try {
- var pageContextMap = {};
- var promises = [];
- _.each(this.spec.widgets, function (widget) {
- var modelRef = widget && widget.data && widget.data.dataViews[0] ? widget.data.dataViews[0].modelRef : null;
- if (modelRef) {
- var sourceSpec = _.find(this.spec.dataSources.sources.models, function (source) {
- return source.id === modelRef;
- });
- promises.push(this._getModule(sourceSpec, false).then(function (module) {
- if (!this.spec.pageContext) {
- this.spec.pageContext = [];
- }
- if (!_.isEmpty(widget.filters)) {
- this._buildPageContext(module, pageContextMap, widget, sourceSpec.id);
- delete widget.filters;
- }
- if (!_.isEmpty(widget.localFilters)) {
- this._updateLocalFilters(module, widget.localFilters);
- }
- }.bind(this)));
- }
- }.bind(this));
- return Promise.all(promises).then(function () {
- if (!_.isEmpty(pageContextMap)) {
- this.spec.pageContext = _.values(pageContextMap);
- }
- }.bind(this));
- } catch (error) {
- throw error;
- }
- },
- _upgradeShapingFilters: function _upgradeShapingFilters() {
- try {
- var pageContextMap = {};
- var promises = [];
- _.each(this.spec.datasetShaping, function (shaping) {
- var sourceSpec = _.find(this.spec.dataSources.sources.models, function (source) {
- return source.assetId === shaping.id;
- });
- if (sourceSpec) {
- promises.push(this._getModule(sourceSpec, false).then(function (module) {
- if (!this.spec.pageContext) {
- this.spec.pageContext = [];
- }
- if (!_.isEmpty(shaping.filters)) {
- this._addShapingFiltersToPageContext(module, pageContextMap, shaping, sourceSpec.id);
- }
- delete shaping.filters;
- }.bind(this)));
- }
- }.bind(this));
- return Promise.all(promises).then(function () {
- if (!_.isEmpty(pageContextMap)) {
- this.spec.pageContext = this.spec.pageContext.concat(_.values(pageContextMap));
- }
- }.bind(this));
- } catch (error) {
- throw error;
- }
- },
- _updateLocalFilters: function _updateLocalFilters(module, filters) {
- try {
- _.each(filters, function (filter) {
- if (filter.values) {
- if (filter.values[0] && _.isObject(filter.values[0]) && !filter.values[0].operator) {
- this._updateFilterUseValues(module, filter, 'object');
- } else if (filter.values[0] && typeof filter.values[0] === 'string') {
- this._updateFilterUseValues(module, filter, 'string');
- } else if (!filter.values[0]) {
- this._updateFilterUseValues(module, filter, 'null');
- } else {
- this._updateLocalFilters(module, filter.values);
- }
- }
- }.bind(this));
- } catch (error) {
- throw error;
- }
- },
- _addShapingFiltersToPageContext: function _addShapingFiltersToPageContext(module, pageContextMap, shape, sourceId) {
- _.each(shape.filters, function (filter) {
- var mappedProps = this._createTuplesAndHierarchies(module, filter, this.ORIGIN_FILTER);
- var pageContext = {
- 'origin': this.ORIGIN_FILTER,
- 'table': '',
- 'alias': '',
- 'sourceId': sourceId,
- 'scope': 'global',
- 'hierarchyNames': mappedProps.hierarchyNames,
- 'hierarchyUniqueNames': mappedProps.hierarchies
- };
- if (filter.operator === 'between' || filter.operator === 'notbetween' || filter.operator === 'lt' || filter.operator === 'gt') {
- pageContext.conditions = this._createCondition(filter);
- } else {
- if (filter.operator === 'notin') {
- pageContext.exclude = true;
- }
- pageContext.tupleSet = mappedProps.tupleSet;
- }
- var uniqueKey = mappedProps.key + pageContext.scope + pageContext.sourceId;
- if (_.isEmpty(pageContextMap[uniqueKey])) {
- pageContextMap[uniqueKey] = pageContext;
- }
- }.bind(this));
- },
- _buildPageContext: function _buildPageContext(module, pageContextMap, widget, sourceId) {
- _.each(widget.filters, function (filter) {
- var mappedProps = this._createTuplesAndHierarchies(module, filter, this.ORIGIN_VISUALIZATION);
- var pageContext = {
- 'origin': this.ORIGIN_VISUALIZATION,
- 'table': '',
- 'alias': '',
- 'tupleSet': mappedProps.tupleSet,
- 'sourceId': sourceId,
- 'hierarchies': mappedProps.hierarchyList,
- 'hierarchyUniqueNames': mappedProps.hierarchies,
- 'scope': this.getContainerPageId(widget.id),
- 'eventSourceId': widget.id,
- 'eventGroupId': this._eventGroupMap[widget.id]
- };
- var uniqueKey = mappedProps.key + pageContext.eventGroupId + pageContext.scope + pageContext.sourceId;
- if (_.isEmpty(pageContextMap[uniqueKey])) {
- pageContextMap[uniqueKey] = pageContext;
- }
- }.bind(this));
- },
- _createCondition: function _createCondition(filter) {
- var condition = {
- from: '',
- to: '',
- attributeUniqueNames: [filter.columnId]
- };
- if (filter.operator === 'between' || filter.operator === 'notbetween') {
- condition.from = [filter.values[0].d || filter.values[0].displayValue || filter.values[0]];
- condition.to = [filter.values[1].d || filter.values[1].displayValue || filter.values[1]];
- } else if (filter.operator === 'lt') {
- condition.to = [filter.values[0].d || filter.values[0].displayValue || filter.values[0]];
- } else {
- condition.from = [filter.values[0].d || filter.values[0].displayValue || filter.values[0]];
- }
- if (filter.operator === 'notbetween') {
- condition.invert = true;
- }
- return [condition];
- },
- _createTuplesAndHierarchies: function _createTuplesAndHierarchies(module, filter, origin) {
- var properties;
- switch (filter.operator) {
- case 'in':
- case 'notin':
- case 'isnull':
- case 'between':
- case 'notbetween':
- case 'lt':
- case 'gt':
- this._updateFilterUseValues(module, filter);
- properties = this._buildEdgeFilterTupleSet(module, filter, origin);
- break;
- case 'or':
- case 'not':
- properties = this._buildDataPointFilterTupleSet(module, filter, origin);
- break;
- default:
- properties = {
- 'tupleSet': '',
- 'hierachyList': '',
- 'hierarchies': ''
- };
- break;
- }
- return properties;
- },
- _getMetadataColumn: function _getMetadataColumn(module, columnId) {
- return module ? module.getMetadataColumn(columnId) : null;
- },
- _getMetadataColumnLabel: function _getMetadataColumnLabel(mdColumn) {
- return mdColumn ? mdColumn.getLabel() : null;
- },
- isFacetEnabled: function isFacetEnabled(mdColumn) {
- var facetDefinition = mdColumn && mdColumn.getFacetDefinition ? mdColumn.getFacetDefinition() : null;
- return facetDefinition && facetDefinition.enabled && facetDefinition.enabled.enumValue !== 'false' ? true : false;
- },
- isOlapPackage: function isOlapPackage(mdColumn) {
- var retval = false;
- if (mdColumn) {
- var sourceCategory = mdColumn.getSourceCategory();
- retval = sourceCategory && sourceCategory !== 'column' && mdColumn.getObjectType() === 'QueryItem';
- }
- return retval;
- },
- _isDateOrTimeValue: function _isDateOrTimeValue(dateStr) {
- return isNaN(dateStr) && !isNaN(Date.parse(dateStr));
- },
- _isDateOrTime: function _isDateOrTime(metadata, value) {
- return metadata && metadata.isDateOrTimeType() && this._isDateOrTimeValue(value);
- },
- _isRangeOperator: function _isRangeOperator(operator) {
- return operator && (operator === 'between' || operator === 'notbetween' || operator === 'lt' || operator === 'gt');
- },
- _isRangeFilter: function _isRangeFilter(metadataColumn, filter, value) {
- return this._isRangeOperator(filter.operator) && (_.isNumber(value) || this._isDateOrTime(metadataColumn, value));
- },
- _updateFilterUseValues: function _updateFilterUseValues(module, filter, type) {
- var metadataColumn = this._getMetadataColumn(module, filter.columnId);
- var facetEnabled = this.isFacetEnabled(metadataColumn);
- var isOlap = this.isOlapPackage(metadataColumn);
- if (filter && filter.values) {
- var updateValuesList = [];
- _.each(filter.values, function (value) {
- var mappedObj = {};
- if (type === 'string') {
- mappedObj.u = value;
- mappedObj.d = value;
- } else if (type === 'null') {
- mappedObj = null;
- } else {
- mappedObj.u = !facetEnabled || isOlap || this._isRangeFilter(metadataColumn, filter, value.useValue) || value.useValue === null ? value.useValue : this._mapUseValue(filter.columnId, value.useValue);
- mappedObj.d = value.displayValue;
- }
- updateValuesList.push(mappedObj);
- }.bind(this));
- delete filter.values;
- filter.values = updateValuesList;
- }
- },
- _mapUseValue: function _mapUseValue(hun, value) {
- value = typeof value === 'string' ? value.replace(/]/g, ']]') : value;
- return hun + '->' + '[' + value + ']';
- },
- _buildEdgeFilterTupleSet: function _buildEdgeFilterTupleSet(module, filter, origin) {
- var hunKey = '';
- var tupleSet = {};
- var hierarchyList = [];
- var hierarchies = [];
- var hierarchyNames = [];
- if (origin === this.ORIGIN_FILTER) {
- hierarchyNames.push(this._getMetadataColumnLabel(this._getMetadataColumn(module, filter.columnId)));
- } else {
- hierarchyList.push({
- 'hierarchyUniqueName': filter.columnId
- });
- }
- _.each(filter.values, function (value) {
- tupleSet[value.u] = value;
- hunKey += filter.columnId;
- hierarchies.push(filter.columnId);
- });
- var filterProps = {};
- filterProps.tupleSet = JSON.stringify(tupleSet);
- filterProps.hierarchies = _.uniq(hierarchies);
- filterProps.key = hunKey;
- if (origin === this.ORIGIN_FILTER) {
- filterProps.hierarchyNames = hierarchyNames;
- } else if (origin === this.ORIGIN_VISUALIZATION) {
- filterProps.hierarchyList = hierarchyList;
- }
- return filterProps;
- },
- _buildDataPointFilterTupleSet: function _buildDataPointFilterTupleSet(module, filter) {
- var hunKey = '';
- var tupleSet = {};
- var hierarchyList = [];
- var hierarchies = [];
- if (filter.values) {
- _.each(filter.values, function (filters) {
- if (filters.operator === 'and') {
- this._buildAndFilterTuple(module, tupleSet, hierarchyList, filters);
- }
- }.bind(this));
- }
- hierarchyList = _.uniq(hierarchyList);
- _.each(hierarchyList, function (h) {
- hierarchies.push({
- 'hierarchyUniqueName': h
- });
- hunKey += h;
- });
- return {
- 'tupleSet': JSON.stringify(tupleSet),
- 'hierarchyList': _.uniq(hierarchies),
- 'hierarchies': _.uniq(hierarchyList),
- 'key': hunKey
- };
- },
- _buildAndFilterTuple: function _buildAndFilterTuple(module, tupleSet, hierarchyList, filter) {
- var tupleKey = '';
- var tupleValues = [];
- _.each(filter.values, function (value) {
- this._updateFilterUseValues(module, value);
- _.each(value.values, function (value) {
- tupleKey += value.u;
- tupleValues.push(value);
- }.bind(this));
- hierarchyList.push(value.columnId);
- }.bind(this));
- tupleSet[tupleKey] = tupleValues;
- },
- _upgradeShaping: function _upgradeShaping(datasetShapingsToUpgrade) {
- try {
- var datasetShapingInst = datasetShapingsToUpgrade.shift();
- if (datasetShapingInst) {
- return this._upgradeShapingInstance(datasetShapingInst).then(function () {
- this.spec.queriedForUpgrade = true;
- return this._upgradeShaping(datasetShapingsToUpgrade);
- }.bind(this));
- } else {
- return Promise.resolve(true);
- }
- } catch (error) {
- throw error;
- }
- },
- _getSourcesCollection: function _getSourcesCollection(dataSourceModel) {
- var sourcesCollection = this.dataSourcesService.getSourcesCollection(dataSourceModel);
- return sourcesCollection.getSources();
- },
- _getModule: function _getModule(sourceSpec, forceTemp) {
- if (!sourceSpec) {
- throw new Error('Could not find source specfication');
- }
- if (forceTemp === true) {
- sourceSpec.useTempModule = true;
- }
- var sources = this._getSourcesCollection(this.spec.dataSources);
- var existingSource = _.find(sources, function (source) {
- return source.getAssetId() === sourceSpec.assetId;
- });
- if (!existingSource) {
- throw new Error('Could not find source module');
- } else {
- var showErrorToast = typeof this.data.showErrorToast === 'undefined' ? true : this.data.showErrorToast;
- return existingSource.getModule(null, showErrorToast);
- }
- },
- _upgradeShapingInstance: function _upgradeShapingInstance(datasetShapingInst) {
- try {
- var sourceSpec = _.find(this.spec.dataSources.sources.models, function (source) {
- return source.assetId === datasetShapingInst.id;
- });
- if (!sourceSpec) {
- return Promise.resolve(true);
- }
- return this._getModule(sourceSpec, true).then(function (module) {
- return this._addCalculation(module, datasetShapingInst.calculations);
- }.bind(this), function (failure) {
- if (this.data.pinUpgrade) {
- // Cleanup any temp modules that were created
- this.dataSourcesService.destroy();
- }
- throw failure;
- }.bind(this));
- } catch (error) {
- throw error;
- }
- },
- _addCalculation: function _addCalculation(module, calculations) {
- var calculation = calculations.shift();
- if (calculation) {
- // For percent change, the new opereation to use is ¢
- var operation = calculation.expr.op === '%d' ? '¢' : calculation.expr.op;
- var calcProperties = {
- inputtedName: calculation.label,
- operation: operation,
- elementOperands: [],
- numberOperands: []
- };
- _.each(calculation.expr.params, function (param) {
- var metaDataColumn = module.getMetadataColumn(this._calcIdMap[param.col] || param.col);
- calcProperties.elementOperands.push(metaDataColumn.moserObject);
- }.bind(this));
- // For old % change calculation we need to reverse the array of data items or we won't get the same numbers as in R6.
- if (operation === '¢') {
- calcProperties.elementOperands.reverse();
- }
- return module.addCalculation(calcProperties).then(function (newCalculationId) {
- this._calcIdMap[calculation.id] = newCalculationId;
- return this._addCalculation(module, calculations);
- }.bind(this));
- } else {
- return Promise.resolve(true);
- }
- },
- _updateWidgetCalculationReferences: function _updateWidgetCalculationReferences() {
- try {
- _.each(this.spec.widgets, function (widget) {
- var dataViews = widget.data && widget.data.dataViews ? widget.data.dataViews : [];
- _.each(dataViews, function (dataView) {
- _.each(dataView.dataItems, function (dataItem) {
- dataItem.itemId = this._calcIdMap[dataItem.itemId] || dataItem.itemId;
- }.bind(this));
- }.bind(this));
- _.each(widget.localFilters, function (localFilter) {
- localFilter.columnId = this._calcIdMap[localFilter.columnId] || localFilter.columnId;
- }.bind(this));
- }.bind(this));
- } catch (error) {
- throw error;
- }
- },
- down: function down(spec) {
- return Promise.resolve(spec);
- }
- });
- return new UpgradeShaping();
- });
- //# sourceMappingURL=waca_shaping.js.map
|