vines-services 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +5 -5
- data/Rakefile +13 -11
- data/bin/vines-services +0 -1
- data/lib/vines/services/command/init.rb +156 -139
- data/lib/vines/services/controller/messages_controller.rb +8 -3
- data/lib/vines/services/controller/users_controller.rb +11 -11
- data/lib/vines/services/indexer.rb +1 -1
- data/lib/vines/services/priority_queue.rb +12 -12
- data/lib/vines/services/roster.rb +85 -46
- data/lib/vines/services/storage/couchdb/service.rb +1 -1
- data/lib/vines/services/storage/couchdb/system.rb +1 -1
- data/lib/vines/services/storage/couchdb/upload.rb +1 -1
- data/lib/vines/services/storage/couchdb/user.rb +13 -3
- data/lib/vines/services/storage/couchdb.rb +8 -12
- data/lib/vines/services/version.rb +1 -1
- data/test/priority_queue_test.rb +1 -1
- data/web/coffeescripts/api.coffee +6 -0
- data/web/coffeescripts/files.coffee +65 -39
- data/web/coffeescripts/services.coffee +5 -2
- data/web/coffeescripts/setup.coffee +35 -12
- data/web/coffeescripts/systems.coffee +115 -228
- data/web/javascripts/api.js +69 -0
- data/web/javascripts/app.js +2 -0
- data/web/javascripts/commands.js +28 -0
- data/web/javascripts/files.js +424 -0
- data/web/javascripts/init.js +27 -0
- data/web/javascripts/services.js +404 -0
- data/web/javascripts/setup.js +485 -0
- data/web/javascripts/systems.js +342 -0
- data/web/stylesheets/app.css +714 -0
- data/web/stylesheets/services.css +4 -14
- data/web/stylesheets/setup.css +1 -2
- data/web/stylesheets/systems.css +124 -108
- metadata +95 -92
| @@ -0,0 +1,404 @@ | |
| 1 | 
            +
            var ServicesPage;
         | 
| 2 | 
            +
            var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
         | 
| 3 | 
            +
            ServicesPage = (function() {
         | 
| 4 | 
            +
              var ATTRS, MEMBERS, SERVICES, SYSTEMS, USERS;
         | 
| 5 | 
            +
              SERVICES = 'http://getvines.com/protocol/services';
         | 
| 6 | 
            +
              MEMBERS = 'http://getvines.com/protocol/services/members';
         | 
| 7 | 
            +
              SYSTEMS = 'http://getvines.com/protocol/systems';
         | 
| 8 | 
            +
              ATTRS = 'http://getvines.com/protocol/systems/attributes';
         | 
| 9 | 
            +
              USERS = 'http://getvines.com/protocol/users';
         | 
| 10 | 
            +
              function ServicesPage(session) {
         | 
| 11 | 
            +
                this.session = session;
         | 
| 12 | 
            +
                this.api = new Api(this.session);
         | 
| 13 | 
            +
                this.selectedService = null;
         | 
| 14 | 
            +
                this.validateTimeout = null;
         | 
| 15 | 
            +
                this.layout = null;
         | 
| 16 | 
            +
                this.users = [];
         | 
| 17 | 
            +
              }
         | 
| 18 | 
            +
              ServicesPage.prototype.deleteService = function(event) {
         | 
| 19 | 
            +
                var selected;
         | 
| 20 | 
            +
                this.drawBlankSlate();
         | 
| 21 | 
            +
                this.toggleForm('#remove-contact-form');
         | 
| 22 | 
            +
                selected = $("#services li[data-id='" + this.selectedService.id + "']");
         | 
| 23 | 
            +
                this.api.remove(SERVICES, this.selectedService.id, __bind(function(result) {
         | 
| 24 | 
            +
                  return selected.fadeOut(200, function() {
         | 
| 25 | 
            +
                    selected.remove();
         | 
| 26 | 
            +
                    return this.selectedService = null;
         | 
| 27 | 
            +
                  });
         | 
| 28 | 
            +
                }, this));
         | 
| 29 | 
            +
                return false;
         | 
| 30 | 
            +
              };
         | 
| 31 | 
            +
              ServicesPage.prototype.icon = function(member) {
         | 
| 32 | 
            +
                var icon, icons;
         | 
| 33 | 
            +
                icons = {
         | 
| 34 | 
            +
                  darwin: 'mac.png',
         | 
| 35 | 
            +
                  linux: 'linux.png',
         | 
| 36 | 
            +
                  windows: 'windows.png'
         | 
| 37 | 
            +
                };
         | 
| 38 | 
            +
                icon = icons[member.os] || 'run.png';
         | 
| 39 | 
            +
                return "images/" + icon;
         | 
| 40 | 
            +
              };
         | 
| 41 | 
            +
              ServicesPage.prototype.drawMember = function(member) {
         | 
| 42 | 
            +
                var node;
         | 
| 43 | 
            +
                if (!this.editorVisible()) {
         | 
| 44 | 
            +
                  return;
         | 
| 45 | 
            +
                }
         | 
| 46 | 
            +
                node = $("<li>\n  <span class=\"icon\"><img src=\"" + (this.icon(member)) + "\"/></span>\n  <span class=\"text\"></span>\n</li>").appendTo('#members');
         | 
| 47 | 
            +
                return $('.text', node).text(member.name);
         | 
| 48 | 
            +
              };
         | 
| 49 | 
            +
              ServicesPage.prototype.operators = function() {
         | 
| 50 | 
            +
                var node, operator, _i, _len, _ref, _results;
         | 
| 51 | 
            +
                _ref = ['like', 'not like', 'starts with', 'ends with', 'is', 'is not', '>', '>=', '<', '<=', 'and', 'or'];
         | 
| 52 | 
            +
                _results = [];
         | 
| 53 | 
            +
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 54 | 
            +
                  operator = _ref[_i];
         | 
| 55 | 
            +
                  node = $("<li data-selector=\"" + operator + "\">\n  " + operator + "\n</li>").appendTo('#operators');
         | 
| 56 | 
            +
                  _results.push(node.click(__bind(function(event) {
         | 
| 57 | 
            +
                    var name;
         | 
| 58 | 
            +
                    $('#syntax').focus();
         | 
| 59 | 
            +
                    name = $(event.currentTarget).attr('data-selector');
         | 
| 60 | 
            +
                    $('#syntax').val($('#syntax').val() + (" " + name + " "));
         | 
| 61 | 
            +
                    return this.validateIn();
         | 
| 62 | 
            +
                  }, this)));
         | 
| 63 | 
            +
                }
         | 
| 64 | 
            +
                return _results;
         | 
| 65 | 
            +
              };
         | 
| 66 | 
            +
              ServicesPage.prototype.selectService = function(node) {
         | 
| 67 | 
            +
                var id, name;
         | 
| 68 | 
            +
                id = $(node).attr('data-id');
         | 
| 69 | 
            +
                name = $(node).attr('data-name');
         | 
| 70 | 
            +
                $('#services li').removeClass('selected');
         | 
| 71 | 
            +
                $(node).addClass('selected');
         | 
| 72 | 
            +
                $('#remove-service-msg').html("Are you sure you want to remove the " + ("<strong>" + name + "</strong> service?"));
         | 
| 73 | 
            +
                $('#remove-service-form .buttons').fadeIn(200);
         | 
| 74 | 
            +
                return this.api.get(SERVICES, {
         | 
| 75 | 
            +
                  id: id
         | 
| 76 | 
            +
                }, __bind(function(result) {
         | 
| 77 | 
            +
                  this.selectedService = result;
         | 
| 78 | 
            +
                  return this.drawEditor(result);
         | 
| 79 | 
            +
                }, this));
         | 
| 80 | 
            +
              };
         | 
| 81 | 
            +
              ServicesPage.prototype.serviceNode = function(service) {
         | 
| 82 | 
            +
                var label, node;
         | 
| 83 | 
            +
                label = service.size === 1 ? 'system' : 'systems';
         | 
| 84 | 
            +
                node = $("<li data-id=\"" + service.id + "\" data-name=\"\" data-size=\"" + service.size + "\">\n  <span class=\"text\">" + service.name + "</span>\n  <span class=\"count\">" + service.size + " " + label + "</span>\n</li>").appendTo('#services');
         | 
| 85 | 
            +
                node.attr('data-name', service.name);
         | 
| 86 | 
            +
                $('.text', node).text(service.name);
         | 
| 87 | 
            +
                node.click(__bind(function(event) {
         | 
| 88 | 
            +
                  return this.selectService(event.currentTarget);
         | 
| 89 | 
            +
                }, this));
         | 
| 90 | 
            +
                return node;
         | 
| 91 | 
            +
              };
         | 
| 92 | 
            +
              ServicesPage.prototype.findServices = function() {
         | 
| 93 | 
            +
                return this.api.get(SERVICES, {}, __bind(function(result) {
         | 
| 94 | 
            +
                  var row, _i, _len, _ref, _results;
         | 
| 95 | 
            +
                  _ref = result.rows;
         | 
| 96 | 
            +
                  _results = [];
         | 
| 97 | 
            +
                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 98 | 
            +
                    row = _ref[_i];
         | 
| 99 | 
            +
                    _results.push(this.serviceNode(row));
         | 
| 100 | 
            +
                  }
         | 
| 101 | 
            +
                  return _results;
         | 
| 102 | 
            +
                }, this));
         | 
| 103 | 
            +
              };
         | 
| 104 | 
            +
              ServicesPage.prototype.findMembers = function(id) {
         | 
| 105 | 
            +
                return this.api.get(MEMBERS, {
         | 
| 106 | 
            +
                  id: id
         | 
| 107 | 
            +
                }, __bind(function(result) {
         | 
| 108 | 
            +
                  var row, _i, _len, _ref, _results;
         | 
| 109 | 
            +
                  _ref = result.rows;
         | 
| 110 | 
            +
                  _results = [];
         | 
| 111 | 
            +
                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 112 | 
            +
                    row = _ref[_i];
         | 
| 113 | 
            +
                    _results.push(this.drawMember(row));
         | 
| 114 | 
            +
                  }
         | 
| 115 | 
            +
                  return _results;
         | 
| 116 | 
            +
                }, this));
         | 
| 117 | 
            +
              };
         | 
| 118 | 
            +
              ServicesPage.prototype.findUsers = function(syntax) {
         | 
| 119 | 
            +
                return this.api.get(USERS, {}, __bind(function(result) {
         | 
| 120 | 
            +
                  var row;
         | 
| 121 | 
            +
                  this.users = (function() {
         | 
| 122 | 
            +
                    var _i, _len, _ref, _results;
         | 
| 123 | 
            +
                    _ref = result.rows;
         | 
| 124 | 
            +
                    _results = [];
         | 
| 125 | 
            +
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 126 | 
            +
                      row = _ref[_i];
         | 
| 127 | 
            +
                      if (!row.system) {
         | 
| 128 | 
            +
                        _results.push(row);
         | 
| 129 | 
            +
                      }
         | 
| 130 | 
            +
                    }
         | 
| 131 | 
            +
                    return _results;
         | 
| 132 | 
            +
                  })();
         | 
| 133 | 
            +
                  return this.drawUsers();
         | 
| 134 | 
            +
                }, this));
         | 
| 135 | 
            +
              };
         | 
| 136 | 
            +
              ServicesPage.prototype.attributeNode = function(attribute) {
         | 
| 137 | 
            +
                var node;
         | 
| 138 | 
            +
                node = $('<li data-name=""></li>').appendTo('#attributes');
         | 
| 139 | 
            +
                node.text(attribute);
         | 
| 140 | 
            +
                node.attr('data-name', attribute);
         | 
| 141 | 
            +
                return node.click(__bind(function(event) {
         | 
| 142 | 
            +
                  var name;
         | 
| 143 | 
            +
                  $('#syntax').focus();
         | 
| 144 | 
            +
                  name = $(event.currentTarget).attr('data-name');
         | 
| 145 | 
            +
                  $('#syntax').val($('#syntax').val() + (" " + name + " "));
         | 
| 146 | 
            +
                  return this.validateIn();
         | 
| 147 | 
            +
                }, this));
         | 
| 148 | 
            +
              };
         | 
| 149 | 
            +
              ServicesPage.prototype.findAttributes = function(syntax) {
         | 
| 150 | 
            +
                return this.api.get(ATTRS, {}, __bind(function(result) {
         | 
| 151 | 
            +
                  var row, _i, _len, _ref, _results;
         | 
| 152 | 
            +
                  _ref = result.rows;
         | 
| 153 | 
            +
                  _results = [];
         | 
| 154 | 
            +
                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 155 | 
            +
                    row = _ref[_i];
         | 
| 156 | 
            +
                    _results.push(this.attributeNode(row));
         | 
| 157 | 
            +
                  }
         | 
| 158 | 
            +
                  return _results;
         | 
| 159 | 
            +
                }, this));
         | 
| 160 | 
            +
              };
         | 
| 161 | 
            +
              ServicesPage.prototype.validateIn = function(millis) {
         | 
| 162 | 
            +
                clearTimeout(this.validateTimeout);
         | 
| 163 | 
            +
                return this.validateTimeout = setTimeout((__bind(function() {
         | 
| 164 | 
            +
                  return this.validate();
         | 
| 165 | 
            +
                }, this)), millis || 500);
         | 
| 166 | 
            +
              };
         | 
| 167 | 
            +
              ServicesPage.prototype.validate = function() {
         | 
| 168 | 
            +
                var code, prev;
         | 
| 169 | 
            +
                $('#syntax-status').text('');
         | 
| 170 | 
            +
                prev = $('#syntax').data('prev');
         | 
| 171 | 
            +
                code = $.trim($('#syntax').val());
         | 
| 172 | 
            +
                $('#syntax').data('prev', code);
         | 
| 173 | 
            +
                if (!(code && code !== prev)) {
         | 
| 174 | 
            +
                  return;
         | 
| 175 | 
            +
                }
         | 
| 176 | 
            +
                $('#syntax-status').text('Searching . . .');
         | 
| 177 | 
            +
                $('#members').empty();
         | 
| 178 | 
            +
                return this.api.get2(MEMBERS, code, __bind(function(result) {
         | 
| 179 | 
            +
                  var row, _i, _len, _ref, _results;
         | 
| 180 | 
            +
                  if (result.ok) {
         | 
| 181 | 
            +
                    $('#syntax-status').text('');
         | 
| 182 | 
            +
                    _ref = result.rows;
         | 
| 183 | 
            +
                    _results = [];
         | 
| 184 | 
            +
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 185 | 
            +
                      row = _ref[_i];
         | 
| 186 | 
            +
                      _results.push(this.drawMember(row));
         | 
| 187 | 
            +
                    }
         | 
| 188 | 
            +
                    return _results;
         | 
| 189 | 
            +
                  } else {
         | 
| 190 | 
            +
                    return $('#syntax-status').text(result.error);
         | 
| 191 | 
            +
                  }
         | 
| 192 | 
            +
                }, this));
         | 
| 193 | 
            +
              };
         | 
| 194 | 
            +
              ServicesPage.prototype.validateForm = function() {
         | 
| 195 | 
            +
                var name, valid;
         | 
| 196 | 
            +
                $('#name-error').empty();
         | 
| 197 | 
            +
                valid = true;
         | 
| 198 | 
            +
                name = $.trim($('#name').val());
         | 
| 199 | 
            +
                if (name === '') {
         | 
| 200 | 
            +
                  $('#name-error').text('Name is required.');
         | 
| 201 | 
            +
                  valid = false;
         | 
| 202 | 
            +
                }
         | 
| 203 | 
            +
                return valid;
         | 
| 204 | 
            +
              };
         | 
| 205 | 
            +
              ServicesPage.prototype.save = function() {
         | 
| 206 | 
            +
                var accounts, service, u, users;
         | 
| 207 | 
            +
                if (!this.validateForm()) {
         | 
| 208 | 
            +
                  return;
         | 
| 209 | 
            +
                }
         | 
| 210 | 
            +
                users = $('#users :checked').map(function() {
         | 
| 211 | 
            +
                  return $(this).val();
         | 
| 212 | 
            +
                }).get();
         | 
| 213 | 
            +
                accounts = $('#unix-users').val().split(',');
         | 
| 214 | 
            +
                accounts = (function() {
         | 
| 215 | 
            +
                  var _i, _len, _results;
         | 
| 216 | 
            +
                  _results = [];
         | 
| 217 | 
            +
                  for (_i = 0, _len = accounts.length; _i < _len; _i++) {
         | 
| 218 | 
            +
                    u = accounts[_i];
         | 
| 219 | 
            +
                    if ($.trim(u).length > 0) {
         | 
| 220 | 
            +
                      _results.push($.trim(u));
         | 
| 221 | 
            +
                    }
         | 
| 222 | 
            +
                  }
         | 
| 223 | 
            +
                  return _results;
         | 
| 224 | 
            +
                })();
         | 
| 225 | 
            +
                service = {
         | 
| 226 | 
            +
                  name: $('#name').val(),
         | 
| 227 | 
            +
                  code: $('#syntax').val(),
         | 
| 228 | 
            +
                  accounts: accounts,
         | 
| 229 | 
            +
                  users: users
         | 
| 230 | 
            +
                };
         | 
| 231 | 
            +
                if ($('#id').val().length > 0) {
         | 
| 232 | 
            +
                  service['id'] = $('#id').val();
         | 
| 233 | 
            +
                }
         | 
| 234 | 
            +
                this.api.save(SERVICES, service, __bind(function(result) {
         | 
| 235 | 
            +
                  var node;
         | 
| 236 | 
            +
                  new Notification('Service saved successfully');
         | 
| 237 | 
            +
                  result.size = $('#members').length;
         | 
| 238 | 
            +
                  $('#id').val(result.id);
         | 
| 239 | 
            +
                  node = $("#services li[data-id='" + result.id + "']");
         | 
| 240 | 
            +
                  if (node.length === 0) {
         | 
| 241 | 
            +
                    node = this.serviceNode(result);
         | 
| 242 | 
            +
                    return this.selectService(node);
         | 
| 243 | 
            +
                  } else {
         | 
| 244 | 
            +
                    return $('.text', node).text(result.name);
         | 
| 245 | 
            +
                  }
         | 
| 246 | 
            +
                }, this));
         | 
| 247 | 
            +
                return false;
         | 
| 248 | 
            +
              };
         | 
| 249 | 
            +
              ServicesPage.prototype.drawBlankSlate = function() {
         | 
| 250 | 
            +
                $('#beta').empty();
         | 
| 251 | 
            +
                $("<form id=\"blank-slate\">\n  <p>\n    Services are dynamically updated groups of systems based on\n    criteria you define. Send a command to the service and it runs\n    on every system in the group.\n  </p>\n  <input type=\"submit\" id=\"blank-slate-add\" value=\"Add Service\"/>\n</form>").appendTo('#beta');
         | 
| 252 | 
            +
                if (!this.api.user.permissions.services) {
         | 
| 253 | 
            +
                  $('#blank-slate-add').remove();
         | 
| 254 | 
            +
                }
         | 
| 255 | 
            +
                return $('#blank-slate').submit(__bind(function() {
         | 
| 256 | 
            +
                  this.drawEditor();
         | 
| 257 | 
            +
                  return false;
         | 
| 258 | 
            +
                }, this));
         | 
| 259 | 
            +
              };
         | 
| 260 | 
            +
              ServicesPage.prototype.draw = function() {
         | 
| 261 | 
            +
                var fn;
         | 
| 262 | 
            +
                if (!this.session.connected()) {
         | 
| 263 | 
            +
                  window.location.hash = '';
         | 
| 264 | 
            +
                  return;
         | 
| 265 | 
            +
                }
         | 
| 266 | 
            +
                $('body').attr('id', 'services-page');
         | 
| 267 | 
            +
                $('#container').hide().empty();
         | 
| 268 | 
            +
                $("<div id=\"alpha\" class=\"sidebar column y-fill\">\n  <h2>Services <div id=\"search-services-icon\"></div></h2>\n  <div id=\"search-services-form\"></div>\n  <ul id=\"services\" class=\"selectable scroll y-fill\"></ul>\n  <div id=\"alpha-controls\" class=\"controls\">\n    <div id=\"add-service\"></div>\n    <div id=\"remove-service\"></div>\n  </div>\n  <form id=\"remove-service-form\" class=\"overlay\" style=\"display:none;\">\n    <h2>Remove Service</h2>\n    <p id=\"remove-service-msg\">Select a service in the list above to remove.</p>\n    <fieldset class=\"buttons\" style=\"display:none;\">\n      <input id=\"remove-service-cancel\" type=\"button\" value=\"Cancel\"/>\n      <input id=\"remove-service-ok\" type=\"submit\" value=\"Remove\"/>\n    </fieldset>\n  </form>\n</div>\n<div id=\"beta\" class=\"primary column x-fill y-fill\"></div>\n<div id=\"charlie\" class=\"sidebar column y-fill\">\n  <h2>Operators</h2>\n  <ul id=\"operators\"></ul>\n  <h2>Attributes <div id=\"search-attributes-icon\"></div></h2>\n  <div id=\"search-attributes-form\"></div>\n  <ul id=\"attributes\" class=\"y-fill scroll\"></ul>\n</div>").appendTo('#container');
         | 
| 269 | 
            +
                new Button('#add-service', ICONS.plus);
         | 
| 270 | 
            +
                new Button('#remove-service', ICONS.minus);
         | 
| 271 | 
            +
                if (!this.api.user.permissions.services) {
         | 
| 272 | 
            +
                  $('#alpha-controls div').remove();
         | 
| 273 | 
            +
                }
         | 
| 274 | 
            +
                this.drawBlankSlate();
         | 
| 275 | 
            +
                $('#add-service').click(__bind(function() {
         | 
| 276 | 
            +
                  return this.drawEditor();
         | 
| 277 | 
            +
                }, this));
         | 
| 278 | 
            +
                $('#remove-service').click(__bind(function() {
         | 
| 279 | 
            +
                  return this.toggleForm('#remove-service-form');
         | 
| 280 | 
            +
                }, this));
         | 
| 281 | 
            +
                $('#remove-service-cancel').click(__bind(function() {
         | 
| 282 | 
            +
                  return this.toggleForm('#remove-service-form');
         | 
| 283 | 
            +
                }, this));
         | 
| 284 | 
            +
                $('#remove-service-form').submit(__bind(function() {
         | 
| 285 | 
            +
                  return this.deleteService();
         | 
| 286 | 
            +
                }, this));
         | 
| 287 | 
            +
                this.operators();
         | 
| 288 | 
            +
                this.findServices();
         | 
| 289 | 
            +
                this.findAttributes();
         | 
| 290 | 
            +
                this.findUsers();
         | 
| 291 | 
            +
                $('#container').show();
         | 
| 292 | 
            +
                this.layout = this.resize();
         | 
| 293 | 
            +
                fn = __bind(function() {
         | 
| 294 | 
            +
                  this.layout.resize();
         | 
| 295 | 
            +
                  return this.layout.resize();
         | 
| 296 | 
            +
                }, this);
         | 
| 297 | 
            +
                new Filter({
         | 
| 298 | 
            +
                  list: '#services',
         | 
| 299 | 
            +
                  icon: '#search-services-icon',
         | 
| 300 | 
            +
                  form: '#search-services-form',
         | 
| 301 | 
            +
                  attrs: ['data-name'],
         | 
| 302 | 
            +
                  open: fn,
         | 
| 303 | 
            +
                  close: fn
         | 
| 304 | 
            +
                });
         | 
| 305 | 
            +
                return new Filter({
         | 
| 306 | 
            +
                  list: '#attributes',
         | 
| 307 | 
            +
                  icon: '#search-attributes-icon',
         | 
| 308 | 
            +
                  form: '#search-attributes-form',
         | 
| 309 | 
            +
                  attrs: ['data-name'],
         | 
| 310 | 
            +
                  open: fn,
         | 
| 311 | 
            +
                  close: fn
         | 
| 312 | 
            +
                });
         | 
| 313 | 
            +
              };
         | 
| 314 | 
            +
              ServicesPage.prototype.drawEditor = function(service) {
         | 
| 315 | 
            +
                if (!this.pageVisible()) {
         | 
| 316 | 
            +
                  return;
         | 
| 317 | 
            +
                }
         | 
| 318 | 
            +
                if (!service) {
         | 
| 319 | 
            +
                  this.selectedService = null;
         | 
| 320 | 
            +
                  $('#services li').removeClass('selected');
         | 
| 321 | 
            +
                }
         | 
| 322 | 
            +
                $('#beta').empty();
         | 
| 323 | 
            +
                $("<form id=\"editor-form\" class=\"sections y-fill scroll\">\n  <input id=\"id\" type=\"hidden\"/>\n  <div>\n    <section>\n      <h2>Service</h2>\n      <fieldset>\n        <label for=\"name\">Name</label>\n        <input id=\"name\" type=\"text\"/>\n        <p id=\"name-error\" class=\"error\"></p>\n        <label for=\"syntax\">Criteria</label>\n        <textarea id=\"syntax\" placeholder=\"fqdn starts with 'www.' and platform is 'mac_os_x'\"></textarea>\n        <p id=\"syntax-status\"></p>\n      </fieldset>\n    </section>\n    <section>\n      <h2>Members</h2>\n      <fieldset id=\"service-preview\">\n        <ul id=\"members\" class=\"scroll\"></ul>\n      </fieldset>\n    </section>\n    <section>\n      <h2>Permissions</h2>\n      <fieldset>\n        <label>Users</label>\n        <ul id=\"users\" class=\"scroll\"></ul>\n        <label for=\"unix-users\">Unix Accounts</label>\n        <input id=\"unix-users\" type=\"text\"/>\n      </fieldset>\n    </section>\n  </div>\n</form>\n<form id=\"editor-buttons\">\n  <input id=\"save\" type=\"submit\" value=\"Save\"/>\n</form>").appendTo('#beta');
         | 
| 324 | 
            +
                if (service) {
         | 
| 325 | 
            +
                  this.findMembers(service.id);
         | 
| 326 | 
            +
                  $('#id').val(service.id);
         | 
| 327 | 
            +
                  $('#name').val(service.name);
         | 
| 328 | 
            +
                  $('#syntax').val(service.code);
         | 
| 329 | 
            +
                  $('#unix-users').val(service.accounts.join(', '));
         | 
| 330 | 
            +
                }
         | 
| 331 | 
            +
                if (this.users.length > 0) {
         | 
| 332 | 
            +
                  this.drawUsers();
         | 
| 333 | 
            +
                }
         | 
| 334 | 
            +
                this.layout.resize();
         | 
| 335 | 
            +
                $('#name').focus();
         | 
| 336 | 
            +
                $('#syntax').change(__bind(function() {
         | 
| 337 | 
            +
                  return this.validateIn();
         | 
| 338 | 
            +
                }, this));
         | 
| 339 | 
            +
                $('#syntax').keyup(__bind(function() {
         | 
| 340 | 
            +
                  return this.validateIn();
         | 
| 341 | 
            +
                }, this));
         | 
| 342 | 
            +
                $('#editor-form').submit(__bind(function() {
         | 
| 343 | 
            +
                  return this.save();
         | 
| 344 | 
            +
                }, this));
         | 
| 345 | 
            +
                return $('#editor-buttons').submit(__bind(function() {
         | 
| 346 | 
            +
                  return this.save();
         | 
| 347 | 
            +
                }, this));
         | 
| 348 | 
            +
              };
         | 
| 349 | 
            +
              ServicesPage.prototype.drawUsers = function() {
         | 
| 350 | 
            +
                var node, user, _i, _len, _ref;
         | 
| 351 | 
            +
                if (!this.editorVisible()) {
         | 
| 352 | 
            +
                  return;
         | 
| 353 | 
            +
                }
         | 
| 354 | 
            +
                $('#users').empty();
         | 
| 355 | 
            +
                _ref = this.users;
         | 
| 356 | 
            +
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 357 | 
            +
                  user = _ref[_i];
         | 
| 358 | 
            +
                  node = $("<li>\n  <input id='user-" + user.jid + "' type='checkbox' value='" + user.jid + "'/>\n  <label for='user-" + user.jid + "'>" + user.jid + "</label>\n</li>").appendTo('#users');
         | 
| 359 | 
            +
                  if (user.jid === this.session.bareJid()) {
         | 
| 360 | 
            +
                    $('input', node).prop('checked', true);
         | 
| 361 | 
            +
                  }
         | 
| 362 | 
            +
                }
         | 
| 363 | 
            +
                if (this.selectedService) {
         | 
| 364 | 
            +
                  return $('#users input[type="checkbox"]').val(this.selectedService.users);
         | 
| 365 | 
            +
                }
         | 
| 366 | 
            +
              };
         | 
| 367 | 
            +
              ServicesPage.prototype.toggleForm = function(form, fn) {
         | 
| 368 | 
            +
                form = $(form);
         | 
| 369 | 
            +
                $('form.overlay').each(function() {
         | 
| 370 | 
            +
                  if (this.id !== form.attr('id')) {
         | 
| 371 | 
            +
                    return $(this).hide();
         | 
| 372 | 
            +
                  }
         | 
| 373 | 
            +
                });
         | 
| 374 | 
            +
                if (form.is(':hidden')) {
         | 
| 375 | 
            +
                  if (fn) {
         | 
| 376 | 
            +
                    fn();
         | 
| 377 | 
            +
                  }
         | 
| 378 | 
            +
                  return form.fadeIn(100);
         | 
| 379 | 
            +
                } else {
         | 
| 380 | 
            +
                  return form.fadeOut(100, function() {
         | 
| 381 | 
            +
                    form[0].reset();
         | 
| 382 | 
            +
                    if (fn) {
         | 
| 383 | 
            +
                      return fn();
         | 
| 384 | 
            +
                    }
         | 
| 385 | 
            +
                  });
         | 
| 386 | 
            +
                }
         | 
| 387 | 
            +
              };
         | 
| 388 | 
            +
              ServicesPage.prototype.pageVisible = function() {
         | 
| 389 | 
            +
                return $('#services-page').length > 0;
         | 
| 390 | 
            +
              };
         | 
| 391 | 
            +
              ServicesPage.prototype.editorVisible = function() {
         | 
| 392 | 
            +
                return $('#services-page #editor-form').length > 0;
         | 
| 393 | 
            +
              };
         | 
| 394 | 
            +
              ServicesPage.prototype.resize = function() {
         | 
| 395 | 
            +
                var a, b, c;
         | 
| 396 | 
            +
                a = $('#alpha');
         | 
| 397 | 
            +
                b = $('#beta');
         | 
| 398 | 
            +
                c = $('#charlie');
         | 
| 399 | 
            +
                return new Layout(function() {
         | 
| 400 | 
            +
                  return c.css('left', a.width() + b.width());
         | 
| 401 | 
            +
                });
         | 
| 402 | 
            +
              };
         | 
| 403 | 
            +
              return ServicesPage;
         | 
| 404 | 
            +
            })();
         |