aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/groups
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps/groups')
-rw-r--r--server/sonar-web/src/main/js/apps/groups/app.js47
-rw-r--r--server/sonar-web/src/main/js/apps/groups/create-view.js30
-rw-r--r--server/sonar-web/src/main/js/apps/groups/delete-view.js32
-rw-r--r--server/sonar-web/src/main/js/apps/groups/form-view.js25
-rw-r--r--server/sonar-web/src/main/js/apps/groups/group.js35
-rw-r--r--server/sonar-web/src/main/js/apps/groups/groups.js40
-rw-r--r--server/sonar-web/src/main/js/apps/groups/header-view.js25
-rw-r--r--server/sonar-web/src/main/js/apps/groups/layout.js16
-rw-r--r--server/sonar-web/src/main/js/apps/groups/list-footer-view.js34
-rw-r--r--server/sonar-web/src/main/js/apps/groups/list-item-view.js59
-rw-r--r--server/sonar-web/src/main/js/apps/groups/list-view.js11
-rw-r--r--server/sonar-web/src/main/js/apps/groups/search-view.js49
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-delete.hbs13
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-form.hbs24
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-header.hbs9
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-layout.hbs6
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-list-footer.hbs6
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-list-item.hbs16
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-search.hbs6
-rw-r--r--server/sonar-web/src/main/js/apps/groups/templates/groups-users.hbs10
-rw-r--r--server/sonar-web/src/main/js/apps/groups/update-view.js29
-rw-r--r--server/sonar-web/src/main/js/apps/groups/users-view.js42
22 files changed, 564 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/apps/groups/app.js b/server/sonar-web/src/main/js/apps/groups/app.js
new file mode 100644
index 00000000000..55c6dfef534
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/app.js
@@ -0,0 +1,47 @@
+define([
+ './layout',
+ './groups',
+ './header-view',
+ './search-view',
+ './list-view',
+ './list-footer-view'
+], function (Layout, Groups, HeaderView, SearchView, ListView, ListFooterView) {
+
+ var App = new Marionette.Application(),
+ init = function (options) {
+ // Layout
+ this.layout = new Layout({ el: options.el });
+ this.layout.render();
+
+ // Collection
+ this.groups = new Groups();
+
+ // Header View
+ this.headerView = new HeaderView({ collection: this.groups });
+ this.layout.headerRegion.show(this.headerView);
+
+ // Search View
+ this.searchView = new SearchView({ collection: this.groups });
+ this.layout.searchRegion.show(this.searchView);
+
+ // List View
+ this.listView = new ListView({ collection: this.groups });
+ this.layout.listRegion.show(this.listView);
+
+ // List Footer View
+ this.listFooterView = new ListFooterView({ collection: this.groups });
+ this.layout.listFooterRegion.show(this.listFooterView);
+
+ // Go!
+ this.groups.fetch();
+ };
+
+ App.on('start', function (options) {
+ window.requestMessages().done(function () {
+ init.call(App, options);
+ });
+ });
+
+ return App;
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/create-view.js b/server/sonar-web/src/main/js/apps/groups/create-view.js
new file mode 100644
index 00000000000..8d5cfce55aa
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/create-view.js
@@ -0,0 +1,30 @@
+define([
+ './group',
+ './form-view'
+], function (Group, FormView) {
+
+ return FormView.extend({
+
+ sendRequest: function () {
+ var that = this,
+ group = new Group({
+ name: this.$('#create-group-name').val(),
+ description: this.$('#create-group-description').val()
+ });
+ this.disableForm();
+ return group.save(null, {
+ statusCode: {
+ // do not show global error
+ 400: null
+ }
+ }).done(function () {
+ that.collection.refresh();
+ that.close();
+ }).fail(function (jqXHR) {
+ that.enableForm();
+ that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings);
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/delete-view.js b/server/sonar-web/src/main/js/apps/groups/delete-view.js
new file mode 100644
index 00000000000..8fd83d34031
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/delete-view.js
@@ -0,0 +1,32 @@
+define([
+ 'components/common/modal-form',
+ './templates'
+], function (ModalForm) {
+
+ return ModalForm.extend({
+ template: Templates['groups-delete'],
+
+ onFormSubmit: function () {
+ ModalForm.prototype.onFormSubmit.apply(this, arguments);
+ this.sendRequest();
+ },
+
+ sendRequest: function () {
+ var that = this,
+ collection = this.model.collection;
+ return this.model.destroy({
+ wait: true,
+ statusCode: {
+ // do not show global error
+ 400: null
+ }
+ }).done(function () {
+ collection.total--;
+ that.close();
+ }).fail(function (jqXHR) {
+ that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings);
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/form-view.js b/server/sonar-web/src/main/js/apps/groups/form-view.js
new file mode 100644
index 00000000000..aa872784e1e
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/form-view.js
@@ -0,0 +1,25 @@
+define([
+ 'components/common/modal-form',
+ './templates'
+], function (ModalForm) {
+
+ return ModalForm.extend({
+ template: Templates['groups-form'],
+
+ onRender: function () {
+ ModalForm.prototype.onRender.apply(this, arguments);
+ this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' });
+ },
+
+ onClose: function () {
+ ModalForm.prototype.onClose.apply(this, arguments);
+ this.$('[data-toggle="tooltip"]').tooltip('destroy');
+ },
+
+ onFormSubmit: function () {
+ ModalForm.prototype.onFormSubmit.apply(this, arguments);
+ this.sendRequest();
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/group.js b/server/sonar-web/src/main/js/apps/groups/group.js
new file mode 100644
index 00000000000..406f9ba3a3a
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/group.js
@@ -0,0 +1,35 @@
+define(function () {
+
+ return Backbone.Model.extend({
+ urlRoot: function () {
+ return baseUrl + '/api/usergroups';
+ },
+
+ sync: function (method, model, options) {
+ var opts = options || {};
+ if (method === 'create') {
+ _.defaults(opts, {
+ url: this.urlRoot() + '/create',
+ type: 'POST',
+ data: _.pick(model.toJSON(), 'name', 'description')
+ });
+ }
+ if (method === 'update') {
+ _.defaults(opts, {
+ url: this.urlRoot() + '/update',
+ type: 'POST',
+ data: _.pick(model.toJSON(), 'id', 'name', 'description')
+ });
+ }
+ if (method === 'delete') {
+ _.defaults(opts, {
+ url: this.urlRoot() + '/delete',
+ type: 'POST',
+ data: { id: this.id }
+ });
+ }
+ return Backbone.ajax(opts);
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/groups.js b/server/sonar-web/src/main/js/apps/groups/groups.js
new file mode 100644
index 00000000000..9ddd6c9f9a1
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/groups.js
@@ -0,0 +1,40 @@
+define([
+ './group'
+], function (Group) {
+
+ return Backbone.Collection.extend({
+ model: Group,
+
+ url: function () {
+ return baseUrl + '/api/usergroups/search';
+ },
+
+ parse: function (r) {
+ this.total = +r.total;
+ this.p = +r.p;
+ this.ps = +r.ps;
+ return r.groups;
+ },
+
+ fetch: function (options) {
+ var d = (options && options.data) || {};
+ this.q = d.q;
+ return Backbone.Collection.prototype.fetch.apply(this, arguments);
+ },
+
+ fetchMore: function () {
+ var p = this.p + 1;
+ return this.fetch({ add: true, remove: false, data: { p: p, ps: this.ps, q: this.q } });
+ },
+
+ refresh: function () {
+ return this.fetch({ reset: true, data: { q: this.q } });
+ },
+
+ hasMore: function () {
+ return this.total > this.p * this.ps;
+ }
+
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/header-view.js b/server/sonar-web/src/main/js/apps/groups/header-view.js
new file mode 100644
index 00000000000..da6f7f60919
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/header-view.js
@@ -0,0 +1,25 @@
+define([
+ './create-view',
+ './templates'
+], function (CreateView) {
+
+ return Marionette.ItemView.extend({
+ template: Templates['groups-header'],
+
+ events: {
+ 'click #groups-create': 'onCreateClick'
+ },
+
+ onCreateClick: function (e) {
+ e.preventDefault();
+ this.createGroup();
+ },
+
+ createGroup: function () {
+ new CreateView({
+ collection: this.collection
+ }).render();
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/layout.js b/server/sonar-web/src/main/js/apps/groups/layout.js
new file mode 100644
index 00000000000..a60fb06f35f
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/layout.js
@@ -0,0 +1,16 @@
+define([
+ './templates'
+], function () {
+
+ return Marionette.Layout.extend({
+ template: Templates['groups-layout'],
+
+ regions: {
+ headerRegion: '#groups-header',
+ searchRegion: '#groups-search',
+ listRegion: '#groups-list',
+ listFooterRegion: '#groups-list-footer'
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/list-footer-view.js b/server/sonar-web/src/main/js/apps/groups/list-footer-view.js
new file mode 100644
index 00000000000..cdad034f24a
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/list-footer-view.js
@@ -0,0 +1,34 @@
+define([
+ './templates'
+], function () {
+
+ return Marionette.ItemView.extend({
+ template: Templates['groups-list-footer'],
+
+ collectionEvents: {
+ 'all': 'render'
+ },
+
+ events: {
+ 'click #groups-fetch-more': 'onMoreClick'
+ },
+
+ onMoreClick: function (e) {
+ e.preventDefault();
+ this.fetchMore();
+ },
+
+ fetchMore: function () {
+ this.collection.fetchMore();
+ },
+
+ serializeData: function () {
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ total: this.collection.total,
+ count: this.collection.length,
+ more: this.collection.hasMore()
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/list-item-view.js b/server/sonar-web/src/main/js/apps/groups/list-item-view.js
new file mode 100644
index 00000000000..43eaa5b0d24
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/list-item-view.js
@@ -0,0 +1,59 @@
+define([
+ './update-view',
+ './delete-view',
+ './users-view',
+ './templates'
+], function (UpdateView, DeleteView, UsersView) {
+
+ return Marionette.ItemView.extend({
+ tagName: 'li',
+ className: 'panel panel-vertical',
+ template: Templates['groups-list-item'],
+
+ events: {
+ 'click .js-group-update': 'onUpdateClick',
+ 'click .js-group-delete': 'onDeleteClick',
+ 'click .js-group-users': 'onUsersClick'
+ },
+
+ onRender: function () {
+ this.$el.attr('data-id', this.model.id);
+ this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' });
+ },
+
+ onClose: function () {
+ this.$('[data-toggle="tooltip"]').tooltip('destroy');
+ },
+
+ onUpdateClick: function (e) {
+ e.preventDefault();
+ this.updateGroup();
+ },
+
+ onDeleteClick: function (e) {
+ e.preventDefault();
+ this.deleteGroup();
+ },
+
+ onUsersClick: function (e) {
+ e.preventDefault();
+ this.showUsers();
+ },
+
+ updateGroup: function () {
+ new UpdateView({
+ model: this.model,
+ collection: this.model.collection
+ }).render();
+ },
+
+ deleteGroup: function () {
+ new DeleteView({ model: this.model }).render();
+ },
+
+ showUsers: function () {
+ new UsersView({ model: this.model }).render();
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/list-view.js b/server/sonar-web/src/main/js/apps/groups/list-view.js
new file mode 100644
index 00000000000..138c36b7619
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/list-view.js
@@ -0,0 +1,11 @@
+define([
+ './list-item-view',
+ './templates'
+], function (ListItemView) {
+
+ return Marionette.CollectionView.extend({
+ tagName: 'ul',
+ itemView: ListItemView
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/search-view.js b/server/sonar-web/src/main/js/apps/groups/search-view.js
new file mode 100644
index 00000000000..1540d7eb36e
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/search-view.js
@@ -0,0 +1,49 @@
+define([
+ './templates'
+], function () {
+
+ return Marionette.ItemView.extend({
+ template: Templates['groups-search'],
+
+ events: {
+ 'submit #groups-search-form': 'onFormSubmit',
+ 'search #groups-search-query': 'debouncedOnKeyUp',
+ 'keyup #groups-search-query': 'debouncedOnKeyUp'
+ },
+
+ initialize: function () {
+ this._bufferedValue = null;
+ this.debouncedOnKeyUp = _.debounce(this.onKeyUp, 400);
+ },
+
+ onRender: function () {
+ this.delegateEvents();
+ },
+
+ onFormSubmit: function (e) {
+ e.preventDefault();
+ this.debouncedOnKeyUp();
+ },
+
+ onKeyUp: function () {
+ var q = this.getQuery();
+ if (q === this._bufferedValue) {
+ return;
+ }
+ this._bufferedValue = this.getQuery();
+ if (this.searchRequest != null) {
+ this.searchRequest.abort();
+ }
+ this.searchRequest = this.search(q);
+ },
+
+ getQuery: function () {
+ return this.$('#groups-search-query').val();
+ },
+
+ search: function (q) {
+ return this.collection.fetch({ reset: true, data: { q: q } });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-delete.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-delete.hbs
new file mode 100644
index 00000000000..0644817633e
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-delete.hbs
@@ -0,0 +1,13 @@
+<form id="delete-group-form" autocomplete="off">
+ <div class="modal-head">
+ <h2>Delete Group</h2>
+ </div>
+ <div class="modal-body">
+ <div class="js-modal-messages"></div>
+ Are you sure you want to delete "{{name}}"?
+ </div>
+ <div class="modal-foot">
+ <button id="delete-group-submit">Delete</button>
+ <a href="#" class="js-modal-close" id="delete-group-cancel">Cancel</a>
+ </div>
+</form>
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-form.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-form.hbs
new file mode 100644
index 00000000000..a0927b33a73
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-form.hbs
@@ -0,0 +1,24 @@
+<form id="create-group-form" autocomplete="off">
+ <div class="modal-head">
+ <h2>{{#if id}}Update{{else}}Create{{/if}} Group</h2>
+ </div>
+ <div class="modal-body">
+ <div class="js-modal-messages"></div>
+ <div class="modal-field">
+ <label for="create-group-name">Name<em class="mandatory">*</em></label>
+ {{! keep this fake field to hack browser autofill }}
+ <input id="create-group-name-fake" name="name-fake" type="text" class="hidden">
+ <input id="create-group-name" name="name" type="text" size="50" maxlength="255" required value="{{name}}">
+ </div>
+ <div class="modal-field">
+ <label for="create-group-description">Description</label>
+ {{! keep this fake field to hack browser autofill }}
+ <textarea id="create-group-description-fake" name="description-fake" class="hidden"></textarea>
+ <textarea id="create-group-description" name="description">{{description}}</textarea>
+ </div>
+ </div>
+ <div class="modal-foot">
+ <button id="create-group-submit">{{#if id}}Update{{else}}Create{{/if}}</button>
+ <a href="#" class="js-modal-close" id="create-group-cancel">Cancel</a>
+ </div>
+</form>
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-header.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-header.hbs
new file mode 100644
index 00000000000..19ba74febf8
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-header.hbs
@@ -0,0 +1,9 @@
+<header class="page-header">
+ <h1 class="page-title">{{t 'user_groups.page'}}</h1>
+ <div class="page-actions">
+ <div class="button-group">
+ <button id="groups-create">Create Group</button>
+ </div>
+ </div>
+ <p class="page-description">{{t 'user_groups.page.description'}}</p>
+</header>
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-layout.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-layout.hbs
new file mode 100644
index 00000000000..4cad08c767e
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-layout.hbs
@@ -0,0 +1,6 @@
+<div class="page">
+ <div id="groups-header"></div>
+ <div id="groups-search"></div>
+ <div id="groups-list"></div>
+ <div id="groups-list-footer"></div>
+</div>
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-list-footer.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-list-footer.hbs
new file mode 100644
index 00000000000..841ab40ecd9
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-list-footer.hbs
@@ -0,0 +1,6 @@
+<footer class="spacer-top note text-center">
+ {{count}}/{{total}} shown
+ {{#if more}}
+ <a id="groups-fetch-more" class="spacer-left" href="#">show more</a>
+ {{/if}}
+</footer>
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-list-item.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-list-item.hbs
new file mode 100644
index 00000000000..611cc382493
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-list-item.hbs
@@ -0,0 +1,16 @@
+<div class="pull-right big-spacer-left nowrap">
+ <a class="js-group-update icon-edit little-spacer-right" title="Update Details" data-toggle="tooltip" href="#"></a>
+ <a class="js-group-delete icon-delete" title="Deactivate" data-toggle="tooltip" href="#"></a>
+</div>
+
+<div class="display-inline-block text-top width-20">
+ <strong class="js-group-name">{{name}}</strong>
+</div>
+
+<div class="display-inline-block text-top big-spacer-left width-10">
+ Members: <a class="js-group-users" href="#">{{membersCount}}</a>
+</div>
+
+<div class="display-inline-block text-top big-spacer-left width-50">
+ <span class="js-group-description">{{description}}</span>
+</div>
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-search.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-search.hbs
new file mode 100644
index 00000000000..5e81ec0b32a
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-search.hbs
@@ -0,0 +1,6 @@
+<div class="panel panel-vertical bordered-bottom spacer-bottom">
+ <form id="groups-search-form" class="search-box">
+ <button id="groups-search-submit" class="search-box-submit button-clean"><i class="icon-search"></i></button>
+ <input id="groups-search-query" class="search-box-input" type="search" name="q" placeholder="Search" maxlength="100">
+ </form>
+</div>
diff --git a/server/sonar-web/src/main/js/apps/groups/templates/groups-users.hbs b/server/sonar-web/src/main/js/apps/groups/templates/groups-users.hbs
new file mode 100644
index 00000000000..eb346c0e31b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/templates/groups-users.hbs
@@ -0,0 +1,10 @@
+<div class="modal-head">
+ <h2>Update users</h2>
+</div>
+<div class="modal-body">
+ <div class="js-modal-messages"></div>
+ <div id="groups-users"></div>
+</div>
+<div class="modal-foot">
+ <a href="#" class="js-modal-close" id="groups-users-done">Done</a>
+</div>
diff --git a/server/sonar-web/src/main/js/apps/groups/update-view.js b/server/sonar-web/src/main/js/apps/groups/update-view.js
new file mode 100644
index 00000000000..71383a1793d
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/update-view.js
@@ -0,0 +1,29 @@
+define([
+ './form-view'
+], function (FormView) {
+
+ return FormView.extend({
+
+ sendRequest: function () {
+ var that = this;
+ this.model.set({
+ name: this.$('#create-group-name').val(),
+ description: this.$('#create-group-description').val()
+ });
+ this.disableForm();
+ return this.model.save(null, {
+ statusCode: {
+ // do not show global error
+ 400: null
+ }
+ }).done(function () {
+ that.collection.refresh();
+ that.close();
+ }).fail(function (jqXHR) {
+ that.enableForm();
+ that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings);
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/apps/groups/users-view.js b/server/sonar-web/src/main/js/apps/groups/users-view.js
new file mode 100644
index 00000000000..bd236b67040
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/groups/users-view.js
@@ -0,0 +1,42 @@
+define([
+ 'components/common/modals',
+ 'components/common/select-list',
+ './templates'
+], function (Modal) {
+
+ return Modal.extend({
+ template: Templates['groups-users'],
+
+ onRender: function () {
+ Modal.prototype.onRender.apply(this, arguments);
+ new window.SelectList({
+ el: this.$('#groups-users'),
+ width: '100%',
+ readOnly: false,
+ focusSearch: false,
+ format: function (item) {
+ return item.name + '<br><span class="note">' + item.login + '</span>';
+ },
+ queryParam: 'q',
+ searchUrl: baseUrl + '/api/usergroups/users?ps=100&id=' + this.model.id,
+ selectUrl: baseUrl + '/api/usergroups/add_user',
+ deselectUrl: baseUrl + '/api/usergroups/remove_user',
+ extra: {
+ groupId: this.model.id
+ },
+ selectParameter: 'userLogin',
+ selectParameterValue: 'login',
+ parse: function (r) {
+ this.more = false;
+ return r.users;
+ }
+ });
+ },
+
+ onClose: function () {
+ this.model.collection.refresh();
+ Modal.prototype.onClose.apply(this, arguments);
+ }
+ });
+
+});