diff --git a/scm-ui-components/packages/ui-components/src/buttons/Button.js b/scm-ui-components/packages/ui-components/src/buttons/Button.js index 2102bb540a..5e80db1e45 100644 --- a/scm-ui-components/packages/ui-components/src/buttons/Button.js +++ b/scm-ui-components/packages/ui-components/src/buttons/Button.js @@ -12,6 +12,8 @@ export type ButtonProps = { fullWidth?: boolean, className?: string, children?: React.Node, + + // context props classes: any }; diff --git a/scm-ui-components/packages/ui-types/src/RepositoryPermissions.js b/scm-ui-components/packages/ui-types/src/RepositoryPermissions.js index ed3c925283..14a2298fbe 100644 --- a/scm-ui-components/packages/ui-types/src/RepositoryPermissions.js +++ b/scm-ui-components/packages/ui-types/src/RepositoryPermissions.js @@ -1,14 +1,15 @@ //@flow import type {Links} from "./hal"; +export type PermissionCreateEntry = { + name: string, + role?: string, + verbs?: string[], + groupPermission: boolean +} + export type Permission = PermissionCreateEntry & { _links: Links }; -export type PermissionCreateEntry = { - name: string, - verbs: string[], - groupPermission: boolean -} - export type PermissionCollection = Permission[]; diff --git a/scm-ui/public/locales/de/config.json b/scm-ui/public/locales/de/config.json index eff3efa718..71ab66ff22 100644 --- a/scm-ui/public/locales/de/config.json +++ b/scm-ui/public/locales/de/config.json @@ -29,6 +29,10 @@ "submit": "Speichern" } }, + "role": { + "name": "Name", + "system": "System" + }, "config-form": { "submit": "Speichern", "submit-success-notification": "Einstellungen wurden erfolgreich geƤndert!", diff --git a/scm-ui/public/locales/de/repos.json b/scm-ui/public/locales/de/repos.json index f4ee071613..4ba7a725e6 100644 --- a/scm-ui/public/locales/de/repos.json +++ b/scm-ui/public/locales/de/repos.json @@ -119,6 +119,7 @@ "error-subtitle": "Unbekannter Fehler bei Berechtigung", "name": "Benutzer oder Gruppe", "role": "Rolle", + "custom": "CUSTOM", "permissions": "Berechtigung", "group-permission": "Gruppenberechtigung", "user-permission": "Benutzerberechtigung", diff --git a/scm-ui/public/locales/en/repos.json b/scm-ui/public/locales/en/repos.json index 7344547d49..9a2e83f983 100644 --- a/scm-ui/public/locales/en/repos.json +++ b/scm-ui/public/locales/en/repos.json @@ -122,6 +122,7 @@ "error-subtitle": "Unknown permissions error", "name": "User or group", "role": "Role", + "custom": "CUSTOM", "permissions": "Permissions", "group-permission": "Group Permission", "user-permission": "User Permission", diff --git a/scm-ui/src/repos/permissions/containers/AdvancedPermissionsDialog.js b/scm-ui/src/repos/permissions/containers/AdvancedPermissionsDialog.js index cc662e5f06..d15b9112b9 100644 --- a/scm-ui/src/repos/permissions/containers/AdvancedPermissionsDialog.js +++ b/scm-ui/src/repos/permissions/containers/AdvancedPermissionsDialog.js @@ -26,9 +26,11 @@ class AdvancedPermissionsDialog extends React.Component { const verbs = {}; props.availableVerbs.forEach( - verb => (verbs[verb] = props.selectedVerbs.includes(verb)) + verb => + (verbs[verb] = props.selectedVerbs + ? props.selectedVerbs.includes(verb) + : false) ); - this.state = { verbs }; } diff --git a/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js b/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js index 94fc707dc1..8ee1e7edbb 100644 --- a/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js +++ b/scm-ui/src/repos/permissions/containers/CreatePermissionForm.js @@ -1,6 +1,12 @@ // @flow import React from "react"; import { translate } from "react-i18next"; +import type { + RepositoryRole, + PermissionCollection, + PermissionCreateEntry, + SelectValue +} from "@scm-manager/ui-types"; import { Autocomplete, SubmitButton, @@ -8,31 +14,27 @@ import { LabelWithHelpIcon, Radio } from "@scm-manager/ui-components"; -import RoleSelector from "../components/RoleSelector"; -import type { - RepositoryRole, - PermissionCollection, - PermissionCreateEntry, - SelectValue -} from "@scm-manager/ui-types"; import * as validator from "../components/permissionValidation"; -import { findMatchingRoleName } from "../modules/permissions"; +import RoleSelector from "../components/RoleSelector"; import AdvancedPermissionsDialog from "./AdvancedPermissionsDialog"; type Props = { - t: string => string, availableRoles: RepositoryRole[], availableVerbs: string[], createPermission: (permission: PermissionCreateEntry) => void, loading: boolean, currentPermissions: PermissionCollection, groupAutoCompleteLink: string, - userAutoCompleteLink: string + userAutoCompleteLink: string, + + // Context props + t: string => string }; type State = { name: string, - verbs: string[], + role?: string, + verbs?: string[], groupPermission: boolean, valid: boolean, value?: SelectValue, @@ -45,7 +47,8 @@ class CreatePermissionForm extends React.Component { this.state = { name: "", - verbs: props.availableRoles[0].verbs, + role: props.availableRoles[0].name, + verbs: undefined, groupPermission: false, valid: true, value: undefined, @@ -90,6 +93,7 @@ class CreatePermissionForm extends React.Component { }); }); } + renderAutocompletionField = () => { const { t } = this.props; if (this.state.groupPermission) { @@ -134,13 +138,9 @@ class CreatePermissionForm extends React.Component { render() { const { t, availableRoles, availableVerbs, loading } = this.props; + const { role, verbs, showAdvancedDialog } = this.state; - const { verbs, showAdvancedDialog } = this.state; - - const availableRoleNames = availableRoles.map( - r => r.name - ); - const matchingRole = findMatchingRoleName(availableRoles, verbs); + const availableRoleNames = availableRoles.map(r => r.name); const advancedDialog = showAdvancedDialog ? ( { label={t("permission.role")} helpText={t("permission.help.roleHelpText")} handleRoleChange={this.handleRoleChange} - role={matchingRole} + role={role} />
@@ -230,6 +230,7 @@ class CreatePermissionForm extends React.Component { submitAdvancedPermissionsDialog = (newVerbs: string[]) => { this.setState({ showAdvancedDialog: false, + role: undefined, verbs: newVerbs }); }; @@ -237,6 +238,7 @@ class CreatePermissionForm extends React.Component { submit = e => { this.props.createPermission({ name: this.state.name, + role: this.state.role, verbs: this.state.verbs, groupPermission: this.state.groupPermission }); @@ -247,7 +249,8 @@ class CreatePermissionForm extends React.Component { removeState = () => { this.setState({ name: "", - verbs: this.props.availableRoles[0].verbs, + role: this.props.availableRoles[0].name, + verbs: undefined, valid: true, value: undefined }); @@ -259,14 +262,12 @@ class CreatePermissionForm extends React.Component { return; } this.setState({ - verbs: selectedRole.verbs + role: selectedRole.name }); }; findAvailableRole = (roleName: string) => { - return this.props.availableRoles.find( - role => role.name === roleName - ); + 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 02c43d254c..eff984ad5d 100644 --- a/scm-ui/src/repos/permissions/containers/Permissions.js +++ b/scm-ui/src/repos/permissions/containers/Permissions.js @@ -19,7 +19,9 @@ import { getDeletePermissionsFailure, getModifyPermissionsFailure, modifyPermissionReset, - deletePermissionReset, getAvailableRepositoryRoles, getAvailableRepositoryVerbs + deletePermissionReset, + getAvailableRepositoryRoles, + getAvailableRepositoryVerbs } from "../modules/permissions"; import { Loading, @@ -38,11 +40,14 @@ import CreatePermissionForm from "./CreatePermissionForm"; import type { History } from "history"; import { getPermissionsLink } from "../../modules/repos"; import { - getGroupAutoCompleteLink, getRepositoryRolesLink, getRepositoryVerbsLink, + getGroupAutoCompleteLink, + getRepositoryRolesLink, + getRepositoryVerbsLink, getUserAutoCompleteLink } from "../../../modules/indexResource"; type Props = { + availablePermissions: boolean, availableRepositoryRoles: RepositoryRole[], availableVerbs: string[], namespace: string, @@ -59,7 +64,10 @@ type Props = { userAutoCompleteLink: string, //dispatch functions - fetchAvailablePermissionsIfNeeded: () => void, + fetchAvailablePermissionsIfNeeded: ( + repositoryRolesLink: string, + repositoryVerbsLink: string + ) => void, fetchPermissions: (link: string, namespace: string, repoName: string) => void, createPermission: ( link: string, @@ -77,7 +85,6 @@ type Props = { history: History }; - class Permissions extends React.Component { componentDidMount() { const { @@ -251,8 +258,16 @@ const mapDispatchToProps = dispatch => { fetchPermissions: (link: string, namespace: string, repoName: string) => { dispatch(fetchPermissions(link, namespace, repoName)); }, - fetchAvailablePermissionsIfNeeded: (repositoryRolesLink: string, repositoryVerbsLink: string) => { - dispatch(fetchAvailablePermissionsIfNeeded(repositoryRolesLink, repositoryVerbsLink)); + 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 c90d6ab968..5fed0084a7 100644 --- a/scm-ui/src/repos/permissions/containers/SinglePermission.js +++ b/scm-ui/src/repos/permissions/containers/SinglePermission.js @@ -1,16 +1,12 @@ // @flow import React from "react"; -import type { - RepositoryRole, - Permission -} from "@scm-manager/ui-types"; +import type { RepositoryRole, Permission } from "@scm-manager/ui-types"; import { translate } from "react-i18next"; import { modifyPermission, isModifyPermissionPending, deletePermission, - isDeletePermissionPending, - findMatchingRoleName + isDeletePermissionPending } from "../modules/permissions"; import { connect } from "react-redux"; import type { History } from "history"; @@ -47,7 +43,6 @@ type Props = { }; type State = { - role: string, permission: Permission, showAdvancedDialog: boolean }; @@ -69,39 +64,34 @@ class SinglePermission extends React.Component { constructor(props: Props) { super(props); - const defaultPermission = props.availableRoles - ? props.availableRoles[0] + const defaultPermission = props.availableRepositoryRoles + ? props.availableRepositoryRoles[0] : {}; this.state = { permission: { name: "", + role: undefined, verbs: defaultPermission.verbs, groupPermission: false, _links: {} }, - role: defaultPermission.name, showAdvancedDialog: false }; } componentDidMount() { - const { availableRepositoryRoles, permission } = this.props; - - const matchingRole = findMatchingRoleName( - availableRepositoryRoles, - permission.verbs - ); + const { permission } = this.props; if (permission) { this.setState({ permission: { name: permission.name, + role: permission.role, verbs: permission.verbs, groupPermission: permission.groupPermission, _links: permission._links - }, - role: matchingRole + } }); } } @@ -115,7 +105,7 @@ class SinglePermission extends React.Component { }; render() { - const { role, permission, showAdvancedDialog } = this.state; + const { permission, showAdvancedDialog } = this.state; const { t, availableRepositoryRoles, @@ -125,18 +115,17 @@ class SinglePermission extends React.Component { repoName, classes } = this.props; - const availableRoleNames = !!availableRepositoryRoles && availableRepositoryRoles.map( - r => r.name - ); + const availableRoleNames = + !!availableRepositoryRoles && availableRepositoryRoles.map(r => r.name); const readOnly = !this.mayChangePermissions(); const roleSelector = readOnly ? ( - {role} + {permission.role ? permission.role : t("permission.custom")} ) : ( @@ -154,9 +143,15 @@ class SinglePermission extends React.Component { const iconType = permission && permission.groupPermission ? ( - + ) : ( - + ); return ( @@ -199,42 +194,41 @@ class SinglePermission extends React.Component { submitAdvancedPermissionsDialog = (newVerbs: string[]) => { const { permission } = this.state; - const newRole = findMatchingRoleName( - this.props.availableRoles, - newVerbs - ); this.setState( { showAdvancedDialog: false, - permission: { ...permission, verbs: newVerbs }, - role: newRole + permission: { ...permission, role: undefined, verbs: newVerbs } }, - () => this.modifyPermission(newVerbs) + () => this.modifyPermissionVerbs(newVerbs) ); }; handleRoleChange = (role: string) => { - const selectedRole = this.findAvailableRole(role); + const { permission } = this.state; this.setState( { - permission: { - ...this.state.permission, - verbs: selectedRole.verbs - }, - role: role + permission: { ...permission, role: role, verbs: undefined } }, - () => this.modifyPermission(selectedRole.verbs) + () => this.modifyPermissionRole(role) ); }; findAvailableRole = (roleName: string) => { const { availableRepositoryRoles } = this.props; - return availableRepositoryRoles.find( - role => role.name === roleName + return availableRepositoryRoles.find(role => role.name === roleName); + }; + + modifyPermissionRole = (role: string) => { + let permission = this.state.permission; + permission.role = role; + this.props.modifyPermission( + permission, + this.props.namespace, + this.props.repoName ); }; - modifyPermission = (verbs: string[]) => { + modifyPermissionVerbs = (verbs: string[]) => { let permission = this.state.permission; permission.verbs = verbs; this.props.modifyPermission( diff --git a/scm-ui/src/repos/permissions/modules/permissions.js b/scm-ui/src/repos/permissions/modules/permissions.js index 2aa9d139c5..abd25eb459 100644 --- a/scm-ui/src/repos/permissions/modules/permissions.js +++ b/scm-ui/src/repos/permissions/modules/permissions.js @@ -739,35 +739,3 @@ export function getModifyPermissionsFailure( } return null; } - -export function findMatchingRoleName( - availableRoles: RepositoryRole[], - verbs: string[] -) { - if (!verbs) { - return ""; - } - const matchingRole = - !!availableRoles && - availableRoles.find(role => { - return equalVerbs(role.verbs, verbs); - }); - - if (matchingRole) { - return matchingRole.name; - } else { - return ""; - } -} - -function equalVerbs(verbs1: string[], verbs2: string[]) { - if (!verbs1 || !verbs2) { - return false; - } - - if (verbs1.length !== verbs2.length) { - return false; - } - - return verbs1.every(verb => verbs2.includes(verb)); -}