'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