/** * Licensed Materials - Property of IBM * * IBM Cognos Products: SHARE * * Copyright IBM Corp. 2015, 2017 * * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define([ 'jquery', 'underscore', 'moment-timezone', 'rave2', 'q', 'bi/commons/utils/BidiUtil', 'text!bi/schedule/templates/SubscriptionManagementLoading.html', 'text!bi/schedule/templates/SubscriptionManagement.html', 'text!bi/notifications/templates/emptyMessageList.html', 'bi/glass/app/ContentView', 'bi/sharecommon/utils/simpledoT', 'bi/sharecommon/utils/translator', 'bi/schedule/app/appControler', 'bi/schedule/utils/CadenceLabelGenerator', 'bi/commons/ui/properties/CheckBox', 'bi/commons/utils/Utils', 'bi/schedule/utils/charts/BarChart', 'datatables' ], function($, _, moment, rave, Q, BidiUtil, loadingViewTemplate, viewTemplate, emptyListTemplate, ContentView, dot, t, controler, cadence, CheckBox, Utils, BarChart) { var DEFAULT_DELAY = 500; var __STANDARD_DATE_TIME_FORMAT = 'lll'; var view = ContentView.extend({ init: function(options) { view.inherited('init', this, arguments); // Initialise default values this.subscriptionsCount = 0; this.enabledCount = 0; this.disabledCount = 0; this.windowWidth = 0; this.timezone = options.glassContext.services.userProfile.preferences.timeZoneID; this.contentLocale = this.glassContext.services.userProfile.preferences.contentLocale || "en-us"; $.extend(this, options); this._id = _.uniqueId("smv_"); this.$subscriptionsListDiv = null; this.$noSubscriptionsDiv = null; }, activate: function() { return this.updateView(); }, // nothing to do, but needs to be present for AppView.js logic from Glass deactivate: function() { }, getContent: function() { return {}; }, getTitle: function() { return t.translate("subscribe_mgmt_label"); }, getIcon: function() { return 'common-subscribe_icon'; }, render: function() { var deferred = $.Deferred(); var subscribe_graph_title = t.translate("subscribe_graph_title"); var subscribe_last_refresh_label = t.translate("subscribe_last_refresh_label"); // Set up the Subscription Management Loading template // I don't like this but it works (for now) var loadingHtmlGenerator = dot.simpleTemplate(loadingViewTemplate); var currentTime = moment(new Date()).locale(this.contentLocale).tz(this.timezone).format(__STANDARD_DATE_TIME_FORMAT); var attributes = { subscribe_graph_title: subscribe_graph_title, subscribe_last_refresh_label: subscribe_last_refresh_label, current_time: currentTime }; this.$el.html(loadingHtmlGenerator(attributes)); var loadingAnimation = Utils.getLoadingAnimation(2); this.$el.find('div.s10n_loading').html(loadingAnimation); deferred.resolve(this); controler.getSubscriptions(this.glassContext).then(function(data) { var subscriptions = []; this.enabledCount = 0; var dataLength = data.length; for(var i = 0; i < dataLength; i++) { var name = _.escape(data[i].name.substr(0, 3) + BidiUtil.enforceTextDirection(data[i].name.substr(3))) || ""; var nameInAttr = _.escape(data[i].name)|| ""; var cadenceLabel = cadence.getLabelFor(data[i].scheduleInfo, this.timezone, this.contentLocale); var ownerName = data[i].scheduleInfo ? _.escape(data[i].scheduleInfo.ownerName) || "" : ""; var lastModified = data[i].scheduleInfo ? data[i].scheduleInfo.modificationTime || "" : ""; lastModified = moment(lastModified).locale(this.contentLocale).tz(this.timezone).format(__STANDARD_DATE_TIME_FORMAT); data[i].checkbox_aria_label = t.translate("subscribe_mgmt_checkbox_description", { 'subscription_name': nameInAttr }); var isEnabled = data[i].scheduleInfo.active || false; if(isEnabled) { this.enabledCount++; } subscriptions.push({ id: data[i].id, name: name, owner: ownerName, active: isEnabled, modifiedTime: lastModified, cadence_label: cadenceLabel, // "Every Wednesday at 5pm" context_menu_description: t.translate("subs_mgmt_context_menu_description", { 'subscription_name': nameInAttr }) }); } this.subscriptionsCount = subscriptions.length; this.disabledCount = subscriptions.length - this.enabledCount; var htmlGenerator = dot.simpleTemplate(viewTemplate); var currentTime = moment(new Date()).locale(this.contentLocale).tz(this.timezone).format(__STANDARD_DATE_TIME_FORMAT); var attributes = { id: this._id, subscribe_graph_title: subscribe_graph_title, subscribe_last_refresh_label: subscribe_last_refresh_label, current_time: currentTime, ariaLabel: t.translate("subscriptions_table_accessible_label"), chartDescription: t.translate("subscribe_graph_description", { enabled: this.enabledCount, disabled: this.disabledCount }), columns: this._tableColumnHeaders(), subs: subscriptions }; this.$el.html(htmlGenerator(attributes)); // By default both are displayed. We choose which to hide later this.$subscriptionsListDiv = this.$el.find('.subscriptions_list'); this.$noSubscriptionsDiv = this.$el.find('.no_subscriptions_message'); var emptyTemplate = dot.template(emptyListTemplate); this.$noSubscriptionsDiv.html(emptyTemplate({ 'text': t.translate("subscription_list_is_empty") })); this._setSvg(); this._renderChart(); this._renderCheckBoxes(data); if (this.subscriptionsCount > 0) { this.$subscriptionsListDiv.find('.subscriptions_list_table').dataTable({ paging: false, searching: false, info: false, aaSorting: [[1, 'asc']], scrollY: '60vh', scrollX: 'auto', width: '100%' }); this.$noSubscriptionsDiv.hide(); } else { this.$subscriptionsListDiv.hide(); } this._fixTableBodyHeight(); this._setEvents(); }.bind(this)); return deferred.promise(); }, updateView: function() { this.$el.empty(); return this.render(); }, _renderChart: function() { var chartData = [ { name: 'enabled', value: this.enabledCount }, { name: 'disabled', value: this.disabledCount } ]; // This initialises AND draws the chart this._chart = new BarChart({ $el: this.$el.find('svg.chart'), data: chartData }); }, _updateChart: function(data) { this._chart.redraw(data); }, _renderCheckBoxes: function(data) { var _self = this; for(var i = 0; i < data.length; i++) { var stateToggler = new CheckBox({ 'id': 'subscription_' + data[i].id, 'el': _self.$el.find("[data-subscription-id='"+ data[i].id +"'] > td:first"), 'name': data[i].id, 'label': '', 'ariaLabel': data[i].checkbox_aria_label, 'checked': data[i].scheduleInfo.active, 'onChange': function(name, value) { _self._handleCheckBoxes({ subscriptionId: name, state: value, $checkbox: this.getPropertyNode() // 'this' is CheckBox NOT SubMgmtView }); } }); stateToggler.doRender(); } }, _handleCheckBoxes: function(properties) { var subscriptionId = properties.subscriptionId; var state = properties.state; var $checkbox = properties.$checkbox; $checkbox.addClass('disabled'); controler.getSubscriptionDetails(subscriptionId, this.glassContext).then(function(data) { subscriptionDescriptor = data; subscriptionDescriptor.scheduleInfo.active = state; this._toggleSingleSubscriptionStatus(subscriptionDescriptor).then(function() { $checkbox.removeClass('disabled'); }); }.bind(this)); }, _toggleSingleSubscriptionStatus: function(descriptor) { var deferred = Q.defer(); controler.updateSubscription(descriptor, this.glassContext).done(function(data) { this._updateSubscriptionList().then(function() { deferred.resolve(); }); }.bind(this)); return deferred.promise; }, _fixTableBodyHeight: function() { var contentHeight = this.$el.find('div.s10n_main').height(); // this is height of pane minus top and bottom padding var topHeight = this.$el.find('div.s10n_header').height() + this.$el.find('svg.chart').height(); // The magic number 40 is for the padding in the content view from the css class s10n_container this.$el.find('div.dataTables_scrollBody').height(contentHeight - topHeight - 40); }, _setEvents: function() { var _self = this; window.onresize = function() { if(_self.$el.find('svg.chart').css('visibility') !== 'hidden' && $(window).width() !== _self.windowWidth) { _self.windowWidth = $(window).width(); _self._updateChart(); } // Fix height of datatable container _self._fixTableBodyHeight(); }; $('button.btnContextMenu').on('clicktap', function(event) { var menuProperties = { 'menuId': 'com.ibm.bi.subscribe_mgmt.contextMenu', 'position': { pageX: event.pageX, pageY: event.pageY }, 'activeObject': { currentTarget: event.currentTarget, subscriptionId: $(event.currentTarget).closest('tr').data('subscription-id'), updateCallback: _self.updateView.bind(_self), deleteCallbacks: { hideRow: _self._hideDeleteRow.bind(_self), undoDelete: _self._undoDeleteAndShowRow.bind(_self), complete: _self._completeSubscriptionDelete.bind(_self) } } }; _self.glassContext.appController.showContextMenu(menuProperties); }); }, _hideDeleteRow: function($subscriptionRow) { var deferred = Q.defer(); var _self = this; $subscriptionRow.hide(DEFAULT_DELAY, function() { if(_self.subscriptionsCount == 1) { _self.$noSubscriptionsDiv.show(); _self.$subscriptionsListDiv.hide(); } deferred.resolve(); }); return deferred.promise; }, _undoDeleteAndShowRow: function($subscriptionRow) { var _self = this; // An undo should show right away that is the reason for zero $subscriptionRow.show(0, function() { if(_self.subscriptionsCount == 1) { _self.$noSubscriptionsDiv.hide(); _self.$subscriptionsListDiv.show(); } }); }, _completeSubscriptionDelete: function(options) { if(options.pending) { controler.deleteSubscription(options.subscriptionId, this.glassContext).done(function() { this._updateSubscriptionList(); }.bind(this)); } }, _updateSubscriptionList: function() { var deferred = Q.defer(); controler.getSubscriptions(this.glassContext).done(function(data) { this.subscriptionsCount = data.length; var enabled = _.countBy(data, function(s) { if(s.scheduleInfo.active) return "enabled"; }); if(!enabled.enabled) { enabled.enabled = 0; } this.enabledCount = enabled.enabled; this.disabledCount = this.subscriptionsCount - enabled.enabled; if(this.subscriptionsCount === 0) { this.$noSubscriptionsDiv.show(); this.$subscriptionsListDiv.hide(); } var chartData = [ { name: 'enabled', value: this.enabledCount }, { name: 'disabled', value: this.disabledCount } ]; this._updateChart(chartData); deferred.resolve(); }.bind(this)); return deferred.promise; }, _setSvg: function() { var $icons = this.$el.find('.common_icon'); for(var i = 0; i < $icons.length; i++) { var $icon = $($icons[i]); Utils.setIcon($icon, 'common-' + $icon.data('icon'), t.translate('svg_menu_icon')); } }, _tableColumnHeaders: function() { return [ { 'name': 'enable', 'label': t.translate("subscribe_status_header"), 'class': 's10n_status_col' }, // Subscription name column { 'name': 'name', 'label': t.translate("subscribe_header"), 'sort': true }, // Owner column { 'name': 'owner', 'label': t.translate("subscribe_owner_header"), 'sort': true }, // Modified column { 'name': 'modified', 'label': t.translate("subscribe_modified_header"), 'sort': true }, // Context Menu column to modify/view history/delete { 'name': 'context' } ]; } }); return view; });