diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2015-09-14 13:45:40 +0200 |
---|---|---|
committer | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2015-09-28 16:35:02 +0200 |
commit | 24b80b59a96988e27c6aae6234d7d00c22ebc262 (patch) | |
tree | 8dd2a34ce8ed3add3256b391c5113c5f122b1a6d /server/sonar-web/src/main/js/apps/permission-templates | |
parent | 2634b3b9ed7c5601a886fa7ba8e3ad0cdc76c100 (diff) | |
download | sonarqube-24b80b59a96988e27c6aae6234d7d00c22ebc262.tar.gz sonarqube-24b80b59a96988e27c6aae6234d7d00c22ebc262.zip |
SONAR-6801 rewrite the permission templates page
Diffstat (limited to 'server/sonar-web/src/main/js/apps/permission-templates')
18 files changed, 632 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/apps/permission-templates/app.jsx b/server/sonar-web/src/main/js/apps/permission-templates/app.jsx new file mode 100644 index 00000000000..44ff6954266 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/app.jsx @@ -0,0 +1,23 @@ +import $ from 'jquery'; +import React from 'react'; +import Main from './main'; + +let topQualifiers = []; + +export default { + start(options) { + $.when( + window.requestMessages(), + this.requestTopQualifiers() + ).then(() => { + var el = document.querySelector(options.el); + React.render(<Main topQualifiers={topQualifiers}/>, el); + }); + }, + + requestTopQualifiers() { + return $.get(baseUrl + '/api/navigation/global').done(r => { + topQualifiers = r.qualifiers; + }); + } +}; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/create-view.jsx b/server/sonar-web/src/main/js/apps/permission-templates/create-view.jsx new file mode 100644 index 00000000000..733e970069f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/create-view.jsx @@ -0,0 +1,26 @@ +import FormView from './form-view'; +import {createPermissionTemplate} from '../../api/permissions'; + +export default FormView.extend({ + sendRequest: function () { + var that = this; + this.disableForm(); + return createPermissionTemplate({ + data: { + name: this.$('#permission-template-name').val(), + description: this.$('#permission-template-description').val(), + projectKeyPattern: this.$('#permission-template-project-key-pattern').val() + }, + statusCode: { + // do not show global error + 400: null + } + }).done(function () { + that.options.refresh(); + that.destroy(); + }).fail(function (jqXHR) { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/delete-view.jsx b/server/sonar-web/src/main/js/apps/permission-templates/delete-view.jsx new file mode 100644 index 00000000000..60b81fb701c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/delete-view.jsx @@ -0,0 +1,28 @@ +import ModalForm from '../../components/common/modal-form'; +import {deletePermissionTemplate} from '../../api/permissions'; +import './templates'; + +export default ModalForm.extend({ + template: Templates['permission-templates-delete'], + + onFormSubmit: function () { + ModalForm.prototype.onFormSubmit.apply(this, arguments); + this.sendRequest(); + }, + + sendRequest: function () { + var that = this; + return deletePermissionTemplate({ + data: { templateId: this.model.id }, + statusCode: { + // do not show global error + 400: null + } + }).done(function () { + that.options.refresh(); + that.destroy(); + }).fail(function (jqXHR) { + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/form-view.js b/server/sonar-web/src/main/js/apps/permission-templates/form-view.js new file mode 100644 index 00000000000..71d0802a790 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/form-view.js @@ -0,0 +1,25 @@ +import ModalForm from '../../components/common/modal-form'; +import './templates'; + +export default ModalForm.extend({ + template: Templates['permission-templates-form'], + + onRender: function () { + this._super(); + this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); + this.$('#create-custom-measure-metric').select2({ + width: '250px', + minimumResultsForSearch: 20 + }); + }, + + onDestroy: function () { + this._super(); + 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/permission-templates/groups-view.js b/server/sonar-web/src/main/js/apps/permission-templates/groups-view.js new file mode 100644 index 00000000000..21831f45c31 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/groups-view.js @@ -0,0 +1,52 @@ +import Modal from '../../components/common/modals'; +import '../../components/common/select-list'; +import './templates'; + +function getSearchUrl (permission, permissionTemplate) { + return baseUrl + '/api/permissions/template_groups?ps=100&permission=' + permission + + '&templateId=' + permissionTemplate.id; +} + +export default Modal.extend({ + template: Templates['permission-templates-groups'], + + onRender: function () { + this._super(); + new window.SelectList({ + el: this.$('#permission-templates-groups'), + width: '100%', + readOnly: false, + focusSearch: false, + format: function (item) { + return item.name; + }, + queryParam: 'q', + searchUrl: getSearchUrl(this.options.permission, this.options.permissionTemplate), + selectUrl: baseUrl + '/api/permissions/add_group_to_template', + deselectUrl: baseUrl + '/api/permissions/remove_group_from_template', + extra: { + permission: this.options.permission, + templateId: this.options.permissionTemplate.id + }, + selectParameter: 'groupName', + selectParameterValue: 'name', + parse: function (r) { + this.more = false; + return r.groups; + } + }); + }, + + onDestroy: function () { + if (this.options.refresh) { + this.options.refresh(); + } + this._super(); + }, + + serializeData: function () { + return _.extend(Modal.prototype.serializeData.apply(this, arguments), { + permissionTemplateName: this.options.permissionTemplate.name + }); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/header.jsx b/server/sonar-web/src/main/js/apps/permission-templates/header.jsx new file mode 100644 index 00000000000..0325d4bf6cb --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/header.jsx @@ -0,0 +1,23 @@ +import React from 'react'; +import CreateView from './create-view'; + +export default React.createClass({ + onCreate(e) { + e.preventDefault(); + new CreateView({ + refresh: this.props.refresh + }).render(); + }, + + render() { + return ( + <header id="project-permissions-header" className="page-header"> + <h1 className="page-title">{window.t('permission_templates.page')}</h1> + <div className="page-actions"> + <button onClick={this.onCreate}>Create</button> + </div> + <p className="page-description">{window.t('roles.page.description')}</p> + </header> + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/main.jsx b/server/sonar-web/src/main/js/apps/permission-templates/main.jsx new file mode 100644 index 00000000000..1a0abfc8ead --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/main.jsx @@ -0,0 +1,76 @@ +import _ from 'underscore'; +import React from 'react'; +import Header from './header'; +import PermissionTemplates from './permission-templates'; +import {getPermissionTemplates} from '../../api/permissions'; + +const PERMISSIONS_ORDER = ['user', 'codeviewer', 'issueadmin', 'admin']; + +export default React.createClass({ + propTypes: { + topQualifiers: React.PropTypes.array.isRequired + }, + + getInitialState() { + return { permissions: [], permissionTemplates: [] }; + }, + + componentDidMount() { + this.requestPermissions(); + }, + + sortPermissions(permissions) { + return _.sortBy(permissions, p => PERMISSIONS_ORDER.indexOf(p.key)); + }, + + mergePermissionsToTemplates(permissionTemplates, basePermissions) { + return permissionTemplates.map(permissionTemplate => { + // it's important to keep the order of the permission template's permissions + // the same as the order of base permissions + let permissions = basePermissions.map(basePermission => { + let projectPermission = _.findWhere(permissionTemplate.permissions, { key: basePermission.key }); + return _.extend({ usersCount: 0, groupsCount: 0 }, basePermission, projectPermission); + }); + return _.extend({}, permissionTemplate, { permissions: permissions }); + }); + }, + + mergeDefaultsToTemplates(permissionTemplates, defaultTemplates = []) { + return permissionTemplates.map(permissionTemplate => { + let defaultFor = []; + defaultTemplates.forEach(defaultTemplate => { + if (defaultTemplate.templateId === permissionTemplate.id) { + defaultFor.push(defaultTemplate.qualifier); + } + }); + return _.extend({}, permissionTemplate, { defaultFor }); + }); + }, + + requestPermissions() { + getPermissionTemplates().done(r => { + let permissions = this.sortPermissions(r.permissions); + let permissionTemplates = this.mergePermissionsToTemplates(r.permissionTemplates, permissions); + let permissionTemplatesWithDefaults = this.mergeDefaultsToTemplates(permissionTemplates, r.defaultTemplates); + this.setState({ + permissionTemplates: permissionTemplatesWithDefaults, + permissions: permissions + }); + }); + }, + + render() { + return ( + <div className="page"> + <Header + refresh={this.requestPermissions}/> + + <PermissionTemplates + permissionTemplates={this.state.permissionTemplates} + permissions={this.state.permissions} + topQualifiers={this.props.topQualifiers} + refresh={this.requestPermissions}/> + </div> + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.jsx new file mode 100644 index 00000000000..2cfb51b4123 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.jsx @@ -0,0 +1,24 @@ +import _ from 'underscore'; +import React from 'react'; +import QualifierIcon from '../../components/shared/qualifier-icon'; + +export default React.createClass({ + propTypes: { + permissionTemplate: React.PropTypes.object.isRequired + }, + + render() { + if (_.size(this.props.permissionTemplate.defaultFor) === 0) { + return null; + } + let defaults = this.props.permissionTemplate.defaultFor.map(qualifier => { + return <li key={qualifier}><QualifierIcon qualifier={qualifier}/> {window.t('qualifier', qualifier)}</li>; + }); + return ( + <ul className="list-inline nowrap spacer-bottom"> + <li>Default for</li> + {defaults} + </ul> + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.jsx new file mode 100644 index 00000000000..6bda07a46b2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.jsx @@ -0,0 +1,47 @@ +import _ from 'underscore'; +import React from 'react'; +import {setDefaultPermissionTemplate} from '../../api/permissions'; +import QualifierIcon from '../../components/shared/qualifier-icon'; + +export default React.createClass({ + propTypes: { + permissionTemplate: React.PropTypes.object.isRequired, + topQualifiers: React.PropTypes.array.isRequired, + refresh: React.PropTypes.func.isRequired + }, + + getAvailableQualifiers() { + return _.difference(this.props.topQualifiers, this.props.permissionTemplate.defaultFor); + }, + + setDefault(qualifier, e) { + e.preventDefault(); + setDefaultPermissionTemplate(this.props.permissionTemplate.id, qualifier).done(() => this.props.refresh()); + }, + + render() { + let availableQualifiers = this.getAvailableQualifiers(); + if (availableQualifiers.length === 0) { + return null; + } + + let qualifiers = availableQualifiers.map(qualifier => { + return ( + <li key={qualifier}> + <a onClick={this.setDefault.bind(this, qualifier)} href="#"> + Set Default for <QualifierIcon qualifier={qualifier}/> {window.t('qualifier', qualifier)} + </a> + </li> + ); + }); + + return ( + <span className="dropdown little-spacer-right"> + <button className="dropdown-toggle" data-toggle="dropdown"> + Set Default <i className="icon-dropdown"></i> + </button> + <ul className="dropdown-menu">{qualifiers}</ul> + </span> + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-template.jsx new file mode 100644 index 00000000000..71645b34d75 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template.jsx @@ -0,0 +1,116 @@ +import _ from 'underscore'; +import React from 'react'; +import Defaults from './permission-template-defaults'; +import SetDefaults from './permission-template-set-defaults'; +import UsersView from './users-view'; +import GroupsView from './groups-view'; +import UpdateView from './update-view'; +import DeleteView from './delete-view'; + +export default React.createClass({ + propTypes: { + permissionTemplate: React.PropTypes.object.isRequired, + topQualifiers: React.PropTypes.array.isRequired, + refresh: React.PropTypes.func.isRequired + }, + + showGroups(permission, e) { + e.preventDefault(); + new GroupsView({ + permission: permission, + permissionTemplate: this.props.permissionTemplate, + refresh: this.props.refresh + }).render(); + }, + + showUsers(permission, e) { + e.preventDefault(); + new UsersView({ + permission: permission, + permissionTemplate: this.props.permissionTemplate, + refresh: this.props.refresh + }).render(); + }, + + onUpdate(e) { + e.preventDefault(); + new UpdateView({ + model: new Backbone.Model(this.props.permissionTemplate), + refresh: this.props.refresh + }).render(); + }, + + onDelete(e) { + e.preventDefault(); + new DeleteView({ + model: new Backbone.Model(this.props.permissionTemplate), + refresh: this.props.refresh + }).render(); + }, + + renderAssociation() { + let projectKeyPattern = this.props.permissionTemplate.projectKeyPattern; + if (!projectKeyPattern) { + return null; + } + return <div className="spacer-bottom">Project Key Pattern: <code>{projectKeyPattern}</code></div>; + }, + + renderDeleteButton() { + if (_.size(this.props.permissionTemplate.defaultFor) > 0) { + return null; + } + return <button onClick={this.onDelete} className="button-red">Delete</button>; + }, + + render() { + let permissions = this.props.permissionTemplate.permissions.map(p => { + return ( + <td key={p.key}> + <table> + <tr> + <td className="spacer-right">Users</td> + <td className="spacer-left bordered-left">{p.usersCount}</td> + <td className="spacer-left"> + <a onClick={this.showUsers.bind(this, p.key)} className="icon-bullet-list" title="Update Users" + data-toggle="tooltip" href="#"></a> + </td> + </tr> + <tr> + <td className="spacer-right">Groups</td> + <td className="spacer-left bordered-left">{p.groupsCount}</td> + <td className="spacer-left"> + <a onClick={this.showGroups.bind(this, p.key)} className="icon-bullet-list" title="Update Users" + data-toggle="tooltip" href="#"></a> + </td> + </tr> + </table> + </td> + ); + }); + return ( + <tr> + <td> + <strong>{this.props.permissionTemplate.name}</strong> + <p className="note little-spacer-top">{this.props.permissionTemplate.description}</p> + </td> + {permissions} + <td className="thin text-right"> + {this.renderAssociation()} + <Defaults permissionTemplate={this.props.permissionTemplate}/> + <div className="nowrap"> + <SetDefaults + permissionTemplate={this.props.permissionTemplate} + topQualifiers={this.props.topQualifiers} + refresh={this.props.refresh}/> + + <div className="button-group"> + <button onClick={this.onUpdate}>Update</button> + {this.renderDeleteButton()} + </div> + </div> + </td> + </tr> + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-templates.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permission-templates.jsx new file mode 100644 index 00000000000..a86379e256d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-templates.jsx @@ -0,0 +1,28 @@ +import React from 'react'; +import PermissionsHeader from './permissions-header'; +import PermissionTemplate from './permission-template'; + +export default React.createClass({ + propTypes:{ + permissionTemplates: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, + permissions: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, + topQualifiers: React.PropTypes.array.isRequired, + refresh: React.PropTypes.func.isRequired + }, + + render() { + let permissionTemplates = this.props.permissionTemplates.map(p => { + return <PermissionTemplate + key={p.id} + permissionTemplate={p} + topQualifiers={this.props.topQualifiers} + refresh={this.props.refresh}/>; + }); + return ( + <table id="permission-templates" className="data zebra"> + <PermissionsHeader permissions={this.props.permissions}/> + <tbody>{permissionTemplates}</tbody> + </table> + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permissions-header.jsx b/server/sonar-web/src/main/js/apps/permission-templates/permissions-header.jsx new file mode 100644 index 00000000000..7768f9ec414 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/permissions-header.jsx @@ -0,0 +1,27 @@ +import React from 'react'; + +export default React.createClass({ + propTypes: { + permissions: React.PropTypes.arrayOf(React.PropTypes.object).isRequired + }, + + render() { + let cellWidth = (80 / this.props.permissions.length) + '%'; + let cells = this.props.permissions.map(p => { + return ( + <th key={p.key} style={{ width: cellWidth }}> + {p.name}<br/><span className="small">{p.description}</span> + </th> + ); + }); + return ( + <thead> + <tr> + <th style={{ width: '20%' }}> </th> + {cells} + <th className="thin"> </th> + </tr> + </thead> + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-delete.hbs b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-delete.hbs new file mode 100644 index 00000000000..178214f7ba0 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-delete.hbs @@ -0,0 +1,13 @@ +<form id="delete-permission-template-form"> + <div class="modal-head"> + <h2>Delete Permission Template</h2> + </div> + <div class="modal-body"> + <div class="js-modal-messages"></div> + Are you sure you want to delete permission template "{{name}}"? + </div> + <div class="modal-foot"> + <button id="delete-permission-template-submit" class="button-red">Delete</button> + <a href="#" class="js-modal-close" id="delete-permission-template-cancel">Cancel</a> + </div> +</form> diff --git a/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-form.hbs b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-form.hbs new file mode 100644 index 00000000000..3478f988bdd --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-form.hbs @@ -0,0 +1,28 @@ +<form id="permission-template-form" autocomplete="off"> + <div class="modal-head"> + <h2>{{#if id}}Update{{else}}Create{{/if}} Permission Template</h2> + </div> + <div class="modal-body"> + <div class="js-modal-messages"></div> + + <div class="modal-field"> + <label for="permission-template-name">Name<em class="mandatory">*</em></label> + <input id="permission-template-name" name="name" type="text" maxlength="256" required value="{{name}}"> + </div> + + <div class="modal-field"> + <label for="permission-template-description">Description</label> + <textarea id="permission-template-description" name="description" maxlength="4000" rows="5">{{description}}</textarea> + </div> + + <div class="modal-field"> + <label for="permission-template-project-key-pattern">Project Key Pattern</label> + <input id="permission-template-project-key-pattern" name="keyPattern" type="text" maxlength="500" + value="{{projectKeyPattern}}"> + </div> + </div> + <div class="modal-foot"> + <button id="permission-template-submit">{{#if id}}Update{{else}}Create{{/if}}</button> + <a href="#" class="js-modal-close" id="permission-template-cancel">Cancel</a> + </div> +</form> diff --git a/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-groups.hbs b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-groups.hbs new file mode 100644 index 00000000000..3301ece4ca5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-groups.hbs @@ -0,0 +1,10 @@ +<div class="modal-head"> + <h2>Update Groups of "{{permissionTemplateName}}"</h2> +</div> +<div class="modal-body"> + <div class="js-modal-messages"></div> + <div id="permission-templates-groups"></div> +</div> +<div class="modal-foot"> + <a href="#" class="js-modal-close">Done</a> +</div> diff --git a/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-users.hbs b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-users.hbs new file mode 100644 index 00000000000..d51f89a5e34 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-users.hbs @@ -0,0 +1,10 @@ +<div class="modal-head"> + <h2>Update Users of "{{permissionTemplateName}}"</h2> +</div> +<div class="modal-body"> + <div class="js-modal-messages"></div> + <div id="permission-templates-users"></div> +</div> +<div class="modal-foot"> + <a href="#" class="js-modal-close">Done</a> +</div> diff --git a/server/sonar-web/src/main/js/apps/permission-templates/update-view.jsx b/server/sonar-web/src/main/js/apps/permission-templates/update-view.jsx new file mode 100644 index 00000000000..38e546b820d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/update-view.jsx @@ -0,0 +1,27 @@ +import FormView from './form-view'; +import {updatePermissionTemplate} from '../../api/permissions'; + +export default FormView.extend({ + sendRequest: function () { + var that = this; + this.disableForm(); + return updatePermissionTemplate({ + data: { + id: this.model.id, + name: this.$('#permission-template-name').val(), + description: this.$('#permission-template-description').val(), + projectKeyPattern: this.$('#permission-template-project-key-pattern').val() + }, + statusCode: { + // do not show global error + 400: null + } + }).done(function () { + that.options.refresh(); + that.destroy(); + }).fail(function (jqXHR) { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); + } +}); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/users-view.js b/server/sonar-web/src/main/js/apps/permission-templates/users-view.js new file mode 100644 index 00000000000..31275f25b6f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/users-view.js @@ -0,0 +1,49 @@ +import Modal from '../../components/common/modals'; +import '../../components/common/select-list'; +import './templates'; + +export default Modal.extend({ + template: Templates['permission-templates-users'], + + onRender: function () { + this._super(); + var searchUrl = baseUrl + '/api/permissions/template_users?ps=100&permission=' + this.options.permission + + '&templateId=' + this.options.permissionTemplate.id; + new window.SelectList({ + el: this.$('#permission-templates-users'), + width: '100%', + readOnly: false, + focusSearch: false, + format: function (item) { + return item.name + '<br><span class="note">' + item.login + '</span>'; + }, + queryParam: 'q', + searchUrl: searchUrl, + selectUrl: baseUrl + '/api/permissions/add_user_to_template', + deselectUrl: baseUrl + '/api/permissions/remove_user_from_template', + extra: { + permission: this.options.permission, + templateId: this.options.permissionTemplate.id + }, + selectParameter: 'login', + selectParameterValue: 'login', + parse: function (r) { + this.more = false; + return r.users; + } + }); + }, + + onDestroy: function () { + if (this.options.refresh) { + this.options.refresh(); + } + this._super(); + }, + + serializeData: function () { + return _.extend(Modal.prototype.serializeData.apply(this, arguments), { + permissionTemplateName: this.options.permissionTemplate.name + }); + } +}); |