| // 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 = $('<div>').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 = $('<div>').addClass('tier-item'); |
| var $header = $('<div>').addClass('header'); |
| var $title = $('<div>').addClass('title').append($('<span>')); |
| var $content = $('<div>').addClass('content'); |
| var $browser = $('#browser .container'); |
| var $dashboard = elems.dashboard({ |
| context: context, |
| dashboardItems: dashboardItems |
| }); |
| var $detailLink = $('<div>').addClass('detail-link'); |
| var $info = $('<div>').addClass('info'); |
| var $cidrLabel = $('<span>').addClass('cidr-label'); |
| var $cidr = $('<span>').addClass('cidr'); |
| |
| $detailLink.click(function() { |
| $browser.cloudBrowser('addPanel', { |
| title: tier.displayname ? tier.displayname : tier.name, |
| complete: function($panel) { |
| var $detailView = $('<div>').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 = $('<div></div>').addClass('connector-line'); |
| var $router = args.$router; |
| var $tier = args.$tier; |
| var isHighlighted = args.isHighlighted; |
| var $connectorStart = $('<div></div>').addClass('connector-start'); |
| var $connectorMid = $('<div></div>').addClass('connector-mid'); |
| var $connectorEnd = $('<div></div>').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($('<span></span>').addClass('icon').html(' ')); |
| |
| return $router; |
| }, |
| |
| tierPlaceholder: function(args) { |
| var context = args.context; |
| var $placeholder = $('<div>').addClass('tier-placeholder'); |
| |
| $placeholder.append($('<span>').append('Create network')); |
| $placeholder.click(function() { |
| addTierDialog({ |
| context: context, |
| $placeholder: $placeholder |
| }); |
| }); |
| |
| return $placeholder; |
| }, |
| |
| dashboard: function(args) { |
| var $dashboard = $('<div>').addClass('dashboard'); |
| var context = args.context; |
| var tier = context.networks[0]; |
| |
| $(args.dashboardItems).map(function(index, dashboardItem) { |
| var $dashboardItem = $('<div>').addClass('dashboard-item'); |
| var $name = $('<div>').addClass('name').append($('<span>')); |
| var $total = $('<div>').addClass('total').append($('<span>')); |
| 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 = $('<div>'); |
| var $loading = $('<div>').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 = $('<div>').addClass('vpc-network-chart'); |
| var $tiers = $('<div>').addClass('tiers'); |
| var $toolbar = $('<div>').addClass('toolbar'); |
| var $info = $('<div>').addClass('info-box'); |
| |
| $toolbar.appendTo($chart); |
| $tiers.appendTo($chart); |
| |
| // Get tiers |
| var $loading = $('<div>').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').length) { |
| $info.appendTo($chart).append( |
| $('<span>').addClass('color-key'), |
| $('<span>').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)); |