// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. (function($, cloudStack, _l) { /** * Notification handling */ var notifications = { activeTasks: [], cornerAlert: function(args, options) { if (!options) options = {}; var $container = $('#main-area'); // Put in main container box var $cornerAlert = $('
').addClass('notification corner-alert') .hide() .appendTo('html body') .append( $('
').addClass('top-arrow'), $('
').addClass('title').append( $('').html( options.error ? options.error : _l('label.task.completed') ) ) ) .append( $('
').addClass('message') .append( $('').html(_l(args.message)) ) ); if (options.error) { $cornerAlert.addClass('error'); } return $cornerAlert .css({ opacity: 0, position: 'absolute', top: $('#header .notifications').offset().top, left: $('#header .notifications').offset().left }) .animate({ opacity: 1 }, { complete: function() { setTimeout(function() { $cornerAlert.fadeOut('fast', function() { $cornerAlert.remove(); }); }, 3000); } }) .show(); }, add: function(args, $popup, $total) { var currentTotal = parseInt($total.html()); var newTotal = currentTotal + 1; var desc = args.desc; var section = $('html body') .find('[cloudStack-container]') .data('cloudStack-args') .sections[args.section]; var _custom = args._custom; var $item = $('
  • ') .append( $('').html(_l(args.desc)) ) .append( $('
    ').addClass('remove') ); var additionalComplete = args.complete; // Get information for specified section path $item.data('notification-section', args.section); $item.data('notification-custom', _custom); $popup.find('ul').append($item); $total.html(newTotal); $total.parent().addClass('pending'); $item.addClass('pending'); // Setup timer var pollTimer = setInterval(function() { args.poll({ _custom: _custom, pollTimer: pollTimer, complete: function(args) { clearInterval(pollTimer); notifications.cornerAlert({ message: $item.html() }); notifications.activeTasks.pop(pollTimer); $item.removeClass('pending'); if (additionalComplete) additionalComplete(); }, incomplete: function(args) {}, error: function(args) { if (args && args.message) { cloudStack.dialog.notice({ message: _s(args.message) }); } clearInterval(pollTimer); notifications.activeTasks.pop(pollTimer); notifications.cornerAlert({ message: $item.html() }, { error: _l('label.error') }); $item.removeClass('pending').addClass('error').append( $('
    ').addClass('subtitle').html(args && args.message ? args.message : _l('label.error')) ); $item.attr('title', args && args.message ? args.message : _l('label.error')); if (additionalComplete) additionalComplete(); } }); }, args.interval); notifications.activeTasks.push(pollTimer); return $total; }, /** * Set total to 0 */ resetTotal: function($popup) { var $total = $popup.data('notifications-attach-to').find('div.total span'); var $items = $popup.find('ul li'); var total = $items.size(); var completed = $items.filter(':not(.pending)').size(); var newTotal = total - completed; if (newTotal < 0) newTotal = completed; $total.html(newTotal); if (!newTotal) $total.parent().removeClass('pending'); }, /** * Remove item from notification list */ removeItem: function($popup, $item) { if ($item.closest('li').hasClass('pending')) return false; $item.remove(); return true; }, /** * Remove all completed notifications */ clear: function($popup) { $popup.find('ul li').each(function() { var $item = $(this); if (!$item.hasClass('pending')) { notifications.removeItem($popup, $item); } }); }, popup: { create: function($attachTo) { var $popup = $('
    ') .addClass('notification-box') .append( // Header $('

    ').html(_l('label.notifications')) ) .append( // Container $('
    ').addClass('container') .append( // Notification list $('
      ') ) ) .append( // Buttons $('
      ').addClass('buttons') .append( // Clear list $('
      ').addClass('button clear-list') .append( $('').html(_l('label.clear.list')) ) ) .append( $('
      ').addClass('button close') .append( $('').html(_l('label.close')) ) ) ) .css({ position: 'absolute' }) .data('notifications-attach-to', $attachTo) .hide(); if (!$attachTo.hasClass('notifications')) $attachTo.addClass('notifications'); $attachTo.data('notifications-popup', $popup); return $popup; }, show: function($popup, $attachTo) { notifications.resetTotal($popup); return notifications.popup.reposition($popup, $attachTo) .overlay({ closeAction: function() { notifications.popup.hide($popup); } }) .fadeIn(); }, hide: function($popup) { $popup.fadeOut(); }, reposition: function($popup, $attachTo) { return $popup .css({ zIndex: 10000, top: $attachTo.offset().top + $attachTo.height() + 10, left: $attachTo.offset().left - $attachTo.width() }); } } }; /** * Define notification widget -- this is basically represented in a * notifications icon, that contains a pop-up list of notifications */ $.fn.notifications = function(method, args) { var $attachTo = this; var $total = $attachTo.find('div.total span'); var $popup; var init = function() { $popup = notifications.popup.create($attachTo).appendTo('html body'); }; if (method == 'add') notifications.add(args, $attachTo.data('notifications-popup'), $total); else init(); return this; }; /** * Notifications UI helpers */ cloudStack.ui.notifications = { add: function(notification, success, successArgs, error, errorArgs) { if (!notification) { success(successArgs); return false; }; var $notifications = $('div.notifications'); if (!notification.poll) { cloudStack.ui.event.call('addNotification', { section: notification.section, desc: notification.desc, interval: 0, poll: function(args) { success(successArgs); args.complete(); } }); } else { cloudStack.ui.event.call('addNotification', { section: notification.section, desc: notification.desc, interval: notification.interval ? notification.interval : g_queryAsyncJobResultInterval, _custom: notification._custom, poll: function(args) { var complete = args.complete; var notificationError = args.error; notification.poll({ _custom: args._custom, complete: function(args) { success($.extend(successArgs, args)); complete(args); }, error: function(args) { error($.extend(errorArgs, args)); notificationError(args); } }); } }); } return true; } }; // Setup notification listener -- accepts same args as $(window).bind('cloudStack.addNotification', function(event, data) { $('.notifications').notifications('add', data); }); $(document).click(function(event) { var $target = $(event.target); var $attachTo, $popup; // Notifications header area if ($target.closest('.notifications').size()) { $attachTo = $target.closest('.notifications'); $popup = $attachTo.data('notifications-popup'); notifications.popup.show($popup, $attachTo); return false; } // Notification item if ($target.is('.notification-box li span')) { var $li = $target.closest('.notification-box li'); $('#navigation ul li').filter(function() { return $(this).hasClass($li.data('notification-section')); }).click(); $('div.overlay').click(); return false; } // Popup if ($target.closest('div.notification-box').size()) { $popup = $target.closest('div.notification-box'); // Clear list if ($target.closest('.button.clear-list').size()) { notifications.clear($popup); } // Remove instance item else if ($target.hasClass('remove')) { notifications.removeItem($popup, $target.closest('li')); } // Close button else if ($target.closest('.button.close')) { $('div.overlay').click(); } return false; } return true; }); $(window).resize(function(event) { var $popup = $('div.notification-box:visible'); if ($popup.size()) notifications.popup.reposition($popup, $popup.data('notifications-attach-to')); }); })(window.jQuery, window.cloudStack, window._l);