Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / ui / static / snf / js / ui / web / ui_public_keys_view.js @ 375a9cb5

History | View | Annotate | Download (10.7 kB)

1 ac07ff0d Kostas Papadimitriou
// Copyright 2013 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 e9392f3c Kostas Papadimitriou
;(function(root){
36 ac07ff0d Kostas Papadimitriou
    
37 e9392f3c Kostas Papadimitriou
    // root
38 e9392f3c Kostas Papadimitriou
    var root = root;
39 e9392f3c Kostas Papadimitriou
    
40 e9392f3c Kostas Papadimitriou
    // setup namepsaces
41 e9392f3c Kostas Papadimitriou
    var snf = root.synnefo = root.synnefo || {};
42 e9392f3c Kostas Papadimitriou
    var models = snf.models = snf.models || {}
43 e9392f3c Kostas Papadimitriou
    var storage = snf.storage = snf.storage || {};
44 e9392f3c Kostas Papadimitriou
    var ui = snf.ui = snf.ui || {};
45 ac07ff0d Kostas Papadimitriou
    var util = snf.util || {};
46 e9392f3c Kostas Papadimitriou
    var views = snf.views = snf.views || {}
47 e9392f3c Kostas Papadimitriou
48 e9392f3c Kostas Papadimitriou
    // shortcuts
49 e9392f3c Kostas Papadimitriou
    var bb = root.Backbone;
50 e9392f3c Kostas Papadimitriou
    
51 ac07ff0d Kostas Papadimitriou
    // logging
52 ac07ff0d Kostas Papadimitriou
    var logger = new snf.logging.logger("SNF-VIEWS");
53 ac07ff0d Kostas Papadimitriou
    var debug = _.bind(logger.debug, logger);
54 ac07ff0d Kostas Papadimitriou
      
55 ac07ff0d Kostas Papadimitriou
    views.PublicKeyCreateView = views.Overlay.extend({
56 ac07ff0d Kostas Papadimitriou
        view_id: "public_key_create_view",
57 556dcd88 Kostas Papadimitriou
        
58 ac07ff0d Kostas Papadimitriou
        content_selector: "#public-key-create-content",
59 ac07ff0d Kostas Papadimitriou
        css_class: 'overlay-public-key-create overlay-info',
60 ac07ff0d Kostas Papadimitriou
        overlay_id: "public_key_create_view",
61 e9392f3c Kostas Papadimitriou
62 ac07ff0d Kostas Papadimitriou
        subtitle: "",
63 ac07ff0d Kostas Papadimitriou
        title: "Create new SSH key",
64 ac07ff0d Kostas Papadimitriou
        
65 ac07ff0d Kostas Papadimitriou
        initialize: function() {
66 ac07ff0d Kostas Papadimitriou
            views.PublicKeyCreateView.__super__.initialize.apply(this, arguments);
67 ac07ff0d Kostas Papadimitriou
            this.form = this.$("form.model-form");
68 ac07ff0d Kostas Papadimitriou
            this.submit = this.$(".form-actions .submit");
69 ac07ff0d Kostas Papadimitriou
            this.cancel = this.$(".form-actions .cancel");
70 ac07ff0d Kostas Papadimitriou
            this.close = this.$(".form-actions .close");
71 ac07ff0d Kostas Papadimitriou
            this.error = this.$(".error-msg");
72 ac07ff0d Kostas Papadimitriou
            this.model_actions = this.$(".model-actions");
73 ac07ff0d Kostas Papadimitriou
            this.form_actions_cont = this.$(".form-actions");
74 ac07ff0d Kostas Papadimitriou
            this.form_actions = this.$(".form-actions .form-action");
75 ac07ff0d Kostas Papadimitriou
76 ac07ff0d Kostas Papadimitriou
            this.input_name = this.form.find(".input-name");
77 ac07ff0d Kostas Papadimitriou
            this.input_key = this.form.find("textarea");
78 ac07ff0d Kostas Papadimitriou
            this.input_file = this.form.find(".content-input-file");
79 e9392f3c Kostas Papadimitriou
            
80 ac07ff0d Kostas Papadimitriou
            this.generate_action = this.$(".model-action.generate");
81 ac07ff0d Kostas Papadimitriou
            this.generate_msg = this.$(".generate-msg");
82 ac07ff0d Kostas Papadimitriou
            this.generate_download = this.generate_msg.find(".download");
83 ac07ff0d Kostas Papadimitriou
            this.generate_success = this.generate_msg.find(".success");
84 ac07ff0d Kostas Papadimitriou
85 ac07ff0d Kostas Papadimitriou
            this.generating = false;
86 ac07ff0d Kostas Papadimitriou
            this.in_progress = false;
87 ac07ff0d Kostas Papadimitriou
            this.init_handlers();
88 ac07ff0d Kostas Papadimitriou
        },
89 e9392f3c Kostas Papadimitriou
90 ac07ff0d Kostas Papadimitriou
        _init_reader: function() {
91 ac07ff0d Kostas Papadimitriou
          var opts = {
92 ac07ff0d Kostas Papadimitriou
            dragClass: "drag",
93 ac07ff0d Kostas Papadimitriou
            accept: false,
94 ac07ff0d Kostas Papadimitriou
            readAsDefault: 'BinaryString',
95 ac07ff0d Kostas Papadimitriou
            on: {
96 ac07ff0d Kostas Papadimitriou
              loadend: _.bind(function(e, file) {
97 ac07ff0d Kostas Papadimitriou
                this.input_key.val(e.target.result);
98 ac07ff0d Kostas Papadimitriou
                this.validate_form();
99 ac07ff0d Kostas Papadimitriou
              }, this),
100 ac07ff0d Kostas Papadimitriou
              error: function() {}
101 e9392f3c Kostas Papadimitriou
            }
102 ac07ff0d Kostas Papadimitriou
          }
103 ac07ff0d Kostas Papadimitriou
          FileReaderJS.setupInput(this.input_file.get(0), opts);
104 e9392f3c Kostas Papadimitriou
        },
105 e9392f3c Kostas Papadimitriou
        
106 ac07ff0d Kostas Papadimitriou
        validate_form: function() {
107 ac07ff0d Kostas Papadimitriou
          this.form.find(".error").removeClass("error");
108 ac07ff0d Kostas Papadimitriou
          this.form.find(".errors").empty();
109 ac07ff0d Kostas Papadimitriou
110 ac07ff0d Kostas Papadimitriou
          var name = _.trim(this.input_name.val());
111 ac07ff0d Kostas Papadimitriou
          var key = _.trim(this.input_key.val());
112 ac07ff0d Kostas Papadimitriou
          var error = false;
113 ac07ff0d Kostas Papadimitriou
114 ac07ff0d Kostas Papadimitriou
          if (!name) {
115 ac07ff0d Kostas Papadimitriou
            this.input_name.parent().addClass("error");
116 ac07ff0d Kostas Papadimitriou
            error = true;
117 ac07ff0d Kostas Papadimitriou
          }
118 ac07ff0d Kostas Papadimitriou
119 ac07ff0d Kostas Papadimitriou
          if (!key) {
120 ac07ff0d Kostas Papadimitriou
            this.input_key.parent().addClass("error");
121 ac07ff0d Kostas Papadimitriou
            error = true;
122 ac07ff0d Kostas Papadimitriou
          } else {
123 ac07ff0d Kostas Papadimitriou
            try {
124 ac07ff0d Kostas Papadimitriou
              key = snf.util.validatePublicKey(key);
125 ac07ff0d Kostas Papadimitriou
            } catch (err) {
126 ac07ff0d Kostas Papadimitriou
              this.input_key.parent().addClass("error");
127 ac07ff0d Kostas Papadimitriou
              this.input_key.parent().find(".errors").append("<span class='error'>"+err+"</span>");
128 ac07ff0d Kostas Papadimitriou
              error = true;
129 ac07ff0d Kostas Papadimitriou
            }
130 ac07ff0d Kostas Papadimitriou
          }
131 e9392f3c Kostas Papadimitriou
132 ac07ff0d Kostas Papadimitriou
          if (error) { return false }
133 ac07ff0d Kostas Papadimitriou
          return { key: key, name: name }
134 e9392f3c Kostas Papadimitriou
        },
135 e9392f3c Kostas Papadimitriou
136 ac07ff0d Kostas Papadimitriou
        _reset_form: function() {
137 ac07ff0d Kostas Papadimitriou
          this.input_name.val("");
138 ac07ff0d Kostas Papadimitriou
          this.input_key.val("");
139 ac07ff0d Kostas Papadimitriou
          this.input_file.val("");
140 ac07ff0d Kostas Papadimitriou
          this.form.find(".error").removeClass("error");
141 ac07ff0d Kostas Papadimitriou
          this.form.find(".errors").empty();
142 ac07ff0d Kostas Papadimitriou
          this.form.show();
143 ac07ff0d Kostas Papadimitriou
          this.generate_msg.hide();
144 ac07ff0d Kostas Papadimitriou
          this.form_actions.show();
145 ac07ff0d Kostas Papadimitriou
          this.input_file.show();
146 ac07ff0d Kostas Papadimitriou
          this.close.hide();
147 ac07ff0d Kostas Papadimitriou
          this.error.hide();
148 ac07ff0d Kostas Papadimitriou
          this.model_actions.show();
149 556dcd88 Kostas Papadimitriou
        },
150 556dcd88 Kostas Papadimitriou
151 ac07ff0d Kostas Papadimitriou
        beforeOpen: function() {
152 ac07ff0d Kostas Papadimitriou
          this.private_key = undefined;
153 ac07ff0d Kostas Papadimitriou
          this._reset_form();
154 ac07ff0d Kostas Papadimitriou
          this._init_reader();
155 ac07ff0d Kostas Papadimitriou
          this.unset_in_progress();
156 c1c836ec Kostas Papadimitriou
        },
157 a45b4f10 Kostas Papadimitriou
158 a45b4f10 Kostas Papadimitriou
        onOpen: function() {
159 a45b4f10 Kostas Papadimitriou
          views.PublicKeyCreateView.__super__.onOpen.apply(this, arguments);
160 a45b4f10 Kostas Papadimitriou
          this.input_name.focus();
161 a45b4f10 Kostas Papadimitriou
        },
162 c1c836ec Kostas Papadimitriou
        
163 ac07ff0d Kostas Papadimitriou
        init_handlers: function() {
164 ac07ff0d Kostas Papadimitriou
          this.cancel.click(_.bind(function() { this.hide(); }, this));
165 ac07ff0d Kostas Papadimitriou
          this.close.click(_.bind(function() { this.hide(); }, this));
166 ac07ff0d Kostas Papadimitriou
          this.generate_action.click(_.bind(this.generate, this));
167 ac07ff0d Kostas Papadimitriou
          this.generate_download.click(_.bind(this.download_key, this));
168 ac07ff0d Kostas Papadimitriou
          this.form.submit(_.bind(function(e){
169 ac07ff0d Kostas Papadimitriou
            e.preventDefault();
170 ac07ff0d Kostas Papadimitriou
            this.submit_key(_.bind(function() {
171 ac07ff0d Kostas Papadimitriou
              this.hide();
172 ac07ff0d Kostas Papadimitriou
            }, this))
173 ac07ff0d Kostas Papadimitriou
          }, this));
174 ac07ff0d Kostas Papadimitriou
          this.submit.click(_.bind(function() {
175 ac07ff0d Kostas Papadimitriou
            this.form.submit();
176 ac07ff0d Kostas Papadimitriou
          }, this));
177 c1c836ec Kostas Papadimitriou
        },
178 e9392f3c Kostas Papadimitriou
        
179 ac07ff0d Kostas Papadimitriou
        set_in_progress: function() {
180 ac07ff0d Kostas Papadimitriou
          this.in_progress = true;
181 ac07ff0d Kostas Papadimitriou
          this.submit.addClass("in-progress");
182 c72a830d Kostas Papadimitriou
        },
183 c72a830d Kostas Papadimitriou
184 ac07ff0d Kostas Papadimitriou
        unset_in_progress: function() {
185 ac07ff0d Kostas Papadimitriou
          this.in_progress = false;
186 ac07ff0d Kostas Papadimitriou
          this.submit.removeClass("in-progress");
187 c72a830d Kostas Papadimitriou
        },
188 c72a830d Kostas Papadimitriou
189 ac07ff0d Kostas Papadimitriou
        submit_key: function(cb) {
190 ac07ff0d Kostas Papadimitriou
          var data = this.validate_form();
191 ac07ff0d Kostas Papadimitriou
          if (!data) { return }
192 ac07ff0d Kostas Papadimitriou
          this.set_in_progress();
193 ac07ff0d Kostas Papadimitriou
          var params = {
194 ac07ff0d Kostas Papadimitriou
            complete: _.bind(function() {
195 ac07ff0d Kostas Papadimitriou
              synnefo.storage.keys.fetch();
196 ac07ff0d Kostas Papadimitriou
              this.unset_in_progress();
197 ac07ff0d Kostas Papadimitriou
              cb && cb();
198 ac07ff0d Kostas Papadimitriou
            }, this)
199 ac07ff0d Kostas Papadimitriou
          };
200 ac07ff0d Kostas Papadimitriou
201 ac07ff0d Kostas Papadimitriou
          synnefo.storage.keys.create({
202 ac07ff0d Kostas Papadimitriou
            content: data.key, 
203 ac07ff0d Kostas Papadimitriou
            name: data.name,
204 ac07ff0d Kostas Papadimitriou
          }, params);
205 e9392f3c Kostas Papadimitriou
        },
206 e9392f3c Kostas Papadimitriou
207 ac07ff0d Kostas Papadimitriou
        download_key: function() {
208 ac07ff0d Kostas Papadimitriou
          try {
209 ac07ff0d Kostas Papadimitriou
            var blob = new Blob([this.private_key], {
210 ac07ff0d Kostas Papadimitriou
              type: "application/x-perm-key;charset=utf-8"
211 ac07ff0d Kostas Papadimitriou
            });
212 ac07ff0d Kostas Papadimitriou
            saveAs(blob, "id_rsa");
213 ac07ff0d Kostas Papadimitriou
          } catch (err) {
214 ac07ff0d Kostas Papadimitriou
            alert(this.private_key);
215 ac07ff0d Kostas Papadimitriou
          }
216 e9392f3c Kostas Papadimitriou
        },
217 dec4cd84 Kostas Papadimitriou
        
218 dec4cd84 Kostas Papadimitriou
        _generated_key_name: function() {
219 e6a4b75c Kostas Papadimitriou
          if (this.input_name.val()) {
220 e6a4b75c Kostas Papadimitriou
            return this.input_name.val();
221 e6a4b75c Kostas Papadimitriou
          }
222 dec4cd84 Kostas Papadimitriou
          var name_tpl = "Generated ssh key name";
223 dec4cd84 Kostas Papadimitriou
          var name = name_tpl;
224 dec4cd84 Kostas Papadimitriou
          var exists = function() {
225 dec4cd84 Kostas Papadimitriou
            return synnefo.storage.keys.filter(function(key){
226 dec4cd84 Kostas Papadimitriou
              return key.get("name") == name;
227 dec4cd84 Kostas Papadimitriou
            }).length > 0;
228 dec4cd84 Kostas Papadimitriou
          }
229 dec4cd84 Kostas Papadimitriou
230 dec4cd84 Kostas Papadimitriou
          var count = 1;
231 dec4cd84 Kostas Papadimitriou
          while(exists()) {
232 dec4cd84 Kostas Papadimitriou
            name = name_tpl + " {0}".format(++count);
233 dec4cd84 Kostas Papadimitriou
          }
234 dec4cd84 Kostas Papadimitriou
          return name;
235 dec4cd84 Kostas Papadimitriou
        },
236 e9392f3c Kostas Papadimitriou
237 ac07ff0d Kostas Papadimitriou
        generate: function() {
238 ac07ff0d Kostas Papadimitriou
          this.error.hide();
239 ac07ff0d Kostas Papadimitriou
          this.generate_msg.hide();
240 ac07ff0d Kostas Papadimitriou
241 ac07ff0d Kostas Papadimitriou
          if (this.generating) { return }
242 ac07ff0d Kostas Papadimitriou
          
243 ac07ff0d Kostas Papadimitriou
          this.generating = true;
244 ac07ff0d Kostas Papadimitriou
          this.generate_action.addClass("in-progress");
245 ac07ff0d Kostas Papadimitriou
          
246 ac07ff0d Kostas Papadimitriou
          var success = _.bind(function(key) {
247 ac07ff0d Kostas Papadimitriou
            this.generating = false;
248 ac07ff0d Kostas Papadimitriou
            this.generate_action.removeClass("in-progress");
249 dec4cd84 Kostas Papadimitriou
            this.input_name.val(this._generated_key_name());
250 ac07ff0d Kostas Papadimitriou
            this.input_key.val(key.public);
251 ac07ff0d Kostas Papadimitriou
            this.generate_msg.show();
252 ac07ff0d Kostas Papadimitriou
            this.private_key = key.private;
253 ac07ff0d Kostas Papadimitriou
            this.form.hide();
254 ac07ff0d Kostas Papadimitriou
            this.form_actions.hide();
255 ac07ff0d Kostas Papadimitriou
            this.close.show();
256 ac07ff0d Kostas Papadimitriou
            this.model_actions.hide();
257 ac07ff0d Kostas Papadimitriou
            this.submit_key();
258 ac07ff0d Kostas Papadimitriou
          }, this);
259 ac07ff0d Kostas Papadimitriou
          var error = _.bind(function() {
260 ac07ff0d Kostas Papadimitriou
            this.generating = false;
261 ac07ff0d Kostas Papadimitriou
            this.generate_action.removeClass("in-progress");
262 ac07ff0d Kostas Papadimitriou
            this.generate_progress.hide();
263 ac07ff0d Kostas Papadimitriou
            this.private_key = undefined;
264 ac07ff0d Kostas Papadimitriou
            this.show_error();
265 ac07ff0d Kostas Papadimitriou
          }, this);
266 ac07ff0d Kostas Papadimitriou
          var key = storage.keys.generate_new(success, error);
267 e9392f3c Kostas Papadimitriou
        },
268 e9392f3c Kostas Papadimitriou
269 ac07ff0d Kostas Papadimitriou
        show_error: function(msg) {
270 ac07ff0d Kostas Papadimitriou
          msg = msg === undefined ? "Something went wrong. Please try again later." : msg;
271 ac07ff0d Kostas Papadimitriou
          if (msg) { this.error.find("p").html(msg) }
272 ac07ff0d Kostas Papadimitriou
          this.error.show();
273 e9392f3c Kostas Papadimitriou
        }
274 ac07ff0d Kostas Papadimitriou
    });
275 e9392f3c Kostas Papadimitriou
276 ac07ff0d Kostas Papadimitriou
    views.PublicKeyView = views.ext.ModelView.extend({
277 ac07ff0d Kostas Papadimitriou
      tpl: '#public-key-view-tpl',
278 ac07ff0d Kostas Papadimitriou
      post_init_element: function() {
279 ac07ff0d Kostas Papadimitriou
        this.content = this.$(".content-cont");
280 ac07ff0d Kostas Papadimitriou
        this.content.hide();
281 ac07ff0d Kostas Papadimitriou
        this.content_toggler = this.$(".cont-toggler");
282 ac07ff0d Kostas Papadimitriou
        this.content_toggler.click(this.toggle_content);
283 ac07ff0d Kostas Papadimitriou
        this.content_visible = false;
284 ac07ff0d Kostas Papadimitriou
      },
285 ac07ff0d Kostas Papadimitriou
286 ac07ff0d Kostas Papadimitriou
      toggle_content: function() {
287 ac07ff0d Kostas Papadimitriou
        if (!this.content_visible) {
288 375a9cb5 Kostas Papadimitriou
          this.content.slideDown(function() {
289 375a9cb5 Kostas Papadimitriou
            $(window).trigger("resize");
290 375a9cb5 Kostas Papadimitriou
          });
291 ac07ff0d Kostas Papadimitriou
          this.content_visible = true;
292 ac07ff0d Kostas Papadimitriou
          this.content_toggler.addClass("open");
293 ac07ff0d Kostas Papadimitriou
        } else {
294 375a9cb5 Kostas Papadimitriou
          this.content.slideUp(function() {
295 375a9cb5 Kostas Papadimitriou
            $(window).trigger("resize");
296 375a9cb5 Kostas Papadimitriou
          });
297 ac07ff0d Kostas Papadimitriou
          this.content_visible = false;
298 ac07ff0d Kostas Papadimitriou
          this.content_toggler.removeClass("open");
299 e9392f3c Kostas Papadimitriou
        }
300 ac07ff0d Kostas Papadimitriou
      },
301 ac07ff0d Kostas Papadimitriou
302 ac07ff0d Kostas Papadimitriou
      remove_key: function() {
303 ac07ff0d Kostas Papadimitriou
        this.model.actions.reset_pending();
304 ac07ff0d Kostas Papadimitriou
        this.model.remove(function() {
305 ac07ff0d Kostas Papadimitriou
            synnefo.storage.keys.fetch();
306 ac07ff0d Kostas Papadimitriou
        });
307 ac07ff0d Kostas Papadimitriou
      }
308 ac07ff0d Kostas Papadimitriou
    });
309 ac07ff0d Kostas Papadimitriou
    
310 ac07ff0d Kostas Papadimitriou
    views.PublicKeysCollectionView = views.ext.CollectionView.extend({
311 ac07ff0d Kostas Papadimitriou
      collection: storage.keys,
312 ac07ff0d Kostas Papadimitriou
      collection_name: 'keys',
313 ac07ff0d Kostas Papadimitriou
      model_view_cls: views.PublicKeyView,
314 ac07ff0d Kostas Papadimitriou
      create_view_cls: views.PublicKeyCreateView
315 ac07ff0d Kostas Papadimitriou
    });
316 ac07ff0d Kostas Papadimitriou
317 ac07ff0d Kostas Papadimitriou
    views.PublicKeysPaneView = views.ext.PaneView.extend({
318 ac07ff0d Kostas Papadimitriou
      id: "pane",
319 ac07ff0d Kostas Papadimitriou
      el: '#public-keys-pane',
320 ac07ff0d Kostas Papadimitriou
      collection_view_cls: views.PublicKeysCollectionView,
321 ac07ff0d Kostas Papadimitriou
      collection_view_selector: '#public-keys-list-view'
322 e9392f3c Kostas Papadimitriou
    });
323 e9392f3c Kostas Papadimitriou
324 ac07ff0d Kostas Papadimitriou
})(this);