Large diffs are not rendered by default.

@@ -19,7 +19,7 @@
.panel .tile .footer a:hover { text-decoration: underline; }
.panel .tile .footer .button { display: inline-block; font-weight: bold; }
.panel .tile .footer .button:hover { text-decoration: none; }
.panel .tile .dropdown.button.tiny { z-index: 99999; background: none; box-shadow: none; position: absolute; width: 30px; height: 24px; top: 0; right: 0; color: #8cc63e; font-size: 1.1rem; padding: 0 0 0 0; border: none; }
.panel .tile .dropdown.button.tiny { z-index: 99998; background: none; box-shadow: none; position: absolute; width: 30px; height: 24px; top: 0; right: 0; color: #8cc63e; font-size: 1.1rem; padding: 0 0 0 0; border: none; }
.panel .tile .dropdown.button.tiny:hover { color: #8cc63e; }
.panel .tile .dropdown.button.tiny::before, .panel .tile .dropdown.button.tiny::after { border: none; }
.panel .tile .dropdown.button.tiny .fi-widget { position: relative; top: 4px; background-image: url(../../img/svg/gear.svg); display: inline-block; width: 20px; height: 20px; }
@@ -37,6 +37,8 @@

#scaling-groups .icon { background-image: url(../../img/svg/icon_instances_scaling_groups.svg); }

#stacks .icon { background-image: url(../../img/svg/icon_cloud_formation.svg); }

#elastic-ips .icon { background-image: url(../../img/svg/icon_elastic_IP.svg); }

#volumes .icon { background-image: url(../../img/svg/icon_volumes.svg); }
@@ -103,3 +103,7 @@
/* Small screen */
@media screen and (max-width: 1020px) { .columns.datagrid { padding-left: 1rem; } }
.content { width: 100%; padding-left: 10px; padding-right: 10px; }

.panel { overflow: hidden; min-height: 400px; }

label { font-weight: bold; color: #6a737b; }
@@ -50,7 +50,11 @@

.keyvalsummary { line-height: 1.375rem; }

#sample-template { margin-left: 1.5rem; width: 90%; }
.param-name { color: #6a737b; }

#sample-template-div .chosen-container { margin-left: 1.5rem; margin-bottom: 0.75rem; width: 90% !important; }

.chosen-container { width: 100%; }

#template-file { margin-left: 1.5rem; width: 90%; }

@@ -108,14 +108,14 @@

.status.Create-failed { background-color: darkred; }

.status.Rollback-in-progress { background-color: #f10000; }
.status.Rollback-in-progress { background-color: #6a737b; }

.status.Rollback-complete { background-color: #03405f; }
.status.Rollback-complete { background-color: #444; }

.status.Rollback-failed { background-color: darkred; }

.status.Delete-in-progress { background-color: #525960; }
.status.Delete-in-progress { background-color: #6a737b; }

.status.Delete-complete { background-color: #03405f; }
.status.Delete-complete { background-color: #444; }

.status.Delete-failed { background-color: darkred; }
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -61,9 +61,9 @@ describe("BucketContentsPage", function() {
it("Initial value of total is 0", function() {
expect(scope.total).toEqual(0);
});
it("Initial value of chunkSize is 10", function() {
it("Initial value of chunkSize is 100", function() {

expect(scope.chunkSize).toEqual(10);
expect(scope.chunkSize).toEqual(100);
});
});

@@ -15,7 +15,7 @@ angular.module('BucketContentsPage', ['LandingPage', 'EucaConsoleUtils'])
$scope.copyingAll = false;
$scope.progress = 0;
$scope.total = 0;
$scope.chunkSize = 10; // set this based on how many keys we want to delete at once
$scope.chunkSize = 100; // set this based on how many keys we want to delete at once
$scope.index = 0;
$scope.items = null;
$scope.op_prefix = '';
@@ -32,7 +32,7 @@ angular.module('BucketContentsPage', ['LandingPage', 'EucaConsoleUtils'])
$scope.putKeysUrl = options.put_keys_url;
$scope.makeObjectPublicUrl = options.make_object_public_url;
// set upload button target based on media query
if (window.matchMedia(Foundation.media_queries.small).matches === false) {
if (Foundation.utils.is_medium_up()) {
$('#upload-file-btn').attr('target', '_blank');
}
$scope.updatePasteValues();
@@ -18,7 +18,7 @@ angular.module('BucketDetailsPage', ['S3SharingPanel', 'EucaConsoleUtils'])
$scope.handleUnsavedChanges();
$scope.handleUnsavedSharingEntry($scope.bucketDetailsForm);
// set upload button target based on media query
if (window.matchMedia(Foundation.media_queries.small).matches === false) {
if (Foundation.utils.is_medium_up()) {
$('#upload-file-action').attr('target', '_blank');
}
};
@@ -41,7 +41,7 @@ angular.module('UploadFilePage', ['S3SharingPanel', 'S3MetadataEditor'])
$scope.$on('s3:sharingPanelAclUpdated', function () {
$scope.hasChangesToBeSaved = true;
});
$scope.$watch('files', function (newVals) {
$scope.$watchCollection('files', function (newVals) {
$('#size-error').css('display', 'none');
$scope.isNotValid = false;
if (newVals.length > 0) {
@@ -105,7 +105,9 @@ angular.module('UploadFilePage', ['S3SharingPanel', 'S3MetadataEditor'])
var parentWindow = window.opener;
$('#upload-files-modal').foundation('reveal', 'close');
$scope.hasChangesToBeSaved = false;
parentWindow.postMessage('s3:fileUploaded', '*');
if (parentWindow) {
parentWindow.postMessage('s3:fileUploaded', '*');
}
$scope.cancel();
}
if ($scope.uploading === true) {
@@ -127,7 +129,7 @@ angular.module('UploadFilePage', ['S3SharingPanel', 'S3MetadataEditor'])
$scope.cancel();
};
$scope.cancel = function () {
if (window.matchMedia(Foundation.media_queries.small).matches === false) {
if (Foundation.utils.is_medium_up()) {
window.close();
}
else {
@@ -20,7 +20,7 @@ angular.module('BucketsPage', ['LandingPage', 'EucaConsoleUtils'])
$scope.copyingAll = false;
$scope.progress = 0;
$scope.total = 0;
$scope.chunkSize = 10; // set this based on how many keys we want to delete at once
$scope.chunkSize = 10; // set this based on how many keys we want to copy at once
$scope.index = 0;
$scope.items = null;
$scope.hasCopyItem = false;
@@ -8,7 +8,6 @@ angular.module('ELBPage', ['EucaConsoleUtils'])
.controller('ELBPageCtrl', function ($scope, eucaUnescapeJson) {
$scope.initController = function (optionsJson) {
var options = JSON.parse(eucaUnescapeJson(optionsJson));
$scope.elbInUse = options.in_use;
$scope.hasImage = options.has_image;
$scope.setWatch();
$scope.setFocus();
@@ -8,7 +8,6 @@
angular.module('ELBsPage', ['LandingPage'])
.controller('ELBsPageCtrl', function ($scope) {
$scope.elbName = '';
$scope.elbInUse = false;
$scope.revealModal = function (action, elb) {
$scope.elbName = elb.name;
var modal = $('#' + action + '-elb-modal');
@@ -6,7 +6,11 @@

(function($) {
// Initialize all Zurb Foundation components
$(document).foundation();
$(document).foundation({
offcanvas : {
open_method: 'overlap_single',
}
});

$(document).ready(function () {

@@ -12,7 +12,7 @@ angular.module('ImagePage', ['BlockDeviceMappingEditor', 'TagEditor', 'EucaConso
$scope.imageCancelUrl = '';
$scope.imagesUrl = '';
$scope.transitionalStates = ['pending', 'storing'];
$scope.isPublic = '';
$scope.isPublic = false;
$scope.errorClass= '';
$scope.launchPermissions = [];
$scope.isAccountNotTyped = true;
@@ -24,7 +24,9 @@ angular.module('ImagePage', ['BlockDeviceMappingEditor', 'TagEditor', 'EucaConso
$scope.cancelling = false;
$scope.initController = function (optionsJson) {
var options = JSON.parse(eucaUnescapeJson(optionsJson));
$scope.isPublic = options.is_public;
if (options.hasOwnProperty('is_public') && options.is_public === 'true') {
$scope.isPublic = true;
}
$scope.launchPermissions = options.image_launch_permissions;
$scope.imageStatusEndpoint = options.image_state_json_url;
$scope.imageCancelUrl = options.image_cancel_url;
@@ -8,23 +8,26 @@ angular.module('StackPage', ['MagicSearch', 'EucaConsoleUtils'])
.controller('StackPageCtrl', function ($scope, $http, $timeout, eucaUnescapeJson) {
$scope.stackStatusEndpoint = '';
$scope.stackTemplateEndpoint = '';
$scope.transitionalStates = ['create-in-progress', 'rollback-in-progress', 'delete-in-progress'];
$scope.transitionalStates = ['Create-in-progress', 'Rollback-in-progress', 'Delete-in-progress'];
$scope.stackStatus = '';
$scope.templateLoading = true;
$scope.eventsLoading = true;
$scope.resources = [];
$scope.initController = function (optionsJson) {
var options = JSON.parse(eucaUnescapeJson(optionsJson));
$scope.stack_name = optionsJson.stack_name;
$scope.stackStatusEndpoint = options.stack_status_json_url;
$scope.stackTemplateEndpoint = options.stack_template_url;
$scope.stackEventsEndpointOrig = options.stack_events_url;
$scope.stackEventsEndpoint = options.stack_events_url;
$scope.stackStatus = options.stack_status;
if ($scope.stackStatusEndpoint) {
$scope.getStackState();
}
if ($scope.stackEventsEndpoint) {
$scope.getStackEvents();
}
//$scope.setWatch();
$scope.setWatch();
$scope.setFocus();
};
$scope.isTransitional = function () {
@@ -100,8 +103,10 @@ angular.module('StackPage', ['MagicSearch', 'EucaConsoleUtils'])
if ($scope.isTransitional()) {
$scope.isUpdating = true;
$timeout(function() {$scope.getStackState();}, 4000); // Poll every 4 seconds
$scope.getStackEvents();
} else {
$scope.isUpdating = false;
$scope.updateStatusReasons();
}
}
});
@@ -122,8 +127,36 @@ angular.module('StackPage', ['MagicSearch', 'EucaConsoleUtils'])
var results = oData ? oData.results : '';
$scope.eventsLoading = false;
if (results) {
for (var i=0; i<results.events.length; i++) {
results.events[i].status_reason = '';
}
$scope.unfilteredEvents = results.events;
$scope.searchEvents();
$('#events-table').stickyTableHeaders();
$scope.updateStatusReasons();
}
});
};
$scope.updateStatusReasons = function() {
if ($scope.unfilteredEvents === undefined) {
return;
}
// look for first stack status and pull status reason
$timeout(function() {
for (var i=0; i<$scope.unfilteredEvents.length; i++) {
if ($scope.unfilteredEvents[i].type == 'AWS::CloudFormation::Stack') {
$scope.statusReason = $scope.unfilteredEvents[i].status_reason;
break;
}
}
});
// look for status for each resource and pull status reason
angular.forEach($scope.resources, function(value, key) {
for (var i=0; i<$scope.unfilteredEvents.length; i++) {
if (value.physical_id == $scope.unfilteredEvents[i].physical_id) {
value.status_reason = $scope.unfilteredEvents[i].status_reason;
break;
}
}
});
};
@@ -156,7 +189,7 @@ angular.module('StackPage', ['MagicSearch', 'EucaConsoleUtils'])
$scope.events = filteredItems;
};
$scope.$on('searchUpdated', function($event, query) {
$scope.jsonEndpoint = decodeURIComponent($scope.jsonEndpointPrefix + "&" + query);
$scope.stackEventsEndpoint = decodeURIComponent($scope.stackEventsEndpointOrig + "?" + query);
$scope.getStackEvents();
});
$scope.$on('textSearch', function($event, text, filter_keys) {
@@ -5,7 +5,7 @@
*/

// Launch Instance page includes the Tag Editor, the Image Picker, BDM editor, and security group rules editor
angular.module('StackWizard', ['TagEditor', 'EucaConsoleUtils'])
angular.module('StackWizard', ['TagEditor', 'EucaConsoleUtils', 'localytics.directives'])
.directive('file', function(){
return {
restrict: 'A',
@@ -15,6 +15,9 @@ angular.module('StackWizard', ['TagEditor', 'EucaConsoleUtils'])
$scope.templateIdent = event.target.files[0].name;
$scope.$apply();
$scope.checkRequiredInput();
if ($scope.templateIdent !== undefined) {
$scope.getStackTemplateInfo();
}
});
}
};
@@ -32,30 +35,33 @@ angular.module('StackWizard', ['TagEditor', 'EucaConsoleUtils'])
$scope.step2Invalid = true;
$scope.imageJsonURL = '';
$scope.isNotValid = true;
$scope.loading = false;
$scope.paramModels = [];
$scope.initController = function (optionsJson) {
var options = JSON.parse(eucaUnescapeJson(optionsJson));
$scope.stackTemplateEndpoint = options.stack_template_url;
$scope.templates = options.sample_templates;
$scope.setInitialValues();
//$('#sample-template').chosen({'width': '100%', search_contains: true});
$scope.watchTags();
$scope.setWatcher();
$scope.setWatchers();
$scope.setFocus();
$timeout(function() {
$('#sample-template').trigger('chosen:updated');
}, 1000);
};
$scope.setFocus = function () {
$timeout(function() {
$("#name").focus();
}, 50);
};
$("#name").on('change', function() {
$timeout(function() {
$scope.stackName = $("#name").val();
$scope.checkRequiredInput();
});
});
$('#template-url').on('change', function(){
$timeout(function() {
$scope.checkRequiredInput();
$scope.templateIdent = $scope.templateUrl;
if ($scope.templateIdent !== undefined) {
$scope.getStackTemplateInfo();
}
});
});
$scope.setInitialValues = function () {
@@ -110,23 +116,31 @@ angular.module('StackWizard', ['TagEditor', 'EucaConsoleUtils'])
// Once invalid name has been entered, do not enable the button unless the name length is valid
$scope.isNotValid = true;
}
if ($scope.isNotValid === false) {
$scope.getStackTemplateInfo();
}
} else if ($scope.currentStepIndex == 2) {
$scope.isNotValid = false;
if ($scope.parametersObject === undefined) {
$scope.isNotValid = true;
}
angular.forEach($scope.parameters, function(param, idx) {
var val = $scope.paramModels[param.name];
if (val === undefined) {
$scope.isNotValid = true;
}
});
}
};
$scope.setWatcher = function () {
$scope.setWatchers = function () {
$scope.$watch('stackName', function(){
$scope.checkRequiredInput();
});
$scope.$watch('inputtype', function(){
$scope.checkRequiredInput();
});
$scope.$watch('templateSample', function(){
$scope.checkRequiredInput();
$scope.templateIdent = $scope.templateSample;
if ($scope.templateSample !== undefined) {
$scope.templateIdent = $scope.templateSample.label;
if ($scope.templateIdent !== undefined) {
$scope.getStackTemplateInfo();
}
}
});
$scope.$watch('currentStepIndex', function(){
$scope.setWizardFocus($scope.currentStepIndex);
@@ -222,35 +236,28 @@ angular.module('StackWizard', ['TagEditor', 'EucaConsoleUtils'])
var file = $scope.templateFiles[0];
fd.append('template-file', file);
}
$scope.loading = true;
$scope.description = '';
$http.post($scope.stackTemplateEndpoint, fd, {
headers: {'Content-Type': undefined},
transformRequest: angular.identity
}).
success(function(oData) {
var results = oData ? oData.results : '';
if (results) {
$scope.loading = false;
$scope.description = results.description;
$scope.parameters = results.parameters;
$timeout(function () {
$scope.updateParamSummary();
}, 100);
angular.forEach($scope.parameters, function(param, idx) {
$scope.paramModels[param.name] = param.default;
});
$scope.checkRequiredInput();
}
}).
error(function (oData, status) {
eucaHandleError(oData, status);
});
};
$scope.updateParamSummary = function() {
$scope.parametersObject = [];
angular.forEach($scope.parameters, function(param, idx) {
if (param.options === undefined) {
$scope.parametersObject.push({'name':param.name, 'value':$('input#'+param.name).val()});
}
else {
$scope.parametersObject.push({'name':param.name, 'value':$('select#'+param.name).val()});
}
});
};
})
;

Large diffs are not rendered by default.

@@ -0,0 +1,281 @@
/*! Copyright (c) 2011 by Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders
MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */

;(function ($, window, undefined) {
'use strict';

var name = 'stickyTableHeaders',
id = 0,
defaults = {
fixedOffset: 0,
leftOffset: 0,
marginTop: 0,
scrollableArea: window
};

function Plugin (el, options) {
// To avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this;

// Access to jQuery and DOM versions of element
base.$el = $(el);
base.el = el;
base.id = id++;
base.$window = $(window);
base.$document = $(document);

// Listen for destroyed, call teardown
base.$el.bind('destroyed',
$.proxy(base.teardown, base));

// Cache DOM refs for performance reasons
base.$clonedHeader = null;
base.$originalHeader = null;

// Keep track of state
base.isSticky = false;
base.hasBeenSticky = false;
base.leftOffset = null;
base.topOffset = null;

base.init = function () {
base.$el.each(function () {
var $this = $(this);

// remove padding on <table> to fix issue #7
$this.css('padding', 0);

base.$originalHeader = $('thead:first', this);
base.$clonedHeader = base.$originalHeader.clone();
$this.trigger('clonedHeader.' + name, [base.$clonedHeader]);

base.$clonedHeader.addClass('tableFloatingHeader');
base.$clonedHeader.css('display', 'none');

base.$originalHeader.addClass('tableFloatingHeaderOriginal');

base.$originalHeader.after(base.$clonedHeader);

base.$printStyle = $('<style type="text/css" media="print">' +
'.tableFloatingHeader{display:none !important;}' +
'.tableFloatingHeaderOriginal{position:static !important;}' +
'</style>');
$('head').append(base.$printStyle);
});

base.setOptions(options);
base.updateWidth();
base.toggleHeaders();
base.bind();
};

base.destroy = function (){
base.$el.unbind('destroyed', base.teardown);
base.teardown();
};

base.teardown = function(){
if (base.isSticky) {
base.$originalHeader.css('position', 'static');
}
$.removeData(base.el, 'plugin_' + name);
base.unbind();

base.$clonedHeader.remove();
base.$originalHeader.removeClass('tableFloatingHeaderOriginal');
base.$originalHeader.css('visibility', 'visible');
base.$printStyle.remove();

base.el = null;
base.$el = null;
};

base.bind = function(){
base.$scrollableArea.on('scroll.' + name, base.toggleHeaders);
if (!base.isWindowScrolling) {
base.$window.on('scroll.' + name + base.id, base.setPositionValues);
base.$window.on('resize.' + name + base.id, base.toggleHeaders);
}
base.$scrollableArea.on('resize.' + name, base.toggleHeaders);
base.$scrollableArea.on('resize.' + name, base.updateWidth);
};

base.unbind = function(){
// unbind window events by specifying handle so we don't remove too much
base.$scrollableArea.off('.' + name, base.toggleHeaders);
if (!base.isWindowScrolling) {
base.$window.off('.' + name + base.id, base.setPositionValues);
base.$window.off('.' + name + base.id, base.toggleHeaders);
}
base.$scrollableArea.off('.' + name, base.updateWidth);
};

base.toggleHeaders = function () {
if (base.$el) {
base.$el.each(function () {
var $this = $(this),
newLeft,
newTopOffset = base.isWindowScrolling ? (
isNaN(base.options.fixedOffset) ?
base.options.fixedOffset.outerHeight() :
base.options.fixedOffset
) :
base.$scrollableArea.offset().top + (!isNaN(base.options.fixedOffset) ? base.options.fixedOffset : 0),
offset = $this.offset(),

scrollTop = base.$scrollableArea.scrollTop() + newTopOffset,
scrollLeft = base.$scrollableArea.scrollLeft(),

scrolledPastTop = base.isWindowScrolling ?
scrollTop > offset.top :
newTopOffset > offset.top,
notScrolledPastBottom = (base.isWindowScrolling ? scrollTop : 0) <
(offset.top + $this.height() - base.$clonedHeader.height() - (base.isWindowScrolling ? 0 : newTopOffset));

if (scrolledPastTop && notScrolledPastBottom) {
newLeft = offset.left - scrollLeft + base.options.leftOffset;
base.$originalHeader.css({
'position': 'fixed',
'margin-top': base.options.marginTop,
'left': newLeft,
'z-index': 3 // #18: opacity bug
});
base.leftOffset = newLeft;
base.topOffset = newTopOffset;
base.$clonedHeader.css('display', '');
if (!base.isSticky) {
base.isSticky = true;
// make sure the width is correct: the user might have resized the browser while in static mode
base.updateWidth();
}
base.setPositionValues();
} else if (base.isSticky) {
base.$originalHeader.css('position', 'static');
base.$clonedHeader.css('display', 'none');
base.isSticky = false;
base.resetWidth($('td,th', base.$clonedHeader), $('td,th', base.$originalHeader));
}
});
}
};

base.setPositionValues = function () {
var winScrollTop = base.$window.scrollTop(),
winScrollLeft = base.$window.scrollLeft();
if (!base.isSticky ||
winScrollTop < 0 || winScrollTop + base.$window.height() > base.$document.height() ||
winScrollLeft < 0 || winScrollLeft + base.$window.width() > base.$document.width()) {
return;
}
base.$originalHeader.css({
'top': base.topOffset - (base.isWindowScrolling ? 0 : winScrollTop),
'left': base.leftOffset - (base.isWindowScrolling ? 0 : winScrollLeft)
});
};

base.updateWidth = function () {
if (!base.isSticky) {
return;
}
// Copy cell widths from clone
if (!base.$originalHeaderCells) {
base.$originalHeaderCells = $('th,td', base.$originalHeader);
}
if (!base.$clonedHeaderCells) {
base.$clonedHeaderCells = $('th,td', base.$clonedHeader);
}
var cellWidths = base.getWidth(base.$clonedHeaderCells);
base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells);

// Copy row width from whole table
base.$originalHeader.css('width', base.$clonedHeader.width());
};

base.getWidth = function ($clonedHeaders) {
var widths = [];
$clonedHeaders.each(function (index) {
var width, $this = $(this);

if ($this.css('box-sizing') === 'border-box') {
width = $this[0].getBoundingClientRect().width; // #39: border-box bug
} else {
var $origTh = $('th', base.$originalHeader);
if ($origTh.css('border-collapse') === 'collapse') {
if (window.getComputedStyle) {
width = parseFloat(window.getComputedStyle(this, null).width);
} else {
// ie8 only
var leftPadding = parseFloat($this.css('padding-left'));
var rightPadding = parseFloat($this.css('padding-right'));
// Needs more investigation - this is assuming constant border around this cell and it's neighbours.
var border = parseFloat($this.css('border-width'));
width = $this.outerWidth() - leftPadding - rightPadding - border;
}
} else {
width = $this.width();
}
}

widths[index] = width;
});
return widths;
};

base.setWidth = function (widths, $clonedHeaders, $origHeaders) {
$clonedHeaders.each(function (index) {
var width = widths[index];
$origHeaders.eq(index).css({
'min-width': width,
'max-width': width
});
});
};

base.resetWidth = function ($clonedHeaders, $origHeaders) {
$clonedHeaders.each(function (index) {
var $this = $(this);
$origHeaders.eq(index).css({
'min-width': $this.css('min-width'),
'max-width': $this.css('max-width')
});
});
};

base.setOptions = function (options) {
base.options = $.extend({}, defaults, options);
base.$scrollableArea = $(base.options.scrollableArea);
base.isWindowScrolling = base.$scrollableArea[0] === window;
};

base.updateOptions = function (options) {
base.setOptions(options);
// scrollableArea might have changed
base.unbind();
base.bind();
base.updateWidth();
base.toggleHeaders();
};

// Run initializer
base.init();
}

// A plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[name] = function ( options ) {
return this.each(function () {
var instance = $.data(this, 'plugin_' + name);
if (instance) {
if (typeof options === 'string') {
instance[options].apply(instance);
} else {
instance.updateOptions(options);
}
} else if(options !== 'destroy') {
$.data(this, 'plugin_' + name, new Plugin( this, options ));
}
});
};

})(jQuery, window);
@@ -146,7 +146,7 @@ h1, h2, h3, h4, h5, h6 {
// Logo bar (top-most bar)
#logobar {
height: 44px;
padding: 5px 0 10px 15px;
padding: 5px 0 10px 0;
margin-top: 20px;
background-color: #fff;
color: #333;
@@ -186,16 +186,16 @@ h1, h2, h3, h4, h5, h6 {
position: relative;
top: -10px;
}
.menu-label {
display: block;
position: relative;
top: -25px;
}
#logo {
display: inline-block;
width: 199px; height: 55px;
width: 199px; height: 32px;
background: url(../img/eucalogo-199x22.png) no-repeat;
}
.product-name {
font-size: 1.4rem;
position: relative;
top: -12px;
}
#selected-region {
position: relative;
display: inline-block;
@@ -209,6 +209,7 @@ h1, h2, h3, h4, h5, h6 {
}
}
#offcanvas-icon {
left: -1000px;
display: none;
margin-right: 12px;
i {
@@ -1086,6 +1087,7 @@ footer {
top: 4px;
}
#offcanvas-icon {
left: 0px;
display: inline-block !important;
margin-right: 12px;
}
@@ -1099,6 +1101,65 @@ footer {
}
}

// On-canvas Nav adjustments
#nav-drop ul {
list-style-type: none;
.dropdown {
margin-bottom: 0.5rem;
}
li {
a {
padding: 0.125rem;
}
}
}

// Off-canvas Nav adjustments
div.left-off-canvas-menu {
z-index: 999999 !important;
color: white;
background-color: white;
border-style: solid;
border-width: 0 1px 0 0;
border-color: $euca-grey;
}

ul.off-canvas-list {
padding-left: 0.5rem;
li {
label {
background-color: white;
color: $euca-grey;
padding-left: 0.5rem;
border-top: 0;
}
a {
background-color: white;
color: $euca-grey;
padding: 0.5rem;
border-bottom: 0;
label {
background-color: white;
color: $euca-grey;
padding-left: 0.5rem;
border-top: 0;
}
}
a:hover:not(.nolink) {
background-color: lighten($euca-grey, 50%);
color: black;
}
a.nolink:hover {
background-color: white;
color: $euca-grey;
}
.dropdown {
background-color: white;
margin-bottom: 0;
}
}
}

/* Responsive tweaks for landing page title */
@media screen and (max-width: $row-width) {
#pagetitle.landingpage {
@@ -91,7 +91,7 @@ $tile-row-height: 24px;
}
}
.dropdown.button.tiny {
z-index: 99999;
z-index: 99998;
background: none;
box-shadow: none;
position: absolute;
@@ -150,6 +150,7 @@ $tile-row-height: 24px;
#instances-running .icon { background-image: url(../../img/svg/icon_running_instances.svg); }
#instances-stopped .icon { background-image: url(../../img/svg/icon_stopped_instances.svg); }
#scaling-groups .icon { background-image: url(../../img/svg/icon_instances_scaling_groups.svg); }
#stacks .icon { background-image: url(../../img/svg/icon_cloud_formation.svg); }
#elastic-ips .icon { background-image: url(../../img/svg/icon_elastic_IP.svg); }
#volumes .icon { background-image: url(../../img/svg/icon_volumes.svg); }
#snapshots .icon { background-image: url(../../img/svg/icon_snapshot.svg); }
@@ -7,3 +7,12 @@
padding-right: 10px;
}

.panel {
overflow: hidden;
min-height: 400px;
}

label {
font-weight: bold;
color: $euca-grey;
}
@@ -36,11 +36,22 @@
line-height: 1.375rem;
}

.param-name {
color: $euca-grey;
}

$template-indent: 1.5rem;

#sample-template {
margin-left: $template-indent;
width: 90%;
#sample-template-div {
.chosen-container {
margin-left: $template-indent;
margin-bottom: 0.75rem;
width: 90% !important;
}
}

.chosen-container {
width: 100%;
}

#template-file {
@@ -5,11 +5,11 @@
$stack-status-color-create-in-progress: lighten($euca-darkblue, 20%);
$stack-status-color-create-complete: $euca-darkblue;
$stack-status-color-create-failed: darkred;
$stack-status-color-rollback-in-progress: lighten(darkred, 20%);
$stack-status-color-rollback-complete: $euca-darkblue;
$stack-status-color-rollback-in-progress: $euca-grey;
$stack-status-color-rollback-complete: $euca-darkgrey;
$stack-status-color-rollback-failed: darkred;
$stack-status-color-delete-in-progress: darken($euca-grey, 10%);
$stack-status-color-delete-complete: $euca-darkblue;
$stack-status-color-delete-in-progress: $euca-grey;
$stack-status-color-delete-complete: $euca-darkgrey;
$stack-status-color-delete-failed: darkred;

// Stack status
@@ -5,25 +5,12 @@
detailpage_action request.route_path('elb_delete', id=elb.name) if elb else '';
action landingpage_action if landingpage else detailpage_action;">
<h3 i18n:translate="">Delete load balancer</h3>
<div ng-show="!!elbInUse" tal:condition="in_use if elb else True">
<p>
<span i18n:translate="">Load balancer</span>
<span tal:condition="elb" class="breakword"><b>${elb_name}</b></span>
<span tal:condition="not elb" class="breakword"><b>{{ elbName }}</b></span>
<span i18n:translate="">is in use and may not be deleted.</span>
</p>
<p i18n:translate="">
Change the load balancer from ??? detail page,
and then try to delete this load balancer again.
</p>
</div>
<p ng-show="!elbInUse" tal:condition="not in_use if elb else True">
<span i18n:translate="">Are you sure you want to delete the load balancer</span>
<p>
<span i18n:translate="">Are you sure you want to delete load balancer</span>
<span tal:condition="elb" class="breakword"><b>${elb_name}</b></span>
<span tal:condition="not elb" class="breakword"><b>{{ elbName }}</b></span>
?
<span tal:condition="not elb" class="breakword"><b>{{ elbName }}</b></span>?
</p>
<form action="${action}" method="post" ng-show="!elbInUse"
<form action="${action}" method="post"
tal:condition="not in_use if elb else True">
${structure:delete_form['csrf_token']}
<div tal:condition="landingpage" tal:omit-tag="">
@@ -33,10 +20,10 @@
<input type="hidden" name="name" value="${elb_name}" />
</div>
<div class="dialog-submit-button">
<button type="submit" id="delete_elb_submit_button" class="button expand" i18n:translate="">Yes, Delete</button>
<button type="submit" id="delete_elb_submit_button" class="button expand" i18n:translate="">Yes, Delete Load Balancer</button>
</div>
<div class="dialog-progress-display hide">
<span i18n:translate="">Sending request </span>&nbsp;<em><span class="busy">&nbsp;</span></em>
<span i18n:translate="">Sending request </span>&nbsp;<i class="busy"></i>
</div>
</form>
<a href="#" id="delete_elb_close_link" class="close-reveal-modal">&#215;</a>
@@ -131,8 +131,8 @@
<div tal:condition="not is_owned_by_user">
<div class="row controls-wrapper readonly">
<div class="small-12 columns value" ng-cloak="">
<span ng-show="isPublic">Public</span>
<span ng-hide="isPublic">Private</span>
<span ng-show="isPublic === true">Public</span>
<span ng-show="isPublic === false">Private</span>
</div>
</div>
</div>
@@ -141,25 +141,25 @@
<div class="small-12 columns value">
<div id="sharing-radio-buttons">
<span class="padded-element">
<input type="radio" name="sharing" value="true" ng-model="isPublic" /> Public
<input type="radio" name="sharing" ng-value="true" ng-model="isPublic" /> Public
</span>
<span class="padded-element">
<input type="radio" class="padded-element" name="sharing" value="false" ng-model="isPublic" /> Private
<input type="radio" class="padded-element" name="sharing" ng-value="false" ng-model="isPublic" /> Private
</span>
</div>
<div class="bottom-padding" ng-show="isPublic">
<div class="bottom-padding" ng-show="isPublic === true">
<span i18n:translate="">
Anyone can see this image.
</span>
</div>
<div class="bottom-padding" ng-hide="isPublic">
<div class="bottom-padding" ng-show="isPublic === false">
<span i18n:translate="">
Only my account and accounts I share with can see this image.
</span>
</div>
</div>
</div>
<div class="row controls-wrapper readonly" ng-hide="isPublic">
<div class="row controls-wrapper readonly" ng-show="isPublic === false">
<div id="private-account-input-field" class="small-12 columns value" ng-class="errorClass">
<div class="subsection-label top-bottom-padding" ng-show="launchPermissions.length > 0">
<span i18n:translate="">
@@ -62,22 +62,22 @@
<p class="description" i18n:translate="">
Specify the number, name(s), size, availability zone, and tags.
</p>
${panel('form_field', field=launch_form['number'], leftcol_width=3, rightcol_width=9, min=1, max=10, maxlength=2, ng_attrs={'model': 'instanceNumber'}, pattern=layout.integer_gt_zero_pattern)}
${panel('form_field', field=launch_form['number'], leftcol_width=3, rightcol_width=9, leftcol_width_large=3, rightcol_width_large=9, min=1, max=10, maxlength=2, ng_attrs={'model': 'instanceNumber'}, pattern=layout.integer_gt_zero_pattern)}
<div class="row controls-wrapper" ng-cloak="">
<div class="small-3 columns">
<div class="large-3 small-3 columns">
<label>
<span i18n:translate="">Name</span><span ng-show="instanceNumber > 1">s</span>
</label>
</div>
<div class="small-9 columns field inline">
<div class="large-9 small-9 columns field inline">
<span ng-repeat="name in buildNumberList()">
<input class="name" placeholder="instance{{ $index + 1 }}"
name="name_{{ $index }}" ng-model="instanceNames[$index]" />
</span>
</div>
</div>
${panel('form_field', field=launch_form['instance_type'], leftcol_width=3, rightcol_width=9, ng_attrs={'model': 'instanceType'})}
${panel('form_field', field=launch_form['zone'], leftcol_width=3, rightcol_width=9, ng_attrs={'model': 'instanceZone'})}
${panel('form_field', field=launch_form['instance_type'], leftcol_width=3, rightcol_width=9, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'instanceType'})}
${panel('form_field', field=launch_form['zone'], leftcol_width=3, rightcol_width=9, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'instanceZone'})}
<hr />
${panel('tag_editor', show_name_tag=False, leftcol_width=3, rightcol_width=9)}
<hr />
@@ -107,35 +107,35 @@
<p class="description" i18n:translate="">Specify key pair and security group.</p>
</div>
<div tal:condition="is_vpc_supported">
${panel('form_field', field=launch_form['vpc_network'], ng_attrs={'model': 'instanceVPC'}, leftcol_width=4, rightcol_width=8)}
${panel('form_field', field=launch_form['vpc_network'], ng_attrs={'model': 'instanceVPC'}, leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9)}
<div ng-show="instanceVPC != 'None'">
${panel('form_field', field=launch_form['vpc_subnet'], leftcol_width=4, rightcol_width=8, ng_attrs={'model': 'subnetVPC', 'options': 'k as v for (k, v) in vpcSubnetChoices'})}
<span id="hidden_vpc_subnet_empty_option" class="hide" i18n:translate="">No subnets found</span>
${panel('form_field', field=launch_form['associate_public_ip_address'], leftcol_width=4, rightcol_width=8)}
</div>
</div>
${panel('form_field', field=launch_form['keypair'], leftcol_width=4, rightcol_width=8, ng_attrs={'model': 'keyPair', 'options': 'k as v for (k, v) in keyPairChoices'})}
${panel('form_field', field=launch_form['keypair'], leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'keyPair', 'options': 'k as v for (k, v) in keyPairChoices'})}
<div class="row">
<div class="small-8 columns right" id="create-keypair-link">
<div class="large-9 small-8 columns right" id="create-keypair-link">
<span class="or" i18n:translate="">Or: </span>
<a ng-click="showCreateKeypairModal()" i18n:translate="">Create key pair</a>
</div>
</div>
${panel('form_field', field=launch_form['securitygroup'], leftcol_width=4, rightcol_width=8, ng_attrs={'model': 'securityGroups', 'options': 'k as v for (k, v) in securityGroupChoices'}, **security_group_attrs)}
${panel('form_field', field=launch_form['securitygroup'], leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'securityGroups', 'options': 'k as v for (k, v) in securityGroupChoices'}, **security_group_attrs)}
<div class="row">
<div class="small-8 columns right" id="create-securitygroup-link">
<div class="large-9 small-8 columns right" id="create-securitygroup-link">
<span class="or" i18n:translate="">Or: </span>
<a data-reveal-id="create-securitygroup-modal" i18n:translate="">Create security group</a>
</div>
</div>
${panel('securitygroup_rules_preview', leftcol_width=4, rightcol_width=8)}
${panel('securitygroup_rules_preview', leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9)}
<hr />
<p class="description" i18n:translate="">Specify an IAM role if you would like to give this instance special access privileges.</p>
<div class="row">
<div class="small-4 columns">
<div class="large-3 small-4 columns">
<label class="right" i18n:translate="">Role</label>
</div>
<div class="small-8 columns field">
<div class="large-9 small-8 columns field">
<select id="role" ng-options="k as v for (k, v) in roleList" ng-model="role" name="role"></select>
</div>
</div>
@@ -147,8 +147,8 @@
</label>
</div>
<div class="row">
<div class="small-4 columns">&nbsp;</div>
<div class="small-8 columns field inline">
<div class="large-3 small-4 columns">&nbsp;</div>
<div class="large-9 small-8 columns field inline">
<button type="submit" class="button" ng-click="saveOptions()" id="launch-instance-btn-step3" ng-disabled="isNotValid">
<span i18n:translate="">Launch Instance<span ng-show="instanceNumber > 1">s</span></span>
</button>
@@ -167,10 +167,10 @@
User data and other advanced options (optional).
</p>
<div class="row controls-wrapper readonly">
<div class="small-4 columns">
<div class="large-3 small-4 columns">
<label i18n:translate="">User data<span class="helptext-icon" title="User data file may not exceed 16 KB" data-tooltip="">?</span></label>
</div>
<div class="small-8 columns value">
<div class="large-9 small-8 columns value">
<input type="radio" id="inputtype" name="inputtype" value="text" ng-model="inputtype"/>
<label id='userdatalabel' i18n:translate="">Enter text</label>
<textarea id="userdata" name="userdata" ng-show="inputtype=='text'"></textarea>
@@ -181,21 +181,21 @@

</div>
</div>
${panel('form_field', field=launch_form['kernel_id'])}
${panel('form_field', field=launch_form['ramdisk_id'])}
<div class="small-8 columns right">
${panel('form_field', field=launch_form['kernel_id'], leftcol_width_large=3, rightcol_width_large=9)}
${panel('form_field', field=launch_form['ramdisk_id'], leftcol_width_large=3, rightcol_width_large=9)}
<div class="large-9 small-8 columns right">
${structure:launch_form.monitoring_enabled(**{'ng-model': 'monitoringEnabled'})}
${launch_form['monitoring_enabled'].label}
</div>
<div class="small-8 columns right" tal:condition="layout.cloud_type == 'euca' and not is_vpc_supported">
<div class="large-9 small-8 columns right" tal:condition="layout.cloud_type == 'euca' and not is_vpc_supported">
${structure:launch_form.private_addressing(**{'ng-model': 'privateAddressing'})}
${launch_form['private_addressing'].label}
</div>
<hr/>
${panel('bdmapping_editor', image=image, snapshot_choices=snapshot_choices)}
<div class="row">
<div class="small-4 columns">&nbsp;</div>
<div class="small-8 columns field inline">
<div class="large-3 small-4 columns">&nbsp;</div>
<div class="large-9 small-8 columns field inline">
<button type="submit" class="button" ng-click="saveOptions()" id="launch-instance-btn-step4" ng-disabled="isNotValid">
<span i18n:translate="">Launch Instance</span><span ng-show="instanceNumber > 1">s</span>
</button>
@@ -135,7 +135,7 @@
<div tal:condition="not image" style="text-align:center;">
<strong style="color:red;" i18n:translate="">Image not found</strong>
</div>
<hr/>
<hr tal:condition="launch_config.block_device_mappings" />
${panel('bdmapping_editor', image=image, launch_config=launch_config, read_only=True)}
</form>
<div>&nbsp;</div>
@@ -63,9 +63,9 @@
<p class="description" i18n:translate="">
Please specify the launch configuration name and the instance size/type.
</p>
${panel('form_field', field=create_form['name'], leftcol_width=3, rightcol_width=9, ng_attrs={'model': 'launchconfigName'}, **html_attrs_val)}
${panel('form_field', field=create_form['name'], leftcol_width=3, rightcol_width=9, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'launchconfigName'}, **html_attrs_val)}
<div tal:condition="not preset">
${panel('form_field', field=create_form['instance_type'], leftcol_width=3, rightcol_width=9, ng_attrs={'model': 'instanceType'})}
${panel('form_field', field=create_form['instance_type'], leftcol_width=3, rightcol_width=9, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'instanceType'})}
</div>
<div tal:condition="preset" ng-cloak="true">
<div class="row">
@@ -99,52 +99,52 @@
Please specify your network and security settings.
</p>
<div tal:condition="is_vpc_supported">
${panel('form_field', field=create_form['associate_public_ip_address'], leftcol_width=4, rightcol_width=8)}
${panel('form_field', field=create_form['associate_public_ip_address'], leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9)}
</div>
<div tal:condition="not preset">
${panel('form_field', field=create_form['keypair'], leftcol_width=4, rightcol_width=8, ng_attrs={'model': 'keyPair', 'options': 'k as v for (k, v) in keyPairChoices'})}
${panel('form_field', field=create_form['keypair'], leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'keyPair', 'options': 'k as v for (k, v) in keyPairChoices'})}
<div class="row">
<div class="small-8 columns right" id="create-keypair-link">
<div class="large-9 small-8 columns right" id="create-keypair-link">
<span class="or" i18n:translate="">Or: </span>
<a ng-click="showCreateKeypairModal()" i18n:translate="">Create key pair</a>
</div>
</div>
</div>
<div tal:condition="preset" ng-cloak="true">
<div class="row">
<div class="small-4 columns"><label class="right">Key pair&nbsp;</label></div>
<div class="small-8 columns field inline">{{ keyPairSelected || 'none' }}</div>
<div class="large-3 small-4 columns"><label class="right">Key pair&nbsp;</label></div>
<div class="large-9 small-8 columns field inline">{{ keyPairSelected || 'none' }}</div>
<input type="hidden" name="keypair" value="{{ keyPairSelected || 'none' }}" />
</div>
</div>
<div tal:condition="not preset">
${panel('form_field', field=create_form['securitygroup'], leftcol_width=4, rightcol_width=8, ng_attrs={'model': 'securityGroups', 'options': 'k as v for (k, v) in securityGroupChoices'}, **security_group_attrs)}
${panel('form_field', field=create_form['securitygroup'], leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'securityGroups', 'options': 'k as v for (k, v) in securityGroupChoices'}, **security_group_attrs)}
<div class="row">
<div class="small-8 columns right" id="create-securitygroup-link">
<div class="large-9 small-8 columns right" id="create-securitygroup-link">
<span class="or" i18n:translate="">Or: </span>
<a data-reveal-id="create-securitygroup-modal" i18n:translate="">Create security group</a>
</div>
</div>
</div>
<div tal:condition="preset" ng-cloak="true">
<div class="row">
<div class="small-4 columns"><label class="right">Security group&nbsp;</label></div>
<div class="small-8 columns field inline" ng-repeat="sgroup in securityGroups">
<div class="large-3 small-4 columns"><label class="right">Security group&nbsp;</label></div>
<div class="large-9 small-8 columns field inline" ng-repeat="sgroup in securityGroups">
{{ securityGroupChoices[sgroup] }}
</div>
</div>
<div ng-repeat="sGroup in securityGroups" class="hide">
<input type="hidden" name="securitygroup" value="{{ sGroup }}" />
</div>
</div>
${panel('securitygroup_rules_preview', leftcol_width=4, rightcol_width=8)}
${panel('securitygroup_rules_preview', leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9)}
<hr />
<p class="description" i18n:translate="">Specify an IAM role if you would like to give this instance special access privileges.</p>
<div class="row">
<div class="small-4 columns">
<div class="large-3 small-4 columns">
<label class="right" i18n:translate="">Role</label>
</div>
<div class="small-8 columns field">
<div class="large-9 small-8 columns field">
<select id="role" ng-options="k as v for (k, v) in roleList" ng-model="role" name="role"></select>
</div>
</div>
@@ -156,8 +156,8 @@
</label>
</div>
<div class="row">
<div class="small-4 columns">&nbsp;</div>
<div class="small-8 columns field inline">
<div class="large-3 small-4 columns">&nbsp;</div>
<div class="large-9 small-8 columns field inline">
${structure:create_form.create_sg_from_lc(**{'ng-model': 'isCreateSGChecked'})}
${structure:create_form['create_sg_from_lc'].label}
<button type="submit" class="button" ng-click="saveOptions()" id="create-launchconfig-btn-step3" ng-disabled="isNotValid">
@@ -179,10 +179,10 @@
Please specify user data and other advanced options (optional).
</p>
<div class="row controls-wrapper readonly">
<div class="small-4 columns">
<div class="large-3 large-3 small-4 columns">
<label i18n:translate="">User data<span class="helptext-icon" title="User data file may not exceed 16 KB" data-tooltip="">?</span></label>
</div>
<div class="small-8 columns value">
<div class="large-9 small-8 columns value">
<input type="radio" id="inputtype" name="inputtype" value="text" ng-model="inputtype"/>
<label id='userdatalabel' i18n:translate="">Enter text</label>
<textarea id="userdata" name="userdata" ng-show="inputtype=='text'"></textarea>
@@ -193,17 +193,17 @@

</div>
</div>
${panel('form_field', field=create_form['kernel_id'])}
${panel('form_field', field=create_form['ramdisk_id'])}
<div class="small-8 columns right">
${panel('form_field', field=create_form['kernel_id'], leftcol_width_large=3, rightcol_width_large=9)}
${panel('form_field', field=create_form['ramdisk_id'], leftcol_width_large=3, rightcol_width_large=9)}
<div class="large-9 small-8 columns right">
${structure:create_form.monitoring_enabled(**{'ng-model': 'monitoringEnabled'})}
${structure:create_form.monitoring_enabled.label}
</div>
<hr/>
${panel('bdmapping_editor', image=image, snapshot_choices=snapshot_choices, disable_dot=True)}
<div class="row">
<div class="small-4 columns">&nbsp;</div>
<div class="small-8 columns field inline">
<div class="large-3 small-4 columns">&nbsp;</div>
<div class="large-9 small-8 columns field inline">
<input id="create_sg_from_lc_slave" type="checkbox" ng-model="isCreateSGChecked" />
<label i18n:translate="">Create scaling group using this launch configuration</label>
<button type="submit" class="button" ng-click="saveOptions()" id="create-launchconfig-btn-step4" ng-disabled="isNotValid">
@@ -14,7 +14,7 @@
</metal:breadcrumbs>
<!-- Notifications -->
<metal:block metal:use-macro="layout.global_macros['notifications']" />
<h3 id="pagetitle"><strong i18n:translate="">Launch configuration</strong></h3>
<h3 id="pagetitle"><strong i18n:translate="">Launch configurations</strong></h3>
<div metal:use-macro="layout.global_macros['landing_page_datagrid']">
<div metal:fill-slot="new_button">
<a class="button" i18n:translate="" id="create-launchconfig-btn"
@@ -37,9 +37,10 @@
<a class="left-off-canvas-toggle" id="offcanvas-icon"
tal:condition="request.user.is_authenticated()">
<i class="fi-list"></i>
<span class="menu-label" i18n:translate="">Menu</span>
</a>
<a id="logo" href="${layout.home_url}" title="${layout.site_title}"></a>
<a href="${layout.home_url}" title="${layout.site_title}">
<span class="product-name">HP Helion Eucalyptus</span>
</a>
<section tal:condition="request.user.is_authenticated()" id="user-dropdown-section">
<a href="#" data-dropdown="user-dropdown" class="small secondary dropdown">
<span class="${layout.cloud_type} username-label">${layout.username_label}</span>
@@ -65,7 +65,7 @@
</div>
<div class="row" id="new-blockdevice-entry" tal:condition="not read_only">
<div class="medium-2 columns">
<label class="left" i18n:translate="">Volume</label><br/>
<label i18n:translate="">Volume</label>
<select name="volume_type" ng-model="newVolumeType">
<option value="EBS">EBS</option>
<!--! There can be only one ephemeral device in Eucalyptus -->
@@ -76,17 +76,17 @@
</select>
</div>
<div class="medium-2 columns">
<label class="left" i18n:translate="">Mapping</label><br/>
<label i18n:translate="">Mapping</label>
<input type="text" name="path" id="new-mapping-path" ng-model="newMappingPath" />
</div>
<div class="medium-4 columns" ng-show="newVolumeType !== 'ephemeral'">
<label class="left" i18n:translate="">Create from snapshot</label><br/>
<label i18n:translate="">Create from snapshot</label>
<select name="snapshot_id" ng-model="newSnapshotID">
<option tal:repeat="choice snapshot_choices" value="${choice[0]}">${choice[1]}</option>
</select>
</div>
<div class="medium-1 columns" ng-show="newVolumeType !== 'ephemeral'">
<label class="left" i18n:translate="">Size</label><br/>
<label i18n:translate="">Size</label>
<input class="number" id="new-size" ng-model="newSize" />
</div>
<div class="medium-3 columns" ng-show="newVolumeType !== 'ephemeral'">
@@ -3,8 +3,8 @@
<div ng-repeat="groupID in securityGroups" ng-init="isRuleExpanded[groupID] = false;">
<div ng-show="selectedGroupRules[groupID].length > 0 &amp;&amp; selectedGroupRules[groupID][0].ip_protocol != '-1'">
<div class="row">
<div class="small-${leftcol_width} columns">&nbsp;</div>
<div class="small-${rightcol_width} columns rules-title">
<div class="large-${leftcol_width_large} small-${leftcol_width} columns">&nbsp;</div>
<div class="large-${rightcol_width_large} small-${rightcol_width} columns rules-title">
<a ng-click="isRuleExpanded[groupID] = !isRuleExpanded[groupID]">
<i class="fi-plus" ng-show="!isRuleExpanded[groupID]"></i>
<i class="fi-minus" ng-show="isRuleExpanded[groupID]"></i>
@@ -17,13 +17,13 @@
</div>
<div class="row controls-wrapper rules-display" ng-repeat="rule in selectedGroupRules[groupID] | filter: {rule_type: 'inbound'}" ng-show="isRuleExpanded[groupID]">
<div ng-if="$first">
<div class="small-${leftcol_width} columns">&nbsp;</div>
<div class="small-${rightcol_width} columns rules-title">
<div class="large-${leftcol_width_large} small-${leftcol_width} columns">&nbsp;</div>
<div class="large-${rightcol_width_large} small-${rightcol_width} columns rules-title">
<span id="security-group-rule-type" i18n:translate="">Inbound:</span>
</div>
</div>
<div class="small-${leftcol_width} columns">&nbsp;</div>
<div class="small-${rightcol_width} columns">
<div class="large-${leftcol_width_large} small-${leftcol_width} columns">&nbsp;</div>
<div class="large-${rightcol_width_large} small-${rightcol_width} columns">
<strong i18n:translate="">Rule</strong>:
{{ rule.ip_protocol.toUpperCase() }}
({{ rule.from_port }}<span ng-show="rule.to_port != rule.from_port"> - {{ rule.to_port }}</span>)
@@ -35,13 +35,13 @@
</div>
<div class="row controls-wrapper rules-display" ng-repeat="rule in selectedGroupRules[groupID] | filter: {rule_type: 'outbound'}" ng-show="isRuleExpanded[groupID]">
<div ng-if="$first">
<div class="small-${leftcol_width} columns">&nbsp;</div>
<div class="small-${rightcol_width} columns rules-title">
<div class="large-${leftcol_width_large} small-${leftcol_width} columns">&nbsp;</div>
<div class="large-${rightcol_width_large} small-${rightcol_width} columns rules-title">
<span id="security-group-rule-type" i18n:translate="">Outbound:</span>
</div>
</div>
<div class="small-${leftcol_width} columns">&nbsp;</div>
<div class="small-${rightcol_width} columns">
<div class="large-${leftcol_width_large} small-${leftcol_width} columns">&nbsp;</div>
<div class="large-${rightcol_width_large} small-${rightcol_width} columns">
<strong i18n:translate="">Rule</strong>:
{{ rule.ip_protocol.toUpperCase() }}
({{ rule.from_port }}<span ng-show="rule.to_port != rule.from_port"> - {{ rule.to_port }}</span>)
@@ -54,8 +54,8 @@
</div>
<div ng-show="selectedGroupRules[groupID].length === 0 || selectedGroupRules[groupID][0].ip_protocol == '-1'">
<div class="row">
<div class="small-${leftcol_width} columns">&nbsp;</div>
<div class="small-${rightcol_width} columns rules-title">
<div class="large-${leftcol_width_large} small-${leftcol_width} columns">&nbsp;</div>
<div class="large-${rightcol_width_large} small-${rightcol_width} columns rules-title">
<a ng-click="isRuleExpanded[groupID] = !isRuleExpanded[groupID]">
<i class="fi-plus" ng-show="!isRuleExpanded[groupID]"></i>
<i class="fi-minus" ng-show="isRuleExpanded[groupID]"></i>
@@ -69,8 +69,8 @@
</div>
</div>
<div class="row rules-display" ng-show="isRuleExpanded[groupID]">
<div class="small-${leftcol_width} columns">&nbsp;</div>
<div class="small-${rightcol_width} columns rules-title">
<div class="large-${leftcol_width_large} small-${leftcol_width} columns">&nbsp;</div>
<div class="large-${rightcol_width_large} small-${rightcol_width} columns rules-title">
<p class="normal-word-break">
<strong i18n:translate="">WARNING: </strong>
<span i18n:translate="">
@@ -1,71 +1,64 @@
<!-- top nav links (reused in off-canvas menu) -->
<ul class="resources-nav left-align ${'off-canvas-list' if off_canvas else ''}" i18n:domain="eucaconsole" >
<li><a id="resource-menu-dashboard" class="lnk-dashboard" i18n:translate=""
href="${request.route_path('dashboard')}">Dashboard</a></li>
<li><a id="resource-menu-images" href="${request.route_path('images')}" i18n:translate="">Images</a></li>
<li tal:condition="not layout.account_access">
<a id="resource-menuitem-instances" href="${request.route_path('instances')}" i18n:translate="">Instances</a>
</li>
<ul class="resources-nav left-align ${'off-canvas-list' if off_canvas else ''}" i18n:domain="eucaconsole">
<li><a id="resource-menu-dashboard" class="lnk-dashboard"
href="${request.route_path('dashboard')}" i18n:translate="">DASHBOARD</a></li>
<li><a id="resource-menu-images" class="lnk-dashboard"
href="${request.route_path('images')}" i18n:translate="">IMAGES</a></li>
<li class="has-dropdown" tal:condition="layout.account_access">
<a id="resource-menu-instances" i18n:translate="">Instances</a>
<a id="resource-menu-instances" class="nolink" i18n:translate="">INSTANCES</a>
<ul class="dropdown">
<li><a id="resource-menuitem-instances" i18n:translate=""
href="${request.route_path('instances')}">Instances</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li><a id="resource-menuitem-instance-types" i18n:translate=""
href="${request.route_path('instance_types')}">Instance Types</a></li>
<li tal:condition="layout.account_access">
<a id="resource-menuitem-instance-types" i18n:translate=""
href="${request.route_path('instance_types')}">Instance types</a>
</li>
</ul>
</li>
<li tal:condition="not layout.account_access">
<a id="resource-menuitem-instances" i18n:translate="" href="${request.route_path('instances')}">INSTANCES</a>
</li>
<li class="has-dropdown">
<a id="resource-menu-instances" i18n:translate="">CloudFormation</a>
<a id="resource-menu-instances" class="nolink" i18n:translate="">CLOUDFORMATION</a>
<ul class="dropdown">
<li><a id="resource-menuitem-instances" i18n:translate=""
href="${request.route_path('stacks')}">Stacks</a></li>
</ul>
</li>
<li class="has-dropdown">
<a id="resource-menu-autoscaling" i18n:translate="">Auto Scaling</a>
<a id="resource-menu-netsec" class="nolink" i18n:translate="">NETWORK &amp; SECURITY</a>
<ul class="dropdown">
<li><a id="resource-menuitem-scalinggroups" i18n:translate=""
href="${request.route_path('scalinggroups')}">Scaling Groups</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li><a id="resource-menuitem-launchconfigs" i18n:translate=""
href="${request.route_path('launchconfigs')}">Launch Configurations</a></li>
<li><a id="resource-menuitem-eips" href="${request.route_path('ipaddresses')}" i18n:translate="">Elastic IP addresses</a></li>
<li><a id="resource-menuitem-securitygroups" i18n:translate=""
href="${request.route_path('securitygroups')}">Security groups</a></li>
<li><a id="resource-menuitem-elb" i18n:translate=""
href="${request.route_path('elbs')}">Load balancers</a></li>
<li><a id="resource-menuitem-keypairs" href="${request.route_path('keypairs')}" i18n:translate="">Key pairs</a></li>
</ul>
</li>
<li class="has-dropdown">
<a id="resource-menu-storage" i18n:translate="">Storage</a>
<a id="resource-menu-storage" class="nolink" i18n:translate="">STORAGE</a>
<ul class="dropdown">
<li><a id="resource-menuitem-volumes" href="${request.route_path('volumes')}" i18n:translate="">Volumes</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li><a id="resource-menuitem-snapshots" href="${request.route_path('snapshots')}" i18n:translate="">Snapshots</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li><a id="resource-menuitem-buckets" href="${request.route_path('buckets')}" i18n:translate="">Buckets (S3)</a></li>
</ul>
</li>
<li class="has-dropdown">
<a id="resource-menu-netsec" i18n:translate="">Network &amp; Security</a>
<a id="resource-menu-autoscaling" class="nolink" i18n:translate="">AUTO SCALING</a>
<ul class="dropdown">
<li><a id="resource-menuitem-eips" href="${request.route_path('ipaddresses')}" i18n:translate="">Elastic IPs</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li><a id="resource-menuitem-securitygroups" i18n:translate=""
href="${request.route_path('securitygroups')}">Security Groups</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li><a id="resource-menuitem-elb" i18n:translate=""
href="${request.route_path('elbs')}">Load Balancers</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li><a id="resource-menuitem-keypairs" href="${request.route_path('keypairs')}" i18n:translate="">Key Pairs</a></li>
<li><a id="resource-menuitem-scalinggroups" i18n:translate=""
href="${request.route_path('scalinggroups')}">Auto scaling groups</a></li>
<li><a id="resource-menuitem-launchconfigs" i18n:translate=""
href="${request.route_path('launchconfigs')}">Launch configurations</a></li>
</ul>
</li>
<li class="has-dropdown" tal:condition="layout.user_access or layout.group_access or layout.role_access">
<a id="resource-menu-iam" i18n:translate="">Identity &amp; Access</a>
<a id="resource-menu-iam" class="nolink" i18n:translate="">IDENTITY &amp; ACCESS</a>
<ul class="dropdown">
<li tal:condition="layout.account_access"><a id="resource-menuitem-users" href="${request.route_path('accounts')}" i18n:translate="">Accounts</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li tal:condition="layout.user_access"><a id="resource-menuitem-users" href="${request.route_path('users')}" i18n:translate="">Users</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li tal:condition="layout.group_access"><a id="resource-menuitem-groups" href="${request.route_path('groups')}" i18n:translate="">Groups</a></li>
<li class="divider" tal:condition="not off_canvas"></li>
<li tal:condition="layout.role_access"><a id="resource-menuitem-roles" href="${request.route_path('roles')}" i18n:translate="">Roles</a></li>
</ul>
</li>
@@ -40,23 +40,23 @@
<div class="content active" id="step1"
tal:define="html_attrs_val {'pattern': '^[^\/\\\]{1,255}$'};
vpc_subnet_html_attrs {'data-placeholder': vpc_subnet_placeholder_text};">
${panel('form_field', field=create_form['name'], ng_attrs={'model': 'scalingGroupName'}, **html_attrs_val)}
${panel('form_field', field=create_form['name'], leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'scalingGroupName'}, **html_attrs_val)}
<div tal:condition="launch_config_param">
<input type="hidden" id="hidden_launch_config_input" name="launch_config" value="${launch_config_param}" />
<div class="row controls-wrapper">
<div class="small-4 columns">
<div class="large-3 small-4 columns">
<label class="right" i18n:translate="">Launch configuration</label>
</div>
<div class="small-8 columns launchconfig-value">${launch_config_param}</div>
<div class="large-9 small-8 columns launchconfig-value">${launch_config_param}</div>
</div>
</div>
<div tal:condition="not launch_config_param">
${panel('form_field', field=create_form['launch_config'], ng_attrs={'model': 'launchConfig'})}
${panel('form_field', field=create_form['launch_config'], leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'launchConfig'})}
</div>
<div tal:condition="is_vpc_supported">
${panel('form_field', field=create_form['vpc_network'], ng_attrs={'model': 'vpcNetwork'}, leftcol_width=4, rightcol_width=8)}
${panel('form_field', field=create_form['vpc_network'], leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'vpcNetwork'}, leftcol_width=4, rightcol_width=8)}
<div ng-show="vpcNetwork != '' &amp;&amp; vpcNetwork != 'None'">
${panel('form_field', field=create_form['vpc_subnet'], leftcol_width=4, rightcol_width=8, ng_attrs={'model': 'vpcSubnets', 'options': 'k as v for (k, v) in vpcSubnetChoices'}, **vpc_subnet_html_attrs)}
${panel('form_field', field=create_form['vpc_subnet'], leftcol_width=4, rightcol_width=8, leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'vpcSubnets', 'options': 'k as v for (k, v) in vpcSubnetChoices'}, **vpc_subnet_html_attrs)}
<span id="vpc_subnet_empty_option" class="hide" i18n:translate="">No subnets found</span>
</div>
</div>
@@ -66,9 +66,9 @@
<h6 i18n:translate="">Capacity</h6>
</div>
<div class="medium-10 columns">
${panel('form_field', field=create_form['min_size'], maxlength=2, ng_attrs={'model': 'minSize', 'change': 'handleSizeChange()'})}
${panel('form_field', field=create_form['desired_capacity'], maxlength=2, ng_attrs={'model': 'desiredCapacity', 'change': 'handleSizeChange()'})}
${panel('form_field', field=create_form['max_size'], maxlength=2, ng_attrs={'model': 'maxSize', 'change': 'handleSizeChange()'})}
${panel('form_field', field=create_form['min_size'], leftcol_width_large=6, rightcol_width_large=6, maxlength=2, ng_attrs={'model': 'minSize', 'change': 'handleSizeChange()'})}
${panel('form_field', field=create_form['desired_capacity'], leftcol_width_large=6, rightcol_width_large=6, maxlength=2, ng_attrs={'model': 'desiredCapacity', 'change': 'handleSizeChange()'})}
${panel('form_field', field=create_form['max_size'], leftcol_width_large=6, rightcol_width_large=6, maxlength=2, ng_attrs={'model': 'maxSize', 'change': 'handleSizeChange()'})}
</div>
</div>
<hr />
@@ -82,8 +82,8 @@
</div>
<div>&nbsp;</div>
<div class="row">
<div class="small-4 columns">&nbsp;</div>
<div class="small-8 columns field inline">
<div class="large-3 small-4 columns">&nbsp;</div>
<div class="large-9 small-8 columns field inline">
<a id="visit-step-2" class="button small round" ng-click="visitNextStep(2, $event)" ng-disabled="isNotValid">
<span i18n:translate="">Next</span>
<a class="cancel-link" href="${request.route_path('scalinggroups')}" i18n:translate="">Cancel</a>
@@ -94,12 +94,12 @@
<!--! Step 2: Membership tab content -->
<div class="content" id="step2" tal:define="avail_zones_attrs {'data-placeholder': avail_zones_placeholder_text};
load_balancers_html_attrs {'data-placeholder': elb_placeholder_text}">
${panel('form_field', field=create_form['health_check_type'], ng_attrs={'model': 'healthCheckType'})}
${panel('form_field', field=create_form['health_check_period'], ng_attrs={'model': 'healthCheckPeriod'}, step=30)}
${panel('form_field', field=create_form['health_check_type'], leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'healthCheckType'})}
${panel('form_field', field=create_form['health_check_period'], leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'healthCheckPeriod'}, step=30)}
<div ng-show="vpcNetwork == '' || vpcNetwork == 'None'">
${panel('form_field', field=create_form['availability_zones'], ng_attrs={'model': 'availZones'}, **avail_zones_attrs)}
${panel('form_field', field=create_form['availability_zones'], leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'availZones'}, **avail_zones_attrs)}
</div>
${panel('form_field', field=create_form['load_balancers'], ng_attrs={'model': 'loadBalancers'}, **load_balancers_html_attrs)}
${panel('form_field', field=create_form['load_balancers'], leftcol_width_large=3, rightcol_width_large=9, ng_attrs={'model': 'loadBalancers'}, **load_balancers_html_attrs)}
<div>&nbsp;</div>
<hr />
<div>
@@ -109,8 +109,8 @@
</label>
</div>
<div class="row">
<div class="small-4 columns">&nbsp;</div>
<div class="small-8 columns field inline">
<div class="large-3 small-4 columns">&nbsp;</div>
<div class="large-9 small-8 columns field inline">
<button type="submit" class="button" id="create-scalinggroup-btn" ng-disabled="isNotValid">
<span i18n:translate="">Create Scaling Group</span>
</button>