'use strict'; /** * Licensed Materials - Property of IBM * * IBM Cognos Products: Dashboard * * Copyright IBM Corp. 2015, 2020 * * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['jquery', 'underscore', '../../lib/@waca/core-client/js/core-client/ui/core/View', 'text!./templates/DataSourcePanel.html', '../nls/StringResources', '../../DynamicFileLoader', '../../lib/@waca/core-client/js/core-client/utils/BidiUtil', '../../lib/@waca/core-client/js/core-client/utils/BrowserUtils'], function ($, _, BaseView, template, resources, DynamicFileLoader, BidiUtil, BrowserUtils) { 'use strict'; var DataSourcePanel = BaseView.extend({ templateString: template, events: { 'primaryaction .backButton ': 'goBack' }, init: function init() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; DataSourcePanel.inherited('init', this, arguments); $.extend(this, options); this.slideout = options.slideout; this.dashboardView = options.glassContext.appController.getCurrentContentView(); this.initialize(); // Indicate that this view must be reloaded when the dashboard view is reloaded // because we depend on the datasource service this.dashboardView.addReloadableObject(this.viewId, this); this._cachedControllers = []; }, initialize: function initialize() { this.dashboardApi = this.dashboardView.getDashboardApi(); this.currentView = null; this.viewEntries = []; this.iconsFeature = this.dashboardApi.getFeature('Icons'); this._setupEvents(); this._setupPostRelinkHandler(); }, _setupPostRelinkHandler: function _setupPostRelinkHandler() { this.relinkHandler = this.dashboardApi.getFeature('.LifeCycleManager').registerLifeCycleHandler('post:relink', this._onRelink.bind(this)); }, _onRelink: function _onRelink() { this._cachedControllers = []; }, reload: function reload() { this.initialize(); if (this.isRendered) { this.render(); } }, _setupEvents: function _setupEvents() { this.registeredEvents = []; var dataSourcesSvc = this.dashboardApi.getFeature('dataSources.deprecated'); this.dataSourceCollection = dataSourcesSvc.getSourcesCollection(); this.registeredEvents.push(this.dashboardApi.on('widget:selected', this.handleWidgetSelection.bind(this))); this.registeredEvents.push(this.dashboardApi.on('dataSourceGrid:dataSourceSelected', this.showMetadataTree.bind(this))); this.registeredEvents.push(this.dashboardApi.on('dataSourcePanel:dataSourceAdded', this.handleDataSourceAddedByUser.bind(this))); this.registeredEvents.push(this.dashboardApi.on('dataSourceGrid:clearSourceSelected', this.clearGridSourceSelection.bind(this))); }, render: function render() { this.isRendered = true; // We will hide the slideout default pin button this.slideout.$el.addClass('sidepane'); this.$el.empty(); this.$el.addClass('datasetPanel'); var dataSourceIcon = this.iconsFeature.getIcon('common-data_source'); var previousIcon = this.iconsFeature.getIcon('common-previous'); var sHtml = this.dotTemplate({ dataSourceIcon: dataSourceIcon.id, previousIcon: previousIcon.id, goBackLabel: resources.get('backLabel') }); this.$el.append(sHtml); this._$dataSourceHeaderTitle = this.$('.datasetHeader .title'); this._$typeIcon = this.$('.datasetHeader .typeIcon'); this._$backButton = this.$('.datasetHeader .backButton'); this.showView(this._getViewOptions(), undefined, true); }, setTransientState: function setTransientState(name, value) { this.dashboardView.setTransientState(name, value); }, getTransientState: function getTransientState(name) { return this.dashboardView.getTransientState(name); }, getDataSourceListOptions: function getDataSourceListOptions() { return { id: 'dataSourceList', title: resources.get('sourcePaneLabel'), module: 'dashboard-analytics/dataSources/views/DataSourceList' }; }, remove: function remove() { this.dashboardView.removeReloadableObject(this.viewId, this); if (this.registeredEvents.length) { _.each(this.registeredEvents, function (collectionEvent) { if (collectionEvent) { collectionEvent.remove(); } }); this.registeredEvents.length = 0; } for (var i = 0; i < this.viewEntries.length; i += 1) { var _cachedView = this.viewEntries[i]._cachedView; if (_cachedView) { _cachedView.remove(); this.viewEntries[i]._cachedView = null; } } this.viewEntries.length = 0; this._cachedControllers.length = 0; this.slideout = null; this.dashboardView = null; this.dashboardApi = null; this.iconsFeature = null; this.dataSourceCollection = null; this.relinkHandler && this.relinkHandler.remove(); this.relinkHandler = null; DataSourcePanel.inherited('remove', this, arguments); }, showView: function showView(options, preventRender) { var setFocus = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (options.forceRefreshMetadata) { // Return when the current view is not metadata panel if (this.currentView && !this.currentView.back) { return; } else { this._removeViewEntry({ id: options.id }); } } //Save the state of the pane this.setTransientState(this._getStateName(), $.extend({}, options)); if (!options.id) { options.id = options.title; } var viewEntry = this._findViewEntry(options); if (viewEntry) { this._enableCachedView(viewEntry, preventRender, setFocus); return; } // Add common attributes to the view options options.panelController = this; options.dashboardApi = this.dashboardApi; var registerView = function (view) { options._cachedView = view; this.viewEntries.push(options); this._enableCachedView(options, undefined, setFocus); }.bind(this); if (this._viewInstance) { registerView(this._viewInstance); } else { DynamicFileLoader.load([options.module]).then(function (modules) { var view = new modules[0](options); registerView(view); }.bind(this)); } }, /** * Goes back and shows the previous view * @param preventRender When true the view will not be rendered */ goBack: function goBack(preventRender) { if (this.currentView && this.currentView.back) { this.showView(this.currentView.back, preventRender); this.currSourceId = null; } }, clearIcons: function clearIcons() { this.$('.datasetHeader .icons').empty(); }, addIcon: function addIcon($icon, handler) { var $button = $('
'); $button.attr('aria-labelledby', $icon.attr('id')); $button.append($icon); $button.on('primaryaction', handler); this.$('.datasetHeader .icons').append($button); }, renderDataSourcePaneButtons: function renderDataSourcePaneButtons(collectionId) { return this.dashboardApi.findGlassCollection(collectionId).then(function (buttonsCollection) { if (buttonsCollection) { buttonsCollection.sort(function (a, b) { return (a.weight || 0) - (b.weight || 0); }); buttonsCollection.forEach(function (buttonDefinition) { this._renderDataSourceButton(buttonDefinition); }.bind(this)); } }.bind(this)); }, _renderDataSourceButton: function _renderDataSourceButton(buttonDefinition) { var id = this.viewId + buttonDefinition.name; var icon = {}; var buttonIcon = buttonDefinition.icon; if (buttonIcon.indexOf('add-new') !== -1) { icon = this.iconsFeature.getIcon('addNew'); } else if (buttonIcon.indexOf('menuoverflow') !== -1) { icon = this.iconsFeature.getIcon('overflowMenuHorizontal32'); } else if (buttonIcon.indexOf('warning') !== -1 || buttonIcon.indexOf('error') !== -1) { icon = this.iconsFeature.getIcon('common-warning'); } var btnSVG = this._getSVGIcon(icon.id); var $addBtn = $('
' + btnSVG + '
'); //Add Source Button var label = buttonDefinition.label; $addBtn.attr('title', label); $addBtn.attr('aria-label', label); this.addIcon($addBtn, this.executeAction.bind(this, buttonDefinition)); }, renderSelectSourceButton: function renderSelectSourceButton(buttonDefinition) { var id = this.viewId + buttonDefinition.name; var label = buttonDefinition.label; var $button = $(''); $button.attr('title', label); $button.attr('aria-label', label); $button.on('primaryaction', this.executeAction.bind(this, buttonDefinition)); return $button; }, executeAction: function executeAction(buttonDefinition, evt) { var actionController = buttonDefinition.actionController; if (!actionController) { return; } if (buttonDefinition.name && this._cachedControllers[buttonDefinition.name]) { this._cachedControllers[buttonDefinition.name].execute(evt, buttonDefinition); } else { require([actionController], function (ActionController) { var controller = new ActionController({ dashboardApi: this.dashboardApi, dataSourcePanel: this }); if (buttonDefinition.name) { this._cachedControllers[buttonDefinition.name] = controller; } controller.execute(evt, buttonDefinition); }.bind(this)); } }, setFocus: function setFocus() { //This is being handled by the sub-view. }, /* * Private Methods */ _getViewOptions: function _getViewOptions() { // check if there is an active data source set in explore view, if yes we want to show metadata tree of this data source var activeSourceId = this.dashboardApi.getActiveDataSourceId(); var options = this.getTransientState(this._getStateName()); if (activeSourceId) { if (!options || !options.dataSource || options.dataSource.getId() !== activeSourceId) { if (!options) { // options is null when we render the datasource panel for the first time, mark 'dataSourceListRendered' state to true so that when DataSourceList.render() is called for goBack, // it doesn't try to load the metadata this.setTransientState('dataSourceListRendered', true); } options = this._getActiveDataSourceOptions(activeSourceId); } } if (!options) { options = this.getDataSourceListOptions(); } return options; }, _getActiveDataSourceOptions: function _getActiveDataSourceOptions(activeSourceId) { var dataSource = this.dataSourceCollection.getSource(activeSourceId); var name = dataSource.getName(); var options = { id: dataSource.getId(), module: 'dashboard-analytics/dataSources/views/Metadata', dataSource: dataSource, back: this.getDataSourceListOptions(), title: name, dataSourceName: name }; return options; }, _getStateName: function _getStateName() { return 'dataSourcePaneState'; }, _enableCachedView: function _enableCachedView(viewEntry, preventRender) { var setFocus = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; //Toggle elements which are only visible in one view. this._$backButton.toggle(!!viewEntry.back); this._$typeIcon.toggle(!!viewEntry.back); this.setTypeIcon(viewEntry.dataSource); var isIE = BrowserUtils.isIE(); if (this.currentView && this.currentView._cachedView) { if (isIE) { this.currentView._cachedView.hide(); } else { this.currentView._cachedView.detach(); } } this.clearIcons(); if (viewEntry.title) { this._$dataSourceHeaderTitle.text(viewEntry.title); this._$dataSourceHeaderTitle.attr('title', viewEntry.title); this._$dataSourceHeaderTitle.attr('aria-label', viewEntry.title); this._$dataSourceHeaderTitle.attr('dir', BidiUtil.resolveBaseTextDir(viewEntry.title)); } if (!viewEntry._cachedView) return; if (isIE && viewEntry._cachedView && viewEntry._cachedView.$el.parent().length !== 0) { viewEntry._cachedView.$el.show(); } else { this.$('.datasetContent').append(viewEntry._cachedView.$el); } //currentView needs to be set before the cached view is rendered. This is so that user //can still return to data source list pane in case of error since the view will always be partially rendered with //'go back' button. this.currentView = viewEntry; this.currentView && this.currentView._cachedView && this.currentView._cachedView.show({ forceRefreshMetadata: viewEntry.forceRefreshMetadata, preventRender: preventRender, setFocus: setFocus }); }, setTypeIcon: function setTypeIcon(dataSource) { var dataSourceIcon = this.iconsFeature.getIcon('common-data_source'); var typeIcon = this._getSVGIcon(dataSourceIcon.id); if (dataSource) { //These rules should match those in templates/DataSourceItem.html var state = dataSource.getState(), type = dataSource.getType(); if (state === 'loading') { typeIcon = ''; } else if (type === 'module') { var modelIcon = this.iconsFeature.getIcon('common-titan-model'); typeIcon = this._getSVGIcon(modelIcon.id); } else if (type === 'uploadedFile') { var uploadIcon = this.iconsFeature.getIcon('common-upload'); typeIcon = this._getSVGIcon(uploadIcon.id); } else { var dataSetIcon = this.iconsFeature.getIcon('common-dataset'); typeIcon = this._getSVGIcon(dataSetIcon.id); } } this._$typeIcon.html(typeIcon); }, _getSVGIcon: function _getSVGIcon(SVGIconId) { return SVGIconId && ''; }, _findViewEntry: function _findViewEntry(options) { return _.find(this.viewEntries, function (viewEntry) { return options.id === viewEntry.id; }); }, _removeViewEntry: function _removeViewEntry(options) { var entry = _.findWhere(this.viewEntries, { id: options.id }); if (entry && entry._cachedView) { entry._cachedView.remove(); } this.viewEntries = _.without(this.viewEntries, entry); }, /** * Override Gemini base behavior */ _hideDataSourcePanel: function _hideDataSourcePanel() { // Empty method. }, loadMetadata: function loadMetadata(dataSource) { var forceRefreshMetadata = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var setFocus = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; dataSource.getLocalizedName().then(function (name) { this.currSourceId = dataSource.getId(); this.showView({ id: dataSource.getId(), dataSourceName: name, module: 'dashboard-analytics/dataSources/views/Metadata', dataSource: dataSource, back: this.getDataSourceListOptions(), forceRefreshMetadata: forceRefreshMetadata, title: name }, undefined, setFocus); }.bind(this)); }, handleDataSourceAddedByUser: function handleDataSourceAddedByUser(event) { if (event.sender && this.dataSourceCollection) { this.dashboardApi.triggerDashboardEvent('dataSourcePanel:dataSourceSelected', { sender: event.sender }); this.showMetadataTree(event, true); } }, showMetadataTree: function showMetadataTree(event) { var setFocus = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (typeof setFocus !== 'boolean') { setFocus = false; } if (event.sender && this.dataSourceCollection) { this.loadMetadata(this.dataSourceCollection.getSource(event.sender), false, setFocus); } }, /** * Clear the UI selection from the metadata tree */ clearGridSourceSelection: function clearGridSourceSelection() { if (this.dataSourceCollection) { var $items = this.$el.find('.bi-common-treeItem'); $items.removeClass('is-selected'); } }, handleWidgetSelection: function handleWidgetSelection(event) { if (event.sender && this.dataSourceCollection) { var sourceId = this.dataSourceCollection.usesSource(event.sender); if (sourceId && this.currSourceId !== sourceId) { var source = this.dataSourceCollection.getSource(sourceId); if (source.getState() !== 'error') { //Don't attempt to show a tree for a source in an error state. this.currSourceId = sourceId; this.loadMetadata(source); } } } } }); return DataSourcePanel; }); //# sourceMappingURL=DataSourcePanel.js.map