Load available permissions and find matching role

This commit is contained in:
René Pfeuffer
2019-01-24 09:53:26 +01:00
parent 5d3cbff461
commit 5b8518fbd9
4 changed files with 286 additions and 219 deletions

View File

@@ -5,6 +5,7 @@ import { Select } from "@scm-manager/ui-components";
type Props = { type Props = {
t: string => string, t: string => string,
availableTypes: string[],
handleTypeChange: string => void, handleTypeChange: string => void,
type: string, type: string,
label?: string, label?: string,
@@ -14,14 +15,22 @@ type Props = {
class TypeSelector extends React.Component<Props> { class TypeSelector extends React.Component<Props> {
render() { render() {
const { type, handleTypeChange, loading, label, helpText } = this.props; const {
const types = ["READ", "OWNER", "WRITE"]; availableTypes,
type,
handleTypeChange,
loading,
label,
helpText
} = this.props;
if (!availableTypes) return null;
return ( return (
<Select <Select
onChange={handleTypeChange} onChange={handleTypeChange}
value={type ? type : "READ"} value={type ? type : availableTypes[0]}
options={this.createSelectOptions(types)} options={this.createSelectOptions(availableTypes)}
loading={loading} loading={loading}
label={label} label={label}
helpText={helpText} helpText={helpText}

View File

@@ -6,6 +6,7 @@ import {
fetchAvailablePermissionsIfNeeded, fetchAvailablePermissionsIfNeeded,
fetchPermissions, fetchPermissions,
getFetchAvailablePermissionsFailure, getFetchAvailablePermissionsFailure,
getAvailablePermissions,
getFetchPermissionsFailure, getFetchPermissionsFailure,
isFetchAvailablePermissionsPending, isFetchAvailablePermissionsPending,
isFetchPermissionsPending, isFetchPermissionsPending,
@@ -22,6 +23,7 @@ import {
} from "../modules/permissions"; } from "../modules/permissions";
import { Loading, ErrorPage } from "@scm-manager/ui-components"; import { Loading, ErrorPage } from "@scm-manager/ui-components";
import type { import type {
AvailableRepositoryPermissions,
Permission, Permission,
PermissionCollection, PermissionCollection,
PermissionCreateEntry PermissionCreateEntry
@@ -36,6 +38,7 @@ import {
} from "../../../modules/indexResource"; } from "../../../modules/indexResource";
type Props = { type Props = {
availablePermissions: AvailableRepositoryPermissions,
namespace: string, namespace: string,
repoName: string, repoName: string,
loading: boolean, loading: boolean,
@@ -97,6 +100,7 @@ class Permissions extends React.Component<Props> {
render() { render() {
const { const {
availablePermissions,
loading, loading,
error, error,
permissions, permissions,
@@ -118,7 +122,7 @@ class Permissions extends React.Component<Props> {
); );
} }
if (loading || !permissions) { if (loading || !permissions || !availablePermissions) {
return <Loading />; return <Loading />;
} }
@@ -149,6 +153,7 @@ class Permissions extends React.Component<Props> {
{permissions.map(permission => { {permissions.map(permission => {
return ( return (
<SinglePermission <SinglePermission
availablePermissions={availablePermissions}
key={permission.name + permission.groupPermission.toString()} key={permission.name + permission.groupPermission.toString()}
namespace={namespace} namespace={namespace}
repoName={repoName} repoName={repoName}
@@ -186,7 +191,9 @@ const mapStateToProps = (state, ownProps) => {
const permissionsLink = getPermissionsLink(state, namespace, repoName); const permissionsLink = getPermissionsLink(state, namespace, repoName);
const groupAutoCompleteLink = getGroupAutoCompleteLink(state); const groupAutoCompleteLink = getGroupAutoCompleteLink(state);
const userAutoCompleteLink = getUserAutoCompleteLink(state); const userAutoCompleteLink = getUserAutoCompleteLink(state);
const availablePermissions = getAvailablePermissions(state);
return { return {
availablePermissions,
namespace, namespace,
repoName, repoName,
error, error,

View File

@@ -1,6 +1,9 @@
// @flow // @flow
import React from "react"; import React from "react";
import type { Permission } from "@scm-manager/ui-types"; import type {
AvailableRepositoryPermissions,
Permission
} from "@scm-manager/ui-types";
import { translate } from "react-i18next"; import { translate } from "react-i18next";
import { import {
modifyPermission, modifyPermission,
@@ -15,6 +18,7 @@ import DeletePermissionButton from "../components/buttons/DeletePermissionButton
import TypeSelector from "../components/TypeSelector"; import TypeSelector from "../components/TypeSelector";
type Props = { type Props = {
availablePermissions: AvailableRepositoryPermissions,
submitForm: Permission => void, submitForm: Permission => void,
modifyPermission: (Permission, string, string) => void, modifyPermission: (Permission, string, string) => void,
permission: Permission, permission: Permission,
@@ -29,6 +33,7 @@ type Props = {
}; };
type State = { type State = {
role: string,
permission: Permission permission: Permission
}; };
@@ -36,30 +41,66 @@ class SinglePermission extends React.Component<Props, State> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
const defaultPermission = props.availablePermissions.availableRoles
? props.availablePermissions.availableRoles[0]
: {};
this.state = { this.state = {
permission: { permission: {
name: "", name: "",
type: "READ", verbs: defaultPermission.verbs,
groupPermission: false, groupPermission: false,
_links: {} _links: {}
} },
role: defaultPermission.name
}; };
} }
componentDidMount() { componentDidMount() {
const { permission } = this.props; const { permission } = this.props;
const matchingRole = this.findMatchingRoleName();
if (permission) { if (permission) {
this.setState({ this.setState({
permission: { permission: {
name: permission.name, name: permission.name,
type: permission.type, verbs: permission.verbs,
groupPermission: permission.groupPermission, groupPermission: permission.groupPermission,
_links: permission._links _links: permission._links
} },
role: matchingRole
}); });
} }
} }
findMatchingRoleName = () => {
const { availablePermissions, permission } = this.props;
if (!permission) {
return "";
}
const matchingRole = availablePermissions.availableRoles.find(role => {
return this.equalVerbs(role.verbs, permission.verbs);
});
if (matchingRole) {
return matchingRole.name;
} else {
return "";
}
};
equalVerbs = (verbs1: string[], verbs2: string[]) => {
if (!verbs1 || !verbs2) {
return false;
}
if (verbs1.length !== verbs2.length) {
return false;
}
return verbs1.every(verb => verbs2.includes(verb));
};
deletePermission = () => { deletePermission = () => {
this.props.deletePermission( this.props.deletePermission(
this.props.permission, this.props.permission,
@@ -69,19 +110,23 @@ class SinglePermission extends React.Component<Props, State> {
}; };
render() { render() {
const { permission } = this.state; const { role, permission } = this.state;
const { loading, namespace, repoName } = this.props; const { availablePermissions, loading, namespace, repoName } = this.props;
const availableRoleNames = availablePermissions.availableRoles.map(
r => r.name
);
const typeSelector = const typeSelector =
this.props.permission._links && this.props.permission._links.update ? ( this.props.permission._links && this.props.permission._links.update ? (
<td> <td>
<TypeSelector <TypeSelector
handleTypeChange={this.handleTypeChange} handleTypeChange={this.handleTypeChange}
type={permission.type ? permission.type : "READ"} availableTypes={availableRoleNames}
type={role}
loading={loading} loading={loading}
/> />
</td> </td>
) : ( ) : (
<td>{permission.type}</td> <td>{role}</td>
); );
return ( return (

View File

@@ -534,6 +534,12 @@ export default function reducer(
// selectors // selectors
export function getAvailablePermissions(state: Object) {
if (state.permissions) {
return state.permissions.available;
}
}
export function getPermissionsOfRepo( export function getPermissionsOfRepo(
state: Object, state: Object,
namespace: string, namespace: string,