previewView.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * Licensed Materials - Property of IBM
  3. *
  4. * IBM Cognos Products: SHARE
  5. *
  6. * (C) Copyright IBM Corp. 2015, 2018
  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. 'underscore',
  13. 'bi/glass/app/ContentView',
  14. 'bi/content_apps/utils/GlassContextHelper',
  15. 'jquery',
  16. 'q',
  17. 'bi/sharecommon/utils/simpledoT',
  18. 'text!bi/notifications/templates/preview.html',
  19. 'bi/sharecommon/utils/translator',
  20. 'bi/commons/utils/ContentFormatter',
  21. 'bi/commons/utils/Utils',
  22. 'bi/notifications/app/n10nController',
  23. 'moment-timezone'
  24. ], function(_,View, GlassContextHelper, $, Q, dot, previewTemplate, t, stringFormater, Utils, controller, moment) {
  25. var DEFAULT_DELAY = 500;
  26. var __STANDAR_DATE_TIME_FORMAT = 'lll';
  27. var previewView = View.extend({
  28. init: function(options){
  29. this.events = {
  30. 'primaryaction .headerBack': 'close'
  31. };
  32. previewView.inherited('init', this, arguments);
  33. this.data = {};
  34. $.extend(this, options);
  35. this.$currentMessageItem = this.messageList.$el.find('#' + this.data.id);
  36. this.timezone = this.glassContext.services.userProfile.preferences.timeZoneID;
  37. this.contentLocale = this.glassContext.services.userProfile.preferences.contentLocale || "en-us";
  38. },
  39. setFocus: function() {
  40. this.$el.find('.n10n_preview_links .n10n_preview_link:first').focus();
  41. },
  42. /**
  43. * Set the events for the notification detail view
  44. *
  45. * @param links_map a map from unique id to link for each link
  46. */
  47. setEvents: function(links_map) {
  48. var glassContext = this.glassContext;
  49. this.$el.find('.n10n_preview_link').click(function(event) {
  50. // on link click, launch saved output viewer
  51. var link = links_map[event.target.id];
  52. this.openLink(link);
  53. }.bind(this));
  54. // Click event to delete the notification
  55. this.$el.find(".n10n_delete_icon:not(.clickBound)").addClass('clickBound').on('primaryaction', function(event) {
  56. if(this.messageList) {
  57. var deletionRequest = {
  58. messageId: this.data.id,
  59. pending: true
  60. };
  61. if (this.glassContext.services.userProfile.preferences.accessibilityFeatures) {
  62. this.glassContext.appController.showMessage(t.translate('delete_notification_confirm_message'), t.translate('delete_confirm'), 'info', ['ok','cancel'], undefined, function(evt) {
  63. if (evt.btn==='ok') {
  64. this._completeNotificationDelete(deletionRequest);
  65. this._focusNextMessage();
  66. }
  67. }.bind(this));
  68. } else {
  69. this.close();
  70. this.$currentMessageItem.hide(DEFAULT_DELAY);
  71. this.glassContext.appController.showToast(t.translate('delete_notification_message'), {
  72. 'type': 'info',
  73. 'btnLabel' : t.translate('delete_undo'),
  74. 'callback' : function() {
  75. deletionRequest.pending = false;
  76. this.messageList.$el.find('#' + deletionRequest.messageId).show(DEFAULT_DELAY);
  77. }.bind(this),
  78. 'newestOnTop' : true,
  79. 'preventDuplicates' : false,
  80. 'timeOut': 6000,
  81. 'extendedTimeOut': 1000,
  82. 'onHidden' : function() {this._completeNotificationDelete(deletionRequest)}.bind(this)
  83. });
  84. this._focusNextMessage();
  85. }
  86. }
  87. }.bind(this));
  88. },
  89. /**
  90. * Well set the keyboard focus to the next message in the notification list
  91. * or if deleting the last message set it to the previous message.
  92. * If no messages are found then it doesn't set focus to anything.
  93. */
  94. _focusNextMessage: function() {
  95. // Make sure the notification view has at least one message in it
  96. this.messageList.focusNextMessage(this.$currentMessageItem);
  97. },
  98. _completeNotificationDelete: function(deleteRequest) {
  99. var $pendingDeleteMessage = this.messageList.$el.find('#' + deleteRequest.messageId);
  100. var context = {
  101. glassContext: this.glassContext
  102. };
  103. if(deleteRequest.pending) {
  104. controller.deleteNotification(deleteRequest.messageId, context).done(function(){
  105. $pendingDeleteMessage.remove();
  106. });
  107. }
  108. },
  109. openLink: function(link) {
  110. var deferred = Q.defer();
  111. // We only care about the output object (link.id). Unfortunately getObjectProperties assumes we are dealing
  112. // with reports so it looks for reportId instead of id.
  113. var properties = {
  114. reportId: link.id
  115. };
  116. var context = {glassContext: this.glassContext};
  117. controller.getObjectProperties(properties, context).then(function(newProperties) {
  118. // user attached an artifact
  119. // Turn reportId back into outputId since it is actually the output object
  120. // and restore original reportId in case client can make use of it
  121. newProperties.outputId = newProperties.reportId;
  122. newProperties.reportId = link.reportId;
  123. this._openObject(newProperties);
  124. deferred.resolve();
  125. }.bind(this)).fail(function(xhr, status, error) {
  126. // May want to consider removing this error handling to let client deal with
  127. // missing output object.
  128. this.glassContext.appController.showToast(t.translate('error_object_not_found'),
  129. {
  130. 'type': 'error',
  131. 'newestOnTop' : true,
  132. 'preventDuplicates' : false,
  133. 'timeOut': 6000,
  134. 'extendedTimeOut': 1000
  135. });
  136. deferred.reject();
  137. }.bind(this));
  138. return deferred.promise;
  139. },
  140. _openObject: function(context) {
  141. this.glassContext.appController.hideSlideOut();
  142. this.glassContext.appController.openAppView( undefined, {
  143. content: {
  144. objRef: context.outputId,
  145. reportId: context.reportId
  146. }
  147. });
  148. },
  149. close: function() {
  150. this.slideout.hide();
  151. },
  152. render: function() {
  153. var deferred = Q.defer();
  154. //clear the existing second panel content
  155. this.$el.find('.preview_tab_panel').remove();
  156. GlassContextHelper.getContentLocales(this.glassContext).then(function(contentLocales) {
  157. this._renderPreview(contentLocales);
  158. deferred.resolve(this);
  159. }.bind(this)).fail(function() {
  160. console.warn("failed to retrieve the current content locales");
  161. this._renderPreview();
  162. deferred.resolve(this);
  163. }.bind(this));
  164. return deferred.promise;
  165. },
  166. _renderPreview: function(contentLocales) {
  167. var data = this.data || {};
  168. var previewAttrs = {
  169. id: data.id,
  170. type_tab: t.translate("type_tab"),
  171. status_tab: t.translate("status_tab"),
  172. owner_tab: t.translate("owner_tab"),
  173. type_name: data.type || "",
  174. owner_name: _.escape(data.sender) || "",
  175. subject: _.escape(data.subject) || "",
  176. created: moment(data.created).locale(this.contentLocale).tz(this.timezone).format(__STANDAR_DATE_TIME_FORMAT),
  177. content: _.escape(data.body) || "",
  178. links: data.links || [],
  179. //HARDCODE ALERT: hard core "read" for now. Wait and see the future content UI
  180. status_name: t.translate("status_name"),
  181. output_links_description: t.translate('preview_output_links_description'),
  182. deleteLabel: t.translate('delete_message_label'),
  183. back: t.translate('back')
  184. };
  185. var links_map=[];
  186. if (data.links) {
  187. for (var i = 0; i<data.links.length; i++) {
  188. var details = this._getLinkDetails(data.links[i], contentLocales);
  189. if(details && details !== "") {
  190. data.links[i].displayName = _.escape(data.links[i].displayName + details);
  191. } else {
  192. data.links[i].displayName = _.escape(data.links[i].displayName);
  193. }
  194. links_map[data.links[i].id] = data.links[i];
  195. }
  196. }
  197. var msg = dot.simpleTemplate(previewTemplate);
  198. this.$el.html(msg(previewAttrs));
  199. this.setEvents(links_map);
  200. this._setIcons();
  201. this.formatLinks();
  202. },
  203. _getLinkDetails: function(link, contentLocales) {
  204. var details;
  205. if (link.format && link.format !== "") {
  206. var linkFormat = this.l10nFormat(link.format);
  207. details = " (" + linkFormat;
  208. if (link.locale && link.locale !== "") {
  209. if (linkFormat !== "") {
  210. details += ", ";
  211. }
  212. details += this.l10nLocale(link.locale, contentLocales);
  213. }
  214. details += ")";
  215. }
  216. return details;
  217. },
  218. l10nLocale: function(locale, contentLocales) {
  219. if (contentLocales && locale in contentLocales) {
  220. return contentLocales[locale];
  221. }
  222. return locale;
  223. },
  224. l10nFormat: function(format) {
  225. switch(format) {
  226. case 'HTML': return t.translate("schedule_format_web");
  227. case 'XHTML': return t.translate("schedule_format_web");
  228. case 'PDF': return t.translate("schedule_format_pdf");
  229. case 'CSV': return t.translate("schedule_format_csv");
  230. case 'XML': return t.translate("schedule_format_xml");
  231. case 'spreadsheetML': return t.translate("schedule_format_xlsx");
  232. case 'xlsxData': return t.translate("schedule_format_xlsx_data");
  233. default: {
  234. console.warn("Unknown format: ", format);
  235. return "";
  236. }
  237. };
  238. },
  239. _setIcons: function(){
  240. var deleteIcon = this.$el.find(".n10n_delete_icon").has("span");
  241. Utils.setIcon(deleteIcon, 'common-remove-trash', t.translate('delete_notification'));
  242. },
  243. formatLinks: function() {
  244. var links = this.$el.find('.n10n_preview_link');
  245. for(var i = 0; i < links.length; i++) {
  246. stringFormater.middleShortenString(links[i]);
  247. }
  248. }
  249. });
  250. return previewView;
  251. });