// 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) { var addTierDialog = function(args) { var $placeholder = args.$placeholder; var context = args.context; var addAction = cloudStack.vpc.tiers.actions.add; cloudStack.dialog.createForm({ context: context, form: addAction.createForm, after: function(args) { var $loading = $('
').addClass('loading-overlay') .prependTo($placeholder); addAction.action({ context: context, data: args.data, $form: args.$form, response: { success: function(args) { cloudStack.ui.notifications.add( // Notification { desc: addAction.label }, // Success function(args) { $loading.remove(); $placeholder.closest('.vpc-network-chart').trigger('reload'); }, {}, // Error function(args) { $loading.remove(); } ); }, error: function(errorMsg) { cloudStack.dialog.notice({ message: _s(errorMsg) }); $loading.remove(); } } }); } }); }; var elems = { tier: function(args) { var tier = args.tier; var context = $.extend(true, {}, args.context, { networks: [tier] }); var dashboardItems = args.dashboardItems; var $tier = $('
').addClass('tier-item'); var $header = $('
').addClass('header'); var $title = $('
').addClass('title').append($('')); var $content = $('
').addClass('content'); var $browser = $('#browser .container'); var $dashboard = elems.dashboard({ context: context, dashboardItems: dashboardItems }); var $detailLink = $('
').addClass('detail-link'); var $info = $('
').addClass('info'); var $cidrLabel = $('').addClass('cidr-label'); var $cidr = $('').addClass('cidr'); $detailLink.click(function() { $browser.cloudBrowser('addPanel', { title: tier.displayname ? tier.displayname : tier.name, complete: function($panel) { var $detailView = $('
').detailView( $.extend(true, {}, cloudStack.vpc.tiers.detailView, { section: 'networks', $browser: $browser, context: context, onActionComplete: function() { $tier.closest('.vpc-network-chart').trigger('reload'); } }) ); $detailView.appendTo($panel); } }); }); $cidrLabel.html('CIDR: '); $cidr.html(tier.cidr); $title.find('span').html(tier.displayname ? tier.displayname : tier.name); $header.append($title, $detailLink); $info.append($cidrLabel, $cidr); $content.append($dashboard, $info); $tier.append($header, $content); return $tier; }, connectorLine: function(args) { var $connector = $('
').addClass('connector-line'); var $router = args.$router; var $tier = args.$tier; var isHighlighted = args.isHighlighted; var $connectorStart = $('
').addClass('connector-start'); var $connectorMid = $('
').addClass('connector-mid'); var $connectorEnd = $('
').addClass('connector-end'); $connector.append($connectorStart, $connectorMid, $connectorEnd); if (isHighlighted) { $connector.addClass('highlighted'); } var posStartOffsetLeft = 5; var posStartOffsetTop = 10; var posStart = { top: $router.position().top + ($router.outerHeight() / 2 + ($tier.index() * posStartOffsetTop)), left: $router.position().left + $router.outerWidth() }; var posStartWidth = 60 - ($tier.index() > 2 ? (($tier.index() + 1) * posStartOffsetLeft) : 0); var posEndOffset = 15; var posEndWidthOffset = 3; var posEnd = { top: $tier.position().top + ($tier.outerHeight() / 2), left: posStart.left + posStartWidth + posEndOffset }; var posEndWidth = Math.abs($tier.position().left - (posStart.left + posStartWidth)) + posEndWidthOffset; // Start line (next to router) $connectorStart.css({ top: posStart.top, left: posStart.left }); $connectorStart.width(posStartWidth); // End line (next to tier) $connectorEnd.css({ top: posEnd.top, left: posEnd.left }); $connectorEnd.width(posEndWidth); // Mid line (connect start->end) if (posStart.top > posEnd.top) { // Tier above router $connectorMid.css({ top: posEnd.top, left: posEnd.left }); $connectorMid.height(posStart.top - posEnd.top); } else { // Tier below router $connectorMid.css({ top: posStart.top, left: posStart.left + posStartWidth + posEndOffset }); $connectorMid.height(posEnd.top - posStart.top); } return $connector; }, router: function(args) { var $router = elems.tier({ context: args.context, tier: { name: 'Router' }, dashboardItems: args.dashboardItems }).addClass('router'); $router.find('.info, .detail-link').remove(); $router.find('.header').prepend($('').addClass('icon').html(' ')); return $router; }, tierPlaceholder: function(args) { var context = args.context; var $placeholder = $('
').addClass('tier-placeholder'); $placeholder.append($('').append('Create network')); $placeholder.click(function() { addTierDialog({ context: context, $placeholder: $placeholder }); }); return $placeholder; }, dashboard: function(args) { var $dashboard = $('
').addClass('dashboard'); var context = args.context; var tier = context.networks[0]; $(args.dashboardItems).map(function(index, dashboardItem) { var $dashboardItem = $('
').addClass('dashboard-item'); var $name = $('
').addClass('name').append($('')); var $total = $('
').addClass('total').append($('')); var id = dashboardItem.id; $name.find('span').html(dashboardItem.name); if (dashboardItem.totalMultiLine) { $total.find('span').html(dashboardItem.totalMultiLine); $total.addClass('multiline'); } else { $total.find('span').html(dashboardItem.total ? dashboardItem.total : 0); } $dashboardItem.append($total, $name); $dashboardItem.appendTo($dashboard); if (dashboardItem._disabled) { $dashboardItem.addClass('disabled'); } $dashboardItem.click(function() { if ($dashboardItem.is('.disabled')) { return false; } var section = cloudStack.vpc.sections[id]; var $section = $('
'); var $loading = $('
').addClass('loading-overlay'); if ($.isFunction(section)) { section = cloudStack.vpc.sections[id](); } var before = section.before; var load = function() { $('#browser .container').cloudBrowser('addPanel', { title: tier.name + ' - ' + dashboardItem.name, maximizeIfSelected: true, complete: function($panel) { if (section.listView) { $section.listView($.extend(true, {}, section, { onActionComplete: function() { $dashboardItem.closest('.vpc-network-chart').trigger('reload'); }, context: context })); } $section.appendTo($panel); } }); }; if (before) { before.check({ context: context, response: { success: function(result) { // true means content exists if (result) { load(); } else { cloudStack.dialog.confirm({ message: before.messages.confirm, action: function() { $loading.appendTo($dashboardItem.closest('.vpc-network-chart')); before.action({ context: context, response: { success: function() { $loading.remove(); $dashboardItem.closest('.vpc-network-chart').trigger('reload'); load(); } } }); } }) } } } }); } else { load(); } }); }); return $dashboard; } }; cloudStack.modules.vpc = function(module) { var vpc = cloudStack.vpc; var vpcSection = cloudStack.sections.network.sections.vpc; var listConfigureAction = vpcSection.listView.actions.configureVpc.action; var detailsConfigureAction = vpcSection.listView.detailView.actions.configureVpc.action; var vpcChart = function(args) { var context = args.context; var vpcItem = context.vpc[0]; var chart = function(args) { args = args ? args : {}; var $chart = $('
').addClass('vpc-network-chart'); var $tiers = $('
').addClass('tiers'); var $toolbar = $('
').addClass('toolbar'); var $info = $('
').addClass('info-box'); $toolbar.appendTo($chart); $tiers.appendTo($chart); // Get tiers var $loading = $('
').addClass('loading-overlay').prependTo($chart); vpc.tiers.dataProvider({ context: context, response: { success: function(data) { var tiers = data.tiers; var $router; var $placeholder = elems.tierPlaceholder({ context: context }); // Router $router = elems.router({ context: context, dashboardItems: data.routerDashboard }).appendTo($chart); $(tiers).map(function(index, tier) { var $tier = elems.tier({ context: context, tier: tier, dashboardItems: tier._dashboardItems }); $tier.appendTo($tiers); // Connect tier to router via line // // -- Needs to execute after chart generation is complete, // so that chart elements have positioning in place. $chart.bind('cloudStack.vpc.chartReady', function() { elems.connectorLine({ $tier: $tier, $router: $router, isHighlighted: tier._highlighted }).appendTo($chart); }); }); // Add placeholder tier $tiers.append($placeholder); $loading.remove(); if (!tiers.length) { addTierDialog({ context: context, $placeholder: $placeholder }); } if (args.complete) { args.complete($chart); } if ($chart.find('.connector-line.highlighted').size()) { $info.appendTo($chart).append( $('').addClass('color-key'), $('').html('= Contains a public network') ); } } } }); $chart.bind('reload', function() { chart({ complete: function($newChart) { $chart.replaceWith($newChart); $newChart.trigger('cloudStack.vpc.chartReady'); } }); }); return $chart; }; $('#browser .container').cloudBrowser('addPanel', { title: vpcItem.displaytext ? vpcItem.displaytext : vpcItem.name, maximizeIfSelected: true, complete: function($panel) { var $chart = chart({ complete: function($chart) { $chart.trigger('cloudStack.vpc.chartReady'); } }); $chart.appendTo($panel); } }); }; listConfigureAction.custom = vpcChart; detailsConfigureAction.custom = vpcChart; }; }(jQuery, cloudStack));