Commit 228b7d1e authored by Kostas Papadimitriou's avatar Kostas Papadimitriou
Browse files

ui: Initial refactoring for network view in vm wizard

parent 8bde1e82
......@@ -3246,7 +3246,7 @@ div.reboot-dialog button.details:hover {
}
.machine .info-content.ips .ips .port-ip-item {
padding: 4px;
padding: 6px;
margin-bottom: 2px;
}
......@@ -3268,6 +3268,7 @@ div.reboot-dialog button.details:hover {
.machine .info-content.ips .port {
width: 15%;
float: left;
margin-top: 9px;
}
.machine .info-content.ips .ips {
......@@ -3282,25 +3283,24 @@ div.reboot-dialog button.details:hover {
}
.machine .info-content.ips .port-item {
border-bottom: 1px solid #6F93A4;
padding: 5px 0;
margin-bottom: 5px;
border-bottom: 1px solid #75A9C1;
}
.machine .info-content.ips .port-item img {
float: left;
margin-top: 6px;
position: relative;
left: 4px;
margin-top: 10px;
margin-right: 3%;
}
.machine .info-content.ips .port-item .port {
font-weight: bold;
padding-top: 6px;
}
.machine .info-content.ips {
background-color: #84B7D0;
padding: 5px 10px;
padding: 0px 10px;
font-size: 0.6em;
}
......@@ -7212,3 +7212,77 @@ input.has-errors {
.model-rename-view .rename-actions .btn.cancel:hover {
background-image: url("../images/cancel-onhover.png");
}
.select-item input {
cursor: pointer;
}
.select-item {
font-size: 0.9em;
padding: 5px 4px;
margin-bottom: 3px;
background-color: #efefef;
cursor: pointer;
}
.select-item.selected {
background-color: #4085A5;
}
.select-item.selected * {
color: #fff;
}
.items-list.floating-ips {
margin-top: -5px;
}
.select-item.floating-ip.not-available {
background-image: none;
}
.select-item.floating-ip.create {
padding-left: 34px;
margin-bottom: 5px;
background-image: url("../images/option-action-add-dark.png");
background-repeat: no-repeat;
background-position: 9px 7px;
}
.select-item.floating-ip.selected * {
color: #222 !important;
font-weight: bold;
}
.select-item.floating-ip {
border-left: 10px solid #efefef;
background-color: #ddd;
margin-bottom: 0;
border-bottom: 1px solid #efefef;
}
.select-item.private-network .name {
float: left;
width: 50%;
}
.select-item.private-network .cidr {
float: left;
width: 40%;
}
.select-item .name {
float: left;
width: 90%;
}
.select-item .ico {
float: left;
width: 5%;
}
.select-item .checkbox {
float: left;
width: 5%;
}
......@@ -104,7 +104,7 @@
storage_attrs: {
'subnets': ['subnets', 'subnet', function(model, attr) {
var subnets = model.get(attr);
if (subnets.length) { return subnets[0] }
if (subnets && subnets.length) { return subnets[0] }
}]
},
......@@ -216,6 +216,16 @@
}
});
this.set({ports: this.ports});
this.floating_ips = synnefo.storage.floating_ips;
this.set({floating_ips: this.floating_ips});
this.available_floating_ips = new Backbone.FilteredCollection(undefined, {
collection: synnefo.storage.floating_ips,
collectionFilter: function(m) {
return !m.get('port_id');
}
});
this.set({available_floating_ips: this.available_floating_ips});
},
})
......
......@@ -1090,13 +1090,13 @@
this.fetcher = undefined;
if (this.update_collection) {
this.fetcher_params = [snf.config.update_interval,
snf.config.update_interval_increase || 500,
snf.config.fast_interval || snf.config.update_interval/2,
snf.config.update_interval_increase_after_calls || 4,
snf.config.update_interval_max || 20000,
true,
{is_recurrent: true, update: true}];
this.fetcher_params = [snf.config.update_interval,
snf.config.update_interval_increase || 500,
snf.config.fast_interval || snf.config.update_interval/2,
snf.config.update_interval_increase_after_calls || 4,
snf.config.update_interval_max || 20000,
true,
{is_recurrent: true, update: true}];
this.fetcher = this.collection.get_fetcher.apply(this.collection,
_.clone(this.fetcher_params));
this.fetcher.start();
......@@ -1179,67 +1179,17 @@
initialize: function() {
views.CreateNetworkingView.__super__.initialize.apply(this, arguments);
this.init_handlers();
this.ssh_list = this.$(".ssh ul");
this.selected_keys = [];
var self = this;
this.$(".create-ssh-key").click(function() {
var confirm_close = true;
if (confirm_close) {
snf.ui.main.public_keys_view.show(self.parent);
} else {
}
});
this.cont = this.$(".step-cont");
},
init_subviews: function() {
var create_view = this.parent;
if (!this.ips_view) {
this.ips_view = new views.CreateColumnSelectListView({
collection: synnefo.storage.floating_ips,
extra_class: 'public-ips',
update_collection: true,
title: 'IP addresses <span class="create-ip-address"><a href="#">manage ip\'s</a></span>',
description: 'Select IP addresses to be assigned to the created machine.',
item_cls: views.CreateColumnIPOptionView,
empty_msg: 'No IP addresses available. <span><a href="">Create a new IP address.</a></span>',
select_first_as_default: true,
filter_items: function(model) {
return !(model.get('port_id'))
},
init_events: function() {
var msg = this.$(".empty span a");
this.$(".empty a").bind('click', function(e) {
e.preventDefault();
msg.text("Creating...");
synnefo.storage.floating_ips.create({
address:undefined, pool: undefined
}, {
error: function() {
alert("Cannot create new ip address");
},
complete: function() {
msg.text("Create a new IP address.");
msg.show();
},
skip_api_error: true,
})
});
}
});
$(this.ips_view.el).appendTo(this.$(".personalize-conts"));
}
if (!this.networks_view) {
this.networks_view = new views.CreateColumnSelectListView({
collection: synnefo.storage.networks,
extra_class: 'private-networks',
title: 'Private networks',
description: 'Select private networks to connect the created machine to. You can manage your private networks from the networks tab.',
item_cls: views.CreateColumnPrivateNetworkOptionView,
filter_items: function(model) { return !model.is_public() }
this.networks_view = new views.NetworkSelectView({
container: this.cont
});
$(this.networks_view.el).appendTo(this.$(".personalize-conts"));
this.networks_view.hide(true);
}
},
......@@ -1250,8 +1200,13 @@
views.CreateNetworkingView.__super__.show.apply(this, arguments);
this.init_subviews();
this.update_layout();
this.networks_view.show(true);
},
hide_step: function() {
this.networks_view && this.networks_view.hide(true);
},
update_layout: function() {
},
......@@ -1261,13 +1216,13 @@
},
get_selected_networks: function() {
if (!this.networks_view) { return [] }
return this.networks_view.get_selected();
if (!this.networks_view) { return [] }
return this.networks_view.get_selected_networks();
},
get_selected_addresses: function() {
if (!this.networks_view) { return [] }
return this.ips_view.get_selected();
if (!this.networks_view) { return [] }
return this.networks_view.get_selected_floating_ips();
},
get: function() {
......@@ -1278,11 +1233,6 @@
},
remove: function() {
if (this.ips_view) {
this.ips_view.remove();
delete this.ips_view;
}
if (this.networks_view) {
this.networks_view.remove();
delete this.networks_view;
......@@ -1513,7 +1463,7 @@
}
_.each(ips, _.bind(function(ip) {
var el = this.make("li", {'class':'selected-ip-address'},
ip.get('ip'));
ip.get('floating_ip_address'));
this.ip_addresses.append(el);
}, this))
......@@ -1725,8 +1675,18 @@
extra['personality'] = _.flatten(personality);
}
extra['networks'] = _.map(data.networks, function(n) { return n.get('id') });
extra['floating_ips'] = _.map(data.addresses, function(ip) { return ip.get('ip') });
extra['networks'] = [];
_.each(data.networks, function(n) {
extra.networks.push({'uuid': n.get('id')})
});
_.each(data.ips, function(ip) {
extra.networks.push({
'uuid': ip.get('network').get('id'),
'fixed_ip': ip.get('floating_ip_address')
});
});
_.map(data.networks, function(n) { return n.get('id') });
storage.vms.create(data.name, data.image, data.flavor,
meta, extra, _.bind(function(data){
_.each(data.addresses, function(ip) {
......@@ -1799,7 +1759,8 @@
// FIXME: this shouldn't be here
// but since we are not calling step.hide this should work
this.steps[1].image_details.hide();
this.current_view && this.current_view.hide_step && this.current_view.hide_step();
this.current_view = this.steps[step];
this.update_controls();
......
......@@ -155,9 +155,7 @@
handle_create_click: function() {
network = synnefo.storage.networks.get_floating_ips_network();
this.collection.create({
floatingip: {
floating_network_id: network.id
}
floatingip: {}
},
{
complete: _.bind(function() {
......
......@@ -679,7 +679,6 @@
} else {
this.set_subtitle(subtitle);
}
this.vms = vms;
this.selected = selected;
this.cb = callback;
......@@ -692,5 +691,283 @@
this.cb(this.get_selected());
}
});
views.NetworkSelectModelView = views.ext.ModelView.extend({
select: function() {
if (!this.delegate_input) {
this.input.attr("checked", true);
this.item.addClass("selected");
}
this.selected = true;
this.trigger("change:select", this, this.selected);
},
deselect: function() {
if (!this.delegate_input) {
this.input.attr("checked", false);
this.item.removeClass("selected");
}
this.selected = false;
this.trigger("change:select", this, this.selected);
},
toggle_select: function() {
if (this.selected) {
this.deselect();
} else {
this.select();
}
},
post_init_element: function() {
this.input = $(this.$("input").get(0));
this.item = $(this.$(".select-item").get(0));
this.delegate_input = this.model.get('noselect');
this.deselect();
var self = this;
if (self.model.get('forced')) {
this.select();
this.input.attr("disabled", true);
$(this.el).attr('title', this.forced_title);
$(this.el).tooltip({
'tipClass': 'tooltip',
'position': 'top center',
'offset': [-5, 0]
});
}
$(this.item).click(function(e) {
if (self.model.get('forced')) { return }
e.stopPropagation();
e.preventDefault();
self.toggle_select();
});
views.NetworkSelectModelView.__super__.post_init_element.apply(this,
arguments);
}
});
views.NetworkSelectNetworkTypeModelView = views.NetworkSelectModelView.extend({
get_network_icon: function() {
var ico = this.model.get('is_public') ? 'internet-small.png' : 'network-small.png';
return synnefo.config.media_url + 'images/' + ico;
},
forced_title: 'You machine will be automatically connected ' +
'to this network.'
});
views.NetworkSelectPublicNetwork = views.NetworkSelectNetworkTypeModelView.extend({
tpl: '#networks-select-public-item-tpl',
classes: 'public-network',
post_init_element: function() {
views.NetworkSelectPublicNetwork.__super__.post_init_element.apply(this);
//$(this.el).attr('title', 'Public network tooltip');
//$(this.el).tooltip({
//'tipClass': 'tooltip',
//'position': 'top center',
//'offset': [-5, 0]
//});
}
});
views.NetworkSelectPrivateNetwork = views.NetworkSelectNetworkTypeModelView.extend({
tpl: '#networks-select-private-item-tpl',
classes: 'private-network'
});
views.NetworkSelectTypeView = views.ext.CollectionView.extend({});
views.NetworkSelectPublicNetworks = views.NetworkSelectTypeView.extend({
tpl: '#networks-select-public-tpl',
model_view_cls: views.NetworkSelectPublicNetwork,
get_floating_ips: function() {
return _.map(this._subviews[1]._subviews[0].selected, function(m) {
return m.id;
});
}
});
views.NetworkSelectFloatingIpView = views.NetworkSelectModelView.extend({
tpl: '#networks-select-floating-ip-tpl'
});
views.NetworkSelectFloatingIpsView = views.ext.CollectionView.extend({
tpl: '#networks-select-floating-ips-tpl',
model_view_cls: views.NetworkSelectFloatingIpView,
select_available: function() {
var selected = false;
this.each_ip_view(function(v) {
if (selected) { return }
v.select();
selected = true;
});
},
deselect_all: function() {
this.each_ip_view(function(v) { v.deselect() });
},
each_ip_view: function(cb) {
_.each(this._subviews, function(view) {
if (view instanceof views.NetworkSelectFloatingIpView) {
cb(view);
}
})
},
post_init: function() {
this.selected = [];
var parent = this.parent_view;
var self = this;
this.handle_ip_select = _.bind(this.handle_ip_select, this);
this.create = this.$(".floating-ip.create");
parent.bind("change:select", function(selected) {
if (parent.selected) {
self.show(true);
self.select_available();
} else {
self.deselect_all();
self.hide(true);
}
});
this.create.click(function() {
self.create_ip();
})
},
post_add_model_view: function(view) {
view.bind("change:select", this.handle_ip_select)
},
post_remove_model_view: function(view) {
view.unbind("change:select", this.handle_ip_select)
},
handle_create_error: function() {},
create_ip: function() {
synnefo.storage.floating_ips.create({floatingip:{}}, {
error: _.bind(this.handle_create_error, this),
skip_api_error: true
});
},
handle_ip_select: function(view) {
if (view.selected) {
this.selected.push(view.model);
} else {
this.selected = _.without(this.selected, view.model);
}
this.update_selected();
},
update_selected: function() {
var selected = this.selected.length;
if (selected) {
this.parent_view.input.attr("checked", true);
this.parent_view.item.addClass("selected");
$(this.parent_view.el).addClass("selected");
} else {
this.parent_view.input.attr("checked", false);
this.parent_view.item.removeClass("selected");
$(this.parent_view.el).removeClass("selected");
}
},
post_show: function() {
if (!this.parent_view.selected) {
this.hide(true);
}
},
get_floating_ips: function() {
return this.selected;
}
});
views.NetworkSelectPrivateNetworks = views.NetworkSelectTypeView.extend({
tpl: '#networks-select-private-tpl',
model_view_cls: views.NetworkSelectPrivateNetwork,
get_networks: function() {
return _.filter(_.map(this._subviews, function(view) {
if (view.selected) { return view.model.id }
}), function(id) { return id });
}
});
views.NetworkSelectView = views.ext.ModelView.extend({
rivets_view: true,
tpl: '#networks-select-view-tpl',
select_public: true,
initialize: function(options) {
this.quotas = synnefo.storage.quotas.get('cyclades.private_network');
options = options || {};
options.model = options.model || new models.Model();
this.private_networks = new Backbone.FilteredCollection(undefined, {
collection: synnefo.storage.networks,
collectionFilter: function(m) {
return !m.get('is_public')
}});
this.public_networks = new Backbone.Collection();
// forced networks
// TODO: check config
this.forced = new models.networks.Network({