/* * Licensed Materials - Property of IBM * * IBM Cognos Products: SHARE * * (C) Copyright IBM Corp. 2015, 2016 * * US Government Users Restricted Rights - Use, duplication or disclosure * restricted by GSA ADP Schedule Contract with IBM Corp. */ define([ "bi/commons/ui/View", 'underscore', 'jquery', 'q', 'bi/sharecommon/utils/simpledoT', 'text!bi/notifications/templates/messagesList.html', 'bi/sharecommon/utils/translator', 'bi/commons/utils/Utils', "bi/notifications/app/n10nController", 'bi/commons/utils/ContentFormatter', 'moment-timezone' ], function(View, _, $, Q, dot, msgTemplate, t, Utils, controller, ContentFormatter, moment) { var DEFAULT_DELAY = 500; var __STANDARD_DATE_FORMAT = 'L'; var messageListView = View.extend({ /** constructor * expects: * { data: , context: } */ init: function(options){ messageListView.inherited('init', this, arguments); $.extend(this, options); this.timezone = this.glassContext.services.userProfile.preferences.timeZoneID; this.defaultLocale = this.glassContext.services.userProfile.preferences.contentLocale || "en-us"; this.KEYS = { 'TAB': 9, 'ENTER': 13, 'SPACE': 32, 'LEFT_ARROW': 37, 'UP_ARROW': 38, 'RIGHT_ARROW': 39, 'DOWN_ARROW': 40 }; }, setData: function(newData) { this.data = newData; }, _setEvents: function() { // Listen for a keydown event on the full message div this.$el.find('.n10n_message').off('.n10n').on('keydown.n10n', this._handleKeyDown.bind(this)); // Listen for a "primaryaction" even on the message content div this.$el.find(".n10n_message_inner:not(.clickBound)").addClass('clickBound').on('primaryaction', function(event) { var messageId = event.currentTarget.parentNode.id; var $notification = this.$el.find(event.currentTarget.parentNode); // If the target of the event isn't selected (and thus shown) // then show it and mark it as selected if(!$notification.hasClass('selected')) { var messageContext = { messageId: messageId, messageListView: this, glassContext: this.glassContext, onHideCallback: this.clear.bind(this) }; controller.showNotificationContent(messageContext, this.slideout) // visually display the current message as read this._displayAsRead($notification); } }.bind(this)); // Listen for a "primaryaction" event on the delete button this.$el.find(".n10n_delete_icon:not(.clickBound)").addClass('clickBound').on('primaryaction', function(event) { var messageId = event.currentTarget.parentNode.id; var deletionRequest = { messageId: messageId, pending: true }; if (this.glassContext.services.userProfile.preferences.accessibilityFeatures) { this.glassContext.appController.showMessage(t.translate('delete_notification_confirm_message'), t.translate('delete_confirm'), 'info', ['ok','cancel'], undefined, function(evt) { if (evt.btn==='ok') { this._completeNotificationDelete(deletionRequest); } }.bind(this)); } else { var $message = $(event.currentTarget.parentNode); $message.hide(DEFAULT_DELAY); this.glassContext.appController.showToast(t.translate('delete_notification_message'), { 'type': 'info', 'btnLabel': t.translate('delete_undo'), 'callback': function() { deletionRequest.pending = false; this.$el.find('#' + deletionRequest.messageId).show(DEFAULT_DELAY); }.bind(this), 'newestOnTop': true, 'preventDuplicates': false, 'timeOut': 6000, 'extendedTimeOut': 1000, 'onHidden': function() { this._completeNotificationDelete(deletionRequest); }.bind(this) }); } }.bind(this)); }, /** * Handles moving the focus to the proper previous or next message in the notification list * depending on keys pressed as well as other factors */ _handleKeyDown: function(event) { var key = event.keyCode || event.charCode || event.which || 0; if(key === this.KEYS.UP_ARROW || key === this.KEYS.DOWN_ARROW || key === this.KEYS.LEFT_ARROW || key === this.KEYS.RIGHT_ARROW) { var $fromTarget = $(event.currentTarget); var $toTarget; switch(key) { case this.KEYS.DOWN_ARROW: case this.KEYS.RIGHT_ARROW: $toTarget = $fromTarget.next(); if($toTarget.css('display') == 'none') { $toTarget = $toTarget.next(); } break; case this.KEYS.UP_ARROW: case this.KEYS.LEFT_ARROW: $toTarget = $fromTarget.prev(); if($toTarget.css('display') == 'none') { $toTarget = $toTarget.prev(); } break; } if($toTarget && $toTarget.length > 0) { $toTarget.find('div.n10n_message_inner').focus(); } event.preventDefault(); } // Check to see the number of siblings to the parent of the // activeElement (the focused one) and load more messages if one or less. if($(event.target.parentNode).nextAll().length <= 1 && (key === this.KEYS.DOWN_ARROW || key === this.KEYS.RIGHT_ARROW)) { if(this.loadMessagesCallback && typeof this.loadMessagesCallback === 'function'){ this.loadMessagesCallback(this.$el.parent()); } } }, _completeNotificationDelete: function(deleteRequest) { var $pendingDeleteMessage = this.$el.find('#'+deleteRequest.messageId); var context = { glassContext: this.glassContext }; if(deleteRequest.pending) { controller.deleteNotification(deleteRequest.messageId, context).done(function(){ $pendingDeleteMessage.remove(); }.bind(this)); } }, clear: function() { // deactivate any selected messages this.$el.find(".n10n_message").removeClass("selected"); }, _displayAsRead: function($el) { $el.attr('aria-label', t.translate('read_notification')); $el.find("strong").contents().unwrap(); $el.find('.wft_message_unread_32').addClass('wft_message_read_32').removeClass('wft_message_unread_32'); }, _formatContent: function(){ var subjects = this.$el.find('.n10n_message_subject'); var dates = this.$el.find('.n10n_message_date'); var senders = this.$el.find('.n10n_message_sender'); for(var i=0; i 0) { var $nextMessage = currentMessage.next('.n10n_message'); if($nextMessage.length == 1) { $nextMessage.find('.n10n_message_inner').focus(); currentMessage = $nextMessage; } else { var $prevMessage = currentMessage.prev('.n10n_message'); if($prevMessage.length == 1) { $prevMessage.find('.n10n_message_inner').focus(); currentMessage = $prevMessage; } } } return currentMessage; } }); return messageListView; });