From 7a65a44016c32c5656e7aa5f0e174e670b6849b0 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Thu, 20 Aug 2015 15:39:03 +0200 Subject: SONAR-6797 rewrite project permissions page --- .../src/main/js/apps/project-permissions/app.jsx | 13 ++++ .../js/apps/project-permissions/groups-view.js | 43 ++++++++++++ .../src/main/js/apps/project-permissions/main.jsx | 80 ++++++++++++++++++++++ .../project-permissions/permissions-footer.jsx | 20 ++++++ .../project-permissions/permissions-header.jsx | 26 +++++++ .../js/apps/project-permissions/permissions.jsx | 23 +++++++ .../main/js/apps/project-permissions/project.jsx | 66 ++++++++++++++++++ .../main/js/apps/project-permissions/search.jsx | 34 +++++++++ .../templates/project-permissions-groups.hbs | 10 +++ .../templates/project-permissions-users.hbs | 10 +++ .../main/js/apps/project-permissions/users-view.js | 43 ++++++++++++ 11 files changed, 368 insertions(+) create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/app.jsx create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/groups-view.js create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/main.jsx create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.jsx create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/permissions-header.jsx create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/permissions.jsx create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/project.jsx create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/search.jsx create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-groups.hbs create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-users.hbs create mode 100644 server/sonar-web/src/main/js/apps/project-permissions/users-view.js (limited to 'server/sonar-web/src/main/js/apps/project-permissions') diff --git a/server/sonar-web/src/main/js/apps/project-permissions/app.jsx b/server/sonar-web/src/main/js/apps/project-permissions/app.jsx new file mode 100644 index 00000000000..28dc73b7f42 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/app.jsx @@ -0,0 +1,13 @@ +import React from 'react'; +import Main from './main'; + +const $ = jQuery; + +export default { + start(options) { + window.requestMessages().done(() => { + var el = document.querySelector(options.el); + React.render(
, el); + }); + } +}; diff --git a/server/sonar-web/src/main/js/apps/project-permissions/groups-view.js b/server/sonar-web/src/main/js/apps/project-permissions/groups-view.js new file mode 100644 index 00000000000..ba98ca7e525 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/groups-view.js @@ -0,0 +1,43 @@ +define([ + 'components/common/modals', + 'components/common/select-list', + './templates' +], function (Modal) { + + return Modal.extend({ + template: Templates['project-permissions-groups'], + + onRender: function () { + this._super(); + new window.SelectList({ + el: this.$('#project-permissions-groups'), + width: '100%', + readOnly: false, + focusSearch: false, + format: function (item) { + return item.name; + }, + queryParam: 'q', + searchUrl: baseUrl + '/api/permissions/groups?ps=100&permission=' + this.options.permission + '&projectId=' + this.options.project, + selectUrl: baseUrl + '/api/permissions/add_group', + deselectUrl: baseUrl + '/api/permissions/remove_group', + extra: { + permission: this.options.permission, + projectId: this.options.project + }, + selectParameter: 'groupName', + selectParameterValue: 'name', + parse: function (r) { + this.more = false; + return r.groups; + } + }); + }, + + onDestroy: function () { + this.options.refresh && this.options.refresh(); + this._super(); + } + }); + +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/main.jsx b/server/sonar-web/src/main/js/apps/project-permissions/main.jsx new file mode 100644 index 00000000000..96b77f7cb72 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/main.jsx @@ -0,0 +1,80 @@ +import React from 'react'; +import Permissions from './permissions'; +import PermissionsFooter from './permissions-footer'; +import Search from './search'; + +let $ = jQuery; + +export default React.createClass({ + getInitialState() { + return { permissions: [], projects: [], total: 0 }; + }, + + componentDidMount() { + this.requestPermissions(); + }, + + mergePermissionsToProjects(projects, basePermissions) { + return projects.map(project => { + // it's important to keep the order of the project permissions the same as the order of base permissions + let permissions = basePermissions.map(basePermission => { + let projectPermission = _.findWhere(project.permissions, { key: basePermission.key }); + if (!projectPermission) { + throw new Error(`Project "${project.name} [${project.key}]" doesn't have permission "${basePermission.key}"`); + } + return _.extend({}, basePermission, projectPermission); + }); + return _.extend({}, project, { permissions: permissions }); + }); + }, + + requestPermissions(page = 1, query = '') { + let url = `${window.baseUrl}/api/permissions/search_project_permissions`; + let data = { p: page, q: query }; + $.get(url, data).done(r => { + let projects = this.mergePermissionsToProjects(r.projects, r.permissions); + if (page > 1) { + projects = [].concat(this.state.projects, projects); + } + this.setState({ + projects: projects, + permissions: r.permissions, + total: r.paging.total, + page: r.paging.pageIndex, + query: query + }); + }); + }, + + loadMore() { + this.requestPermissions(this.state.page + 1, this.state.query); + }, + + search(query) { + this.requestPermissions(1, query); + }, + + render() { + return ( +
+
+

{window.t('roles.page')}

+

{window.t('roles.page.description2')}

+
+ + + + + + +
+ ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.jsx b/server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.jsx new file mode 100644 index 00000000000..f4913a753c2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/permissions-footer.jsx @@ -0,0 +1,20 @@ +import React from 'react'; + +export default React.createClass({ + propTypes:{ + count: React.PropTypes.number.isRequired, + total: React.PropTypes.number.isRequired, + loadMore: React.PropTypes.func.isRequired + }, + + render() { + let hasMore = this.props.total > this.props.count; + let loadMoreLink = show more; + return ( +
+ {this.props.count}/{this.props.total} shown + {hasMore ? loadMoreLink : null} +
+ ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/permissions-header.jsx b/server/sonar-web/src/main/js/apps/project-permissions/permissions-header.jsx new file mode 100644 index 00000000000..a68cca21fc2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/permissions-header.jsx @@ -0,0 +1,26 @@ +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 ( + + {p.name}
{p.description} + + ); + }); + return ( + + +   + {cells} + + + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/permissions.jsx b/server/sonar-web/src/main/js/apps/project-permissions/permissions.jsx new file mode 100644 index 00000000000..4638c209651 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/permissions.jsx @@ -0,0 +1,23 @@ +import React from 'react'; +import PermissionsHeader from './permissions-header'; +import Project from './project'; + +export default React.createClass({ + propTypes:{ + projects: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, + permissions: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, + refresh: React.PropTypes.func.isRequired + }, + + render() { + let projects = this.props.projects.map(p => { + return + }); + return ( + + + {projects} +
+ ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/project.jsx b/server/sonar-web/src/main/js/apps/project-permissions/project.jsx new file mode 100644 index 00000000000..31c03a1572f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/project.jsx @@ -0,0 +1,66 @@ +import React from 'react'; +import UsersView from './users-view'; +import GroupsView from './groups-view'; +import {getProjectUrl} from '../../helpers/Url'; + +export default React.createClass({ + propTypes: { + project: React.PropTypes.object.isRequired, + refresh: React.PropTypes.func.isRequired + }, + + showGroups(permission, e) { + e.preventDefault(); + new GroupsView({ + permission: permission, + project: this.props.project.uuid, + refresh: this.props.refresh + }).render(); + }, + + showUsers(permission, e) { + e.preventDefault(); + new UsersView({ + permission: permission, + project: this.props.project.uuid, + refresh: this.props.refresh + }).render(); + }, + + render() { + let permissions = this.props.project.permissions.map(p => { + return ( + + + + + + + + + + + + +
Users{p.usersCount} + +
Groups{p.groupsCount} + +
+ + ); + }); + return ( + + + + {this.props.project.name} + + + {permissions} + + ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/search.jsx b/server/sonar-web/src/main/js/apps/project-permissions/search.jsx new file mode 100644 index 00000000000..3506d78834b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/search.jsx @@ -0,0 +1,34 @@ +import React from 'react'; + +export default React.createClass({ + propTypes: { + search: React.PropTypes.func.isRequired + }, + + componentWillMount: function () { + this.search = _.debounce(this.search, 250); + }, + + onSubmit(e) { + e.preventDefault(); + this.search(); + }, + + search() { + let q = React.findDOMNode(this.refs.input).value; + this.props.search(q); + }, + + render() { + return ( +
+
+ + +
+
+ ); + } +}); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-groups.hbs b/server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-groups.hbs new file mode 100644 index 00000000000..c5f551e3682 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-groups.hbs @@ -0,0 +1,10 @@ + + + diff --git a/server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-users.hbs b/server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-users.hbs new file mode 100644 index 00000000000..acfd4eaf75d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/templates/project-permissions-users.hbs @@ -0,0 +1,10 @@ + + + diff --git a/server/sonar-web/src/main/js/apps/project-permissions/users-view.js b/server/sonar-web/src/main/js/apps/project-permissions/users-view.js new file mode 100644 index 00000000000..6a715835ba7 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-permissions/users-view.js @@ -0,0 +1,43 @@ +define([ + 'components/common/modals', + 'components/common/select-list', + './templates' +], function (Modal) { + + return Modal.extend({ + template: Templates['project-permissions-users'], + + onRender: function () { + this._super(); + new window.SelectList({ + el: this.$('#project-permissions-users'), + width: '100%', + readOnly: false, + focusSearch: false, + format: function (item) { + return item.name + '
' + item.login + ''; + }, + queryParam: 'q', + searchUrl: baseUrl + '/api/permissions/users?ps=100&permission=' + this.options.permission + '&projectId=' + this.options.project, + selectUrl: baseUrl + '/api/permissions/add_user', + deselectUrl: baseUrl + '/api/permissions/remove_user', + extra: { + permission: this.options.permission, + projectId: this.options.project + }, + selectParameter: 'login', + selectParameterValue: 'login', + parse: function (r) { + this.more = false; + return r.users; + } + }); + }, + + onDestroy: function () { + this.options.refresh && this.options.refresh(); + this._super(); + } + }); + +}); -- cgit v1.2.3