123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910 |
- 'use strict';
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- /**
- * Licensed Materials - Property of IBM
- * IBM Cognos Products: Dashboard
- * (C) Copyright IBM Corp. 2013, 2021
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- *
- * VisActionHelper
- * The VisActionHelper is responsible for loading and executing interactive actions that affect the vismodel.
- *
- */
- define(['jquery', 'underscore', '../../widgets/livewidget/nls/StringResources', '../../DynamicFileLoader', './VisActionSlotSupport', '../../dataSources/utils/DatasourceUtil', '../../apiHelpers/SlotAPIHelper'], function ($, _, resources, DynamicFileLoader, VisActionSlotSupport, DatasourceUtil, SlotAPIHelper) {
- 'use strict';
- var SlotAction = function () {
- function SlotAction(spec) {
- _classCallCheck(this, SlotAction);
- this.spec = spec;
- }
- SlotAction.prototype.getActionId = function getActionId() {
- return this.spec.ACTION_ID;
- };
- SlotAction.prototype.getAvailableActions = function getAvailableActions() {
- return [this.spec];
- };
- return SlotAction;
- }();
- var VisActionHelper = function () {
- function VisActionHelper(attributes) {
- _classCallCheck(this, VisActionHelper);
- this._visModel = attributes.visModel;
- this.selectionController = attributes.selectionController;
- this.pageContext = attributes.pageContext;
- this.ownerWidget = attributes.ownerWidget;
- this.content = attributes.content;
- this.dashboardApi = attributes.ownerWidget.getDashboardApi();
- //Any dynamically loaded actions (eg: FilterLocalExcludeAction) should be saved here for cleanup on remove.
- this._registeredActions = {};
- this.logger = attributes.ownerWidget.logger;
- this._visActionSlotSupport = new VisActionSlotSupport(attributes);
- }
- VisActionHelper.prototype.remove = function remove() {
- var _this = this;
- if (this.toolbar) {
- this.toolbar.remove();
- this.toolbar = null;
- }
- this._visModel = null;
- this.selectionController = null;
- this.pageContext = null;
- this.ownerWidget = null;
- this.visualization = null;
- this.dashboardApi = null;
- this.logger = null;
- // cleanup registered actions (eg FilterLocalKeep, FilterLocalExclude, FilterAllKeep).
- _.each(_.keys(this._registeredActions), function (action) {
- delete _this._registeredActions[action];
- });
- };
- VisActionHelper.prototype._supportsSortAction = function _supportsSortAction() {
- return this._visModel && this._visModel.supportsSortAction();
- };
- VisActionHelper.prototype._supportsContextualTopBottomAction = function _supportsContextualTopBottomAction() {
- return this.getVisualization().getDefinition().getProperty('supportsContextualTopBottomAction');
- };
- VisActionHelper.prototype._supportsNonContextualTopBottomAction = function _supportsNonContextualTopBottomAction() {
- return this.getVisualization().getDefinition().getProperty('supportsNonContextualTopBottomAction');
- };
- VisActionHelper.prototype._supportsFormatAction = function _supportsFormatAction() {
- return this._visModel && this._visModel.supportsFormatAction();
- };
- VisActionHelper.prototype._supportsBinAction = function _supportsBinAction() {
- return this._visModel && this._visModel.supportsBinAction();
- };
- /**
- * Show the actions/labels tooltip for the current selection
- *
- * @param selections - Array of selections
- * @param position - Container node or bounds information where the tooltip should appear
- * @param {boolean} includeApplyFilter - whether to include the 'filter' (apply filter) action
- * @param {boolean} noFilter - true - hide all options on hover or used by grid/crosstab to turn off the filter option
- * @param {boolean} drillOnly
- * @param {boolean} noDrillthrough - whether to include the 'Drill through' (JumpToAction) action
- * @param {options}
- */
- VisActionHelper.prototype.showDataPointActions = function showDataPointActions(selections, position, includeApplyFilter, noFilters, drillOnly, noDrillthrough, options) {
- var _this2 = this;
- options = options || {};
- var actionOptions = {
- includeApplyFilter: includeApplyFilter,
- noFilters: noFilters,
- drillOnly: drillOnly,
- noDrillthrough: noDrillthrough,
- selections: selections,
- isHovering: options.isHover,
- area: options.area,
- isAreaSelected: options.isAreaSelected
- };
- var availableActions = [];
- var fRegisterAction = function fRegisterAction(action) {
- availableActions = availableActions.concat(action.getAvailableActions());
- };
- return this._getExtraDatapointActions(options).then(function (actions) {
- _.each(actions, fRegisterAction);
- var labels = _this2.selectionController.getToolbarLabelsForSelections(selections);
- var sTitle = _this2.selectionController.getToolbarTitleForSelections(selections);
- if (!options.isHover) {
- var _availableActions;
- (_availableActions = availableActions).push.apply(_availableActions, _this2._getDataPointActionList(selections, actionOptions, options));
- }
- if (labels.length > 0 || sTitle.length > 0) {
- var eventOptions = {
- 'targetNode': position ? position.targetNode : null,
- 'targetBounds': position ? position.bounds : null,
- 'actions': availableActions,
- 'labels': labels,
- 'title': sTitle,
- 'options': options,
- 'tooltipContext': { /* This is not used in for now. It is here for the custom tooltip extension */
- content: _this2.content,
- context: _this2._convertOldSelectionToNewSpec(selections)
- }
- };
- eventOptions.toolbarOptions = {
- iconOnly: true,
- isTextEditorOnly: false
- };
- if (availableActions.length === 1) {
- eventOptions.toolbarOptions['isTextEditorOnly'] = true;
- }
- _this2.dashboardApi.triggerDashboardEvent('widget:availableActions', eventOptions);
- }
- });
- };
- /**
- * As agreed, the final selections payload is the union of brushing and pending filters.
- * @example of the payload:
- * {
- * 'area': 'visualization',
- * 'dataPoints': [{
- * 'categories': [{
- * 'dataItemId': 'item0_id',
- * 'columnId': 'item0',
- * 'value': 'value1',
- * 'label': 'value1_label'
- * }, {
- * 'dataItemId': 'item1_id',
- * 'columnId': 'item1',
- * 'value': 'value2',
- * 'label': 'value2_label'
- * }],
- * 'facts': [{
- * 'dataItemId': 'fact2_id',
- * 'columnId': 'fact2',
- * 'value': 1000
- * }]
- * }, {
- * 'categories': [{
- * 'dataItemId': 'item0_id',
- * 'columnId': 'item0',
- * 'value': 'value3',
- * 'label': 'value3_label'
- * }, {
- * 'dataItemId': 'item1_id',
- * 'columnId': 'item1',
- * 'value': 'value2',
- * 'label': 'value2_label'
- * }]
- * }
- */
- VisActionHelper.prototype._getDataPointActionList = function _getDataPointActionList(selections, actionOptions, options) {
- var newSelections = this._getBrushingAndPendingSelections(selections, this.content, options);
- return this.content.getFeature('DataPointActions').getDataPointActionList(newSelections, actionOptions);
- };
- VisActionHelper.prototype._convertOldSelectionToNewSpec = function _convertOldSelectionToNewSpec(selections) {
- var _this3 = this;
- var dataPoints = [];
- var categorySelections = selections && selections.getCategorySelections() || [];
- var selectionEntry = {};
- var categories = [];
- categorySelections.forEach(function (category) {
- categories.push(_this3._toPayLoadValue(category.value, category.slotDataItem.getColumnId(), category.slotDataItem.getId()));
- });
- var ordinalSelections = selections && selections.getOrdinalSelections() || [];
- var facts = _.map(ordinalSelections, function (factItem) {
- return {
- dataItemId: factItem.slotDataItem.getId(),
- columnId: factItem.slotDataItem.getColumnId(),
- value: factItem.value instanceof Object ? factItem.value.value : factItem.value
- };
- });
- if (categories.length) {
- selectionEntry.categories = categories;
- }
- if (facts.length) {
- selectionEntry.facts = facts;
- }
- dataPoints.push(selectionEntry);
- return {
- dataPoints: dataPoints
- };
- };
- VisActionHelper.prototype._getBrushingAndPendingSelections = function _getBrushingAndPendingSelections(selections, content, options) {
- var _this4 = this;
- var dataPoints = [];
- var categorySelections = selections && selections._aCategorySelections || [];
- var selectionEntry = {};
- var categories = [];
- categorySelections.forEach(function (category) {
- if (!category.isEdgeSelection) {
- categories.push(_this4._toPayLoadValue(category.value, category.slotDataItem.getColumnId(), category.slotDataItem.getId()));
- }
- });
- var ordinalSelections = selections && selections._aOrdinalSelections || [];
- var facts = _.map(ordinalSelections, function (factItem) {
- return {
- dataItemId: factItem.slotDataItem.getId(),
- columnId: factItem.slotDataItem.getColumnId(),
- value: factItem.value /* TODO - fix the value here. It should just be the value, but it is a json {value:1234, v:1234} */
- };
- });
- if (categories.length) {
- selectionEntry.categories = categories;
- }
- if (facts.length) {
- selectionEntry.facts = facts;
- }
- dataPoints.push(selectionEntry);
- var selectedDataItemList = selections._aCategorySelections ? selections._aCategorySelections.map(function (selection) {
- return selection.slotDataItem;
- }) : [];
- var pageContextSelections = content.getFeature('DataPointSelections').getSelections(selectedDataItemList);
- var pendingSelections = content.getFeature('DataPointSelections.pending').getSelections(selectedDataItemList);
- // Check if current selection is in pageContext selections
- var selectionInPageContext = false;
- var currentCategoryKey = _.pluck(categories, 'columnId').join();
- pageContextSelections.forEach(function (selection) {
- var categoryKey = _.pluck(selection.categories, 'columnId').join();
- // if current selection is in pageContext selections, use combined selections
- // OR if edge selection, and current selection is in pageContext
- if (currentCategoryKey === categoryKey || currentCategoryKey === '' && _this4._compareCategorySelections(categorySelections, selection.categories)) {
- pageContextSelections = pageContextSelections.concat(pendingSelections);
- selectionInPageContext = true;
- }
- });
- if (!selectionInPageContext) {
- pageContextSelections = pendingSelections;
- }
- dataPoints = dataPoints.concat(pageContextSelections);
- dataPoints = this._uniqueValues(dataPoints);
- return {
- area: options && options.area,
- dataPoints: dataPoints
- };
- };
- VisActionHelper.prototype._compareCategorySelections = function _compareCategorySelections(categorySelections, categories) {
- var values = _.pluck(categorySelections, 'value');
- var categoryKeys = _.pluck(categories, 'value');
- var contains = true;
- values.forEach(function (value) {
- if (!(categoryKeys.indexOf(value.u) !== -1)) {
- contains = false;
- }
- });
- return values && categoryKeys && contains;
- };
- VisActionHelper.prototype._toPayLoadValue = function _toPayLoadValue(value, columnId, dataItemId) {
- var resultPayLoad = {
- dataItemId: dataItemId,
- columnId: columnId,
- value: value.u,
- label: value.d
- };
- if (value.pu || value.p) {
- resultPayLoad.parentId = value.pu || value.p.u;
- }
- return resultPayLoad;
- };
- VisActionHelper.prototype._uniqueValues = function _uniqueValues() {
- var dataPointSelections = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
- var uniqueValues = [];
- var valuesMap = {};
- dataPointSelections.forEach(function (dataPoint) {
- var categoryKey = _.pluck(dataPoint.categories, 'value').join();
- if (!valuesMap[categoryKey]) {
- valuesMap[categoryKey] = 1;
- uniqueValues.push(dataPoint);
- }
- });
- return uniqueValues;
- };
- VisActionHelper.prototype._getExtraDatapointActions = function _getExtraDatapointActions(options) {
- var result = void 0;
- if (!(options && options.slots && options.mapIndex !== undefined)) {
- result = Promise.resolve([]);
- } else {
- options.actions && options.actions.actionOptions && (options.actions.actionOptions.JumpToAction = {
- area: options.area
- });
- result = this.getActionsForSlots(options.slots, options.mapIndex, null, options.actions);
- }
- return result;
- };
- VisActionHelper.prototype.hideToolbarActions = function hideToolbarActions() {
- this.dashboardApi.triggerDashboardEvent('widget:hideToolbar');
- };
- /**
- * @param FilterAction - the class of the filter action.
- * @param slot - the data slot associated with this filter action.
- * @param index - the index of the data item in the slot.
- * @returns a new filter action associated with the passed in data slot.
- */
- VisActionHelper.prototype.getNewFilterActionForSlot = function getNewFilterActionForSlot(FilterAction, slot, index) {
- // This method assumes that the required FilterAction object is loaded.
- //TODO: This action should probably be called FilterSlotAction (and separated from FilterAction)
- // since it is specific to filtering items assigned to visible slots.
- return new FilterAction(this.getVisualization(), slot, index, this.ownerWidget.getDashboardApi(), this.logger);
- };
- /**
- * @param FilterAction - the class of the filter action
- * @param visColumn - the column to create this context filter for.
- * @returns a FilterAction associated with the passed in context visColumn.
- * Note: Use getNewFilterActionForSlot when possible because a slot
- * can override the usage of a column (eg: an attribute column assigned to an ordinal slot becomes a count).
- */
- VisActionHelper.prototype.getNewFilterActionForContextColumn = function getNewFilterActionForContextColumn(FilterDropAction, metadataColumn) {
- // This method assumes that the required FilterAction object is loaded.
- return new FilterDropAction(this.getVisualization(), metadataColumn, this.pageContext, this.ownerWidget.getDashboardApi(), this.logger);
- };
- VisActionHelper.prototype.getActionsForLocalFilter = function getActionsForLocalFilter(metadataColumn, filterId) {
- var _this5 = this;
- var availableActions = []; //The set of all availableActions for this context
- return DynamicFileLoader.load(['dashboard-analytics/visualizations/interactions/FilterDropAction', 'dashboard-analytics/visualizations/interactions/DeleteFilterAction']).then(function (modules) {
- var FilterDropAction = modules[0];
- var DeleteFilterAction = modules[1];
- var existingFilterEntry = filterId && _this5._visModel.localFilters.getFilterEntry({
- id: filterId
- });
- if (existingFilterEntry && _this5._visModel.isFilterEditable(existingFilterEntry)) {
- availableActions.push(_this5.getNewFilterActionForContextColumn(FilterDropAction, metadataColumn));
- }
- availableActions.push(new DeleteFilterAction(_this5._visModel, metadataColumn, filterId));
- return availableActions;
- });
- };
- VisActionHelper.prototype._getSingleSlot = function _getSingleSlot(slots, mapIndex) {
- //if slots length is not 1, return null
- if (slots.length !== 1) {
- return null;
- }
- //if mapIndex exists and its an array of length > 1, return null
- if (mapIndex && mapIndex instanceof Array && mapIndex.length > 1) {
- return null;
- }
- //otherwise, return slots[0]
- return slots[0];
- };
- /**
- * Collect action information for slots that can be used to
- * determine which actions are available for the slots.
- * @param slots {Array} - an array of up to two slots
- * @param mapIndex integer or array of integers corresponding to indices of data items in a slot
- * @param selectionObj selected DOM representing the selected dataItem
- * @param options specifies the additional options necessary to get the actions
- * @return action information for slot
- *
- * @note the case where mapIndex can be an array:
- * (1) create a croostab vis
- * (2) Rows: Revenue, Product Line
- * Values: Order method type, Quantity
- * (3) multi-select two column, and right click on it.
- */
- VisActionHelper.prototype._getActionInfoForSlots = function _getActionInfoForSlots(slots, mapIndex, selectionObj, options) {
- var singleSlot = this._getSingleSlot(slots, mapIndex);
- var focusMode = options && options.focusMode != undefined ? options.focusMode : true;
- var itemsArea = options && options.itemsArea ? options.itemsArea : undefined;
- //DEFECT 253869
- //Verify if mapIndex is defined to differentiate when we're selecting specific data item that is a multi measure or multiple data items (get actions for y axis)
- var isMultiMeasure = singleSlot && mapIndex == undefined ? SlotAPIHelper.isMultiMeasuresSeriesSlot(singleSlot) || SlotAPIHelper.isMultiMeasuresValueSlot(singleSlot) : false;
- var slotState = {
- selectionObj: selectionObj,
- slots: slots,
- singleSlot: singleSlot,
- dataItems: [],
- mapIndex: mapIndex,
- isAuthoringMode: this._visModel.ownerWidget.isAuthoringMode,
- isCalculationEnabled: false,
- isMultiMeasure: isMultiMeasure,
- isEditCalculation: false,
- isMappedToUnavailableSourceColumn: false,
- isFocusMode: focusMode,
- supportsSortAction: this._supportsSortAction(),
- supportsContextualTopBottomAction: this._supportsContextualTopBottomAction(),
- supportsNonContextualTopBottomAction: this._supportsNonContextualTopBottomAction(),
- supportsFormatAction: this._supportsFormatAction(),
- supportsBinAction: this._supportsBinAction(),
- area: itemsArea
- };
- if (mapIndex === undefined || mapIndex === null) {
- mapIndex = 0;
- }
- if (mapIndex && Array.isArray(mapIndex)) {
- _.each(mapIndex, function (index) {
- slotState.dataItems.push(slots[0].getDataItemList()[index]);
- });
- } else {
- slotState.dataItems.push(slots[0].getDataItemList()[mapIndex]);
- }
- slotState.isMappedToUnavailableSourceColumn = _.every(slotState.dataItems, function (dataItem) {
- return dataItem.isColumnUnavailable();
- });
- if (!slotState.isMappedToUnavailableSourceColumn) {
- var slot = slots[0];
- var dataItemList = slot.getDataItemList();
- // [todo] livewidget_cleanup: need to revisit this and test crosstab multiselection again...
- if (mapIndex && Array.isArray(mapIndex)) {
- slotState.isCalculationEnabled = dataItemList[mapIndex[0]].getType() === 'fact';
- } else {
- slotState.isCalculationEnabled = dataItemList[mapIndex].getType() === 'fact';
- }
- var metadataColumn = void 0;
- if (singleSlot) {
- // if singleSlot is defined, mapIndex wont be an array. See _getSingleSlot()
- metadataColumn = dataItemList[mapIndex].getMetadataColumn();
- slotState.isEditCalculation = metadataColumn ? metadataColumn.isEditableCalculation() : false;
- }
- // For the grid, we need to check if the data items selected are type 'fact' to determine if calculation should be enabled
- if (!slotState.isCalculationEnabled && slot.getDefinition().getType() === 'any' && mapIndex && mapIndex.length < 3) {
- slotState.isCalculationEnabled = _.every(mapIndex, function (index) {
- return dataItemList[index].getType() === 'fact';
- });
- }
- }
- return {
- state: slotState,
- actions: this._enableSupportedSlotActions(slotState)
- };
- };
- /**
- * Enable / disable slot actions
- * @param {Object} slotState - state object of the slot information
- * @return array of enabled / disabled actions
- */
- VisActionHelper.prototype._enableSupportedSlotActions = function _enableSupportedSlotActions(slotState) {
- var _this6 = this;
- var actions = {};
- var actionExt = slotState.singleSlot ? slotState.singleSlot.getDefinition().getProperty('actions') : null;
- // 1. Default state of each action
- // Actions defined in the slot takes priority.
- // If no actions are defined (null or undefined) in the slot,
- // all actions are considered as available by default.
- _.each(_.keys(VisActionSlotSupport.SLOT_ACTIONS), function (action) {
- actions[action] = actionExt ? actionExt.indexOf(action) >= 0 : true;
- });
- // 2. Enable / Disable actions for slots
- _.each(_.keys(VisActionSlotSupport.SLOT_ACTIONS), function (action) {
- // Check if the enabled action is available for slot
- if (actions[action]) {
- var slotSupport = _this6._visActionSlotSupport.getInterface(action);
- // action without a validator (supports???Action) is considered enabled
- actions[action] = slotSupport.isSupported ? slotSupport.isSupported(slotState) : true;
- }
- });
- return actions;
- };
- /**
- * Get the list module paths to be loaded
- * @param actionInfo action info object
- * @see {@link _getActionInfoForSlots}
- */
- VisActionHelper.prototype._getActionModules = function _getActionModules(actionInfo) {
- var availableActionModules = [];
- var singleSlot = actionInfo.state.singleSlot;
- if (!actionInfo.state.isMappedToUnavailableSourceColumn) {
- _.each(actionInfo.actions, function (active, action) {
- var actionIndex = VisActionSlotSupport.SLOT_ACTIONS[action];
- availableActionModules[actionIndex] = active ? action : '';
- });
- }
- // defect 246203 & 262087 - if the number of slots is one in the visualization, don't show filter and calculation actions
- // since the filter action is determined by the ordinal slot
- var numberOfSlots = this.getVisualization().getSlots().getSlotList().length;
- //if there are any disallowed actions as defined for a single slot in the vis definition/viprConfig, then remove them here
- if (numberOfSlots == 1) {
- var disallowedActionsForSingleSlot = singleSlot.getDefinition().getProperty('disallowedActions');
- // If we are putting a category into an ordinal slot type then we need to
- // restrict actions since the filters are confused. The user will still be able
- // to apply a filter by dragging a category filter to local filter slots.
- // Note that this affects multiple visualizations and not just Summary widget.
- var dataItem = actionInfo.state.dataItems.length === 1 && actionInfo.state.dataItems[0];
- if (DatasourceUtil.isOrdinalAttribute(singleSlot, dataItem)) {
- if (!disallowedActionsForSingleSlot) {
- disallowedActionsForSingleSlot = [];
- }
- disallowedActionsForSingleSlot = disallowedActionsForSingleSlot.concat(['FilterAction']);
- }
- if (disallowedActionsForSingleSlot) {
- _.each(availableActionModules, function (actionModule, key, availableActionModulesArray) {
- if (disallowedActionsForSingleSlot.indexOf(actionModule) > -1) {
- availableActionModulesArray[key] = '';
- }
- });
- }
- }
- // prepend modules with full path
- return availableActionModules.map(function (sModule) {
- return sModule ? 'dashboard-analytics/visualizations/interactions/' + sModule : '';
- });
- };
- /**
- * Load the action modules and instantiate the action objects
- * @param slots {Array} - an array of up to two slots
- * @param mapIndex integer or array of integers corresponding to indices of data items in a slot
- * @param selectionObj selected DOM representing the selected dataItem
- * @param actionModules array of action module path
- * @param actionInfo action info object
- * @see {@link _getActionInfoForSlots}
- */
- VisActionHelper.prototype._loadActionModules = function _loadActionModules(slots, actionModules, actionInfo, options) {
- var _this7 = this;
- var slotState = actionInfo.state;
- var actions = options || {};
- return DynamicFileLoader.load(actionModules).then(function (modules) {
- var availableActions = []; //The set of all availableActions for this context
- _.each(modules, function (Module, index) {
- if (Module) {
- var action = void 0;
- var slotSupport = _this7._visActionSlotSupport.getInterface(index);
- if (slotSupport.get) {
- action = slotSupport.get(Module, slotState, _this7.dashboardApi);
- }
- if (action) {
- availableActions.push(action);
- }
- }
- });
- var slotId = slotState.singleSlot ? slotState.singleSlot.getId() : slotState.slots[0].getId();
- var actionExt = slotState.singleSlot ? slotState.singleSlot.getDefinition().getProperty('actions') : null;
- if (actions.actionsToKeep && actions.actionsToKeep.length > 0 && actionExt && actionExt.length > 0) {
- // there might not be a real usecase for this scenario, but it is here in case the caller provides
- // its own list of actionsToKeep and we need to intersect it with the list that comes from the viz definition
- actions.actionsToKeep = _.intersection(actions.actionsToKeep, actionExt);
- } else if (actionExt && actionExt.length > 0) {
- actions.actionsToKeep = actionExt;
- }
- var specs = _this7.content.getFeature('SlotActions').getSlotActionList(slotId, slotState.mapIndex, actions);
- _.each(specs, function (spec) {
- spec.text = spec.label;
- availableActions.push(new SlotAction(spec));
- });
- return availableActions;
- });
- };
- /**
- * Gets the actions for an array of up to slots based on the number and types of the slots
- * @param slots {Array} - an array of up to two slots
- * @param mapIndex integer or array of integers corresponding to indices of data items in a slot
- * @param selectionObj selected DOM representing the selected dataItem
- * @param options specifies the additional options necessary to get the actions
- * @returns jquery promise
- */
- VisActionHelper.prototype.getActionsForSlots = function getActionsForSlots(slots, mapIndex, selectionObj, options) {
- // 1. get he summarized information of actions for the slots
- var actionInfo = this._getActionInfoForSlots(slots, mapIndex, selectionObj, options);
- // 2. get the list of modules to load for each actions
- var availableActionModules = this._getActionModules(actionInfo);
- // If there is an `actionsToKeep` array, don't bother loading these availableActions, they will be filtered out in the end.
- // `actionsToKeep` is currently only used for sortAction (rank column). When all actions are refactored to be loaded
- // via _loadActionModules, we will not need this following line here.
- var actions = options && options.actions || options;
- if (actions && actions.actionsToKeep && actions.actionsToKeep.length) {
- availableActionModules = [];
- }
- // 3. load the modules in to an array of action instances
- return this._loadActionModules(slots, availableActionModules, actionInfo, actions);
- };
- /**
- * Load (and display) any available actions that should be rendered on selection
- * of a category column
- * @param slots An array of the category columns of up to two columns
- * @param position an optional object that contains the target node and/or the target bounds which can be set to improve context menu placement.
- * @param selectionObj Selected DOM representing the selected dataItem
- * @param mapIndex An optional integer or array of integers corresponding to indices of data items in a slot
- * @param itemsArea The clicked area of the target items. The area could be of values: visualization, legend, or none
- * @param actions Optional object containing actionsToKeep (array of action ids), and actionOptions (object).
- * When actionsToKeep exists, we will only return those actions. actionOptions contain extra options for each action.
- * @returns promise which is resolved when all actions are loaded.
- */
- VisActionHelper.prototype.showTitleActions = function showTitleActions(slots, position, selectionObj, mapIndex, itemsArea, actions) {
- var _this8 = this;
- if (!slots || slots.length === 0) {
- return Promise.resolve();
- }
- var options = {
- iconOnly: true,
- focusMode: false,
- itemsArea: itemsArea,
- actions: actions
- };
- // Don't show title when multiple selected
- if (slots.length === 1 && mapIndex && mapIndex.length === 1) {
- var index = Array.isArray(mapIndex) ? mapIndex[0] : mapIndex;
- options.toolbarName = slots[0].getDataItemList()[index].getLabel();
- }
- var availableActions = []; //The set of all availableActions for this context
- var fRegisterAction = function fRegisterAction(action) {
- availableActions = availableActions.concat(action.getAvailableActions());
- _this8._registeredActions[action.getActionId()] = action;
- };
- return this.getActionsForSlots(slots, mapIndex, selectionObj, options).then(function (actions) {
- _.each(actions, fRegisterAction);
- slots = slots.length === 1 ? slots[0] : null;
- //When there is only one slot in the slots, pass constructToolar the single slot in order to show the toolbar menu title
- _this8._constructToolbar(availableActions, position, slots, options);
- });
- };
- /* Constructs the toolbar needed
- * @param options : Additional options for the toolbar such as showing only text or icons
- */
- VisActionHelper.prototype._constructToolbar = function _constructToolbar(availableActions, oPosition, slot, options) {
- if (availableActions.length !== 0) {
- //Add additional actions for category column selections here..
- var position = oPosition || {};
- var mapping = slot && slot.mapping;
- var toolbarName = mapping ? this._visModel.getLabelByMapping(mapping) : options.toolbarName ? options.toolbarName : undefined;
- if (position.bounds) {
- var visBounds = this._visModel.ownerWidget.el.getBoundingClientRect();
- var visChart_center_x = visBounds.left + visBounds.width / 2;
- var visElement_center_x = position.bounds.left + position.bounds.width / 2;
- if (visElement_center_x > visChart_center_x) {
- // The element is on the right side of the chart, so try to show the Flyout on the right to avoid hiding the chart.
- position.placement = 'right auto';
- }
- }
- var eventOptions = {
- targetNode: position.targetNode || null,
- targetBounds: position.bounds || null,
- placement: position.placement || 'left auto',
- actions: availableActions,
- toolbarName: toolbarName
- };
- if (options) {
- eventOptions.toolbarOptions = options;
- }
- this.dashboardApi.triggerDashboardEvent('widget:availableActions', eventOptions);
- }
- };
- /**
- * Brings up the UI to edit an existing filter
- * @param filterId - the Id of the filter to edit.
- * @param node - the node to guide placement of the dialog.
- */
- VisActionHelper.prototype.editLocalFilter = function editLocalFilter(filterId, node) {
- var _this9 = this;
- var visualization = this.getVisualization();
- var filterEntry = _.find(visualization.getLocalFilters().getFilterList(), function (filter) {
- return filter.id === filterId;
- });
- var filterDesc = _.find(visualization.getLocalFilters().getFiltersDesc(), function (filter) {
- return filter.dataId === filterId;
- });
- if (!node || !filterDesc || !filterDesc.editEnabled) {
- return Promise.resolve();
- }
- //If this filterEntry has a matching slot dataItem, load the dataItem filter module and launch the editor with the appropriate slot and index defined.
- //otherwise, load the contextFilter module and launch that editor with the metadata column information.
- var matchingSlotDataItem = null;
- if (filterEntry) {
- matchingSlotDataItem = _.find(visualization.getSlots().getMappingInfoList(), function (mapping) {
- var match = mapping.dataItem.getColumnId() === filterEntry.columnId;
- if (match && filterEntry.aggregationType) {
- match = mapping.dataItem.getAggregation() === filterEntry.aggregationType;
- }
- return match;
- });
- }
- //If there's a matchingSlotDataItem, load the slot filter action, otherwise, load the context filter action.
- var actionToLoad = matchingSlotDataItem ? 'dashboard-analytics/visualizations/interactions/FilterAction' : 'dashboard-analytics/visualizations/interactions/FilterDropAction';
- return DynamicFileLoader.load([actionToLoad]).then(function (modules) {
- var FilterAction = modules[0];
- var fAction = matchingSlotDataItem ? _this9.getNewFilterActionForSlot(FilterAction, matchingSlotDataItem.slot, matchingSlotDataItem.indexInSlot) : _this9.getNewFilterActionForContextColumn(FilterAction, visualization.getDataSource().getMetadataColumn(filterEntry.columnId));
- return _this9.renderFilterDialog(fAction.getEditorModuleName(), fAction.getViewOptions(), node);
- });
- };
- VisActionHelper.prototype.renderFilterDialog = function renderFilterDialog(sDialogModuleName, viewOptions, node, launchView, backButtonCallback) {
- var _this10 = this;
- return DynamicFileLoader.load([sDialogModuleName]).then(function (modules) {
- var FilterDialog = modules[0];
- var view = new FilterDialog(viewOptions);
- var preloadDone = view.preload ? view.preload() : Promise.resolve();
- var title = viewOptions.title || resources.get('toolbarActionFilter');
- return preloadDone.then(_this10._createContext.bind(_this10, view, node, title, launchView, backButtonCallback)).then(view.renderCallBack.bind(view));
- });
- };
- VisActionHelper.prototype.resetActionState = function resetActionState(actionName, slot, index) {
- var slotAction = this._getSlotActionByNameOrGroup(slot, actionName, index);
- if (slotAction && slotAction.actions && slotAction.actions.reset) {
- slotAction.actions.reset(slot.getId(), index);
- }
- };
- VisActionHelper.prototype.showAction = function showAction(actionName, slot, node, index) {
- var _this11 = this;
- var slotAction = this._getSlotActionByNameOrGroup(slot, actionName, index);
- if (slotAction) {
- var viewModule = slotAction.view && slotAction.view.module;
- return DynamicFileLoader.load([viewModule]).then(function (modules) {
- var Dialog = modules[0];
- var view = new Dialog({
- state: slotAction.view.state,
- actions: slotAction.actions
- });
- return _this11._createContext(view, node, resources.get(slotAction.text));
- });
- }
- return Promise.resolve();
- };
- VisActionHelper.prototype._getSlotActionByNameOrGroup = function _getSlotActionByNameOrGroup(slot, actionName, index) {
- var specs = this.content.getFeature('SlotActions').getSlotActionList(slot.getId(), index);
- return specs.find(function (spec) {
- return spec.name === actionName || spec.group === actionName;
- });
- };
- VisActionHelper.prototype._createContext = function _createContext(view, node, toolbarLabel, launchView, backButtonCallback) {
- var actions = [{
- responsive: false,
- editable: false,
- changedAction: null,
- subView: view,
- type: 'SubView'
- }];
- return this._setToolbarForEditor(actions, node, toolbarLabel, launchView, backButtonCallback);
- };
- VisActionHelper.prototype._setToolbarForEditor = function _setToolbarForEditor(aActions, node, sLabel, launchView, backButtonCallback) {
- var _this12 = this;
- return DynamicFileLoader.load(['dashboard-analytics/lib/@waca/dashboard-common/dist/ui/AuthoringToolbar']).then(function (modules) {
- var Toolbar = modules[0];
- if (_this12.toolbar) {
- _this12.toolbar.remove();
- }
- _this12.toolbar = new Toolbar({
- container: $('body'),
- placement: launchView && launchView.getPlacement ? launchView.getPlacement() : 'right auto',
- calculateBoundingRect: true,
- launchView: launchView,
- backButtonCallback: backButtonCallback
- });
- if (sLabel) {
- _this12.toolbar.setName(sLabel);
- }
- _this12.toolbar.addItems(aActions);
- _this12.toolbar.setSelectionContext([node]);
- _this12.toolbar.show();
- return _this12.toolbar;
- });
- };
- VisActionHelper.prototype.getVisualization = function getVisualization() {
- //@todo After the old visAPI is removed, not need to have this function
- //Instead the constructor of this class can just set this.visualization = this.widgetAPI.getFeature('Visualization')
- //Right now is is not possible due to deprecated old apis dependencies on
- //visAPI.getUITestApi visAPI.and selectData
- if (!this.visualization) {
- this.visualization = this.content.getFeature('Visualization');
- }
- return this.visualization;
- };
- return VisActionHelper;
- }();
- return VisActionHelper;
- });
- //# sourceMappingURL=VisActionHelper.js.map
|