'use strict'; /* *+------------------------------------------------------------------------+ *| Licensed Materials - Property of IBM *| IBM Cognos Products: Dashboard *| (C) Copyright IBM Corp. 2014, 2020 *| *| US Government Users Restricted Rights - Use, duplication or disclosure *| restricted by GSA ADP Schedule Contract with IBM Corp. *+------------------------------------------------------------------------+ */ define(['../../lib/@waca/dashboard-common/dist/ui/SearchableListView', 'text!./templates/DataSourceItem.html', '../nls/StringResources', '../../util/DashboardFormatter', '../glassControllers/MenuActionHelper', '../../DynamicFileLoader', '../../lib/@waca/dashboard-common/dist/lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/add-data-source_128', 'jquery', 'underscore', 'react-dom', 'react', 'ca-ui-toolkit', '../glassControllers/AddSourceActionHandler'], function (SearchableListView, ItemTemplate, stringResources, Formatter, MenuActionHelper, DynamicFileLoader, em_add_sources, $, _, ReactDOM, React, Toolkit, AddSourceActionHandler) { 'use strict'; var DATASOURCE_SELECTED_EVT = 'dataSourcePanel:dataSourceSelected'; var Button = Toolkit.Button; var View = null; View = SearchableListView.extend({ _baseEvents: { 'click .treeSortContainer': 'onSortClick', 'tap .treeSortContainer': 'onSortClick', 'click input[id^="relink_"]': 'onRelinkButtonClick' }, events: {}, itemTemplate: ItemTemplate, relinkDialogModule: 'dashboard-analytics/dataSources/dialogs/RelinkDialog', isVisible: true, /** * Model change:id event handler * operation before we rerender the data sources list * */ onModelChangeHandler: function onModelChangeHandler() { //setTimeout to make sure all attributes are updated as an atomic operation window.setTimeout(this.render.bind(this), 10); }, init: function init(attributes) { this.listItemClass = 'sourceLabelContainer'; View.inherited('init', this, arguments); var panelAttributes = attributes || {}; this.dashboardApi = panelAttributes.dashboardApi; this.panelController = attributes.panelController; this.dataSourcesSvc = this.dashboardApi.getFeature('dataSources.deprecated'); this.isAlreadyRendered = this.panelController.getTransientState('dataSourceListRendered'); this.panelController.setTransientState('dataSourceListRendered', true); this.registeredEvents = []; this.reactDomNode = null; }, /** * Extend the BaseClass's _setupEvents function and add clicktap event handler for "do more" icon * @override * */ _setupEvents: function _setupEvents() { View.inherited('_setupEvents', this, arguments); this.events['primaryaction ' + '.listitem .ellipsesButton'] = 'onDoMore'; this.events['keydown ' + '.listitem .ellipsesButton'] = 'onKeyDown'; this.events['contextmenu ' + '.listitem'] = 'onDoMore'; }, fetchDataSources: function fetchDataSources() { var dataSourceCollection = this.dataSourcesSvc.getSourcesCollection(); if (dataSourceCollection) { this.dataSourceCollection = dataSourceCollection; this.registeredEvents.push(this.dataSourceCollection.on('change:assetId', function (payload) { this.aDataSources = dataSourceCollection.getSources(); this.onModelChangeHandler(payload); }.bind(this))); this.registeredEvents.push(this.dataSourceCollection.on('change:state', function () { this.aDataSources = dataSourceCollection.getSources(); this.render(); }.bind(this))); this.registeredEvents.push(this.dataSourceCollection.on('add', function () { this.aDataSources = dataSourceCollection.getSources(); this.render(); }.bind(this))); this.registeredEvents.push(this.dataSourceCollection.on('remove', function () { this.aDataSources = dataSourceCollection.getSources(); this.render(); }.bind(this))); this.registeredEvents.push(this.dataSourceCollection.on('change:version', function (event) { var dataSourceId = event.model.id; var dataSource = this.dataSourceCollection.getSource(dataSourceId); this.dashboardApi.triggerDashboardEvent(DATASOURCE_SELECTED_EVT, { sender: dataSourceId, refreshDatasetAction: true }); this.isAlreadyRendered = false; this.loadMetadata(dataSource, true); }.bind(this))); this.aDataSources = dataSourceCollection.getSources(); } else { this._showError(); } }, _showError: function _showError() { DynamicFileLoader.load(['lib/@waca/dashboard-common/dist/ui/dialogs/MessageBox']).then(function (Modules) { var ErrorMsg = Modules[0]; var title = stringResources.get('errorMessageTitle'); var displayMessage = stringResources.get('errorLoadingDataSources'); var msg = new ErrorMsg('error', title, displayMessage); msg.open(); }); }, onRelinkButtonClick: function onRelinkButtonClick() { return false; }, loadMetadata: function loadMetadata(dataSource, forceRefreshMetadata) { return this.panelController.loadMetadata(dataSource, forceRefreshMetadata, true); }, /** * Extend Baseclass's onSelectItem event handler * @override **/ onSelectItem: function onSelectItem(event) { if ($(event.target).parents('.caption').hasClass('missingRef') || !($(event.target).hasClass('datasetLabel') || $(event.target).hasClass('sourceLabelContainer')) || $(event.target).parents('.caption').hasClass('warning')) { return false; } var target = this.getTarget(event.target, 'listitem'); var dsId = target.getAttribute('data-id'); var dataSource = this.dataSourceCollection.getSource(dsId); this.dashboardApi.getFeature('DataSources').setActiveDataSourceId(dsId); this.dashboardApi.triggerDashboardEvent(DATASOURCE_SELECTED_EVT, { sender: dsId }); this.$el.off(); this.loadMetadata(dataSource); }, prepareListItem: function prepareListItem(item) { item.cssClass = 'data-source'; var sDate = null; var timezone = this.dashboardApi.getGlassCoreSvc('.UserProfile').preferences.timeZoneID || 'America/New_York'; if (item.lastModified) { sDate = Formatter.format(item.lastModified, { type: 'date', formatLength: 'short', timezone: timezone }); var sTime = Formatter.format(item.lastModified, { type: 'time', formatLength: 'short', timezone: timezone }); if (sTime) { sDate = sDate + ' ' + sTime; } } item.title = stringResources.get('moreTitle'); item.lastUpdatedString = sDate; return item; }, prepareDataSourceList: function prepareDataSourceList(dataSources) { var _this = this; var aPrepDataSources = []; var whenNamesReady = []; var getName = function getName(source, item) { return source.getLocalizedName().then(function (name) { item.name = name; return source.exists(); }).then(function (exists) { item.state = source.getState(); //State can be updated by the getLocalizedName() and exists() calls, so set it after those calls have finished. item.exists = exists; return source.getModificationTime(); }).then(function (modificationTime) { item.lastModified = modificationTime; }).catch(function () { item.state = 'error'; item.errorCode = '404'; item.exists = false; // recover from error }); }; for (var i = 0; i < dataSources.length; i++) { var item = { type: dataSources[i].getType(), id: dataSources[i].getId() }; if (dataSources[i].getIsOlapPackage()) { item.isOlapPackage = true; } else { item.isOlapPackage = false; } if (dataSources[i].lastModified) { item.lastModified = dataSources[i].lastModified; } else if (dataSources[i].lastUpdated) { item.lastUpdated = dataSources[i].lastUpdated; } aPrepDataSources.push(item); whenNamesReady.push(getName(dataSources[i], item)); } var result = void 0; if (whenNamesReady.length > 0) { var always = function always() { _this.aPrepDataSources = aPrepDataSources; return aPrepDataSources; }; result = Promise.all(whenNamesReady).then(always, always); } else { this.aPrepDataSources = aPrepDataSources; result = Promise.resolve(aPrepDataSources); } return result; }, getListItems: function getListItems() { var result = void 0; if (this.aDataSources) { result = this.prepareDataSourceList(this.aDataSources); } else { this.fetchDataSources(); if (this.aDataSources) { result = this.prepareDataSourceList(this.aDataSources); } else { result = Promise.reject(new Error()); } } return result; }, /** * Sets the visibility to true and calls render * @param options { preventRender: true } If preventRender is true the view will not be rendered */ show: function show(options) { this.isVisible = true; if (options && options.preventRender === true) { return; } this.render(); }, render: function render() { var _this2 = this; this.dashboardApi.getFeature('DataSources').setActiveDataSourceId(null); this.dashboardApi.triggerDashboardEvent(DATASOURCE_SELECTED_EVT, { sender: null }); return View.inherited('render', this, arguments).then(function () { if (_this2.isVisible) { _this2.panelController.clearIcons(); return _this2.panelController.renderDataSourcePaneButtons('com.ibm.bi.dashboard.dataSourcePanel.list.buttons').then(function () { var dataSourceButtons = _this2.panelController.$el.find('.icons .ds_btn'); if (dataSourceButtons && dataSourceButtons[0]) { dataSourceButtons[0].focus(); } }); } }).then(function () { $('.datasetContent').find('.loading').remove(); var dataSourceListBox = _this2.$el.find('.list'); dataSourceListBox.attr('title', stringResources.get('sourcePaneContentLabel')); // Add the empty indicator var dataSourcePanel = _this2.$el.find('.datasetPanel'); dataSourcePanel.attr('data-pageindex', 0); var dataSourceItem = _this2.$el.find('.listitem'); dataSourceItem.removeAttr('tabindex'); dataSourceItem.removeAttr('aria-activedescendant'); dataSourceItem.removeAttr('aria-selected'); dataSourceItem.removeAttr('role'); if (_this2.aDataSources.length === 0) { _this2._getEmptyDataSourceTemplate(dataSourceListBox); dataSourceListBox.addClass('emptyTableContent'); dataSourceListBox.removeClass('list'); dataSourceListBox.removeAttr('role'); dataSourceListBox.removeAttr('aria-multiselectable'); } else { _this2.$el.find('.listitem .sourceLabelContainer').first().attr('tabindex', 0); } // if we are rendering for the first time and we have one source, // we automatically open the source metadata if (!_this2.isAlreadyRendered) { _this2.isAlreadyRendered = true; if (_this2.aDataSources.length === 1 && (!_this2.aDataSources[0].getState() || _this2.aDataSources[0].getState() === 'ready')) { return _this2.loadMetadata(_this2.aDataSources[0]); } else if (_this2.aDataSources.length > 1) { var activeSourceId = _this2.dashboardApi.getActiveDataSourceId(); if (activeSourceId) { var activeDataSource = _this2.aDataSources.find(function (dataSource) { return dataSource.getId() === activeSourceId; }); if (activeDataSource) { return _this2.loadMetadata(activeDataSource); } } } } }); }, onAddDataSourceClicked: function onAddDataSourceClicked() { var addSourceHandler = new AddSourceActionHandler({ 'dashboardApi': this.dashboardApi }); return addSourceHandler.execute(); }, _getEmptyDataSourceTemplate: function _getEmptyDataSourceTemplate(el) { var _this3 = this; var perspectiveLabel = this.dashboardApi.getApplicationLabel().toLowerCase(); var selectSourcesText = stringResources.get('selectSourcesText', { app: perspectiveLabel }); var selectSourcesLabel = stringResources.get('selectSourcesLabel'); this.reactDomNode = el[0]; ReactDOM.render(React.createElement( 'div', { className: 'emptyTableContentWrapper' }, React.createElement( 'div', { className: 'emptyTableImage ba-theme-waca' }, React.createElement( 'svg', { viewBox: em_add_sources.default.viewBox, focusable: 'false', height: '128px', 'margin-top': '3px' }, React.createElement('use', { className: 'ba-graphics-themable', xlinkHref: '#' + em_add_sources.default.id, fill: '#8ee9d4' }) ) ), React.createElement( 'div', { className: 'emptyTableText line1', role: 'option', title: selectSourcesLabel, 'aria-label': selectSourcesLabel }, selectSourcesLabel ), React.createElement( 'div', { className: 'emptyTableText line2', role: 'option', title: selectSourcesText, 'aria-label': selectSourcesText }, selectSourcesText ), React.createElement( 'div', { className: 'selectSourceButton' }, React.createElement(Button, { label: stringResources.get('selectSourcesLabel'), variant: 'solid', intent: 'primary', onClick: function onClick() { return _this3.onAddDataSourceClicked(); }, 'aria-label': selectSourcesLabel }) ) ), this.reactDomNode); return; }, getCustomRenderProperties: function getCustomRenderProperties() { return { newStyle: true, sortFlyout: false, defaultSortIcon: 'wfg_modified_desc' }; }, /** * Context Menu Event handler, User clicks the doMore icon to launch data set context menu * */ onDoMore: function onDoMore(evt) { var id = $(evt.target).parents('div.listitem').attr('data-id'); var name = $(evt.target).parents('div.listitem').attr('data-name'); var dataSource = this.dataSourceCollection.getSource(id); MenuActionHelper.getActionPayload({ 'dashboardApi': this.dashboardApi, 'id': dataSource.getAssetId(), 'type': dataSource.getType(), 'event': evt, 'menuId': 'com.ibm.bi.dashboard.dataSources.dataSourceMenu', 'position': { pageX: evt.pageX, pageY: evt.pageY } }).then(function (payload) { payload.activeObject.dialogModule = this.relinkDialogModule; payload.activeObject.dataSource = dataSource; payload.activeObject.dataSourceName = name; payload.activeObject.dataSourceCollection = this.dataSourceCollection; this.dashboardApi.showContextMenu(payload); }.bind(this)); return false; }, _getSearchableItems: function _getSearchableItems() { return this.aPrepDataSources; }, _getSearchableFieldValue: function _getSearchableFieldValue(value) { return value.name; }, onSortClick: function onSortClick() {}, _showNodeOnFocus: function _showNodeOnFocus($node) { $node.css('display', 'inline'); $node.addClass('hideOnFocusChange'); }, _hideNodeOnUnfocus: function _hideNodeOnUnfocus($node) { $node.css('display', 'none'); $node.removeClass('hideOnFocusChange'); }, _getNextFocusableSiblingElement: function _getNextFocusableSiblingElement($target) { var $nextSiblings = $target.nextAll('[tabindex="-1"]'); var focusedItems = $target.nextAll('[tabindex="0"]'); var currentfocusedItem = focusedItems.length && focusedItems.first()[0]; var $newNodeToFocus = $($nextSiblings[0]); if (currentfocusedItem === $newNodeToFocus[0] || !$newNodeToFocus.length) { // item already focused. return; } if ($newNodeToFocus.css('display') === 'none') { this._showNodeOnFocus($newNodeToFocus); } return $newNodeToFocus; }, _getPreviousFocusableSiblingElement: function _getPreviousFocusableSiblingElement($target) { var $previousSiblings = $target.prevAll('[tabindex="-1"]'); var focusedItems = $target.prevAll('[tabindex="0"]'); var currentfocusedItem = focusedItems.length && focusedItems.first()[0]; var $newNodeToFocus = $($previousSiblings[0]); if (currentfocusedItem === $newNodeToFocus[0] || !$newNodeToFocus.length) { // item already focused. return; } if ($newNodeToFocus.css('display') === 'none') { this._showNodeOnFocus($newNodeToFocus); } if ($target.hasClass('focusable') && $target.hasClass('hideOnFocusChange')) { this._hideNodeOnUnfocus($target); } return $newNodeToFocus.length === 0 ? null : $newNodeToFocus; }, rightArrowHandler: function rightArrowHandler($target) { return this._getNextFocusableSiblingElement($target); }, leftArrowHandler: function leftArrowHandler($target) { return this._getPreviousFocusableSiblingElement($target); }, _findRelatedListItem: function _findRelatedListItem($target) { var $t = $target; if ($target.hasClass('focusable')) { var $ancestor = $target.closest('.listitem'); $t = $ancestor.find(this.itemClassSelector); } return $t; }, downArrowHandler: function downArrowHandler($target) { var $relatedListItem = this._findRelatedListItem($target); if ($target.hasClass('focusable') && $target.hasClass('hideOnFocusChange')) { this._hideNodeOnUnfocus($target); } var $items = this.$(this.itemClassSelector + ':visible'); return $($items[$items.index($relatedListItem) + 1]); }, upArrowHandler: function upArrowHandler($target) { var $relatedListItem = this._findRelatedListItem($target); if ($target.hasClass('focusable') && $target.hasClass('hideOnFocusChange')) { this._hideNodeOnUnfocus($target); } var $items = this.$(this.itemClassSelector + ':visible'); return $($items[$items.index($relatedListItem) - 1]); }, _getCurrentlyFocusedItems: function _getCurrentlyFocusedItems() { return this.$('[tabindex="0"]'); }, _triggerFocusEvent: function _triggerFocusEvent($target) { var $relatedListItem = $target.closest('.listitem'); this.trigger('focus:item', { id: $relatedListItem.attr('data-id') }); }, detach: function detach() { this.$el.detach(); this.isVisible = false; }, hide: function hide() { this.$el.hide(); this.isVisible = false; }, remove: function remove() { if (this.registeredEvents.length) { _.each(this.registeredEvents, function (collectionEvent) { if (collectionEvent) { collectionEvent.remove(); } }); this.registeredEvents = []; } this.aDataSources = null; this.dashboardApi = null; this.panelController = null; this.dataSourcesSvc = null; if (this.reactDomNode) { ReactDOM.unmountComponentAtNode(this.reactDomNode); } View.inherited('remove', this, arguments); } }); return View; }); //# sourceMappingURL=DataSourceList.js.map