Metadata.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. 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; }
  4. 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; }
  5. /*
  6. *+------------------------------------------------------------------------+
  7. *| Licensed Materials - Property of IBM
  8. *| IBM Cognos Products: Content Explorer
  9. *| (C) Copyright IBM Corp. 2016, 2020
  10. *|
  11. *| US Government Users Restricted Rights - Use, duplication or disclosure
  12. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13. *+------------------------------------------------------------------------+
  14. */
  15. define(['../../lib/@waca/core-client/js/core-client/ui/core/View', 'text!./templates/Metadata.html', '../../lib/@waca/core-client/js/core-client/utils/BidiUtil', '../../lib/@waca/loading-indicator/src/js/LoadingIndicatorView', '../../lib/@waca/core-client/js/core-client/ui/KeyCodes', '../nls/StringResources', '../utils/ShapingUIUtils', '../../lib/@waca/dashboard-common/dist/lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/unknown-warning_128', 'react-dom', 'react'], function (View, DataSourceTitleTemplate, BidiUtil, LoadingIndicator, KeyCodes, StringResources, ShapingUIUtils, em_unknown_warning, ReactDOM, React) {
  16. return function (_View) {
  17. _inherits(Metadata, _View);
  18. function Metadata() {
  19. _classCallCheck(this, Metadata);
  20. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  21. args[_key] = arguments[_key];
  22. }
  23. return _possibleConstructorReturn(this, _View.call.apply(_View, [this].concat(args)));
  24. }
  25. Metadata.prototype.init = function init() {
  26. var _View$prototype$init,
  27. _this2 = this;
  28. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  29. args[_key2] = arguments[_key2];
  30. }
  31. var options = args[0];
  32. this.id = options.id;
  33. //Require to set this.templateString before call the parent class
  34. this.templateString = DataSourceTitleTemplate;
  35. (_View$prototype$init = _View.prototype.init).call.apply(_View$prototype$init, [this].concat(args));
  36. this.isVisible = true;
  37. this.dashboardApi = options.dashboardApi;
  38. this.dataSource = options.dataSource;
  39. this.panelController = options.panelController;
  40. //Workaround for now to make sure DataSource is initialized when Metadata is loaded
  41. this.dashboardApi.getFeature('DataSources').getDataSource(this.id);
  42. //handle the change of state(ready, loading) by showing or hiding
  43. //the loading icon
  44. this.changeStateHandler = this.dataSource.on('change:state', this.onSourceChangeState.bind(this));
  45. this.removeHandler = this.dataSource.on('remove', this.onSourceRemoved.bind(this));
  46. // Add dataSource title division
  47. var sHTML = this.dotTemplate({});
  48. this.$el.append(sHTML);
  49. var loadingIndicator = new LoadingIndicator();
  50. loadingIndicator.render().then(function ($el) {
  51. _this2.$el.find('.loading-indicator').append($el);
  52. });
  53. this.$el.on('keydown.metadatatreeKeydown', this.onKeyDown.bind(this));
  54. this.logger = this.dashboardApi.getGlassCoreSvc('.Logger');
  55. };
  56. Metadata.prototype.onKeyDown = function onKeyDown(event) {
  57. //CTRL+C to copy selection tree items
  58. if (event.keyCode === 67 && event.ctrlKey) {
  59. this._copySelectedTreeItems();
  60. return false;
  61. }
  62. };
  63. Metadata.prototype._copySelectedTreeItems = function _copySelectedTreeItems() {
  64. return this.dataSource.getModule().then(function (module) {
  65. ShapingUIUtils.copySelectedTreeItems(module);
  66. }.bind(this));
  67. };
  68. Metadata.prototype.show = function show(options) {
  69. this.isVisible = true;
  70. this.render(options);
  71. };
  72. Metadata.prototype.render = function render(options) {
  73. this.dashboardApi.getFeature('DataSources').setActiveDataSourceId(this.dataSource.getId());
  74. if (!this.isRendered || options && options.forceRefreshMetadata) {
  75. //TODO: Hook up forceRefreshMetadata where necessary, and have it actually force a refresh
  76. this.isRendered = true;
  77. }
  78. this.panelController.clearIcons();
  79. this.panelController.renderDataSourcePaneButtons('com.ibm.bi.dashboard.dataSourcePanel.metadata.buttons').then(function () {
  80. if (this.isVisible && options && options.setFocus) {
  81. var firstButton = this.panelController.$el.find('.buttons .ds_btn');
  82. if (firstButton.length) {
  83. firstButton[0].focus();
  84. }
  85. }
  86. }.bind(this));
  87. return this._renderTree();
  88. };
  89. Metadata.prototype._renderTree = function _renderTree() {
  90. if (!this._module) {
  91. return this.dataSource.getModule().then(function (module) {
  92. this._module = module;
  93. // It's possible we got a module back but we're still in an error case.
  94. // For example, if we have an empty dataset
  95. if (this.dataSource.getState() === 'error') {
  96. this.showError(StringResources.get('errorLoadingDataTree'));
  97. return Promise.resolve();
  98. } else {
  99. this._treeContainer = this.$el.find('.metadataContainer')[0];
  100. return ShapingUIUtils.renderTree(module, this.dashboardApi, this._treeContainer, this.addDataItemsOrAddWidget.bind(this));
  101. }
  102. }.bind(this), function (err) {
  103. this.showError(StringResources.get('errorLoadingDataTree'));
  104. throw err;
  105. }.bind(this));
  106. } else {
  107. return ShapingUIUtils.renderTree(this._module, this.dashboardApi, this._treeContainer, this.addDataItemsOrAddWidget.bind(this));
  108. }
  109. };
  110. Metadata.prototype.showError = function showError(error) {
  111. var $container = this.$el.find('.metadataContainer');
  112. var errorSourcesLabel = StringResources.get('errorSourcesTitle');
  113. this.reactDomNode = $container[0];
  114. ReactDOM.render(React.createElement(
  115. 'div',
  116. { className: 'metadataTreeErrorContentWrapper' },
  117. React.createElement(
  118. 'div',
  119. { className: 'metadataTreeErrorImage ba-theme-waca' },
  120. React.createElement(
  121. 'svg',
  122. { viewBox: em_unknown_warning.default.viewBox, focusable: 'false' },
  123. React.createElement('use', { className: 'ba-graphics-themable', xlinkHref: '#' + em_unknown_warning.default.id, fill: '#8ee9d4' })
  124. )
  125. ),
  126. React.createElement(
  127. 'div',
  128. { className: 'metadataTreeErrorText line1', role: 'option', title: errorSourcesLabel, 'aria-label': errorSourcesLabel },
  129. errorSourcesLabel
  130. ),
  131. React.createElement(
  132. 'div',
  133. { className: 'metadataTreeErrorText line2', role: 'option', title: error, 'aria-label': error },
  134. error
  135. )
  136. ), this.reactDomNode);
  137. };
  138. Metadata.prototype.searchTypeDelay = function searchTypeDelay(evt, searchTerm) {
  139. this._renderTree(searchTerm);
  140. };
  141. Metadata.prototype.addDataItemsOrAddWidget = function addDataItemsOrAddWidget(payload, key) {
  142. if (key.shiftKey && key.keyCode === KeyCodes.RIGHT_ARROW) {
  143. this.addToCanvas(payload);
  144. } else if (key.shiftKey && key.altKey && key.keyCode === KeyCodes.F) {
  145. this.addToFilter(payload, true);
  146. } else if (key.shiftKey && key.keyCode === KeyCodes.F) {
  147. this.addToFilter(payload, false);
  148. }
  149. };
  150. Metadata.prototype.addToCanvas = function addToCanvas(payload) {
  151. if (payload.data && payload.data.utils && payload.data.utils.isValid()) {
  152. this.dashboardApi.addContentToCanvas(payload);
  153. }
  154. };
  155. Metadata.prototype.addToFilter = function addToFilter(payload, globalScope) {
  156. var _this3 = this;
  157. var selectedColumns = payload.data.columns;
  158. var options = {
  159. scope: null,
  160. openViewOnLoad: selectedColumns.length > 1 ? false : true
  161. };
  162. var canvas = this.dashboardApi.getCanvas();
  163. return canvas.getFeature('filterDock').then(function (filterDock) {
  164. if (globalScope && filterDock.isGlobalDockShown === false) {
  165. // if user is trying to add filter to global tab, ensure to see if
  166. // global tab is enabled or not. If not then don't do anything
  167. return;
  168. } else if (!globalScope) {
  169. // if user is trying to add filter to current tab, then use
  170. // the correct scope
  171. options.scope = filterDock.currentScope();
  172. }
  173. // loop through selected items and create filter for each
  174. for (var _iterator = selectedColumns, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
  175. var _ref;
  176. if (_isArray) {
  177. if (_i >= _iterator.length) break;
  178. _ref = _iterator[_i++];
  179. } else {
  180. _i = _iterator.next();
  181. if (_i.done) break;
  182. _ref = _i.value;
  183. }
  184. var column = _ref;
  185. var metadataColumn = column.metadataColumn;
  186. if (_this3._getPageContextType(metadataColumn.getDataType(), metadataColumn.getType()) === 'range') {
  187. options.condition = {};
  188. } else {
  189. options.values = [];
  190. }
  191. canvas.getFilters().addFilter({
  192. sourceId: metadataColumn.getSourceId(),
  193. itemId: metadataColumn.getId()
  194. }, options);
  195. }
  196. });
  197. };
  198. Metadata.prototype._getPageContextType = function _getPageContextType(dataType, usage) {
  199. if (usage === 'fact') {
  200. return 'range';
  201. }
  202. // usage is attribute: non numeric, tree, or date time filter
  203. var isDateType = dataType === 'date' || dataType === 'time' || dataType === 'datetime' || dataType === 'timestamp';
  204. return isDateType ? 'range' : 'tupleset';
  205. };
  206. Metadata.prototype.onSourceChangeState = function onSourceChangeState() {
  207. if (this.isVisible) {
  208. this.panelController.setTypeIcon(this.dataSource);
  209. }
  210. };
  211. Metadata.prototype.onSourceRemoved = function onSourceRemoved(event) {
  212. if (this.isVisible) {
  213. // If the source is removed by UndoRedoController, we don't want to render the dataSourceList after going back.
  214. // This is already taken care by DataSourceList.dataSourceCollection's 'on remove' handler.
  215. var preventRender = event && event.sender === 'UndoRedoController' ? true : false;
  216. this.panelController.goBack(preventRender);
  217. }
  218. };
  219. Metadata.prototype.detach = function detach() {
  220. this.$el.detach();
  221. this.isVisible = false;
  222. };
  223. Metadata.prototype.hide = function hide() {
  224. this.$el.hide();
  225. this.isVisible = false;
  226. };
  227. Metadata.prototype.remove = function remove() {
  228. this.changeStateHandler.remove();
  229. this.removeHandler.remove();
  230. this.changeStateHandler = null;
  231. this.removeHandler = null;
  232. this._module = null;
  233. this.dashboardApi = null;
  234. this.dataSource = null;
  235. this.panelController = null;
  236. this.logger = null;
  237. if (this._treeContainer) {
  238. ReactDOM.unmountComponentAtNode(this._treeContainer);
  239. }
  240. Metadata.inherited('remove', this, arguments);
  241. };
  242. return Metadata;
  243. }(View);
  244. });
  245. //# sourceMappingURL=Metadata.js.map