PromptingService.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Licensed Materials - Property of IBM
  3. *
  4. * IBM Cognos Products: SHARE
  5. *
  6. * (C) Copyright IBM Corp. 2015, 2021
  7. *
  8. * US Government Users Restricted Rights - Use, duplication or disclosure
  9. * restricted by GSA ADP Schedule Contract with IBM Corp.
  10. */
  11. define([
  12. 'bi/glass/core/Events',
  13. 'jquery',
  14. 'bi/sharecommon/utils/translator'
  15. ], function(Events, $, t) {
  16. var DISPATCHER_URI = 'v1/disp';
  17. var SERVER_URI = DISPATCHER_URI + '/rds/';
  18. var PROMPT_PAGE_ENDPOINT = 'promptPage/report/';
  19. var PROMPT_ANSWERS_ENDPOINT = 'promptAnswers/conversationID/';
  20. //jQuery extension to parse xml properly
  21. $.fn.filterNode = function(name) {
  22. return this.find('*').filter(function() {
  23. return this.localName.toLowerCase() === name.toLowerCase();
  24. });
  25. };
  26. var promptingService = Events.extend({
  27. /**
  28. * @classdesc Prompting service class giving access to events related to prompting
  29. * @constructs
  30. * @public
  31. * @param {Object}
  32. * options - set of initial properties
  33. * glassContext
  34. */
  35. init: function(options) {
  36. promptingService.inherited('init', this, arguments);
  37. $.extend(true, this, options);
  38. },
  39. /**
  40. * Called by glass when service is registered
  41. */
  42. initialize: function(glassContext) {
  43. this.glassContext = glassContext;
  44. },
  45. /** This is the first call that should be made when trying to collect-parameter-values.
  46. * Starting with a storeId, it returns a unique id (to be reused later) and a URL.
  47. * Loading this URL in a window/iframe will start the prompt dance.
  48. *
  49. * If you are calling this yourself (and not through the PromptPickerView), then be aware
  50. * you must define this function on the window in order to know when the dance is over:
  51. *
  52. * FinishCollectPrompts: function(success) - success is 1 or 0 depending if there are prompt
  53. * values to retrieve with getPromptAnswers()
  54. *
  55. * @param reportId - the unique id of the report to prompt for
  56. * @returns { id: unique prompt id to use with getPromptAnswers,
  57. * url: where to go to start the dance
  58. *
  59. */
  60. getPromptPageInfo: function(reportId) {
  61. var server_URL = 'v1/objects/' + reportId + '?fields=path,runInAdvancedViewer,base.runInAdvancedViewer';
  62. return this.glassContext.getCoreSvc('.Ajax').ajax({
  63. url: server_URL,
  64. type: 'GET',
  65. dataType: 'json'
  66. }).then(function(response) {
  67. var data = response.data;
  68. return (data.data && data.data[0]) || {};
  69. }).catch(function(err) {
  70. var error = {
  71. message: this.retrieveErrorMessage({result: err, defaultMessage: t.translate('schedule_prompting_wrong_url')})
  72. };
  73. this.glassContext.appController.showErrorMessage(error.message, t.translate('error_label_share'));
  74. throw error;
  75. }.bind(this));
  76. },
  77. /** Retrieves the parameter values from the session and returns them to the caller,
  78. * in JSON format. This format can be passed to the scheduling service as is.
  79. *
  80. * @param promptId the unique prompt id returned by getPromptPageInfo()
  81. * @returns an array of parameter values. EG: [
  82. * {
  83. * 'name': 'Parameter-retailer-B',
  84. * 'value': [{
  85. * 'inclusive': true,
  86. * 'use': 'True',
  87. * 'display': 'Run report with data',
  88. * 'type': 'simpleParmValueItem'
  89. * }]
  90. * }]
  91. */
  92. getPromptAnswers: function(promptId) {
  93. var server_URL = SERVER_URI + PROMPT_ANSWERS_ENDPOINT + promptId;
  94. return this.glassContext.getCoreSvc('.Ajax').ajax({
  95. url: server_URL,
  96. type: 'GET',
  97. dataType: 'xml'
  98. }).then(function(response) {
  99. var data = response.data;
  100. return this._toAnswersJson(data);
  101. }.bind(this)).catch(function(err) {
  102. var error = {
  103. message: this.retrieveErrorMessage({result: err, defaultMessage: t.translate('schedule_prompting_wrong_url')})
  104. };
  105. this.glassContext.appController.showErrorMessage(error.message, t.translate('error_label_share'));
  106. throw error;
  107. }.bind(this));
  108. },
  109. _getXmlAsString: function(xmlDom) {
  110. return (typeof XMLSerializer !== 'undefined') ? (new window.XMLSerializer()).serializeToString(xmlDom) : xmlDom.xml;
  111. },
  112. _toRelativePath: function(fullPath) {
  113. var index = fullPath.indexOf('?');
  114. return DISPATCHER_URI + fullPath.substr(index);
  115. },
  116. _toPagesJson: function(xmlData) {
  117. var response = {};
  118. var $xml = $(xmlData);
  119. response.url = this._toRelativePath($xml.filterNode('url').text());
  120. response.id = $xml.filterNode('promptID').text();
  121. return response;
  122. },
  123. _toAnswersJson: function(xmlData) {
  124. /*
  125. * <promptAnswers>
  126. * <promptValues>
  127. * <name>Parameter-retailer-B</name>
  128. * <values>
  129. * <item>
  130. * <SimplePValue>
  131. * <inclusive>true</inclusive>
  132. * <useValue>[Sales].[Retailer type].[Retailer (by type)].[Retailer name]-&gt;[all].[7].[7351]</useValue>
  133. * <displayValue>4 Your Eyes</displayValue>
  134. * </SimplePValue>
  135. * </item>
  136. * </values>
  137. * </promptValues>
  138. * </promptAnswers>
  139. *
  140. * [{
  141. * 'name': 'Parameter-retailer-B',
  142. * 'value': [{
  143. * 'inclusive': true,
  144. * 'use': 'True',
  145. * 'display': 'Run report with data',
  146. * 'type': 'simpleParmValueItem'
  147. * }]
  148. * }]
  149. */
  150. var response = [];
  151. var $xml = $(xmlData);
  152. var _self = this;
  153. $xml.filterNode('promptValues').each(function(index) {
  154. var answer = {};
  155. answer.name = $(this).filterNode('name').text();
  156. var values = [];
  157. $(this).filterNode('item').each(function(j) {
  158. var value = {};
  159. var $firstChild = $(this).children().first();
  160. var localName = $firstChild.prop('localName');
  161. switch (localName) {
  162. case 'SimplePValue':
  163. {
  164. value.type = 'simpleParmValueItem';
  165. value.inclusive = $firstChild.filterNode('inclusive').text().toUpperCase() == 'TRUE';
  166. _self._setUse(value, $firstChild.filterNode('useValue'));
  167. _self._setDisplay(value, $firstChild.filterNode('displayValue'));
  168. break;
  169. }
  170. case 'RangePValue':
  171. {
  172. /* <rds:RangePValue>
  173. * <rds:inclusive>true</rds:inclusive>
  174. * <rds:start>
  175. * <rds:inclusive>true</rds:inclusive>
  176. * <rds:useValue>2015-11-08T00:00:00.000</rds:useValue>
  177. * <rds:displayValue>Nov 8, 2015 12:00 AM</rds:displayValue>
  178. * </rds:start>
  179. * </rds:RangePValue></rds:item></rds:values></rds:promptValues>
  180. * */
  181. var inclusiveRangeNode = $firstChild.filterNode('inclusive').get(0);
  182. value.inclusive = $(inclusiveRangeNode).text().toUpperCase() == 'TRUE';
  183. $firstChild.children().each(function(k) {
  184. if ($(this).prop('localName') == 'start') {
  185. value.start = {};
  186. value.start.inclusive = $(this).filterNode('inclusive').text().toUpperCase() == 'TRUE';
  187. _self._setUse(value.start, $(this).filterNode('useValue'));
  188. _self._setDisplay(value.start, $(this).filterNode('displayValue'));
  189. value.start.type = 'simpleParmValueItem';
  190. } else if ($(this).prop('localName') == 'end') {
  191. value.end = {};
  192. value.end.inclusive = $(this).filterNode('inclusive').text().toUpperCase() == 'TRUE';
  193. _self._setUse(value.end, $(this).filterNode('useValue'));
  194. _self._setDisplay(value.end, $(this).filterNode('displayValue'));
  195. value.end.type = 'simpleParmValueItem';
  196. }
  197. });
  198. if (value.start && value.end) {
  199. value.type = 'boundRangeParmValueItem';
  200. } else if (value.start) {
  201. value.type = 'unboundedEndRangeParmValueItem';
  202. } else if (value.end) {
  203. value.type = 'unboundedStartRangeParmValueItem';
  204. } else {
  205. value.type = 'rangeParmValueItem';
  206. }
  207. break;
  208. }
  209. }
  210. values.push(value);
  211. });
  212. answer.value = values;
  213. response.push(answer);
  214. });
  215. return response;
  216. },
  217. _getDisplayValuesForURL: function(parameterValues) {
  218. var p_url = '';
  219. for (var i = 0; i < parameterValues.length; i++) {
  220. p_url += 'p_' + parameterValues[i].name + '=';
  221. p_url += parameterValues[i].value[0].display;
  222. //Put '&' in between
  223. if (i !== parameterValues.length - 1) {
  224. p_url += '&';
  225. }
  226. }
  227. return p_url;
  228. },
  229. _setDisplay: function(value, display) {
  230. if (display && display.length > 0) {
  231. value.display = (display.attr('nil') == 'true') ? null : display.text();
  232. }
  233. },
  234. _setUse: function(value, use) {
  235. var useValue = null;
  236. if (use && use.attr('nil') != 'true') {
  237. useValue = use.text();
  238. }
  239. value.use = useValue;
  240. },
  241. retrieveErrorMessage: function(input) {
  242. input = input || {};
  243. var message = input.defaultMessage;
  244. try {
  245. var text = $.parseJSON(input.result.responseText);
  246. message = text.error || returnedResult.message;
  247. } catch (e) {}
  248. return message;
  249. }
  250. });
  251. return promptingService;
  252. });