DrillThroughMappingManager.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. /**
  4. * Licensed Materials - Property of IBM
  5. * IBM Watson Analytics (C) Copyright IBM Corp. 2018, 2019
  6. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  7. *
  8. */
  9. define(['../../dataSources/utils/DatasourceUtil', 'underscore', '../../widgets/livewidget/nls/StringResources', '../../util/ContentUtil', '../../lib/@waca/dashboard-common/dist/utils/ContentUtil'], function (DatasourceUtil, _, StringResources, ContentUtil, ContentUtilCommon) {
  10. var paramProperties = ['name', 'modelFilterItem', 'type', 'capabilities'];
  11. var REPORT = 'report';
  12. var DrillThroughMappingManager = function () {
  13. /**
  14. * @param {object} dashboardApi - Dashboard API
  15. * @param {object} drillService - drill service
  16. */
  17. function DrillThroughMappingManager(dashboardApi, drillService) {
  18. _classCallCheck(this, DrillThroughMappingManager);
  19. this.dashboard = dashboardApi;
  20. this.drillService = drillService;
  21. }
  22. /**
  23. * @param storeId - The cm store id of the target report
  24. */
  25. DrillThroughMappingManager.prototype.getParameters = function getParameters(storeId) {
  26. var _this = this;
  27. return this.dashboard.getGlassSvc('.DrillInfoService').then(function (drillInfoService) {
  28. var attrs = {
  29. type: REPORT,
  30. storeId: storeId
  31. };
  32. return drillInfoService.getParameters(attrs).then(function (response) {
  33. var parameters = response.parameters || [];
  34. var result = [];
  35. _.each(parameters, function (parameter) {
  36. result.push(_.pick(parameter, paramProperties));
  37. });
  38. return result;
  39. }).catch(function (e) {
  40. _this.dashboard.getGlassCoreSvc('.Logger').error('Could not get prompt information from the selected report.', e);
  41. _this.dashboard.showErrorMessage(StringResources.get('drillThroughDefinitionErrorQueryingReport'), StringResources.get('drillThroughDefinitionErrorDlgTitle'));
  42. });
  43. });
  44. };
  45. /**
  46. * function to map drill target parameters to current dashboard metadata, also returns the metadata
  47. * columns within the current context, i.e. same data asset and scope (tab) as the definitionContent.
  48. * @param {string} storeId - The cm store id of the target report
  49. * @param {object} definitionContent - the content that the drill through definition is based on.
  50. * @param {string} mappings - The existing mappings from a drill definition entry.
  51. */
  52. DrillThroughMappingManager.prototype.doMapping = function doMapping(storeId, definitionContent, mappings) {
  53. var _this2 = this;
  54. return this.getParameters(storeId).then(function (parameters) {
  55. if (!parameters.length) {
  56. return Promise.resolve();
  57. }
  58. var datasourceAPI = definitionContent.getFeature('Visualization').getDataSource();
  59. return datasourceAPI.getModule().then(function (module) {
  60. return _this2._mapToMetadata(parameters, definitionContent, mappings, module);
  61. });
  62. });
  63. };
  64. /**
  65. * @param {object} parameters - parameters in the target
  66. * @param {object} definitionContent - the content that the drill through definition is based on.
  67. * @param {string} mappings - The existing mappings from a drill definition entry.
  68. * @param {object} module - module api
  69. */
  70. DrillThroughMappingManager.prototype._mapToMetadata = function _mapToMetadata(parameters, definitionContent, mappings, module) {
  71. var metadataColumnIds = this.getMetadataIds(definitionContent, module);
  72. var mapToColumnIds = []; // columns exist in drill entry mappings, but not in the current content context
  73. parameters.forEach(function (parameter) {
  74. // If saved mappings is passed in, propagate the mapTo to the parameter and do not remap from the current
  75. // content context
  76. if (mappings) {
  77. var mappedParameter = _.find(mappings, function (mapping) {
  78. return mapping.modelFilterItem === parameter.modelFilterItem && mapping.name === parameter.name;
  79. });
  80. if (mappedParameter && mappedParameter.mapTo) {
  81. parameter.mapTo = mappedParameter.mapTo;
  82. if (metadataColumnIds.indexOf(mappedParameter.mapTo) === -1) {
  83. mapToColumnIds.push(mappedParameter.mapTo);
  84. }
  85. }
  86. } else {
  87. // New definition: map the parameter to the current content context
  88. parameter.mapTo = _.find(metadataColumnIds, function (columnId) {
  89. return parameter.modelFilterItem === columnId;
  90. });
  91. }
  92. });
  93. return {
  94. parameterMappings: parameters,
  95. columnLabels: this._getColumnLabels(definitionContent, metadataColumnIds.concat(mapToColumnIds))
  96. };
  97. };
  98. DrillThroughMappingManager.prototype._getColumnLabels = function _getColumnLabels(definitionContent, metadataColumnIds) {
  99. // Collect the column names based on the metadataIds
  100. var columnLabels = [];
  101. var visualization = definitionContent.getFeature('Visualization');
  102. var dataSource = visualization.getDataSource();
  103. metadataColumnIds.forEach(function (columnId) {
  104. var metadataColumn = !DatasourceUtil.isMultiMeasuresSeriesOrValue(columnId) ? dataSource.getMetadataColumn(columnId) : null;
  105. if (metadataColumn) {
  106. columnLabels.push({
  107. columnId: columnId,
  108. label: metadataColumn.getLabel()
  109. });
  110. }
  111. });
  112. return _.sortBy(columnLabels, 'label');
  113. };
  114. /**
  115. * @returns data item ids of the corresponding context, i.e. same data asset and scope
  116. * from dashboard model
  117. */
  118. DrillThroughMappingManager.prototype.getMetadataIds = function getMetadataIds(definitionContent, module) {
  119. var _this3 = this;
  120. var metadataIds = [];
  121. var visualization = definitionContent.getFeature('Visualization');
  122. var dataSource = visualization.getDataSource();
  123. // Collect metadata from content
  124. var eventGroups = this.dashboard.getFeature('EventGroups');
  125. if (eventGroups) {
  126. var groupId = eventGroups.getGroupId(definitionContent.getId());
  127. var contentList = eventGroups.getContentIdList(groupId);
  128. contentList.forEach(function (contentId) {
  129. metadataIds.push.apply(metadataIds, _this3._collectWidgetMetadata(contentId, dataSource.getId()));
  130. });
  131. }
  132. // Collect metadata from localFilters of the visualization
  133. this._collectLocalFilterMetadata(visualization, metadataIds);
  134. // Collect metadata from pageContext of the definitionContent scope
  135. this._collectPageContextMetadata(definitionContent, metadataIds, visualization, 'visualization', module);
  136. this._collectPageContextMetadata(definitionContent, metadataIds, visualization, 'filter', module);
  137. return _.uniq(metadataIds);
  138. };
  139. DrillThroughMappingManager.prototype._collectWidgetMetadata = function _collectWidgetMetadata(contentId, sourceId) {
  140. var content = this.dashboard.getCanvas().getContent(contentId);
  141. var metadataIds = [];
  142. //we should exclude the content where visualization does not exist
  143. var visualization = content.getFeature('Visualization');
  144. if (visualization) {
  145. var dataSource = visualization.getDataSource();
  146. if (!dataSource || dataSource.getId() !== sourceId) {
  147. return metadataIds;
  148. }
  149. var slots = visualization.getSlots();
  150. slots.getDataItemList().forEach(function (dataItem) {
  151. var metadataColumn = dataItem.getMetadataColumn();
  152. if (metadataColumn) {
  153. metadataIds.push(metadataColumn.getId());
  154. }
  155. });
  156. }
  157. return metadataIds;
  158. };
  159. DrillThroughMappingManager.prototype._collectLocalFilterMetadata = function _collectLocalFilterMetadata(visualization, metadataIds) {
  160. var localFilters = visualization.getLocalFilters().getFilterList();
  161. // Collect metadata from local filters.
  162. localFilters.forEach(function (filter) {
  163. metadataIds.push(filter.columnId);
  164. });
  165. };
  166. DrillThroughMappingManager.prototype._collectPageContextMetadata = function _collectPageContextMetadata(definitionContent, metadataIds, visualization, origin, module) {
  167. //@todo: Endor add support for multiple data sources
  168. var type = this.dashboard.getAppConfig('pageContainerType');
  169. var pageContent = ContentUtilCommon.getPageContent(definitionContent, type);
  170. var pageContext = ContentUtil.getPageContext(this.dashboard);
  171. var dataSource = visualization.getDataSource();
  172. var pageContextItems = pageContext.getNetPageContextItems({
  173. scope: pageContent && pageContent.getId(),
  174. sourceId: dataSource.getId(),
  175. origin: origin
  176. });
  177. if (!pageContextItems.length) {
  178. return;
  179. }
  180. if (origin === 'filter') {
  181. pageContextItems = DrillThroughMappingManager.getNetSynchronizedFilterPageContext(visualization, definitionContent, pageContextItems, module);
  182. }
  183. pageContextItems.forEach(function (contextItem) {
  184. metadataIds.push(contextItem.getItemId());
  185. });
  186. };
  187. /**
  188. * Returns an array of net synchronized filter page context
  189. *
  190. * @param {object} visualization - the content visualization
  191. * @param {object} ownerContent - the livewidget instance
  192. * @param {object} filterPageContextItems - the page context filter items
  193. * @param {object} module - module api
  194. *
  195. * @return {array} merged synchronized and filter net page context array
  196. */
  197. DrillThroughMappingManager.getNetSynchronizedFilterPageContext = function getNetSynchronizedFilterPageContext(visualization, ownerContent, filterPageContextItems, module) {
  198. var dataSource = visualization.getDataSource();
  199. if (dataSource.getType() === 'package') {
  200. return filterPageContextItems;
  201. }
  202. var mappedSlots = visualization.getSlots().getMappedSlotList();
  203. var tableRef = [];
  204. mappedSlots.forEach(function (mappedSlot) {
  205. var dataItems = mappedSlot.getDataItemList();
  206. dataItems.forEach(function (dataItem) {
  207. tableRef.push(dataItem.getMetadataColumn().getTableName());
  208. });
  209. });
  210. filterPageContextItems = filterPageContextItems.filter(function (pageContextItem) {
  211. var paggeContextTableRef = DatasourceUtil.getPageContextItemTableRef(dataSource, pageContextItem.getPageContextSpec());
  212. return DatasourceUtil.haveTableJoinsInSameDataSource(module, paggeContextTableRef, tableRef);
  213. //return dataSource.hasJoinedTables(paggeContextTableRef, tableRef);
  214. });
  215. // TODO: last widget reference in JumpTo to be removed
  216. var widget = ownerContent.getFeature('WidgetAPI.deprecated').getVisApi().ownerWidget;
  217. return DatasourceUtil.mergeSynchronizePageContextFilter(filterPageContextItems, widget.getSynchDataFilterEntries());
  218. };
  219. return DrillThroughMappingManager;
  220. }();
  221. return DrillThroughMappingManager;
  222. });
  223. //# sourceMappingURL=DrillThroughMappingManager.js.map