'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Licensed Materials - Property of IBM * * (C) Copyright IBM Corp. 2019, 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/core/APIFactory', './api/PromptsAPI', '../../../DynamicFileLoader', '../../../lib/@waca/core-client/js/core-client/nls/StringResources', '../../../widgets/livewidget/nls/StringResources', 'underscore'], function (APIFactory, PromptsAPI, DynamicFileLoader, StringResources, LiveWidgetStringResources, _) { var Prompts = function () { /** * @classdesc Prompt manager class to handle prompt related gestures. * @constructs * @public * */ function Prompts(options) { _classCallCheck(this, Prompts); this.SEARCH_AND_SELECT = 'searchAndSelect'; this.INPUT_BOX = 'inputBox'; this.CALENDAR = 'calendar'; this.RANGE = 'range'; this.CANCEL = 'cancelPromptDialog'; this.UNSUPPORTED_PROMPT_TYPE = 'unSupportedPromptType'; this.PROMPT_PROPERTIES = ['name', 'capabilities', 'dataType', 'modelFilterItem']; this.SAVED_PROMPT_PROPERTIES = ['name', 'capabilities', 'dataType', 'values', 'modelFilterItem']; this.promptModules = { searchAndSelect: 'dashboard-analytics/features/dashboard/prompts/controls/SearchAndSelectPromptView', inputBox: 'dashboard-analytics/features/dashboard/prompts/controls/InputPromptView', calendar: 'dashboard-analytics/features/dashboard/prompts/controls/DateTimePromptView', range: 'dashboard-analytics/features/dashboard/prompts/controls/RangePromptView' }; this.dashboard = options.dashboardApi; this.logger = this.dashboard.getGlassCoreSvc('.Logger'); // In progress prompt view this._inProgressMap = {}; // Pending prompt cache this._pendingPrompts = []; var preferences = this.dashboard.getGlassCoreSvc('.UserProfile').preferences; this._timeZone = preferences.timeZoneID || 'America/New_York'; this._locale = preferences.productLocale || 'en'; } Prompts.prototype.destroy = function destroy() { if (this.promptDialog) { this.promptDialog.destroy(); this.promptDialog = null; } this.dashboard = null; this._pendingPrompts = null; this._timeZone = null; this._locale = null; }; Prompts.prototype.getAPI = function getAPI() { if (!this.api) { this.api = APIFactory.createAPI(this, [PromptsAPI]); } return this.api; }; /** * @public * @return true if the response status is prompt fault. */ Prompts.prototype.isPromptFault = function isPromptFault(errorResponse) { return errorResponse.status === 412 && errorResponse.responseJSON && errorResponse.responseJSON.errors && errorResponse.responseJSON.errors.length; }; Prompts.prototype.openPromptView = function openPromptView(specList, visualization) { var _this = this; if (!specList || !specList.length) { this.logger.error('Invalid prompt spec'); return Promise.reject(); } var dataSource = this._getDataSource(specList, visualization); if (!dataSource) { // Couldn't find right data source. Throw unsupported error. this.logger.error('Cannon find related data source for selected prompts'); return this._onUnSupportedPrompt(); } var infoList = this._buildPromptValueList(specList, dataSource.getId(), visualization); // If the visualization is preview and there are still unresolved prompts, reject here, Explore will display static view for this preview if (infoList.length > 0 && visualization.isPreview()) { var hasUnresolvedPrompt = infoList.some(function (info) { return !info.values; }); if (hasUnresolvedPrompt) { return Promise.reject(new Error('promptingIsDisabled')); } } // Array of prompt promises when drag and drop multiple prompt items at the same. var valuePromiseList = _.pluck(infoList, 'promptValuesPromise'); var specNameList = _.pluck(infoList, 'name'); return Promise.all(valuePromiseList).then(function (resultList) { var promptViewPromiseList = []; resultList.forEach(function (result, index) { var dlgOptions = {}; dlgOptions.info = infoList[index]; dlgOptions.queryResult = result; // could be QueryResultAPI or undefined depends on what type of prompt is dlgOptions.dialogName = 'dashboard-analytics/lib/@waca/core-client/js/core-client/ui/dialogs/GenericViewDialog'; if (infoList[index].showView) { promptViewPromiseList.push(_this._showPromptView(dlgOptions, specNameList, dataSource.getId())); } else { promptViewPromiseList.push(Promise.resolve(infoList[index])); } }); return Promise.all(promptViewPromiseList).then(function (resolvedPrompts) { var parameterValues = []; _.each(resolvedPrompts, function (resolvedPrompt) { parameterValues.push(resolvedPrompt); }); return parameterValues; }).catch(function (error) { if (error && error.name) { _this._removeInProgressAndExecuteNext(error.name); } throw error; // re-throw }); }).catch(function (jqXHR) { // Possible query Error. Need to clean local cache. var keys = _.keys(_this._inProgressMap); if (keys && keys.length) { // There is only one entry in cache _this._removeInProgressAndExecuteNext(keys[0]); } throw jqXHR; }); }; Prompts.prototype.getPromptSpecList = function getPromptSpecList(errorResponse) { var error = errorResponse.responseJSON.errors[0]; if (!error || !error.code) { return; } var params = error.parameters; if (!params || params.length === 0) { return; } var paramInfoList = _.map(params, function (param) { param.value.name = param.name; return param.value; }); return paramInfoList; }; Prompts.prototype._getDataSource = function _getDataSource(specList, visualization) { var dataSource = null; if (visualization) { dataSource = visualization.getDataSource(); } else { var modelFilterItem = _.find(specList, function (spec) { return spec.modelFilterItem; }); if (modelFilterItem) { var dataSources = this.dashboard.getFeature('DataSources').getDataSourceList(); dataSource = dataSources.forEach(function (dataSource) { return dataSource.getMetadataColumn(modelFilterItem); }); } } return dataSource; }; // TODO remove onCancelPromptDialog and onUnSupportedPrompt from DeprecatedWidgetBase once // new API is live Prompts.prototype._onCancelPromptDialog = function _onCancelPromptDialog() { this.dashboard.undo(); }; Prompts.prototype._onUnSupportedPrompt = function _onUnSupportedPrompt() { var _this2 = this; DynamicFileLoader.load(['dashboard-analytics/lib/@waca/core-client/js/core-client/ui/dialogs/ConfirmationDialog']).then(function (modules) { var dlg = new modules[0]('warning', '', LiveWidgetStringResources.get(_this2.UNSUPPORTED_PROMPT_TYPE)); dlg.confirm(_this2._onCancelPromptDialog.bind(_this2), _this2._onCancelPromptDialog.bind(_this2)); }); return Promise.reject(new Error(this.UNSUPPORTED_PROMPT_TYPE)); }; Prompts.prototype._buildPromptValueList = function _buildPromptValueList(specList, dataSourceId, visualization) { var _this3 = this; var infoList = []; var savedPrompts = visualization && visualization.getSavedPrompts(); _.each(specList, function (spec) { var savedSpec = savedPrompts && savedPrompts.getPromptSpec(spec.name); var info = void 0; if (savedSpec) { info = _.pick(savedSpec, _this3.SAVED_PROMPT_PROPERTIES); if (spec.capabilities.optional && info.values[0] && info.values[0].mun) { info.values[0] = info.values[0].mun; info.showView = false; } else if (spec.rePrompt) { // Flag used to differentiate re-prompt or re-open saved dashboard. // Saved prompts should not be re-prompted unless click on edit prompt button. // showView is undefined by default. info.showView = true; info.rePrompt = true; _this3._initViewInfo(dataSourceId, info, spec); } } else { info = _.pick(spec, _this3.PROMPT_PROPERTIES); // Add optional prompt default value and save it if (spec.capabilities.optional) { info.values = ['nil']; info.showView = false; } else { info.showView = true; _this3._initViewInfo(dataSourceId, info, spec); } } if (!info.showView) { info.promptValuesPromise = Promise.resolve(); } infoList.push(info); }); return infoList; }; Prompts.prototype._initViewInfo = function _initViewInfo(dataSourceId, info, requestSpec) { info.promptModuleName = this._getPromptModuleName(requestSpec); info.columnId = info.modelFilterItem; if (!this.queryService) { this.queryService = this.dashboard.getFeature('QueryService'); } switch (info.promptModuleName) { case this.SEARCH_AND_SELECT: info.promptValuesPromise = this.queryService.getColumnValues(dataSourceId, info.columnId); break; case this.RANGE: info.promptValuesPromise = this.queryService.getColumnMinMaxValues(dataSourceId, info.columnId); break; default: info.promptValuesPromise = Promise.resolve(); } }; /* * Returns the prompt dialog type. */ Prompts.prototype._getPromptModuleName = function _getPromptModuleName(spec) { var promptModuleName = void 0; switch (spec.dataType) { case 'xsdDate': case 'xsdDateTime': case 'xsdTime': if (spec.capabilities.multivalued && spec.capabilities.discreteValue && spec.modelFilterItem) { promptModuleName = this.SEARCH_AND_SELECT; } else { promptModuleName = this.CALENDAR; } break; case 'xsdInt': case 'xsdLong': case 'xsdShort': case 'xsdFloat': case 'xsdDecimal': case 'xsdDouble': if (spec.modelFilterItem) { if (spec.capabilities.multivalued) { if (spec.capabilities.discreteValue) { promptModuleName = this.SEARCH_AND_SELECT; } else { promptModuleName = this.RANGE; } } else { promptModuleName = this.INPUT_BOX; } } else { promptModuleName = this.INPUT_BOX; } break; case 'xsdString': if (spec.modelFilterItem) { promptModuleName = this.SEARCH_AND_SELECT; } else { promptModuleName = this.INPUT_BOX; } break; default: promptModuleName = this.INPUT_BOX; } return promptModuleName; }; Prompts.prototype._showPromptView = function _showPromptView(dlgOptions, specNameList, dataSourceId, pendingViewPromise) { var id = dlgOptions.info.name; var promptViewPromise = this._inProgressMap[id]; if (!promptViewPromise) { promptViewPromise = pendingViewPromise || Promise.defer(); dlgOptions.promptViewPromise = promptViewPromise; if (this._isPrompting()) { // Pending prompt won't return a promise until its turn. Pending prompt view promise is // added to local cache in this._executeNextPrompt() var pendingPrompt = _.find(this._pendingPrompts, function (prompt) { return prompt.id === id; }); if (pendingPrompt) { promptViewPromise = pendingPrompt.pendingViewPromise; } else { pendingPrompt = { id: id, promptFunction: this._showPromptView.bind(this, dlgOptions, specNameList, dataSourceId, promptViewPromise), pendingViewPromise: promptViewPromise }; this._pendingPrompts.push(pendingPrompt); } } else { this._inProgressMap[id] = promptViewPromise; this._prepareAndOpenDialog(dlgOptions, specNameList, dataSourceId); } } return promptViewPromise.promise; }; Prompts.prototype._prepareAndOpenDialog = function _prepareAndOpenDialog(dlgOptions, specNameList, dataSourceId) { var label = dlgOptions.info.caption || dlgOptions.info.name; dlgOptions.viewTitle = StringResources.get('promptControlTitle', { paramLabel: label }); dlgOptions.viewOptions = _.pick(dlgOptions.info, ['promptModuleName', 'name', 'dataType', 'capabilities']); dlgOptions.viewOptions.viewTitle = dlgOptions.viewTitle; switch (dlgOptions.info.promptModuleName) { case this.INPUT_BOX: dlgOptions.viewOptions.label = label; break; case this.CALENDAR: dlgOptions.viewOptions.columnId = dlgOptions.info.modelFilterItem; dlgOptions.viewOptions.timezone = this._timeZone; dlgOptions.viewOptions.locale = this._locale; break; case this.SEARCH_AND_SELECT: { dlgOptions.viewOptions.columnId = dlgOptions.info.modelFilterItem; dlgOptions.viewOptions.singleSelect = !dlgOptions.info.capabilities.multivalued; dlgOptions.viewOptions.queryResult = dlgOptions.queryResult; dlgOptions.viewOptions.getColumnValues = this.queryService.getColumnValues.bind(this, dataSourceId); break; } case this.RANGE: { dlgOptions.viewOptions.columnId = dlgOptions.info.modelFilterItem; dlgOptions.viewOptions.queryResult = dlgOptions.queryResult; dlgOptions.viewOptions.getColumnMinMaxValues = this.queryService.getColumnMinMaxValues.bind(this, dataSourceId); break; } default: } return this._openPromptDialog(dlgOptions, specNameList); }; Prompts.prototype._openPromptDialog = function _openPromptDialog(dlgOptions, specNameList) { var _this4 = this; return DynamicFileLoader.load([this.promptModules[dlgOptions.info.promptModuleName]]).then(function (viewModule) { var dlgClassOptions = { showCloseX: false, buttons: [{ text: StringResources.get('ok'), handler: _this4.onOk.bind(_this4, dlgOptions), type: 'primary', defaultId: 'ok_button' }, { text: StringResources.get('cancel'), handler: _this4.onCancel.bind(_this4, dlgOptions, specNameList), type: 'secondary', defaultId: 'cancel_button' }], title: dlgOptions.viewOptions.viewTitle, titleAriaLabel: StringResources.get('promptDialogTitle', { paramLabel: dlgOptions.label }), viewClass: viewModule[0], viewOptions: dlgOptions.viewOptions }; if (dlgOptions.info.values) { dlgOptions.viewOptions.defaultValues = dlgOptions.info.values; } dlgOptions.viewOptions.enableOk = _this4.enableOk.bind(_this4); return DynamicFileLoader.load([dlgOptions.dialogName]).then(function (modules) { var PromptDialog = modules[0]; _this4.promptDialog = new PromptDialog(dlgClassOptions); _this4.promptDialog.open(); }); }).then(function () { if (_this4.promptDialog.viewOptions.promptModuleName !== _this4.RANGE && _this4.promptDialog.viewOptions.promptModuleName !== _this4.CALENDAR) { _this4.promptDialog.disableOk(); } }).catch(function (error) { _this4.logger.error('Could not open prompt dialog', error); dlgOptions.promptViewPromise.reject(_.extend(error, { name: dlgOptions.info.name })); }); }; Prompts.prototype.onOk = function onOk(options) { this._removeInProgressAndExecuteNext(options.info.name); var promptValueList = void 0; if (this.promptDialog.view.getPromptValues) { promptValueList = this.promptDialog.view.getPromptValues(); } else { promptValueList = []; } var resolvedSpec = options.info; resolvedSpec.values = _.map(promptValueList, function (value) { if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') { return _.pick(value, ['value', 'label']); } else { return { 'value': value, 'label': value }; } }); this.promptDialog.hide(); return options.promptViewPromise.resolve(resolvedSpec); }; Prompts.prototype.onCancel = function onCancel(options, specNameList) { // Cancel one prompt dialog should trigger cancel of all requried prompt actions since // all of the non-optional prompts are required for the query to run. this._cleanPromptCache(options.info.name, specNameList); this.promptDialog.hide(); if (!options.info.rePrompt) { // drag and drop prompts are combined actions need to undo this action. // E.g. Dnd prompts to local filter, slots, canvas, or tab filter zone triggers multiple // events. If cancel happened in on Dnd prompts, need to undo the actions. // But in case of re-prompts, only need to close the prompts dialog. this._onCancelPromptDialog(); } var error = new Error(this.CANCEL); error.name = options.info.name; return options.promptViewPromise.reject(error); }; Prompts.prototype.enableOk = function enableOk(bEnabled) { this.promptDialog.enableOk(bEnabled); }; Prompts.prototype._isPrompting = function _isPrompting() { return _.size(this._inProgressMap) > 0; }; Prompts.prototype._executeNextPrompt = function _executeNextPrompt() { if (this._pendingPrompts.length > 0) { var nextPrompt = this._pendingPrompts.shift(); return nextPrompt.promptFunction(); } }; Prompts.prototype._removeInProgressAndExecuteNext = function _removeInProgressAndExecuteNext(id) { delete this._inProgressMap[id]; this._executeNextPrompt(); }; Prompts.prototype._cleanPromptCache = function _cleanPromptCache(id, specNameList) { // Cancel all current requests this._pendingPrompts = _.filter(this._pendingPrompts, function (pendingPrompt) { return specNameList.indexOf(pendingPrompt.id) === -1; }); delete this._inProgressMap[id]; }; return Prompts; }(); return Prompts; }); //# sourceMappingURL=Prompts.js.map