diff --git a/scm-ui/src/modules/indexResource.js b/scm-ui/src/modules/indexResource.js index 0facb51faa..2c6805d207 100644 --- a/scm-ui/src/modules/indexResource.js +++ b/scm-ui/src/modules/indexResource.js @@ -127,6 +127,14 @@ export function getUsersLink(state: Object) { return getLink(state, "users"); } +export function getRepositoryRolesLink(state: Object) { + return getLink(state, "repositoryRoles"); +} + +export function getRepositoryVerbsLink(state: Object) { + return getLink(state, "repositoryVerbs"); +} + export function getGroupsLink(state: Object) { return getLink(state, "groups"); } diff --git a/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js b/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js index d2300b9864..94fc707dc1 100644 --- a/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js +++ b/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js @@ -10,7 +10,7 @@ import { } from "@scm-manager/ui-components"; import RoleSelector from "../components/RoleSelector"; import type { - AvailableRepositoryPermissions, + RepositoryRole, PermissionCollection, PermissionCreateEntry, SelectValue @@ -21,7 +21,8 @@ import AdvancedPermissionsDialog from "./AdvancedPermissionsDialog"; type Props = { t: string => string, - availablePermissions: AvailableRepositoryPermissions, + availableRoles: RepositoryRole[], + availableVerbs: string[], createPermission: (permission: PermissionCreateEntry) => void, loading: boolean, currentPermissions: PermissionCollection, @@ -44,7 +45,7 @@ class CreatePermissionForm extends React.Component { this.state = { name: "", - verbs: props.availablePermissions.availableRoles[0].verbs, + verbs: props.availableRoles[0].verbs, groupPermission: false, valid: true, value: undefined, @@ -132,18 +133,18 @@ class CreatePermissionForm extends React.Component { }; render() { - const { t, availablePermissions, loading } = this.props; + const { t, availableRoles, availableVerbs, loading } = this.props; const { verbs, showAdvancedDialog } = this.state; - const availableRoleNames = availablePermissions.availableRoles.map( + const availableRoleNames = availableRoles.map( r => r.name ); - const matchingRole = findMatchingRoleName(availablePermissions, verbs); + const matchingRole = findMatchingRoleName(availableRoles, verbs); const advancedDialog = showAdvancedDialog ? ( { removeState = () => { this.setState({ name: "", - verbs: this.props.availablePermissions.availableRoles[0].verbs, + verbs: this.props.availableRoles[0].verbs, valid: true, value: undefined }); @@ -263,7 +264,7 @@ class CreatePermissionForm extends React.Component { }; findAvailableRole = (roleName: string) => { - return this.props.availablePermissions.availableRoles.find( + return this.props.availableRoles.find( role => role.name === roleName ); }; diff --git a/scm-ui/src/repos/permissions/containers/Permissions.js b/scm-ui/src/repos/permissions/containers/Permissions.js index 6fd9cbab38..02c43d254c 100644 --- a/scm-ui/src/repos/permissions/containers/Permissions.js +++ b/scm-ui/src/repos/permissions/containers/Permissions.js @@ -19,7 +19,7 @@ import { getDeletePermissionsFailure, getModifyPermissionsFailure, modifyPermissionReset, - deletePermissionReset + deletePermissionReset, getAvailableRepositoryRoles, getAvailableRepositoryVerbs } from "../modules/permissions"; import { Loading, @@ -28,22 +28,23 @@ import { LabelWithHelpIcon } from "@scm-manager/ui-components"; import type { - AvailableRepositoryPermissions, Permission, PermissionCollection, - PermissionCreateEntry + PermissionCreateEntry, + RepositoryRole } from "@scm-manager/ui-types"; import SinglePermission from "./SinglePermission"; import CreatePermissionForm from "./CreatePermissionForm"; import type { History } from "history"; import { getPermissionsLink } from "../../modules/repos"; import { - getGroupAutoCompleteLink, + getGroupAutoCompleteLink, getRepositoryRolesLink, getRepositoryVerbsLink, getUserAutoCompleteLink } from "../../../modules/indexResource"; type Props = { - availablePermissions: AvailableRepositoryPermissions, + availableRepositoryRoles: RepositoryRole[], + availableVerbs: string[], namespace: string, repoName: string, loading: boolean, @@ -51,6 +52,8 @@ type Props = { permissions: PermissionCollection, hasPermissionToCreate: boolean, loadingCreatePermission: boolean, + repositoryRolesLink: string, + repositoryVerbsLink: string, permissionsLink: string, groupAutoCompleteLink: string, userAutoCompleteLink: string, @@ -85,13 +88,15 @@ class Permissions extends React.Component { modifyPermissionReset, createPermissionReset, deletePermissionReset, - permissionsLink + permissionsLink, + repositoryRolesLink, + repositoryVerbsLink } = this.props; createPermissionReset(namespace, repoName); modifyPermissionReset(namespace, repoName); deletePermissionReset(namespace, repoName); - fetchAvailablePermissionsIfNeeded(); + fetchAvailablePermissionsIfNeeded(repositoryRolesLink, repositoryVerbsLink); fetchPermissions(permissionsLink, namespace, repoName); } @@ -107,6 +112,8 @@ class Permissions extends React.Component { render() { const { availablePermissions, + availableRepositoryRoles, + availableVerbs, loading, error, permissions, @@ -134,7 +141,8 @@ class Permissions extends React.Component { const createPermissionForm = hasPermissionToCreate ? ( this.createPermission(permission)} loading={loadingCreatePermission} currentPermissions={permissions} @@ -174,7 +182,8 @@ class Permissions extends React.Component { {permissions.map(permission => { return ( { repoName ); const hasPermissionToCreate = hasCreatePermission(state, namespace, repoName); + const repositoryRolesLink = getRepositoryRolesLink(state); + const repositoryVerbsLink = getRepositoryVerbsLink(state); const permissionsLink = getPermissionsLink(state, namespace, repoName); const groupAutoCompleteLink = getGroupAutoCompleteLink(state); const userAutoCompleteLink = getUserAutoCompleteLink(state); const availablePermissions = getAvailablePermissions(state); + const availableRepositoryRoles = getAvailableRepositoryRoles(state); + const availableVerbs = getAvailableRepositoryVerbs(state); + return { availablePermissions, + availableRepositoryRoles, + availableVerbs, namespace, repoName, + repositoryRolesLink, + repositoryVerbsLink, error, loading, permissions, @@ -233,8 +251,8 @@ const mapDispatchToProps = dispatch => { fetchPermissions: (link: string, namespace: string, repoName: string) => { dispatch(fetchPermissions(link, namespace, repoName)); }, - fetchAvailablePermissionsIfNeeded: () => { - dispatch(fetchAvailablePermissionsIfNeeded()); + fetchAvailablePermissionsIfNeeded: (repositoryRolesLink: string, repositoryVerbsLink: string) => { + dispatch(fetchAvailablePermissionsIfNeeded(repositoryRolesLink, repositoryVerbsLink)); }, createPermission: ( link: string, diff --git a/scm-ui/src/repos/permissions/containers/SinglePermission.js b/scm-ui/src/repos/permissions/containers/SinglePermission.js index e5a9c604a6..c90d6ab968 100644 --- a/scm-ui/src/repos/permissions/containers/SinglePermission.js +++ b/scm-ui/src/repos/permissions/containers/SinglePermission.js @@ -1,7 +1,7 @@ // @flow import React from "react"; import type { - AvailableRepositoryPermissions, + RepositoryRole, Permission } from "@scm-manager/ui-types"; import { translate } from "react-i18next"; @@ -22,7 +22,8 @@ import classNames from "classnames"; import injectSheet from "react-jss"; type Props = { - availablePermissions: AvailableRepositoryPermissions, + availableRepositoryRoles: RepositoryRole[], + availableRepositoryVerbs: string[], submitForm: Permission => void, modifyPermission: ( permission: Permission, @@ -68,8 +69,8 @@ class SinglePermission extends React.Component { constructor(props: Props) { super(props); - const defaultPermission = props.availablePermissions.availableRoles - ? props.availablePermissions.availableRoles[0] + const defaultPermission = props.availableRoles + ? props.availableRoles[0] : {}; this.state = { @@ -85,10 +86,10 @@ class SinglePermission extends React.Component { } componentDidMount() { - const { availablePermissions, permission } = this.props; + const { availableRepositoryRoles, permission } = this.props; const matchingRole = findMatchingRoleName( - availablePermissions, + availableRepositoryRoles, permission.verbs ); @@ -117,13 +118,14 @@ class SinglePermission extends React.Component { const { role, permission, showAdvancedDialog } = this.state; const { t, - availablePermissions, + availableRepositoryRoles, + availableRepositoryVerbs, loading, namespace, repoName, classes } = this.props; - const availableRoleNames = availablePermissions.availableRoles.map( + const availableRoleNames = !!availableRepositoryRoles && availableRepositoryRoles.map( r => r.name ); const readOnly = !this.mayChangePermissions(); @@ -143,7 +145,7 @@ class SinglePermission extends React.Component { const advancedDialg = showAdvancedDialog ? ( { submitAdvancedPermissionsDialog = (newVerbs: string[]) => { const { permission } = this.state; const newRole = findMatchingRoleName( - this.props.availablePermissions, + this.props.availableRoles, newVerbs ); this.setState( @@ -226,7 +228,8 @@ class SinglePermission extends React.Component { }; findAvailableRole = (roleName: string) => { - return this.props.availablePermissions.availableRoles.find( + const { availableRepositoryRoles } = this.props; + return availableRepositoryRoles.find( role => role.name === roleName ); }; diff --git a/scm-ui/src/repos/permissions/modules/permissions.js b/scm-ui/src/repos/permissions/modules/permissions.js index 8c4161e907..2b0263bf35 100644 --- a/scm-ui/src/repos/permissions/modules/permissions.js +++ b/scm-ui/src/repos/permissions/modules/permissions.js @@ -4,7 +4,7 @@ import type { Action } from "@scm-manager/ui-components"; import { apiClient } from "@scm-manager/ui-components"; import * as types from "../../../modules/types"; import type { - AvailableRepositoryPermissions, + RepositoryRole, Permission, PermissionCollection, PermissionCreateEntry @@ -12,7 +12,6 @@ import type { import { isPending } from "../../../modules/pending"; import { getFailure } from "../../../modules/failure"; import { Dispatch } from "redux"; -import { getLinks } from "../../../modules/indexResource"; export const FETCH_AVAILABLE = "scm/permissions/FETCH_AVAILABLE"; export const FETCH_AVAILABLE_PENDING = `${FETCH_AVAILABLE}_${ @@ -78,22 +77,36 @@ const CONTENT_TYPE = "application/vnd.scmm-repositoryPermission+json"; // fetch available permissions -export function fetchAvailablePermissionsIfNeeded() { +export function fetchAvailablePermissionsIfNeeded(repositoryRolesLink: string, repositoryVerbsLink: string) { return function(dispatch: any, getState: () => Object) { if (shouldFetchAvailablePermissions(getState())) { - return fetchAvailablePermissions(dispatch, getState); + return fetchAvailablePermissions(dispatch, getState, repositoryRolesLink, repositoryVerbsLink); } }; } export function fetchAvailablePermissions( dispatch: any, - getState: () => Object + getState: () => Object, + repositoryRolesLink: string, + repositoryVerbsLink: string ) { dispatch(fetchAvailablePending()); return apiClient - .get(getLinks(getState()).availableRepositoryPermissions.href) - .then(response => response.json()) + .get(repositoryRolesLink) + .then(repositoryRoles => repositoryRoles.json()) + .then(repositoryRoles => repositoryRoles._embedded.repositoryRoles) + .then(repositoryRoles => { + return apiClient.get(repositoryVerbsLink) + .then(repositoryVerbs => repositoryVerbs.json()) + .then(repositoryVerbs => repositoryVerbs.verbs) + .then(repositoryVerbs => { + return { + repositoryVerbs, + repositoryRoles + }; + }); + }) .then(available => { dispatch(fetchAvailableSuccess(available)); }) @@ -121,7 +134,7 @@ export function fetchAvailablePending(): Action { } export function fetchAvailableSuccess( - available: AvailableRepositoryPermissions + available: [RepositoryRole[], string[]] ): Action { return { type: FETCH_AVAILABLE_SUCCESS, @@ -543,6 +556,21 @@ export function getAvailablePermissions(state: Object) { } } +export function getAvailableRepositoryRoles(state: Object) { + return available(state).repositoryRoles; +} + +export function getAvailableRepositoryVerbs(state: Object) { + return available(state).repositoryVerbs; +} + +function available(state: Object) { + if (state.permissions && state.permissions.available) { + return state.permissions.available; + } + return {}; +} + export function getPermissionsOfRepo( state: Object, namespace: string, @@ -705,13 +733,13 @@ export function getModifyPermissionsFailure( } export function findMatchingRoleName( - availablePermissions: AvailableRepositoryPermissions, + availableRoles: RepositoryRole[], verbs: string[] ) { if (!verbs) { return ""; } - const matchingRole = availablePermissions.availableRoles.find(role => { + const matchingRole = !! availableRoles && availableRoles.find(role => { return equalVerbs(role.verbs, verbs); });