root / snf-cyclades-app / synnefo / ui / static / snf / js / ui / web / ui_vms_base_view.js @ 643fe7e3
History | View | Annotate | Download (30.5 kB)
1 | 00469232 | Kostas Papadimitriou | // Copyright 2011 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 00469232 | Kostas Papadimitriou | //
|
3 | 00469232 | Kostas Papadimitriou | // Redistribution and use in source and binary forms, with or
|
4 | 00469232 | Kostas Papadimitriou | // without modification, are permitted provided that the following
|
5 | 00469232 | Kostas Papadimitriou | // conditions are met:
|
6 | 00469232 | Kostas Papadimitriou | //
|
7 | 00469232 | Kostas Papadimitriou | // 1. Redistributions of source code must retain the above
|
8 | 00469232 | Kostas Papadimitriou | // copyright notice, this list of conditions and the following
|
9 | 00469232 | Kostas Papadimitriou | // disclaimer.
|
10 | 00469232 | Kostas Papadimitriou | //
|
11 | 00469232 | Kostas Papadimitriou | // 2. Redistributions in binary form must reproduce the above
|
12 | 00469232 | Kostas Papadimitriou | // copyright notice, this list of conditions and the following
|
13 | 00469232 | Kostas Papadimitriou | // disclaimer in the documentation and/or other materials
|
14 | 00469232 | Kostas Papadimitriou | // provided with the distribution.
|
15 | 00469232 | Kostas Papadimitriou | //
|
16 | 00469232 | Kostas Papadimitriou | // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 00469232 | Kostas Papadimitriou | // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 00469232 | Kostas Papadimitriou | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 00469232 | Kostas Papadimitriou | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 00469232 | Kostas Papadimitriou | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 00469232 | Kostas Papadimitriou | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 00469232 | Kostas Papadimitriou | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 00469232 | Kostas Papadimitriou | // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 00469232 | Kostas Papadimitriou | // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 00469232 | Kostas Papadimitriou | // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 00469232 | Kostas Papadimitriou | // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 00469232 | Kostas Papadimitriou | // POSSIBILITY OF SUCH DAMAGE.
|
28 | 00469232 | Kostas Papadimitriou | //
|
29 | 00469232 | Kostas Papadimitriou | // The views and conclusions contained in the software and
|
30 | 00469232 | Kostas Papadimitriou | // documentation are those of the authors and should not be
|
31 | 00469232 | Kostas Papadimitriou | // interpreted as representing official policies, either expressed
|
32 | 00469232 | Kostas Papadimitriou | // or implied, of GRNET S.A.
|
33 | 00469232 | Kostas Papadimitriou | //
|
34 | 00469232 | Kostas Papadimitriou | |
35 | 8d08f18a | Kostas Papadimitriou | ;(function(root){
|
36 | 8d08f18a | Kostas Papadimitriou | |
37 | 8d08f18a | Kostas Papadimitriou | // root
|
38 | 8d08f18a | Kostas Papadimitriou | var root = root;
|
39 | 8d08f18a | Kostas Papadimitriou | |
40 | 8d08f18a | Kostas Papadimitriou | // setup namepsaces
|
41 | 8d08f18a | Kostas Papadimitriou | var snf = root.synnefo = root.synnefo || {};
|
42 | 8d08f18a | Kostas Papadimitriou | var models = snf.models = snf.models || {}
|
43 | 8d08f18a | Kostas Papadimitriou | var storage = snf.storage = snf.storage || {};
|
44 | 8d08f18a | Kostas Papadimitriou | var ui = snf.ui = snf.ui || {};
|
45 | 8d08f18a | Kostas Papadimitriou | |
46 | 8d08f18a | Kostas Papadimitriou | var views = snf.views = snf.views || {}
|
47 | 8d08f18a | Kostas Papadimitriou | |
48 | 8d08f18a | Kostas Papadimitriou | // shortcuts
|
49 | 8d08f18a | Kostas Papadimitriou | var bb = root.Backbone;
|
50 | 8d08f18a | Kostas Papadimitriou | |
51 | 8d08f18a | Kostas Papadimitriou | // logging
|
52 | 8d08f18a | Kostas Papadimitriou | var logger = new snf.logging.logger("SNF-VIEWS"); |
53 | 8d08f18a | Kostas Papadimitriou | var debug = _.bind(logger.debug, logger);
|
54 | 8d08f18a | Kostas Papadimitriou | |
55 | 75331d54 | Kostas Papadimitriou | var hasKey = Object.prototype.hasOwnProperty;
|
56 | 75331d54 | Kostas Papadimitriou | |
57 | 8d08f18a | Kostas Papadimitriou | // base class for views that contain/handle VMS
|
58 | 8d08f18a | Kostas Papadimitriou | views.VMListView = views.View.extend({ |
59 | 8d08f18a | Kostas Papadimitriou | |
60 | 8d08f18a | Kostas Papadimitriou | // just a flag to identify that
|
61 | 8d08f18a | Kostas Papadimitriou | // views of this type handle vms
|
62 | 8d08f18a | Kostas Papadimitriou | vms_view: true, |
63 | 8d08f18a | Kostas Papadimitriou | |
64 | 8d08f18a | Kostas Papadimitriou | selectors: {},
|
65 | 8d08f18a | Kostas Papadimitriou | hide_actions: true, |
66 | 8d08f18a | Kostas Papadimitriou | pane: "#machines-pane", |
67 | 8d08f18a | Kostas Papadimitriou | metadata_view: undefined, |
68 | 8d08f18a | Kostas Papadimitriou | |
69 | 8d08f18a | Kostas Papadimitriou | initialize: function() { |
70 | 8d08f18a | Kostas Papadimitriou | views.VMListView.__super__.initialize.call(this);
|
71 | 75331d54 | Kostas Papadimitriou | this._vm_els = {};
|
72 | 8d08f18a | Kostas Papadimitriou | this.set_storage_handlers();
|
73 | 8d08f18a | Kostas Papadimitriou | this.set_handlers();
|
74 | 8d08f18a | Kostas Papadimitriou | this.vms_updated_handler();
|
75 | 550d9733 | Kostas Papadimitriou | this.connect_overlay = new views.VMConnectView(); |
76 | 8d08f18a | Kostas Papadimitriou | }, |
77 | 8d08f18a | Kostas Papadimitriou | |
78 | 1e882dd7 | Kostas Papadimitriou | // display vm diagnostics detail overlay view, update based on
|
79 | 1e882dd7 | Kostas Papadimitriou | // diagnostics_update_interval config value.
|
80 | 1e882dd7 | Kostas Papadimitriou | show_build_details_for_vm: function(vm) { |
81 | 1e882dd7 | Kostas Papadimitriou | var cont = null; |
82 | 1e882dd7 | Kostas Papadimitriou | var success = function(data) { |
83 | 1e882dd7 | Kostas Papadimitriou | var message = ""; |
84 | 1e882dd7 | Kostas Papadimitriou | var title = vm.get('name'); |
85 | 1e882dd7 | Kostas Papadimitriou | var info = '<em>Status log messages:</em>'; |
86 | 1e882dd7 | Kostas Papadimitriou | |
87 | 1e882dd7 | Kostas Papadimitriou | var list_el = $('<div class="diagnostics-list">'); |
88 | 1e882dd7 | Kostas Papadimitriou | list_el.append('<div class="empty">No data available</div>');
|
89 | 1e882dd7 | Kostas Papadimitriou | |
90 | 1e882dd7 | Kostas Papadimitriou | cont = list_el; |
91 | 1e882dd7 | Kostas Papadimitriou | var messages = _.clone(data);
|
92 | 1e882dd7 | Kostas Papadimitriou | |
93 | 1e882dd7 | Kostas Papadimitriou | update_overlay_diagnostics(data, cont); |
94 | 1e882dd7 | Kostas Papadimitriou | synnefo.ui.main.details_view.show(title, info, cont); |
95 | 1e882dd7 | Kostas Papadimitriou | } |
96 | 1e882dd7 | Kostas Papadimitriou | |
97 | 1e882dd7 | Kostas Papadimitriou | var update_overlay_diagnostics = function(data) { |
98 | 1e882dd7 | Kostas Papadimitriou | var existing = cont.find(".msg-log-entry"); |
99 | 1e882dd7 | Kostas Papadimitriou | var messages = _.clone(data);
|
100 | 1e882dd7 | Kostas Papadimitriou | |
101 | 1e882dd7 | Kostas Papadimitriou | var to_append = messages.slice(0, messages.length - existing.length); |
102 | 1e882dd7 | Kostas Papadimitriou | to_append.reverse(); |
103 | 1e882dd7 | Kostas Papadimitriou | |
104 | 1e882dd7 | Kostas Papadimitriou | var appending = to_append.length != messages.length;
|
105 | 1e882dd7 | Kostas Papadimitriou | |
106 | 1e882dd7 | Kostas Papadimitriou | if (to_append.length) { cont.find(".empty").hide() } else { |
107 | 1e882dd7 | Kostas Papadimitriou | if (!messages.length) { cont.find(".empty").show() } |
108 | 1e882dd7 | Kostas Papadimitriou | } |
109 | 1e882dd7 | Kostas Papadimitriou | _.each(to_append, function(msg){
|
110 | 1e882dd7 | Kostas Papadimitriou | var el = $('<div class="clearfix msg-log-entry ' + msg.level.toLowerCase() + '">'); |
111 | 1e882dd7 | Kostas Papadimitriou | if (msg.details) {
|
112 | 1e882dd7 | Kostas Papadimitriou | el.addClass("with-details");
|
113 | 1e882dd7 | Kostas Papadimitriou | } |
114 | 1e882dd7 | Kostas Papadimitriou | var display_source_date = synnefo.config.diagnostics_display_source_date;
|
115 | 1e882dd7 | Kostas Papadimitriou | var source_date = ""; |
116 | 1e882dd7 | Kostas Papadimitriou | if (display_source_date) {
|
117 | 1e882dd7 | Kostas Papadimitriou | source_date = '('+synnefo.util.formatDate(new Date(msg.source_date))+')'; |
118 | 1e882dd7 | Kostas Papadimitriou | } |
119 | 1e882dd7 | Kostas Papadimitriou | |
120 | 1e882dd7 | Kostas Papadimitriou | el.append('<span class="date">' + synnefo.util.formatDate(new Date(msg.created)) + source_date + '</span>'); |
121 | 1e882dd7 | Kostas Papadimitriou | el.append('<span class="src">' + _.escape(msg.source) + '</span>'); |
122 | 1e882dd7 | Kostas Papadimitriou | el.append('<span class="msg">' + _.escape(msg.message) + '</span>'); |
123 | 1e882dd7 | Kostas Papadimitriou | if (msg.details) {
|
124 | 1e882dd7 | Kostas Papadimitriou | el.append('<pre class="details">' + _.escape(msg.details) + '</pre>'); |
125 | 1e882dd7 | Kostas Papadimitriou | } |
126 | 1e882dd7 | Kostas Papadimitriou | if (appending) { el.hide(0); el.css({'display':'none'})} |
127 | 1e882dd7 | Kostas Papadimitriou | cont.prepend(el); |
128 | 1e882dd7 | Kostas Papadimitriou | el.click(function(el) {
|
129 | 1e882dd7 | Kostas Papadimitriou | $(this).find(".details").slideToggle(); |
130 | 1e882dd7 | Kostas Papadimitriou | $(this).toggleClass("expanded"); |
131 | 1e882dd7 | Kostas Papadimitriou | }); |
132 | 1e882dd7 | Kostas Papadimitriou | |
133 | 1e882dd7 | Kostas Papadimitriou | if (appending) { el.fadeIn(800); } |
134 | 1e882dd7 | Kostas Papadimitriou | }); |
135 | 1e882dd7 | Kostas Papadimitriou | |
136 | 1e882dd7 | Kostas Papadimitriou | window.setTimeout(function(){
|
137 | 1e882dd7 | Kostas Papadimitriou | if (cont.is(":visible")) { |
138 | 1e882dd7 | Kostas Papadimitriou | vm.get_diagnostics(update_overlay_diagnostics); |
139 | 1e882dd7 | Kostas Papadimitriou | } |
140 | 1e882dd7 | Kostas Papadimitriou | }, synnefo.config.diagnostics_update_interval); |
141 | 1e882dd7 | Kostas Papadimitriou | } |
142 | 1e882dd7 | Kostas Papadimitriou | |
143 | 1e882dd7 | Kostas Papadimitriou | vm.get_diagnostics(success); |
144 | 1e882dd7 | Kostas Papadimitriou | }, |
145 | 1e882dd7 | Kostas Papadimitriou | |
146 | 8d08f18a | Kostas Papadimitriou | // Helpers
|
147 | 8d08f18a | Kostas Papadimitriou | //
|
148 | 8d08f18a | Kostas Papadimitriou | // get element based on this.selectors key/value pairs
|
149 | 8d08f18a | Kostas Papadimitriou | sel: function(id, params) { |
150 | 8d08f18a | Kostas Papadimitriou | if (!this.selectors[id]){ return }; |
151 | 8d08f18a | Kostas Papadimitriou | return $(this.selectors[id].format(params)); |
152 | 8d08f18a | Kostas Papadimitriou | }, |
153 | 8d08f18a | Kostas Papadimitriou | |
154 | 8d08f18a | Kostas Papadimitriou | // vm element based on vm model instance provided
|
155 | 8d08f18a | Kostas Papadimitriou | vm: function(vm) { |
156 | 75331d54 | Kostas Papadimitriou | if (hasKey.call(this._vm_els, vm.id)) { |
157 | 75331d54 | Kostas Papadimitriou | ret = this._vm_els[vm.id];
|
158 | 75331d54 | Kostas Papadimitriou | } else {
|
159 | 75331d54 | Kostas Papadimitriou | return $([]); |
160 | 75331d54 | Kostas Papadimitriou | } |
161 | 75331d54 | Kostas Papadimitriou | |
162 | 75331d54 | Kostas Papadimitriou | return ret;
|
163 | 8d08f18a | Kostas Papadimitriou | }, |
164 | 8d08f18a | Kostas Papadimitriou | |
165 | 8d08f18a | Kostas Papadimitriou | // get vm model instance from DOM element
|
166 | 8d08f18a | Kostas Papadimitriou | vm_for_element: function(el) { |
167 | 8d08f18a | Kostas Papadimitriou | return storage.vms.sel(this.vm_id_for_element(el)); |
168 | 8d08f18a | Kostas Papadimitriou | }, |
169 | 8d08f18a | Kostas Papadimitriou | |
170 | 8d08f18a | Kostas Papadimitriou | |
171 | 8d08f18a | Kostas Papadimitriou | // Event binding and stuff like that
|
172 | 8d08f18a | Kostas Papadimitriou | //
|
173 | 8d08f18a | Kostas Papadimitriou | set_storage_handlers: function() { |
174 | 8d08f18a | Kostas Papadimitriou | storage.vms.bind("add", _.bind(this.vms_updated_handler, this, "add")); |
175 | 8d08f18a | Kostas Papadimitriou | storage.vms.bind("change", _.bind(this.vms_updated_handler, this, "change")); |
176 | 8d08f18a | Kostas Papadimitriou | storage.vms.bind("reset", _.bind(this.vms_updated_handler, this, "reset")); |
177 | 8d08f18a | Kostas Papadimitriou | storage.vms.bind("remove", _.bind(this.vms_updated_handler, this, "remove")); |
178 | 8d08f18a | Kostas Papadimitriou | }, |
179 | 8d08f18a | Kostas Papadimitriou | |
180 | 8d08f18a | Kostas Papadimitriou | // vms updated triggered, update view vms
|
181 | 8d08f18a | Kostas Papadimitriou | vms_updated_handler: function (method, model, arg2, arg3) { |
182 | 8d08f18a | Kostas Papadimitriou | var updated = storage.vms.models;
|
183 | 8d08f18a | Kostas Papadimitriou | if (method == "add") { updated = [model] }; |
184 | 8d08f18a | Kostas Papadimitriou | if (method == "change") { updated = [model] }; |
185 | 8d08f18a | Kostas Papadimitriou | if (method == "remove") { updated = [model] }; |
186 | 8d08f18a | Kostas Papadimitriou | |
187 | 8d08f18a | Kostas Papadimitriou | if (method == "remove") { |
188 | 8d08f18a | Kostas Papadimitriou | this.remove_vm(model)
|
189 | 8d08f18a | Kostas Papadimitriou | return;
|
190 | 8d08f18a | Kostas Papadimitriou | } |
191 | 44660f58 | Kostas Papadimitriou | |
192 | 8d08f18a | Kostas Papadimitriou | this.update_vms(updated);
|
193 | 8d08f18a | Kostas Papadimitriou | }, |
194 | 8d08f18a | Kostas Papadimitriou | |
195 | 8d08f18a | Kostas Papadimitriou | // create vm
|
196 | 8d08f18a | Kostas Papadimitriou | // append it on proper view container
|
197 | 8d08f18a | Kostas Papadimitriou | create_vm: function(vm) { |
198 | 8d08f18a | Kostas Papadimitriou | // create dom element
|
199 | 8d08f18a | Kostas Papadimitriou | var vm_view = this.create_vm_element(vm); |
200 | 8d08f18a | Kostas Papadimitriou | vm_view.find(".vm-actions").attr("id", this.view_id+"-actions-" + vm.id); |
201 | 75331d54 | Kostas Papadimitriou | this._vm_els[vm.id] = vm_view;
|
202 | b042eb04 | Kostas Papadimitriou | var container = this.get_vm_container(vm); |
203 | 8d08f18a | Kostas Papadimitriou | container.append(vm_view); |
204 | 8d08f18a | Kostas Papadimitriou | vm_view.find(".action-indicator").text(""); |
205 | 8d08f18a | Kostas Papadimitriou | if (this.visible()) { |
206 | 8d08f18a | Kostas Papadimitriou | container.show() |
207 | 8d08f18a | Kostas Papadimitriou | } |
208 | 8d08f18a | Kostas Papadimitriou | |
209 | 8d08f18a | Kostas Papadimitriou | // initialize vm specific event handlers
|
210 | 8d08f18a | Kostas Papadimitriou | this.__set_vm_handlers(vm);
|
211 | a6b9836b | Kostas Papadimitriou | vm_view.find(".suspended-notice").click(function(){ |
212 | a6b9836b | Kostas Papadimitriou | synnefo.ui.main.suspended_view.show(vm); |
213 | a6b9836b | Kostas Papadimitriou | }) |
214 | 75331d54 | Kostas Papadimitriou | return vm_view;
|
215 | 8d08f18a | Kostas Papadimitriou | }, |
216 | 8d08f18a | Kostas Papadimitriou | |
217 | 8d08f18a | Kostas Papadimitriou | // create vm dom element
|
218 | 8d08f18a | Kostas Papadimitriou | create_vm_element: function(vm) { |
219 | 8d08f18a | Kostas Papadimitriou | // clone template
|
220 | 23a3bb8e | Kostas Papadimitriou | return this.sel('tpl').clone().attr("id", this.id_tpl + vm.id) |
221 | 8d08f18a | Kostas Papadimitriou | }, |
222 | 8d08f18a | Kostas Papadimitriou | |
223 | 8d08f18a | Kostas Papadimitriou | // get proper vm container
|
224 | 8d08f18a | Kostas Papadimitriou | get_vm_container: function(vm) { |
225 | 8d08f18a | Kostas Papadimitriou | if (vm.is_active()) {
|
226 | 8d08f18a | Kostas Papadimitriou | return this.sel("vm_cont_active"); |
227 | 8d08f18a | Kostas Papadimitriou | } else {
|
228 | 8d08f18a | Kostas Papadimitriou | return this.sel("vm_cont_terminated"); |
229 | 8d08f18a | Kostas Papadimitriou | } |
230 | 8d08f18a | Kostas Papadimitriou | }, |
231 | 8d08f18a | Kostas Papadimitriou | |
232 | 8d08f18a | Kostas Papadimitriou | // create and append inside the proper container the vm model
|
233 | 8d08f18a | Kostas Papadimitriou | // if it doesn't exist update vm data and make it visible
|
234 | 8d08f18a | Kostas Papadimitriou | add: function(vm) { |
235 | 8d08f18a | Kostas Papadimitriou | // create if it does not exist
|
236 | 75331d54 | Kostas Papadimitriou | if (!hasKey.call(this._vm_els, vm.id)) { |
237 | 75331d54 | Kostas Papadimitriou | var el = this.create_vm(vm); |
238 | 75331d54 | Kostas Papadimitriou | el.show(); |
239 | c343513e | Kostas Papadimitriou | this.post_add(vm);
|
240 | 1e882dd7 | Kostas Papadimitriou | this.init_vm_view_handlers(vm);
|
241 | 8d08f18a | Kostas Papadimitriou | } |
242 | 8d08f18a | Kostas Papadimitriou | |
243 | 8d08f18a | Kostas Papadimitriou | return this.vm(vm); |
244 | 8d08f18a | Kostas Papadimitriou | }, |
245 | 1e882dd7 | Kostas Papadimitriou | |
246 | 1e882dd7 | Kostas Papadimitriou | init_vm_view_handlers: function(vm) { |
247 | 1e882dd7 | Kostas Papadimitriou | var self = this; |
248 | 1e882dd7 | Kostas Papadimitriou | var el = this.vm(vm); |
249 | 1e882dd7 | Kostas Papadimitriou | |
250 | 1e882dd7 | Kostas Papadimitriou | // hidden feature, double click on indicators to display
|
251 | 1e882dd7 | Kostas Papadimitriou | // vm diagnostics.
|
252 | 1e882dd7 | Kostas Papadimitriou | el.find(".indicators").bind("dblclick", function(){ |
253 | 1e882dd7 | Kostas Papadimitriou | self.show_build_details_for_vm(vm); |
254 | 1e882dd7 | Kostas Papadimitriou | }); |
255 | 1e882dd7 | Kostas Papadimitriou | |
256 | 1e882dd7 | Kostas Papadimitriou | // this button gets visible if vm creation failed.
|
257 | 1e882dd7 | Kostas Papadimitriou | el.find("div.build-progress .btn").click(function(){ |
258 | 1e882dd7 | Kostas Papadimitriou | self.show_build_details_for_vm(vm); |
259 | 1e882dd7 | Kostas Papadimitriou | }); |
260 | 1e882dd7 | Kostas Papadimitriou | }, |
261 | 8d08f18a | Kostas Papadimitriou | |
262 | 8d08f18a | Kostas Papadimitriou | // helpers for VMListView descendants
|
263 | 8d08f18a | Kostas Papadimitriou | post_add: function(vm) { throw "Not implemented" }, |
264 | 8d08f18a | Kostas Papadimitriou | set_vm_handlers: function(vm) { throw "Not implemented" }, |
265 | 8d08f18a | Kostas Papadimitriou | set_handlers: function() { throw "Not implemented" }, |
266 | 8d08f18a | Kostas Papadimitriou | update_layout: function() { throw "Not implemented" }, |
267 | 8d08f18a | Kostas Papadimitriou | post_update_vm: function(vm) { throw "Not implemented" }, |
268 | 8d08f18a | Kostas Papadimitriou | update_details: function(vm) {}, |
269 | 8d08f18a | Kostas Papadimitriou | |
270 | 8d08f18a | Kostas Papadimitriou | // remove vm
|
271 | 8d08f18a | Kostas Papadimitriou | remove_vm: function(vm) { |
272 | 8d08f18a | Kostas Papadimitriou | // FIXME: some kind of transiton ??? effect maybe ???
|
273 | 8d08f18a | Kostas Papadimitriou | this.vm(vm).remove();
|
274 | 8d08f18a | Kostas Papadimitriou | this.post_remove_vm(vm);
|
275 | 75331d54 | Kostas Papadimitriou | if (hasKey.call(this._vm_els, vm.id)) { |
276 | 75331d54 | Kostas Papadimitriou | delete this._vm_els[vm.id]; |
277 | 75331d54 | Kostas Papadimitriou | } |
278 | 8d08f18a | Kostas Papadimitriou | }, |
279 | 8d08f18a | Kostas Papadimitriou | |
280 | 8d08f18a | Kostas Papadimitriou | // remove all vms from view
|
281 | 8d08f18a | Kostas Papadimitriou | clear: function() { |
282 | 8d08f18a | Kostas Papadimitriou | this.sel('vms').remove(); |
283 | 8d08f18a | Kostas Papadimitriou | this.__update_layout();
|
284 | 8d08f18a | Kostas Papadimitriou | }, |
285 | 8d08f18a | Kostas Papadimitriou | |
286 | 2506f741 | Kostas Papadimitriou | show: function() { |
287 | 2506f741 | Kostas Papadimitriou | views.VMListView.__super__.show.apply(this, arguments); |
288 | f44486d8 | Kostas Papadimitriou | if (storage.vms.length == 0) { this.hide() }; |
289 | 5dad72ea | Kostas Papadimitriou | if (!snf.config.update_hidden_views) {
|
290 | 5dad72ea | Kostas Papadimitriou | this.update_vms(storage.vms.models);
|
291 | 5dad72ea | Kostas Papadimitriou | } |
292 | 2506f741 | Kostas Papadimitriou | }, |
293 | 2506f741 | Kostas Papadimitriou | |
294 | 8d08f18a | Kostas Papadimitriou | // do update for provided vms, then update the view layout
|
295 | 8d08f18a | Kostas Papadimitriou | update_vms: function(vms) { |
296 | 5dad72ea | Kostas Papadimitriou | if (!this.visible() && !snf.config.update_hidden_views) { return }; |
297 | 5dad72ea | Kostas Papadimitriou | |
298 | 8d08f18a | Kostas Papadimitriou | _.each(vms, _.bind(function(vm){
|
299 | 8d08f18a | Kostas Papadimitriou | // vm will be removed
|
300 | 8d08f18a | Kostas Papadimitriou | // no need to update
|
301 | 8d08f18a | Kostas Papadimitriou | if (vm.get("status") == "DELETED") { |
302 | 8d08f18a | Kostas Papadimitriou | return;
|
303 | 8d08f18a | Kostas Papadimitriou | } |
304 | 8d08f18a | Kostas Papadimitriou | |
305 | 8d08f18a | Kostas Papadimitriou | // this won't add it additional times
|
306 | 8d08f18a | Kostas Papadimitriou | this.add(vm);
|
307 | 8d08f18a | Kostas Papadimitriou | this.update_vm(vm);
|
308 | 8d08f18a | Kostas Papadimitriou | }, this))
|
309 | 8d08f18a | Kostas Papadimitriou | |
310 | 8d08f18a | Kostas Papadimitriou | // update view stuff
|
311 | 8d08f18a | Kostas Papadimitriou | this.__update_layout();
|
312 | 8d08f18a | Kostas Papadimitriou | }, |
313 | 8d08f18a | Kostas Papadimitriou | |
314 | e6a4b75c | Kostas Papadimitriou | update_toggles_visibility: function(vm) { |
315 | e6a4b75c | Kostas Papadimitriou | if (vm.is_building() || vm.in_error_state() || vm.get("status") == "DESTROY") { |
316 | e6a4b75c | Kostas Papadimitriou | this.vm(vm).find(".cont-toggler-wrapper.ips").addClass("disabled"); |
317 | e6a4b75c | Kostas Papadimitriou | } else {
|
318 | e6a4b75c | Kostas Papadimitriou | this.vm(vm).find(".cont-toggler-wrapper.ips").removeClass("disabled"); |
319 | e6a4b75c | Kostas Papadimitriou | } |
320 | e6a4b75c | Kostas Papadimitriou | }, |
321 | e6a4b75c | Kostas Papadimitriou | |
322 | 8d08f18a | Kostas Papadimitriou | // update ui for the given vm
|
323 | 8d08f18a | Kostas Papadimitriou | update_vm: function(vm) { |
324 | 643de8c0 | Kostas Papadimitriou | // do not update deleted state vms
|
325 | 643de8c0 | Kostas Papadimitriou | if (!vm || vm.get("status") == 'DELETED') { return }; |
326 | 8d08f18a | Kostas Papadimitriou | this.check_vm_container(vm);
|
327 | 8d08f18a | Kostas Papadimitriou | |
328 | 8d08f18a | Kostas Papadimitriou | this.update_details(vm);
|
329 | 8d08f18a | Kostas Papadimitriou | this.update_transition_state(vm);
|
330 | e6a4b75c | Kostas Papadimitriou | this.update_toggles_visibility(vm);
|
331 | 8d08f18a | Kostas Papadimitriou | |
332 | 8d08f18a | Kostas Papadimitriou | if (this.action_views) { |
333 | 8d08f18a | Kostas Papadimitriou | this.action_views[vm.id].update();
|
334 | 8d08f18a | Kostas Papadimitriou | this.action_views[vm.id].update_layout();
|
335 | 8d08f18a | Kostas Papadimitriou | } |
336 | 8d08f18a | Kostas Papadimitriou | |
337 | a6b9836b | Kostas Papadimitriou | var el = this.vm(vm); |
338 | ab3df8df | Kostas Papadimitriou | if (vm.can_resize()) {
|
339 | ab3df8df | Kostas Papadimitriou | el.addClass("can-resize");
|
340 | ab3df8df | Kostas Papadimitriou | } else {
|
341 | ab3df8df | Kostas Papadimitriou | el.removeClass("can-resize");
|
342 | ab3df8df | Kostas Papadimitriou | } |
343 | ab3df8df | Kostas Papadimitriou | |
344 | a6b9836b | Kostas Papadimitriou | if (vm.get('suspended')) { |
345 | a6b9836b | Kostas Papadimitriou | el.addClass("suspended");
|
346 | a6b9836b | Kostas Papadimitriou | } else {
|
347 | a6b9836b | Kostas Papadimitriou | el.removeClass("suspended");
|
348 | a6b9836b | Kostas Papadimitriou | } |
349 | a6b9836b | Kostas Papadimitriou | |
350 | 027bdc60 | Kostas Papadimitriou | try {
|
351 | 027bdc60 | Kostas Papadimitriou | this.post_update_vm(vm);
|
352 | 027bdc60 | Kostas Papadimitriou | } catch (err) {};
|
353 | 8d08f18a | Kostas Papadimitriou | }, |
354 | 8d08f18a | Kostas Papadimitriou | |
355 | 8d08f18a | Kostas Papadimitriou | // check if vm is placed properly within the view
|
356 | 8d08f18a | Kostas Papadimitriou | // container (e.g. some views might have different
|
357 | 8d08f18a | Kostas Papadimitriou | // containers for terminated or running machines
|
358 | 8d08f18a | Kostas Papadimitriou | check_vm_container: function(vm){ |
359 | 8d08f18a | Kostas Papadimitriou | var el = this.vm(vm); |
360 | 8d08f18a | Kostas Papadimitriou | if (!el.length) { return }; |
361 | 8d08f18a | Kostas Papadimitriou | var self = this; |
362 | 8d08f18a | Kostas Papadimitriou | var selector = vm.is_active() ? 'vm_cont_active' : 'vm_cont_terminated'; |
363 | 8d08f18a | Kostas Papadimitriou | if (el.parent()[0] != this.sel(selector)[0]) { |
364 | 8d08f18a | Kostas Papadimitriou | var cont = this.sel(selector); |
365 | 8d08f18a | Kostas Papadimitriou | var self = this; |
366 | 7c90e31b | Kostas Papadimitriou | |
367 | b042eb04 | Kostas Papadimitriou | el.hide().appendTo(cont).fadeIn(300);
|
368 | 7c90e31b | Kostas Papadimitriou | $(window).trigger('resize'); |
369 | 7c90e31b | Kostas Papadimitriou | |
370 | 7c90e31b | Kostas Papadimitriou | //el.fadeOut(200, function() {
|
371 | 7c90e31b | Kostas Papadimitriou | //el.appendTo(cont);
|
372 | 7c90e31b | Kostas Papadimitriou | //el.fadeIn(200);
|
373 | 7c90e31b | Kostas Papadimitriou | //self.sel(selector).show(function(){
|
374 | 7c90e31b | Kostas Papadimitriou | //$(window).trigger("resize");
|
375 | 7c90e31b | Kostas Papadimitriou | //});
|
376 | 7c90e31b | Kostas Papadimitriou | //});
|
377 | 8d08f18a | Kostas Papadimitriou | } |
378 | 8d08f18a | Kostas Papadimitriou | }, |
379 | 8d08f18a | Kostas Papadimitriou | |
380 | 8d08f18a | Kostas Papadimitriou | __update_layout: function() { |
381 | 8d08f18a | Kostas Papadimitriou | this.update_layout();
|
382 | 8d08f18a | Kostas Papadimitriou | }, |
383 | 8d08f18a | Kostas Papadimitriou | |
384 | 8d08f18a | Kostas Papadimitriou | // append handlers for vm specific events
|
385 | 8d08f18a | Kostas Papadimitriou | __set_vm_handlers: function(vm) { |
386 | 8d08f18a | Kostas Papadimitriou | // show transition on vm status transit
|
387 | 8d08f18a | Kostas Papadimitriou | vm.bind('transition', _.bind(function(){this.show_transition(vm)}, this)); |
388 | 8d08f18a | Kostas Papadimitriou | this.set_vm_handlers(vm);
|
389 | 8d08f18a | Kostas Papadimitriou | }, |
390 | 8d08f18a | Kostas Papadimitriou | |
391 | 8d08f18a | Kostas Papadimitriou | // is vm in transition ??? show the progress spinner
|
392 | 8d08f18a | Kostas Papadimitriou | update_transition_state: function(vm) { |
393 | 1e882dd7 | Kostas Papadimitriou | if (vm.in_transition() && !vm.has_pending_action()){
|
394 | 8d08f18a | Kostas Papadimitriou | this.sel('vm_spinner', vm.id).show(); |
395 | 8d08f18a | Kostas Papadimitriou | } else {
|
396 | 8d08f18a | Kostas Papadimitriou | this.sel('vm_spinner', vm.id).hide(); |
397 | 8d08f18a | Kostas Papadimitriou | } |
398 | 8d08f18a | Kostas Papadimitriou | }, |
399 | 8d08f18a | Kostas Papadimitriou | |
400 | 8d08f18a | Kostas Papadimitriou | show_indicator: function(vm, action) { |
401 | 8d08f18a | Kostas Papadimitriou | var action = action || vm.pending_action;
|
402 | 8d08f18a | Kostas Papadimitriou | this.sel('vm_wave', vm.id).hide(); |
403 | 8d08f18a | Kostas Papadimitriou | this.sel('vm_spinner', vm.id).hide(); |
404 | 8d08f18a | Kostas Papadimitriou | this.vm(vm).find(".action-indicator").removeClass().addClass(action + " action-indicator").show(); |
405 | 8d08f18a | Kostas Papadimitriou | }, |
406 | 8d08f18a | Kostas Papadimitriou | |
407 | 8d08f18a | Kostas Papadimitriou | hide_indicator: function(vm) { |
408 | 8d08f18a | Kostas Papadimitriou | this.vm(vm).find(".action-indicator").removeClass().addClass("action-indicator").hide(); |
409 | 8d08f18a | Kostas Papadimitriou | this.update_transition_state(vm);
|
410 | 8d08f18a | Kostas Papadimitriou | }, |
411 | 8d08f18a | Kostas Papadimitriou | |
412 | 8d08f18a | Kostas Papadimitriou | // display transition animations
|
413 | 8d08f18a | Kostas Papadimitriou | show_transition: function(vm) { |
414 | 8d08f18a | Kostas Papadimitriou | var wave = this.sel('vm_wave', vm.id); |
415 | 8d08f18a | Kostas Papadimitriou | if (!wave || !wave.length) { return } |
416 | 8d08f18a | Kostas Papadimitriou | |
417 | 8d08f18a | Kostas Papadimitriou | var src = wave.attr('src'); |
418 | 8d08f18a | Kostas Papadimitriou | // change src to force gif play from the first frame
|
419 | 8d08f18a | Kostas Papadimitriou | // animate for 500 ms then hide
|
420 | 8d08f18a | Kostas Papadimitriou | wave.attr('src', "").show(); |
421 | 8d08f18a | Kostas Papadimitriou | wave.attr('src', src).fadeIn(200).delay(700).fadeOut(300, function() { |
422 | 8d08f18a | Kostas Papadimitriou | wave.hide(); |
423 | 8d08f18a | Kostas Papadimitriou | }); |
424 | 8d08f18a | Kostas Papadimitriou | }, |
425 | 8d08f18a | Kostas Papadimitriou | |
426 | 8d08f18a | Kostas Papadimitriou | connect_to_console: function(vm) { |
427 | 738a9b18 | Kostas Papadimitriou | // It seems that Safari allows popup windows only if the window.open
|
428 | 738a9b18 | Kostas Papadimitriou | // call is made within an html element click event context.
|
429 | 738a9b18 | Kostas Papadimitriou | // Otherwise its behaviour is based on "Block Pop-Up Windows"
|
430 | 738a9b18 | Kostas Papadimitriou | // setting, which when enabled no notification appears for the user.
|
431 | 738a9b18 | Kostas Papadimitriou | // Since there is no easy way to check for the setting value we use
|
432 | 738a9b18 | Kostas Papadimitriou | // async:false for the action call so that action success handler
|
433 | 738a9b18 | Kostas Papadimitriou | // which opens the new window is called inside the click event
|
434 | 738a9b18 | Kostas Papadimitriou | // context.
|
435 | 738a9b18 | Kostas Papadimitriou | var use_async = true; |
436 | 738a9b18 | Kostas Papadimitriou | if ($.client.browser == "Safari") { |
437 | 738a9b18 | Kostas Papadimitriou | use_async = false;
|
438 | 738a9b18 | Kostas Papadimitriou | } |
439 | 738a9b18 | Kostas Papadimitriou | |
440 | 8d08f18a | Kostas Papadimitriou | vm.call("console", function(console_data) { |
441 | 8d08f18a | Kostas Papadimitriou | var url = vm.get_console_url(console_data);
|
442 | a0839230 | Kostas Papadimitriou | snf.util.open_window(url, "VM_" + vm.get("id") + "_CONSOLE", {'scrollbars': 1, 'fullscreen': 0}); |
443 | 738a9b18 | Kostas Papadimitriou | }, undefined, {async: use_async}); |
444 | 8d08f18a | Kostas Papadimitriou | } |
445 | 8d08f18a | Kostas Papadimitriou | |
446 | 8d08f18a | Kostas Papadimitriou | }); |
447 | 8d08f18a | Kostas Papadimitriou | |
448 | 8d08f18a | Kostas Papadimitriou | // empty message view (just a wrapper to the element containing
|
449 | 8d08f18a | Kostas Papadimitriou | // the empty information message)
|
450 | 8d08f18a | Kostas Papadimitriou | views.EmptyView = views.View.extend({ |
451 | 8d08f18a | Kostas Papadimitriou | el: '#emptymachineslist' |
452 | 8d08f18a | Kostas Papadimitriou | }) |
453 | 8d08f18a | Kostas Papadimitriou | |
454 | 8d08f18a | Kostas Papadimitriou | views.VMActionsView = views.View.extend({ |
455 | 8d08f18a | Kostas Papadimitriou | |
456 | 8d08f18a | Kostas Papadimitriou | initialize: function(vm, parent, el, hide) { |
457 | 8d08f18a | Kostas Papadimitriou | this.hide = hide || false; |
458 | 8d08f18a | Kostas Papadimitriou | this.view = parent;
|
459 | 8d08f18a | Kostas Papadimitriou | this.vm = vm;
|
460 | 8d08f18a | Kostas Papadimitriou | this.vm_el = el;
|
461 | 8d08f18a | Kostas Papadimitriou | this.el = $("#" + parent.view_id + "-actions-" + vm.id); |
462 | 8d08f18a | Kostas Papadimitriou | this.all_action_names = _.keys(views.VMActionsView.STATUS_ACTIONS);
|
463 | 8d08f18a | Kostas Papadimitriou | |
464 | 8d08f18a | Kostas Papadimitriou | // state params
|
465 | 8d08f18a | Kostas Papadimitriou | this.selected_action = false; |
466 | 8d08f18a | Kostas Papadimitriou | |
467 | 8d08f18a | Kostas Papadimitriou | _.bindAll(this);
|
468 | 8d08f18a | Kostas Papadimitriou | window.acts = this;
|
469 | 8d08f18a | Kostas Papadimitriou | this.view_id = "vm_" + vm.id + "_actions"; |
470 | 8d08f18a | Kostas Papadimitriou | views.VMActionsView.__super__.initialize.call(this);
|
471 | 8d08f18a | Kostas Papadimitriou | |
472 | 6a3a5bf7 | Kostas Papadimitriou | this.hovered = false; |
473 | 40810d73 | Kostas Papadimitriou | this.set_hover_handlers();
|
474 | 8d08f18a | Kostas Papadimitriou | }, |
475 | 8d08f18a | Kostas Papadimitriou | |
476 | 8d08f18a | Kostas Papadimitriou | action: function(name) { |
477 | 8d08f18a | Kostas Papadimitriou | return $(this.el).find(".action-container." + name); |
478 | 8d08f18a | Kostas Papadimitriou | }, |
479 | 8d08f18a | Kostas Papadimitriou | |
480 | 8d08f18a | Kostas Papadimitriou | action_link: function(name) { |
481 | 8d08f18a | Kostas Papadimitriou | return this.action(name).find("a"); |
482 | 8d08f18a | Kostas Papadimitriou | }, |
483 | 8d08f18a | Kostas Papadimitriou | |
484 | 8d08f18a | Kostas Papadimitriou | action_confirm_cont: function(name) { |
485 | 8d08f18a | Kostas Papadimitriou | return this.action_confirm(name).parent(); |
486 | 8d08f18a | Kostas Papadimitriou | }, |
487 | 8d08f18a | Kostas Papadimitriou | |
488 | 8d08f18a | Kostas Papadimitriou | action_confirm: function(name) { |
489 | 8d08f18a | Kostas Papadimitriou | return this.action(name).find("button.yes"); |
490 | 8d08f18a | Kostas Papadimitriou | }, |
491 | 8d08f18a | Kostas Papadimitriou | |
492 | 8d08f18a | Kostas Papadimitriou | action_cancel: function(name) { |
493 | 8d08f18a | Kostas Papadimitriou | return this.action(name).find("button.no"); |
494 | 8d08f18a | Kostas Papadimitriou | }, |
495 | 8d08f18a | Kostas Papadimitriou | |
496 | 8d08f18a | Kostas Papadimitriou | hide_actions: function() { |
497 | 8d08f18a | Kostas Papadimitriou | $(this.el).find("a").css("visibility", "hidden"); |
498 | 8d08f18a | Kostas Papadimitriou | }, |
499 | 80bb2140 | Kostas Papadimitriou | |
500 | 80bb2140 | Kostas Papadimitriou | set_can_start: function() { |
501 | 80bb2140 | Kostas Papadimitriou | var el = $(this.el).find("a.action-start").parent(); |
502 | 80bb2140 | Kostas Papadimitriou | el.removeClass("disabled-visible");
|
503 | 80bb2140 | Kostas Papadimitriou | }, |
504 | 80bb2140 | Kostas Papadimitriou | |
505 | 80bb2140 | Kostas Papadimitriou | set_cannot_start: function() { |
506 | 80bb2140 | Kostas Papadimitriou | var el = $(this.el).find("a.action-start").parent(); |
507 | 80bb2140 | Kostas Papadimitriou | el.addClass("disabled-visible")
|
508 | 80bb2140 | Kostas Papadimitriou | }, |
509 | 8d08f18a | Kostas Papadimitriou | |
510 | 8d08f18a | Kostas Papadimitriou | // update the actions layout, depending on the selected actions
|
511 | 8d08f18a | Kostas Papadimitriou | update_layout: function() { |
512 | 80bb2140 | Kostas Papadimitriou | |
513 | 80bb2140 | Kostas Papadimitriou | if (this.vm.get('status') == 'STOPPED') { |
514 | 80bb2140 | Kostas Papadimitriou | if (this.vm.can_start()) { |
515 | 80bb2140 | Kostas Papadimitriou | this.set_can_start();
|
516 | 80bb2140 | Kostas Papadimitriou | } else {
|
517 | 80bb2140 | Kostas Papadimitriou | this.set_cannot_start();
|
518 | 80bb2140 | Kostas Papadimitriou | } |
519 | 80bb2140 | Kostas Papadimitriou | } |
520 | a09b6d74 | Kostas Papadimitriou | |
521 | a09b6d74 | Kostas Papadimitriou | if (!this.vm_handlers_initialized) { |
522 | 8d08f18a | Kostas Papadimitriou | this.vm = storage.vms.get(this.vm.id); |
523 | 6a3a5bf7 | Kostas Papadimitriou | this.init_vm_handlers();
|
524 | a09b6d74 | Kostas Papadimitriou | } |
525 | 122850c5 | Kostas Papadimitriou | |
526 | 8d08f18a | Kostas Papadimitriou | if (!this.vm) { return } |
527 | 6a3a5bf7 | Kostas Papadimitriou | |
528 | 40810d73 | Kostas Papadimitriou | if (!this.hovered && !this.vm.has_pending_action() && this.hide && !this.vm.action_error) { |
529 | 40810d73 | Kostas Papadimitriou | this.el.hide();
|
530 | 40810d73 | Kostas Papadimitriou | this.view.hide_indicator(this.vm); |
531 | 40810d73 | Kostas Papadimitriou | return
|
532 | 40810d73 | Kostas Papadimitriou | }; |
533 | 40810d73 | Kostas Papadimitriou | |
534 | 40810d73 | Kostas Papadimitriou | if (!this.el.is(":visible") && !this.hide) { return }; |
535 | 40810d73 | Kostas Papadimitriou | if (!this.handlers_initialized) { this.set_handlers(); } |
536 | 40810d73 | Kostas Papadimitriou | |
537 | 40810d73 | Kostas Papadimitriou | |
538 | 8d08f18a | Kostas Papadimitriou | // update selected action
|
539 | 8d08f18a | Kostas Papadimitriou | if (this.vm.pending_action) { |
540 | 8d08f18a | Kostas Papadimitriou | this.selected_action = this.vm.pending_action; |
541 | 8d08f18a | Kostas Papadimitriou | } else {
|
542 | 8d08f18a | Kostas Papadimitriou | this.selected_action = false; |
543 | 8d08f18a | Kostas Papadimitriou | } |
544 | 8d08f18a | Kostas Papadimitriou | |
545 | 8d08f18a | Kostas Papadimitriou | // vm actions tha can be performed
|
546 | 8d08f18a | Kostas Papadimitriou | var actions = this.vm.get_available_actions(); |
547 | 8d08f18a | Kostas Papadimitriou | |
548 | 8d08f18a | Kostas Papadimitriou | // had pending action but actions changed and now selected action is
|
549 | 8d08f18a | Kostas Papadimitriou | // not available, hide it from user
|
550 | 8d08f18a | Kostas Papadimitriou | if (this.selected_action && actions.indexOf(this.selected_action) == -1) { |
551 | 8d08f18a | Kostas Papadimitriou | this.reset();
|
552 | 8d08f18a | Kostas Papadimitriou | } |
553 | 8d08f18a | Kostas Papadimitriou | |
554 | 6a3a5bf7 | Kostas Papadimitriou | this.el.show();
|
555 | 6a3a5bf7 | Kostas Papadimitriou | |
556 | 6a3a5bf7 | Kostas Papadimitriou | if ((this.selected_action || this.hovered) && !this.vm.action_error) { |
557 | 8d08f18a | Kostas Papadimitriou | // show selected action
|
558 | 8d08f18a | Kostas Papadimitriou | $(this.el).show(); |
559 | 8d08f18a | Kostas Papadimitriou | $(this.el).find("a").css("visibility", "visible"); |
560 | 8d08f18a | Kostas Papadimitriou | // show action icon
|
561 | 8d08f18a | Kostas Papadimitriou | this.view.show_indicator(this.vm); |
562 | 8d08f18a | Kostas Papadimitriou | } else {
|
563 | 6a3a5bf7 | Kostas Papadimitriou | if (this.hide || this.vm.action_error) { |
564 | 8d08f18a | Kostas Papadimitriou | // view shows actions on machine hover
|
565 | 122850c5 | Kostas Papadimitriou | $(this.el).find("a").css("visibility", "hidden"); |
566 | 8d08f18a | Kostas Papadimitriou | } else {
|
567 | 6a3a5bf7 | Kostas Papadimitriou | if (!this.vm.action_error) { |
568 | 6a3a5bf7 | Kostas Papadimitriou | // view shows actions always
|
569 | 6a3a5bf7 | Kostas Papadimitriou | $(this.el).find("a").css("visibility", "visible"); |
570 | 6a3a5bf7 | Kostas Papadimitriou | $(this.el).show(); |
571 | 6a3a5bf7 | Kostas Papadimitriou | } |
572 | 8d08f18a | Kostas Papadimitriou | } |
573 | 8d08f18a | Kostas Papadimitriou | |
574 | 8d08f18a | Kostas Papadimitriou | this.view.hide_indicator(this.vm); |
575 | 8d08f18a | Kostas Papadimitriou | } |
576 | a09b6d74 | Kostas Papadimitriou | |
577 | 8d08f18a | Kostas Papadimitriou | // update action link styles and shit
|
578 | 8d08f18a | Kostas Papadimitriou | _.each(models.VM.ACTIONS, function(action, index) {
|
579 | 8d08f18a | Kostas Papadimitriou | if (actions.indexOf(action) > -1) { |
580 | 8d08f18a | Kostas Papadimitriou | this.action(action).removeClass("disabled"); |
581 | 13925182 | Kostas Papadimitriou | var inactive = models.VM.AVAILABLE_ACTIONS_INACTIVE[action];
|
582 | 13925182 | Kostas Papadimitriou | |
583 | 2b516a38 | Kostas Papadimitriou | if (inactive && !_.contains(inactive, this.vm.get('status'))) { |
584 | 13925182 | Kostas Papadimitriou | this.action(action).addClass("inactive"); |
585 | 13925182 | Kostas Papadimitriou | } else {
|
586 | 13925182 | Kostas Papadimitriou | this.action(action).removeClass("inactive"); |
587 | 13925182 | Kostas Papadimitriou | } |
588 | 13925182 | Kostas Papadimitriou | |
589 | 8d08f18a | Kostas Papadimitriou | if (this.selected_action == action) { |
590 | 8d08f18a | Kostas Papadimitriou | this.action_confirm_cont(action).css('display', 'block'); |
591 | 8d08f18a | Kostas Papadimitriou | this.action_confirm(action).show();
|
592 | 8d08f18a | Kostas Papadimitriou | this.action(action).removeClass("disabled"); |
593 | 8d08f18a | Kostas Papadimitriou | this.action_link(action).addClass("selected"); |
594 | 8d08f18a | Kostas Papadimitriou | } else {
|
595 | 8d08f18a | Kostas Papadimitriou | this.action_confirm_cont(action).hide();
|
596 | 8d08f18a | Kostas Papadimitriou | this.action_confirm(action).hide();
|
597 | 8d08f18a | Kostas Papadimitriou | this.action_link(action).removeClass("selected"); |
598 | 8d08f18a | Kostas Papadimitriou | } |
599 | 8d08f18a | Kostas Papadimitriou | } else {
|
600 | 8d08f18a | Kostas Papadimitriou | this.action().hide();
|
601 | 8d08f18a | Kostas Papadimitriou | this.action(action).addClass("disabled"); |
602 | 8d08f18a | Kostas Papadimitriou | this.action_confirm(action).hide();
|
603 | 8d08f18a | Kostas Papadimitriou | } |
604 | 8d08f18a | Kostas Papadimitriou | }, this);
|
605 | 8d08f18a | Kostas Papadimitriou | }, |
606 | 8d08f18a | Kostas Papadimitriou | |
607 | 6a3a5bf7 | Kostas Papadimitriou | init_vm_handlers: function() { |
608 | 6a3a5bf7 | Kostas Papadimitriou | try {
|
609 | 6a3a5bf7 | Kostas Papadimitriou | this.vm.unbind("action:fail", this.update_layout) |
610 | 6a3a5bf7 | Kostas Papadimitriou | this.vm.unbind("action:fail:reset", this.update_layout) |
611 | a09b6d74 | Kostas Papadimitriou | } catch (err) { console.log("Error")}; |
612 | a09b6d74 | Kostas Papadimitriou | |
613 | 6a3a5bf7 | Kostas Papadimitriou | this.vm.bind("action:fail", this.update_layout) |
614 | 6a3a5bf7 | Kostas Papadimitriou | this.vm.bind("action:fail:reset", this.update_layout) |
615 | a09b6d74 | Kostas Papadimitriou | |
616 | a09b6d74 | Kostas Papadimitriou | this.vm_handlers_initialized = true; |
617 | 6a3a5bf7 | Kostas Papadimitriou | }, |
618 | 40810d73 | Kostas Papadimitriou | |
619 | 40810d73 | Kostas Papadimitriou | set_hover_handlers: function() { |
620 | 8d08f18a | Kostas Papadimitriou | // vm container hover (icon view)
|
621 | 6a3a5bf7 | Kostas Papadimitriou | this.view.vm(this.vm).hover(_.bind(function() { |
622 | 6a3a5bf7 | Kostas Papadimitriou | this.hovered = true; |
623 | 6a3a5bf7 | Kostas Papadimitriou | this.update_layout();
|
624 | 8d08f18a | Kostas Papadimitriou | |
625 | 6a3a5bf7 | Kostas Papadimitriou | }, this), _.bind(function() { |
626 | c343513e | Kostas Papadimitriou | this.hovered = false; |
627 | c343513e | Kostas Papadimitriou | this.update_layout();
|
628 | 6a3a5bf7 | Kostas Papadimitriou | }, this));
|
629 | 40810d73 | Kostas Papadimitriou | }, |
630 | 6a3a5bf7 | Kostas Papadimitriou | |
631 | 40810d73 | Kostas Papadimitriou | // bind event handlers
|
632 | 40810d73 | Kostas Papadimitriou | set_handlers: function() { |
633 | 40810d73 | Kostas Papadimitriou | var self = this; |
634 | 40810d73 | Kostas Papadimitriou | var vm = this.vm; |
635 | 40810d73 | Kostas Papadimitriou | |
636 | 40810d73 | Kostas Papadimitriou | // initial hide
|
637 | 40810d73 | Kostas Papadimitriou | if (this.hide) { $(this.el).hide() }; |
638 | 8d08f18a | Kostas Papadimitriou | |
639 | 8d08f18a | Kostas Papadimitriou | // action links events
|
640 | 8d08f18a | Kostas Papadimitriou | _.each(models.VM.ACTIONS, function(action) {
|
641 | 8d08f18a | Kostas Papadimitriou | var action = action;
|
642 | 8d08f18a | Kostas Papadimitriou | // indicator hovers
|
643 | 8d08f18a | Kostas Papadimitriou | this.view.vm(this.vm).find(".action-container."+action+" a").hover(function() { |
644 | 8d08f18a | Kostas Papadimitriou | self.view.show_indicator(self.vm, action); |
645 | 8d08f18a | Kostas Papadimitriou | }, function() {
|
646 | 8d08f18a | Kostas Papadimitriou | // clear or show selected action indicator
|
647 | 8d08f18a | Kostas Papadimitriou | if (self.vm.pending_action) {
|
648 | 8d08f18a | Kostas Papadimitriou | self.view.show_indicator(self.vm); |
649 | 8d08f18a | Kostas Papadimitriou | } else {
|
650 | 8d08f18a | Kostas Papadimitriou | self.view.hide_indicator(self.vm); |
651 | 8d08f18a | Kostas Papadimitriou | } |
652 | 8d08f18a | Kostas Papadimitriou | }) |
653 | 8d08f18a | Kostas Papadimitriou | |
654 | 8d08f18a | Kostas Papadimitriou | // action links click events
|
655 | 8d08f18a | Kostas Papadimitriou | $(this.el).find(".action-container."+action+" a").click(function(ev) { |
656 | 8d08f18a | Kostas Papadimitriou | ev.preventDefault(); |
657 | 2c239b28 | Kostas Papadimitriou | if (action == "start" && !self.vm.can_start() && !vm.in_error_state()) { |
658 | 80bb2140 | Kostas Papadimitriou | ui.main.vm_resize_view.show_with_warning(self.vm); |
659 | 80bb2140 | Kostas Papadimitriou | return;
|
660 | 80bb2140 | Kostas Papadimitriou | } |
661 | 80bb2140 | Kostas Papadimitriou | |
662 | 13925182 | Kostas Papadimitriou | if (action == "resize") { |
663 | 13925182 | Kostas Papadimitriou | ui.main.vm_resize_view.show(self.vm); |
664 | 80bb2140 | Kostas Papadimitriou | return;
|
665 | 13925182 | Kostas Papadimitriou | } else {
|
666 | 13925182 | Kostas Papadimitriou | self.set(action); |
667 | 13925182 | Kostas Papadimitriou | } |
668 | 8d08f18a | Kostas Papadimitriou | }).data("action", action);
|
669 | 8d08f18a | Kostas Papadimitriou | |
670 | 8d08f18a | Kostas Papadimitriou | // confirms
|
671 | 8d08f18a | Kostas Papadimitriou | $(this.el).find(".action-container."+action+" button.no").click(function(ev) { |
672 | 8d08f18a | Kostas Papadimitriou | ev.preventDefault(); |
673 | 8d08f18a | Kostas Papadimitriou | self.reset(); |
674 | 8d08f18a | Kostas Papadimitriou | }); |
675 | 8d08f18a | Kostas Papadimitriou | |
676 | 8d08f18a | Kostas Papadimitriou | // cancels
|
677 | 8d08f18a | Kostas Papadimitriou | $(this.el).find(".action-container."+action+" button.yes").click(function(ev) { |
678 | 8d08f18a | Kostas Papadimitriou | ev.preventDefault(); |
679 | b042eb04 | Kostas Papadimitriou | // override console
|
680 | b042eb04 | Kostas Papadimitriou | // ui needs to act (open the console window)
|
681 | b042eb04 | Kostas Papadimitriou | if (action == "console") { |
682 | b042eb04 | Kostas Papadimitriou | self.view.connect_to_console(self.vm); |
683 | b042eb04 | Kostas Papadimitriou | } else {
|
684 | b042eb04 | Kostas Papadimitriou | self.vm.call(action); |
685 | b042eb04 | Kostas Papadimitriou | } |
686 | 8d08f18a | Kostas Papadimitriou | self.reset(); |
687 | 8d08f18a | Kostas Papadimitriou | }); |
688 | 8d08f18a | Kostas Papadimitriou | }, this);
|
689 | 40810d73 | Kostas Papadimitriou | |
690 | 40810d73 | Kostas Papadimitriou | this.handlers_initialized = true; |
691 | 8d08f18a | Kostas Papadimitriou | }, |
692 | 8d08f18a | Kostas Papadimitriou | |
693 | 8d08f18a | Kostas Papadimitriou | // reset actions
|
694 | 8d08f18a | Kostas Papadimitriou | reset: function() { |
695 | 8d08f18a | Kostas Papadimitriou | var prev_action = this.selected_action; |
696 | 8d08f18a | Kostas Papadimitriou | this.selected_action = false; |
697 | 8d08f18a | Kostas Papadimitriou | this.vm.clear_pending_action();
|
698 | 8d08f18a | Kostas Papadimitriou | this.trigger("change", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true}); |
699 | 8d08f18a | Kostas Papadimitriou | this.trigger("remove", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true}); |
700 | 8d08f18a | Kostas Papadimitriou | }, |
701 | 8d08f18a | Kostas Papadimitriou | |
702 | 8d08f18a | Kostas Papadimitriou | // set selected action
|
703 | 8d08f18a | Kostas Papadimitriou | set: function(action_name) { |
704 | d6d1f049 | Kostas Papadimitriou | if (action_name == "snapshot") { return } |
705 | 8d08f18a | Kostas Papadimitriou | this.selected_action = action_name;
|
706 | 8d08f18a | Kostas Papadimitriou | this.vm.update_pending_action(this.selected_action); |
707 | 8d08f18a | Kostas Papadimitriou | this.view.vm(this.vm).find(".action-indicator").show().removeClass().addClass(action_name + " action-indicator"); |
708 | 8d08f18a | Kostas Papadimitriou | this.trigger("change", {'action': this.selected_action, 'vm': this.vm, 'view': this}); |
709 | 8d08f18a | Kostas Papadimitriou | }, |
710 | 8d08f18a | Kostas Papadimitriou | |
711 | 8d08f18a | Kostas Papadimitriou | update: function() { |
712 | 8d08f18a | Kostas Papadimitriou | } |
713 | 8d08f18a | Kostas Papadimitriou | }) |
714 | 8d08f18a | Kostas Papadimitriou | |
715 | 8d08f18a | Kostas Papadimitriou | |
716 | 8d08f18a | Kostas Papadimitriou | views.VMActionsView.STATUS_ACTIONS = { |
717 | 8d08f18a | Kostas Papadimitriou | 'reboot': ['UNKOWN', 'ACTIVE', 'REBOOT'], |
718 | 8d08f18a | Kostas Papadimitriou | 'shutdown': ['UNKOWN', 'ACTIVE', 'REBOOT'], |
719 | 8d08f18a | Kostas Papadimitriou | 'console': ['ACTIVE'], |
720 | 8d08f18a | Kostas Papadimitriou | 'start': ['UNKOWN', 'STOPPED'], |
721 | 13925182 | Kostas Papadimitriou | 'resize': ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD'], |
722 | de0693f8 | Kostas Papadimitriou | 'snapshot': ['ACTIVE', 'STOPPED'], |
723 | 8d08f18a | Kostas Papadimitriou | 'destroy': ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD'] |
724 | 8d08f18a | Kostas Papadimitriou | }; |
725 | 8d08f18a | Kostas Papadimitriou | |
726 | 8d08f18a | Kostas Papadimitriou | // UI helpers
|
727 | 8d08f18a | Kostas Papadimitriou | var uihelpers = snf.ui.helpers = {};
|
728 | f5b3adc1 | Kostas Papadimitriou | |
729 | f5b3adc1 | Kostas Papadimitriou | // OS icon helpers
|
730 | f5b3adc1 | Kostas Papadimitriou | var os_icon = uihelpers.os_icon = function(os) { |
731 | 8d08f18a | Kostas Papadimitriou | var icons = window.os_icons;
|
732 | d42817ee | Olga Brani | if (!icons) { return "unknown" } |
733 | 8d08f18a | Kostas Papadimitriou | if (icons.indexOf(os) == -1) { |
734 | d42817ee | Olga Brani | os = "unknown";
|
735 | 8d08f18a | Kostas Papadimitriou | } |
736 | 8d08f18a | Kostas Papadimitriou | return os;
|
737 | 8d08f18a | Kostas Papadimitriou | } |
738 | f5b3adc1 | Kostas Papadimitriou | |
739 | f5b3adc1 | Kostas Papadimitriou | var os_icon_path = uihelpers.os_icon_path = function(os, size, active) { |
740 | 8d08f18a | Kostas Papadimitriou | size = size || "small";
|
741 | f5b3adc1 | Kostas Papadimitriou | if (active == undefined) { active = true }; |
742 | 8d08f18a | Kostas Papadimitriou | |
743 | f5b3adc1 | Kostas Papadimitriou | var icon = os_icon(os);
|
744 | f5b3adc1 | Kostas Papadimitriou | if (active) {
|
745 | 8d08f18a | Kostas Papadimitriou | icon = icon + "-on";
|
746 | 8d08f18a | Kostas Papadimitriou | } else {
|
747 | 8d08f18a | Kostas Papadimitriou | icon = icon + "-off";
|
748 | 8d08f18a | Kostas Papadimitriou | } |
749 | 8d08f18a | Kostas Papadimitriou | |
750 | c62c6b91 | Kostas Papadimitriou | return (snf.config.machines_icons_url + "{0}/{1}.png").format(size, icon) |
751 | 8d08f18a | Kostas Papadimitriou | } |
752 | f5b3adc1 | Kostas Papadimitriou | |
753 | f5b3adc1 | Kostas Papadimitriou | var os_icon_tag = uihelpers.os_icon_tag = function (os, size, active, attrs) { |
754 | f5b3adc1 | Kostas Papadimitriou | attrs = attrs || {}; |
755 | f5b3adc1 | Kostas Papadimitriou | return '<img src="{0}" />'.format(os_icon_path(os, size, active)); |
756 | f5b3adc1 | Kostas Papadimitriou | } |
757 | f5b3adc1 | Kostas Papadimitriou | |
758 | f5b3adc1 | Kostas Papadimitriou | // VM Icon helpers
|
759 | f5b3adc1 | Kostas Papadimitriou | //
|
760 | f5b3adc1 | Kostas Papadimitriou | // identify icon
|
761 | f5b3adc1 | Kostas Papadimitriou | var vm_icon = uihelpers.vm_icon = function(vm) { |
762 | f5b3adc1 | Kostas Papadimitriou | return os_icon(vm.get_os());
|
763 | f5b3adc1 | Kostas Papadimitriou | } |
764 | f5b3adc1 | Kostas Papadimitriou | |
765 | f5b3adc1 | Kostas Papadimitriou | // get icon url
|
766 | f5b3adc1 | Kostas Papadimitriou | var vm_icon_path = uihelpers.vm_icon_path = function(vm, size) { |
767 | f5b3adc1 | Kostas Papadimitriou | return os_icon_path(vm.get_os(), size, vm.is_active());
|
768 | f5b3adc1 | Kostas Papadimitriou | } |
769 | 8d08f18a | Kostas Papadimitriou | |
770 | 8d08f18a | Kostas Papadimitriou | // get icon IMG tag
|
771 | 8d08f18a | Kostas Papadimitriou | var vm_icon_tag = uihelpers.vm_icon_tag = function (vm, size, attrs) { |
772 | f5b3adc1 | Kostas Papadimitriou | return os_icon_tag(vm.get_os(), size, vm.is_active(), attrs);
|
773 | 8d08f18a | Kostas Papadimitriou | } |
774 | 8d08f18a | Kostas Papadimitriou | |
775 | 9ffd10ce | Kostas Papadimitriou | |
776 | 8d08f18a | Kostas Papadimitriou | snf.ui = _.extend(snf.ui, bb.Events); |
777 | 9ffd10ce | Kostas Papadimitriou | snf.ui.trigger_error = function(code, msg, error, extra) { |
778 | 52a432c7 | Kostas Papadimitriou | if (msg.match(/Script error/i)) { |
779 | 52a432c7 | Kostas Papadimitriou | // No usefull information to display in this case. Plus it's an
|
780 | 52a432c7 | Kostas Papadimitriou | // exception that probably doesn't affect our app.
|
781 | 52a432c7 | Kostas Papadimitriou | return 0; |
782 | 52a432c7 | Kostas Papadimitriou | } |
783 | 52a432c7 | Kostas Papadimitriou | snf.ui.trigger("error", { code:code, msg:msg, error:error, extra:extra || {} }); |
784 | 9ffd10ce | Kostas Papadimitriou | }; |
785 | 365af933 | Kostas Papadimitriou | |
786 | 365af933 | Kostas Papadimitriou | views.VMPortView = views.ext.ModelView.extend({ |
787 | 365af933 | Kostas Papadimitriou | tpl: '#vm-port-view-tpl', |
788 | 365af933 | Kostas Papadimitriou | classes: 'port-item clearfix', |
789 | 9145aad9 | Kostas Papadimitriou | |
790 | 9145aad9 | Kostas Papadimitriou | update_in_progress: function() { |
791 | 5d213e95 | Kostas Papadimitriou | if (this.model.get("in_progress_no_vm")) { |
792 | 9145aad9 | Kostas Papadimitriou | this.set_in_progress();
|
793 | 9145aad9 | Kostas Papadimitriou | } else {
|
794 | 9145aad9 | Kostas Papadimitriou | this.unset_in_progress();
|
795 | 9145aad9 | Kostas Papadimitriou | } |
796 | 9145aad9 | Kostas Papadimitriou | }, |
797 | 9145aad9 | Kostas Papadimitriou | |
798 | 9145aad9 | Kostas Papadimitriou | set_in_progress: function() { |
799 | 9145aad9 | Kostas Papadimitriou | this.el.find(".type").hide(); |
800 | 90fbedb6 | Kostas Papadimitriou | this.el.find(".in-progress").removeClass("hidden").show(); |
801 | 9145aad9 | Kostas Papadimitriou | }, |
802 | 9145aad9 | Kostas Papadimitriou | |
803 | 9145aad9 | Kostas Papadimitriou | unset_in_progress: function() { |
804 | 9145aad9 | Kostas Papadimitriou | this.el.find(".type").show(); |
805 | 9145aad9 | Kostas Papadimitriou | this.el.find(".in-progress").hide(); |
806 | 9145aad9 | Kostas Papadimitriou | }, |
807 | 9145aad9 | Kostas Papadimitriou | |
808 | 9145aad9 | Kostas Papadimitriou | disconnect_port: function(model, e) { |
809 | 9145aad9 | Kostas Papadimitriou | e && e.stopPropagation(); |
810 | 9145aad9 | Kostas Papadimitriou | var network = this.model.get("network"); |
811 | 9145aad9 | Kostas Papadimitriou | this.model.actions.reset_pending();
|
812 | 9145aad9 | Kostas Papadimitriou | this.model.disconnect(_.bind(this.disconnect_port_complete, this)); |
813 | 9145aad9 | Kostas Papadimitriou | }, |
814 | 9145aad9 | Kostas Papadimitriou | |
815 | 9145aad9 | Kostas Papadimitriou | disconnect_port_complete: function() { |
816 | 9145aad9 | Kostas Papadimitriou | }, |
817 | 9145aad9 | Kostas Papadimitriou | |
818 | 365af933 | Kostas Papadimitriou | get_network_name: function() { |
819 | 365af933 | Kostas Papadimitriou | var network = this.model.get('network'); |
820 | 365af933 | Kostas Papadimitriou | var name = network && network.get('name'); |
821 | 365af933 | Kostas Papadimitriou | if (!name) {
|
822 | 33299f73 | Kostas Papadimitriou | if (network && network.get('is_public')) { |
823 | efb056c0 | Kostas Papadimitriou | name = 'Internet'
|
824 | efb056c0 | Kostas Papadimitriou | } else {
|
825 | efb056c0 | Kostas Papadimitriou | name = '(no network name)'
|
826 | efb056c0 | Kostas Papadimitriou | } |
827 | 365af933 | Kostas Papadimitriou | } |
828 | af32efaa | Kostas Papadimitriou | var truncate_length = this.parent_view.options.truncate || 40; |
829 | 6201f0e3 | Kostas Papadimitriou | name = synnefo.util.truncate(name, truncate_length, '...');
|
830 | 365af933 | Kostas Papadimitriou | return name || 'Loading...'; |
831 | 365af933 | Kostas Papadimitriou | }, |
832 | 365af933 | Kostas Papadimitriou | |
833 | 365af933 | Kostas Papadimitriou | get_network_icon: function() { |
834 | 365af933 | Kostas Papadimitriou | var ico;
|
835 | 365af933 | Kostas Papadimitriou | var network = this.model.get('network'); |
836 | 365af933 | Kostas Papadimitriou | if (network) {
|
837 | 365af933 | Kostas Papadimitriou | ico = network.get('is_public') ? 'internet-small.png' : 'network-small.png'; |
838 | 365af933 | Kostas Papadimitriou | } else {
|
839 | 365af933 | Kostas Papadimitriou | ico = 'network-small.png';
|
840 | 365af933 | Kostas Papadimitriou | } |
841 | 365af933 | Kostas Papadimitriou | return synnefo.config.media_url + 'images/' + ico; |
842 | 365af933 | Kostas Papadimitriou | }, |
843 | 365af933 | Kostas Papadimitriou | }); |
844 | 365af933 | Kostas Papadimitriou | |
845 | 365af933 | Kostas Papadimitriou | views.VMPortListView = views.ext.CollectionView.extend({ |
846 | 365af933 | Kostas Papadimitriou | tpl: '#vm-port-list-view-tpl', |
847 | 365af933 | Kostas Papadimitriou | model_view_cls: views.VMPortView
|
848 | 365af933 | Kostas Papadimitriou | }); |
849 | 365af933 | Kostas Papadimitriou | |
850 | 365af933 | Kostas Papadimitriou | views.VMPortIpView = views.ext.ModelView.extend({ |
851 | 9145aad9 | Kostas Papadimitriou | tpl: '#vm-port-ip-tpl', |
852 | 9145aad9 | Kostas Papadimitriou | css_classes: "clearfix" |
853 | 365af933 | Kostas Papadimitriou | }); |
854 | 365af933 | Kostas Papadimitriou | |
855 | 365af933 | Kostas Papadimitriou | views.VMPortIpsView = views.ext.CollectionView.extend({ |
856 | 365af933 | Kostas Papadimitriou | tpl: '#vm-port-ips-tpl', |
857 | 365af933 | Kostas Papadimitriou | model_view_cls: views.VMPortIpView
|
858 | 365af933 | Kostas Papadimitriou | }); |
859 | 8d08f18a | Kostas Papadimitriou | |
860 | 8d08f18a | Kostas Papadimitriou | })(this); |