Revision 69dac1ba
b/snf-cyclades-app/synnefo/ui/static/snf/css/main.css | ||
---|---|---|
6517 | 6517 |
font-size: 0.8em; |
6518 | 6518 |
} |
6519 | 6519 |
|
6520 |
.create-vm .network-select { |
|
6521 |
height: 278px; |
|
6522 |
overflow-y: scroll; |
|
6523 |
padding-right: 10px; |
|
6524 |
} |
|
6525 |
|
|
6520 | 6526 |
.vm-connect .connect-cont { |
6521 | 6527 |
margin-bottom: 20px; |
6522 | 6528 |
border-bottom: 1px solid #A1C8DB; |
... | ... | |
7422 | 7428 |
.steps-container .floating-ips .collection { |
7423 | 7429 |
} |
7424 | 7430 |
|
7431 |
.ip-port-view .title { |
|
7432 |
font-weight: normal !important; |
|
7433 |
} |
|
7434 |
|
|
7435 |
.pane-view .title.floating-ip { |
|
7436 |
font-weight: bold !important; |
|
7437 |
} |
|
7438 |
|
|
7425 | 7439 |
.items-list.floating-ips { |
7426 | 7440 |
margin-top: -5px; |
7427 | 7441 |
} |
b/snf-cyclades-app/synnefo/ui/static/snf/js/models.js | ||
---|---|---|
163 | 163 |
this.trigger("change:" + attr_name, obj); |
164 | 164 |
} else { |
165 | 165 |
var self = this; |
166 |
var retry = window.setInterval(function(){ |
|
167 |
var obj = store.get(val); |
|
168 |
if (obj) { |
|
169 |
data[key] = obj; |
|
170 |
self.set(data, {silent:true}) |
|
171 |
self.trigger("change:" + attr_name, obj); |
|
172 |
clearInterval(retry); |
|
173 |
} |
|
174 |
}, 500); |
|
166 |
var retry_to_resolve = function(store, val, key) { |
|
167 |
var retries = 0; |
|
168 |
var retry = window.setInterval(function(){ |
|
169 |
retries++; |
|
170 |
if (retries > 200) { |
|
171 |
clearInterval(retry); |
|
172 |
} |
|
173 |
var obj = store.get(val); |
|
174 |
if (obj) { |
|
175 |
data[key] = obj; |
|
176 |
self.set(data, {silent:false}); |
|
177 |
clearInterval(retry); |
|
178 |
} |
|
179 |
}, 500); |
|
180 |
return retry |
|
181 |
} |
|
182 |
retry_to_resolve(store, val, key); |
|
175 | 183 |
} |
176 | 184 |
} |
177 | 185 |
|
178 | 186 |
var self = this; |
179 |
this.bind('change:' + attr, function(model) { |
|
180 |
resolve_related_instance.call(model, store, key, attr_resolver(model, attr)); |
|
181 |
}, this); |
|
187 |
function init_bindings(instance, store, key, attr, attr_resolver) { |
|
188 |
instance.bind('change:' + attr, function(model) { |
|
189 |
resolve_related_instance.call(model, store, key, attr_resolver(model, attr)); |
|
190 |
}, this); |
|
182 | 191 |
|
183 |
this.bind('add', function(model) { |
|
184 |
resolve_related_instance.call(model, store, key, attr_resolver(model, attr)); |
|
185 |
}, this); |
|
192 |
instance.bind('add', function(model) { |
|
193 |
resolve_related_instance.call(model, store, key, attr_resolver(model, attr)); |
|
194 |
}, this); |
|
195 |
} |
|
196 |
|
|
197 |
init_bindings(this, store, key, attr, attr_resolver); |
|
186 | 198 |
resolve_related_instance.call(this, store, key, attr_resolver(this, attr)); |
187 | 199 |
}, this); |
188 | 200 |
}, |
... | ... | |
317 | 329 |
initialize: function() { |
318 | 330 |
models.Collection.__super__.initialize.apply(this, arguments); |
319 | 331 |
this.api_call = _.bind(this.api.call, this); |
332 |
if (this.sortFields) { |
|
333 |
_.each(this.sortFields, function(f) { |
|
334 |
this.bind("change:" + f, _.bind(this.resort, this)); |
|
335 |
}, this); |
|
336 |
} |
|
337 |
}, |
|
338 |
|
|
339 |
resort: function() { |
|
340 |
this.sort(); |
|
320 | 341 |
}, |
321 | 342 |
|
322 | 343 |
url: function(options, method) { |
... | ... | |
1024 | 1045 |
return _.contains(["ACTIVE", "STOPPED"], this.get("status")) |
1025 | 1046 |
}, |
1026 | 1047 |
|
1048 |
can_disconnect: function() { |
|
1049 |
return _.contains(["ACTIVE", "STOPPED"], this.get("status")) |
|
1050 |
}, |
|
1051 |
|
|
1027 | 1052 |
can_resize: function() { |
1028 | 1053 |
return this.get('status') == 'STOPPED'; |
1029 | 1054 |
}, |
... | ... | |
1325 | 1350 |
}, |
1326 | 1351 |
|
1327 | 1352 |
connect_floating_ip: function(ip, cb) { |
1353 |
this.set({'status': 'CONNECTING'}); |
|
1328 | 1354 |
synnefo.storage.ports.create({ |
1329 | 1355 |
port: { |
1330 | 1356 |
network_id: ip.get('floating_network_id'), |
... | ... | |
1332 | 1358 |
fixed_ips: [{'ip_address': ip.get('floating_ip_address')}] |
1333 | 1359 |
} |
1334 | 1360 |
}, {complete: cb, skip_api_error: false}) |
1335 |
// TODO: Implement |
|
1336 | 1361 |
}, |
1337 | 1362 |
|
1338 | 1363 |
// action helper |
b/snf-cyclades-app/synnefo/ui/static/snf/js/neutron.js | ||
---|---|---|
414 | 414 |
|
415 | 415 |
disconnect: function(cb) { |
416 | 416 |
var network = this.get('network'); |
417 |
var vm = this.get('vm'); |
|
417 | 418 |
network.pending_disconnects++; |
418 | 419 |
network.update_connecting_status(); |
419 | 420 |
var success = _.bind(function() { |
421 |
if (vm) { |
|
422 |
vm.set({'status': 'DISCONNECTING'}); |
|
423 |
} |
|
420 | 424 |
this.set({'status': 'DISCONNECTING'}); |
421 | 425 |
cb(); |
422 | 426 |
}, this); |
... | ... | |
472 | 476 |
if (vm && vm.get("task_state")) { return false } |
473 | 477 |
if (vm && vm.in_error_state()) { return false } |
474 | 478 |
var status_ok = _.contains(['ACTIVE', 'CONNECTED'], this.get('status')) |
475 |
return status_ok |
|
479 |
var vm_status_ok = vm.can_disconnect(); |
|
480 |
return status_ok && vm_status_ok; |
|
476 | 481 |
}] |
477 | 482 |
}, |
478 | 483 |
|
b/snf-cyclades-app/synnefo/ui/static/snf/js/ui/web/ui_ips_view.js | ||
---|---|---|
94 | 94 |
'CONNECTED': 'status-active', |
95 | 95 |
'ACTIVE': 'status-active', |
96 | 96 |
'CONNECTING': 'status-progress', |
97 |
'DISCONNECTING': 'status-inactive',
|
|
97 |
'DISCONNECTING': 'status-progress',
|
|
98 | 98 |
'DOWN': 'status-inactive', |
99 | 99 |
'DISCONNECTED': 'status-inactive', |
100 | 100 |
'UP': 'status-active', |
b/snf-cyclades-app/synnefo/ui/static/snf/js/ui/web/ui_networks_view.js | ||
---|---|---|
795 | 795 |
tpl: '#networks-select-floating-ips-tpl', |
796 | 796 |
model_view_cls: views.NetworkSelectFloatingIpView, |
797 | 797 |
|
798 |
select_if_available: function() { |
|
799 |
var selected = false; |
|
800 |
if (this._subviews[0]) { |
|
801 |
this._subviews[0].select(); |
|
802 |
} |
|
803 |
}, |
|
804 |
|
|
805 | 798 |
deselect_all: function() { |
806 | 799 |
this.each_ip_view(function(v) { v.deselect() }); |
807 | 800 |
}, |
... | ... | |
854 | 847 |
this.hide_parent(); |
855 | 848 |
return; |
856 | 849 |
} |
850 |
this.select_first(); |
|
857 | 851 |
this.parent_view.item.addClass("selected"); |
858 | 852 |
this.parent_view.input.attr("checked", true); |
859 | 853 |
this.parent_view.selected = true; |
860 | 854 |
this.show(true); |
861 |
this.select_if_available(); |
|
862 | 855 |
}, |
863 | 856 |
|
864 | 857 |
update_available: function() { |
... | ... | |
904 | 897 |
}, |
905 | 898 |
|
906 | 899 |
update_selected: function() { |
900 |
// reset missing entries |
|
907 | 901 |
_.each(this.selected_ips.length, function(ip) { |
908 | 902 |
if (!this.collection.get(ip.id)) { |
909 | 903 |
this.selected_ips = _.without(this.selected_ips, ip); |
... | ... | |
913 | 907 |
if (this.selected_ips.length) { |
914 | 908 |
this.parent_view.input.attr("checked", true); |
915 | 909 |
this.parent_view.item.addClass("selected"); |
916 |
this.parent_view.item.selected = true;
|
|
910 |
this.parent_view.selected = true; |
|
917 | 911 |
} else { |
918 | 912 |
this.parent_view.input.attr("checked", false); |
919 | 913 |
this.parent_view.item.removeClass("selected"); |
920 |
this.parent_view.item.selected = false;
|
|
914 |
this.parent_view.selected = false; |
|
921 | 915 |
} |
922 | 916 |
}, |
923 | 917 |
|
... | ... | |
955 | 949 |
skip_api_error: true |
956 | 950 |
}); |
957 | 951 |
}, |
952 |
|
|
953 |
select_first: function() { |
|
954 |
if (this.selected_ips.length > 0) { return } |
|
955 |
if (this._subviews.length == 0) { return } |
|
956 |
this._subviews[0].select(); |
|
957 |
if (!_.contains(this.selected_ips, this._subviews[0].model)) { |
|
958 |
this.selected_ips.push(this._subviews[0].model); |
|
959 |
} |
|
960 |
}, |
|
958 | 961 |
|
959 | 962 |
post_add_model_view: function(view, model) { |
960 | 963 |
view.bind("change:select", this.handle_ip_select) |
961 | 964 |
if (!this.selected_ips.length && this._subviews.length == 1) { |
962 |
this._subviews[0].select(); |
|
963 |
if (!_.contains(this.selected_ips, model)) { |
|
964 |
this.selected_ips.push(model); |
|
965 |
} |
|
965 |
this.select_first(); |
|
966 | 966 |
} |
967 | 967 |
}, |
968 | 968 |
|
b/snf-cyclades-app/synnefo/ui/static/snf/js/ui/web/ui_public_keys_view.js | ||
---|---|---|
304 | 304 |
this.model.remove(function() { |
305 | 305 |
synnefo.storage.keys.fetch(); |
306 | 306 |
}); |
307 |
}, |
|
308 |
|
|
309 |
post_hide: function() { |
|
310 |
views.PublicKeyView.__super__.post_hide.apply(this); |
|
311 |
if (this.content_visible) { |
|
312 |
this.toggle_content(); |
|
313 |
this.content.hide(); |
|
314 |
} |
|
307 | 315 |
} |
308 | 316 |
}); |
309 | 317 |
|
b/snf-cyclades-app/synnefo/ui/static/snf/js/ui/web/ui_single_view.js | ||
---|---|---|
65 | 65 |
|
66 | 66 |
var self = this; |
67 | 67 |
this.toggler.click(function() { |
68 |
if(self.toggler.parent().parent().hasClass("disabled")) { |
|
69 |
return; |
|
70 |
} |
|
68 | 71 |
self.toggle(); |
69 | 72 |
}); |
70 | 73 |
|
b/snf-cyclades-app/synnefo/ui/static/snf/js/views_ext.js | ||
---|---|---|
237 | 237 |
|
238 | 238 |
update_quota: function() { |
239 | 239 |
var available = this.quota.get_available(); |
240 |
if (available) { |
|
240 |
if (available > 0) {
|
|
241 | 241 |
this.create_button.removeClass("disabled"); |
242 | 242 |
this.create_button.attr("title", this.quota_limit_message || "Quota limit reached") |
243 | 243 |
} else { |
... | ... | |
277 | 277 |
if (!view) { return } |
278 | 278 |
el = view.el; |
279 | 279 |
parent = this.parent_for_model(model); |
280 |
index = this.collection.indexOf(model); |
|
280 | 281 |
if (!parent.find(el).length) { |
281 |
index = this.collection.indexOf(model); |
|
282 | 282 |
anim = true; |
283 | 283 |
this.place_in_parent(parent, el, model, index, anim); |
284 | 284 |
} |
285 |
if (index != view.el.data('index')) { |
|
286 |
this.place_in_parent(parent, el, model, index, false); |
|
287 |
} |
|
285 | 288 |
}, |
286 | 289 |
|
287 | 290 |
handle_collection_change: function() { |
... | ... | |
320 | 323 |
}, |
321 | 324 |
|
322 | 325 |
place_in_parent: function(parent, el, m, index, anim) { |
323 |
var place_func, place_func_context, position_found; |
|
326 |
var place_func, place_func_context, position_found, exists;
|
|
324 | 327 |
|
325 | 328 |
_.each(parent.find(".model-item"), function(el) { |
326 | 329 |
var el = $(el); |
b/snf-cyclades-app/synnefo/ui/templates/partials/ips.html | ||
---|---|---|
5 | 5 |
<div class="inner clearfix main-content"> |
6 | 6 |
<div class="model-logo vm-icon medium2 state1" |
7 | 7 |
data-rv-style="model.vm.status|vm_style"></div> |
8 |
<h5 class="title" data-rv-text="model.vm.name|truncate 50"></h5>
|
|
8 |
<h3 class="title" data-rv-text="model.vm.name|truncate 40"></h3>
|
|
9 | 9 |
<h5 class="subtitle"> |
10 | 10 |
<span class="key" data-rv-show="model.mac_address">MAC:</span> |
11 | 11 |
<span class="value" data-rv-text="model.mac_address"></span> |
... | ... | |
21 | 21 |
<div class="main-content-inner clearfix"> |
22 | 22 |
<img class="logo" src="{{ SYNNEFO_IMAGES_URL }}internet.png" /> |
23 | 23 |
<div class="entry inline" data-rv-class-connected="model.device_id"> |
24 |
<h3 class="title"> |
|
24 |
<h3 class="title floating-ip">
|
|
25 | 25 |
<span data-rv-text="model.floating_ip_address">IP ADDRESS</span> |
26 | 26 |
</h3> |
27 | 27 |
<div data-rv-if="model.port_id" class="ports nested-model-list proxy inline"> |
b/snf-cyclades-app/synnefo/ui/templates/partials/networks.html | ||
---|---|---|
93 | 93 |
<div class="border2"></div> |
94 | 94 |
<div class="inner clearfix main-content"> |
95 | 95 |
<img class="model-logo" data-rv-src="model.vm.status|vm_logo_url" /> |
96 |
<h5 class="title" data-rv-text="model.vm.name"></h5> |
|
96 |
<h5 class="title" data-rv-text="model.vm.name|truncate 35"></h5>
|
|
97 | 97 |
<ul class="ip-addresses"> |
98 | 98 |
<li data-rv-each-item="model.fixed_ips"> |
99 | 99 |
<span data-rv-text="item:ip_address|ip_type" class="type"></span> |
... | ... | |
230 | 230 |
<div class="collection"> |
231 | 231 |
|
232 | 232 |
<div id="create-network" class="create-button"> |
233 |
<a href="#">{% trans "New network +" %}</a>
|
|
233 |
<a href="#">{% trans "New Network +" %}</a>
|
|
234 | 234 |
</div> |
235 | 235 |
|
236 | 236 |
<div class="empty-list hidden"> |
... | ... | |
273 | 273 |
<div class="checkbox"> |
274 | 274 |
<input type="checkbox" data-rv-data-id="model.id" /> |
275 | 275 |
</div> |
276 |
<div class="ico"><img data-rv-src="model.is_public|get_network_icon" /></div> |
|
276 |
<div class="ico"> |
|
277 |
<img data-rv-src="model.is_public|get_network_icon" /> |
|
278 |
</div> |
|
277 | 279 |
<div class="name"> |
278 | 280 |
<span class="" data-rv-text="model.name"></span> |
279 | 281 |
<span class="no-available hidden">{% trans "No IPs available" %}</span> |
... | ... | |
290 | 292 |
<div class="select-item private-network clearfix"> |
291 | 293 |
<div class="checkbox"><input type="checkbox" data-rv-data-id="model.id"></div> |
292 | 294 |
<div class="ico"><img data-rv-src="model.is_public|get_network_icon" /></div> |
293 |
<div class="name"><span class="" data-rv-text="model.name|truncate 50"></span></div>
|
|
295 |
<div class="name"><span class="" data-rv-text="model.name|truncate 45"></span></div>
|
|
294 | 296 |
<div class="cidr"><span class="" data-rv-text="model.subnet.cidr"></span></div> |
295 | 297 |
</div> |
296 | 298 |
</div> |
b/snf-cyclades-app/synnefo/ui/templates/partials/public_keys.html | ||
---|---|---|
90 | 90 |
<div class="collection"> |
91 | 91 |
|
92 | 92 |
<div id="create-keypair" class="create-button"> |
93 |
<a href="#">{% trans "New public key +" %}</a>
|
|
93 |
<a href="#">{% trans "New Keypair +" %}</a>
|
|
94 | 94 |
</div> |
95 | 95 |
|
96 | 96 |
<div class="empty-list hidden"> |
Also available in: Unified diff