PromptPickerView.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /**
  2. * Licensed Materials - Property of IBM
  3. *
  4. * IBM Cognos Products: SHARE
  5. *
  6. * Copyright IBM Corp. 2015, 2020
  7. *
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. */
  10. define([
  11. 'bi/commons/ui/View',
  12. 'jquery',
  13. 'bi/sharecommon/utils/simpledoT',
  14. 'bi/sharecommon/utils/translator',
  15. 'text!bi/schedule/templates/PromptPickerView.html',
  16. 'bi/commons/utils/ContentFormatter',
  17. 'bi/glass/common/ui/ProgressToast'
  18. ], function (View, $, dot, t, viewTemplate, stringFormatter, ProgressToast) {
  19. var view = View.extend({
  20. /** Allows for selecting parameter values for a particular report.
  21. * Uses the old UI. Parameters:
  22. * $el: Location where this View will display selected parameter values,
  23. * in the "name: value" format.
  24. * $toggler: link/button that launches the 'prompting dance'
  25. * reportId: the report to prompt for
  26. * values: Initial values to display. Not used to select the defaults in the prompting dance
  27. * glassContext: the glassContext
  28. */
  29. init: function (options) {
  30. view.inherited('init', this, arguments);
  31. $.extend(this, options);
  32. },
  33. /**
  34. * Calls stopPropagation() on an event when clicking on element that does not have '.prompt-overlay' as an ancestor
  35. * @param {boolean} ignore - if 'true', does not trigger stopPropagation() even if '.prompt-overlay' isn't an ancestor of the clicked element
  36. */
  37. setOverlayEvents: function (ignore) {
  38. $(document).on('clicktap', function (e) {
  39. var $event = $(e.target);
  40. var $p = $event.closest('.prompt-overlay');
  41. if ($p.length == 0 && !ignore) {
  42. e.stopPropagation();
  43. this.close();
  44. }
  45. }.bind(this));
  46. this.$promptOverlay.find('.prompt-iframe').load(function () {
  47. this.$promptOverlay.find('.prompt-iframe').contents().find('.dialogHeader a').on('clicktap', function (_e) {
  48. this.close();
  49. }.bind(this));
  50. // in case of error, an 'OK' button appears, whose default behaviour is to do a
  51. // history.back() (!) Turn that off and close the window instead.
  52. this.$promptOverlay.find('.prompt-iframe').contents().find('#cmdOK').prop('onclick', null).off('click').on('clicktap', function (e) {
  53. e.stopPropagation();
  54. this.close();
  55. }.bind(this));
  56. // this.show();
  57. }.bind(this));
  58. },
  59. setEvents: function () {
  60. this.$toggler.on('primaryaction', function () {
  61. this.showPromptOverlay();
  62. }.bind(this));
  63. },
  64. close: function () {
  65. this.$promptOverlay.remove();
  66. },
  67. show: function () {
  68. if (this.$promptOverlay.css('visibility') == 'hidden') {
  69. // Remove waitForPromptsProgressToast when displaying promptOverlay
  70. if (this.waitForPromptsProgressToast) {
  71. this.waitForPromptsProgressToast.remove(0);
  72. }
  73. this.$promptOverlay.css('visibility', 'visible');
  74. }
  75. },
  76. // prompting call back - NB* APAR 145884 depends on this function remaining here and not being replaced by promptFnOkCallback.
  77. // this is to avoid nested bound function calls in RS's prod/webcontent/bi/js/classicviewer/cvContentView.js
  78. // ... which for unknown reasons cause input object lockup/javascript problems in IE11 only.
  79. onPromptOK: function() {
  80. this.glassContext.getSvc('.Prompting').then(function (promptSvc) {
  81. promptSvc.getPromptAnswers(this.id).then(function(values) {
  82. this.applyPromptValues(values);
  83. }.bind(this));
  84. }.bind(this));
  85. },
  86. getParameterValues: function () {
  87. return this.values;
  88. },
  89. _createProgressToast: function (options) {
  90. return new ProgressToast(options);
  91. },
  92. showPromptOverlay: function () {
  93. var htmlGenerator = dot.simpleTemplate(viewTemplate);
  94. var _self = this;
  95. return this.glassContext.getSvc('.Prompting').then(function (promptSvc) {
  96. var options = { 'noCancelBtn': true, 'noHideBtn': true, 'noDetailsBtn': true };
  97. this.waitForPromptsProgressToast = this._createProgressToast(options);
  98. this.waitForPromptsProgressToast.show(t.translate('parameters_generating_inputs'));
  99. this.waitForPromptsProgressToast.indefinite(t.translate('parameters_generating_inputs'));
  100. return promptSvc.getPromptPageInfo(this.reportId);
  101. }.bind(this))
  102. .then(function (promptInfo) {
  103. this.id = promptInfo.id;
  104. // Use interactive report viewer to retrieve parameter values
  105. window.promptContext = {
  106. promptContext: {
  107. requestType: 'collectParameterValues',
  108. parameters: this.useValues ? this.values : null,
  109. promptFnOkCallback: function (values) {
  110. this.applyPromptValues(values);
  111. }.bind(_self),
  112. promptFnOkCallback1: this.onPromptOK.bind(_self),
  113. promptFnErrorCallback: function (values) {
  114. var errorMessage = values.code + ' ' + values.message;
  115. if (this.waitForPromptsProgressToast) {
  116. this.waitForPromptsProgressToast.remove();
  117. }
  118. _self.glassContext.appController.showToast(errorMessage, {
  119. 'type': 'error',
  120. 'preventDuplicates': true
  121. });
  122. }.bind(_self),
  123. promptFnCancelCallback: function (_values) {
  124. // Cancel clicked on prompt overlay, remove ProgressToast if present
  125. if (this.waitForPromptsProgressToast) {
  126. this.waitForPromptsProgressToast.remove();
  127. }
  128. }.bind(_self),
  129. // promptOpener has to have a function close()
  130. promptOpener: _self
  131. }
  132. };
  133. if (promptInfo && promptInfo._meta) {
  134. var isAdvancedViewer = (promptInfo.runInAdvancedViewer === true) || (promptInfo.base && promptInfo.base[0] && (promptInfo.base[0].runInAdvancedViewer === true));
  135. var perspective = '&perspective=' + (isAdvancedViewer ? 'authoring' : 'classicviewer');
  136. // Report output language will override content locale iff only one report output language is selected, otherwise no.
  137. var overrideContentLocale = (_self.languageOptions && _self.languageOptions.length === 1) ? '&contentLocale=' + _self.languageOptions[0] : '';
  138. promptInfo.url = promptInfo._meta.links.path.url;
  139. promptInfo.url = promptInfo.url.replace('v1/path?path=', '?pathRef=') + perspective + '&format=HTML&a11y=true&Download=false&prompt=true&ui_appbar=false&ui_navbar=false&launchParametersRef=promptContext' + overrideContentLocale;
  140. }
  141. if (!promptInfo.url) {
  142. this.glassContext.appController.showErrorMessage(t.translate('schedule_prompting_wrong_url'), t.translate('error_label_share'));
  143. } else {
  144. var path = promptInfo.url;
  145. var title = t.translate('schedule_prompting_iframe_title');
  146. var attributes = {
  147. prompt_path: path,
  148. prompt_title: title
  149. };
  150. $('body').append(htmlGenerator(attributes));
  151. this.$promptOverlay = $('body').find('.prompt-overlay');
  152. if (this.$promptOverlay) {
  153. this.setOverlayEvents(true);
  154. }
  155. }
  156. }.bind(this))
  157. .catch(function () {
  158. /* swallow */
  159. });
  160. },
  161. render: function () {
  162. this.updateParameterList();
  163. // in update mode the permissions are passed
  164. if (this.hasPermission && !this.hasPermission.write && this.hasPermission.read) {
  165. this.$toggler.prop('disabled', true);
  166. }
  167. this.setEvents();
  168. return Promise.resolve(this);
  169. },
  170. applyPromptValues: function (values) {
  171. this.values = values;
  172. this.updateParameterList();
  173. if (this.onFinish && typeof this.onFinish === 'function') {
  174. this.onFinish();
  175. }
  176. if (this.values.length === 0) {
  177. // No prompts to retrieve, set ProgressToast as complete
  178. if (this.waitForPromptsProgressToast) {
  179. this.waitForPromptsProgressToast.setComplete(100, {
  180. isComplete: true,
  181. completeMsg: t.translate('parameters_none_in_report')
  182. });
  183. }
  184. } else {
  185. // Prompt values exist, but ProgressToast may not have been removed by show() because report has default values and no prompt overlay
  186. if (this.waitForPromptsProgressToast) {
  187. this.waitForPromptsProgressToast.setComplete(100, { isComplete: true });
  188. }
  189. }
  190. },
  191. updateParameterList: function () {
  192. var parameters = this.values;
  193. var toDisplay = '';
  194. for (var i = 0; i < parameters.length; i++) {
  195. var parameter = '';
  196. var displayValues = '';
  197. var name = parameters[i].name;
  198. var values = parameters[i].value;
  199. if (!name)
  200. continue;
  201. if (!values)
  202. continue;
  203. for (var j = 0; j < values.length; j++) {
  204. if (!values[j].type)
  205. continue;
  206. var value = '';
  207. switch (values[j].type) {
  208. case 'rangeParmValueItem':
  209. case 'boundRangeParmValueItem':
  210. case 'unboundedStartRangeParmValueItem':
  211. case 'unboundedEndRangeParmValueItem':
  212. {
  213. if (values[j].start && values[j].end) {
  214. value = t.translate('parameter_range_start_end_label', {
  215. start: values[j].start.display
  216. ? values[j].start.display
  217. : values[j].start.use,
  218. end: values[j].end.display
  219. ? values[j].end.display
  220. : values[j].end.use
  221. });
  222. } else if (values[j].start) {
  223. value = t.translate('parameter_range_start_only_label', {
  224. start: values[j].start.display
  225. ? values[j].start.display
  226. : values[j].start.use
  227. });
  228. } else if (values[j].end) {
  229. value = t.translate('parameter_range_end_only_label', {
  230. end: values[j].end.display
  231. ? values[j].end.display
  232. : values[j].end.use
  233. });
  234. } else {
  235. value = t.translate('parameter_range_none_label');
  236. }
  237. break;
  238. }
  239. case 'simpleParmValueItem':
  240. {
  241. value = values[j].display
  242. ? values[j].display
  243. : values[j].use;
  244. break;
  245. }
  246. case 'hierarchicalParmValueItem':
  247. {
  248. break;
  249. }
  250. }
  251. if (value === '')
  252. continue;
  253. if (displayValues === '') {
  254. displayValues = value;
  255. } else {
  256. displayValues = displayValues + ', ' + value;
  257. }
  258. }
  259. parameter = name + ': ' + displayValues + '; ';
  260. toDisplay += parameter;
  261. }
  262. if (toDisplay === '') {
  263. var none = t.translate('parameter_no_values_set');
  264. this.$el.text(none);
  265. this.$el.attr('title', none);
  266. } else {
  267. this.$el.text(toDisplay);
  268. this.$el.attr('title', toDisplay);
  269. stringFormatter.middleShortenString(this.$el);
  270. }
  271. }
  272. });
  273. return view;
  274. });