From 8fd034d599a38fdde3defadd61ee181abd8015f9 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Wed, 15 May 2019 13:13:48 +0200 Subject: [PATCH] refactor / new structure for repositoryRoles --- .../navLinks/EditRepositoryRoleNavLink.js | 28 ++++ .../EditRepositoryRoleNavLink.test.js | 27 ++++ .../navLinks/RepositoryRoleDetailNavLink.js | 28 ++++ .../RepositoryRoleDetailNavLink.test.js | 31 +++++ .../src/config/components/navLinks/index.js | 2 + .../components/table/PermissionRoleRow.js | 3 +- scm-ui/src/config/containers/Config.js | 13 +- ...ssionRoleForm.js => RepositoryRoleForm.js} | 31 ++--- ...lPermissionRoles.js => RepositoryRoles.js} | 4 +- .../config/containers/SingleRepositoryRole.js | 121 ++++++++++++++++++ 10 files changed, 260 insertions(+), 28 deletions(-) create mode 100644 scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.js create mode 100644 scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.test.js create mode 100644 scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.js create mode 100644 scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.test.js create mode 100644 scm-ui/src/config/components/navLinks/index.js rename scm-ui/src/config/containers/{GlobalPermissionRoleForm.js => RepositoryRoleForm.js} (84%) rename scm-ui/src/config/containers/{GlobalPermissionRoles.js => RepositoryRoles.js} (96%) create mode 100644 scm-ui/src/config/containers/SingleRepositoryRole.js diff --git a/scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.js b/scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.js new file mode 100644 index 0000000000..419ca330cc --- /dev/null +++ b/scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.js @@ -0,0 +1,28 @@ +//@flow +import React from "react"; +import type { User } from "@scm-manager/ui-types"; +import { NavLink } from "@scm-manager/ui-components"; +import { translate } from "react-i18next"; + +type Props = { + user: User, + editUrl: String, + t: string => string +}; + +class EditRepositoryRoleNavLink extends React.Component { + isEditable = () => { + return this.props.user._links.update; + }; + + render() { + const { t, editUrl } = this.props; + + if (!this.isEditable()) { + return null; + } + return ; + } +} + +export default translate("users")(EditRepositoryRoleNavLink); diff --git a/scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.test.js b/scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.test.js new file mode 100644 index 0000000000..7e86e9bcda --- /dev/null +++ b/scm-ui/src/config/components/navLinks/EditRepositoryRoleNavLink.test.js @@ -0,0 +1,27 @@ +import React from "react"; +import { shallow } from "enzyme"; +import "../../../tests/enzyme"; +import "../../../tests/i18n"; +import EditUserNavLink from "./EditRepositoryRoleNavLink"; + +it("should render nothing, if the edit link is missing", () => { + const user = { + _links: {} + }; + + const navLink = shallow(); + expect(navLink.text()).toBe(""); +}); + +it("should render the navLink", () => { + const user = { + _links: { + update: { + href: "/users" + } + } + }; + + const navLink = shallow(); + expect(navLink.text()).not.toBe(""); +}); diff --git a/scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.js b/scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.js new file mode 100644 index 0000000000..cc04aa6b50 --- /dev/null +++ b/scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.js @@ -0,0 +1,28 @@ +//@flow +import React from "react"; +import { translate } from "react-i18next"; +import type { User } from "@scm-manager/ui-types"; +import { NavLink } from "@scm-manager/ui-components"; + +type Props = { + t: string => string, + user: User, + permissionsUrl: String +}; + +class ChangePermissionNavLink extends React.Component { + render() { + const { t, permissionsUrl } = this.props; + + // if (!this.hasPermissionToSetPermission()) { + // return null; + // } + return ; + } + + // hasPermissionToSetPermission = () => { + // return this.props.user._links.permissions; + // }; +} + +export default translate("users")(ChangePermissionNavLink); diff --git a/scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.test.js b/scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.test.js new file mode 100644 index 0000000000..8cf5231387 --- /dev/null +++ b/scm-ui/src/config/components/navLinks/RepositoryRoleDetailNavLink.test.js @@ -0,0 +1,31 @@ +import React from "react"; +import { shallow } from "enzyme"; +import "../../../tests/enzyme"; +import "../../../tests/i18n"; +import SetPermissionsNavLink from "./RepositoryRoleDetailNavLink"; + +it("should render nothing, if the permissions link is missing", () => { + const user = { + _links: {} + }; + + const navLink = shallow( + + ); + expect(navLink.text()).toBe(""); +}); + +it("should render the navLink", () => { + const user = { + _links: { + permissions: { + href: "/permissions" + } + } + }; + + const navLink = shallow( + + ); + expect(navLink.text()).not.toBe(""); +}); diff --git a/scm-ui/src/config/components/navLinks/index.js b/scm-ui/src/config/components/navLinks/index.js new file mode 100644 index 0000000000..7fafde676d --- /dev/null +++ b/scm-ui/src/config/components/navLinks/index.js @@ -0,0 +1,2 @@ +export { default as EditRepositoryRoleNavLink } from "./EditRepositoryRoleNavLink"; +export { default as RepositoryRoleDetailNavLink } from "./RepositoryRoleDetailNavLink"; diff --git a/scm-ui/src/config/components/table/PermissionRoleRow.js b/scm-ui/src/config/components/table/PermissionRoleRow.js index f42627540c..73a2cbc05c 100644 --- a/scm-ui/src/config/components/table/PermissionRoleRow.js +++ b/scm-ui/src/config/components/table/PermissionRoleRow.js @@ -15,7 +15,8 @@ class PermissionRoleRow extends React.Component { render() { const { baseUrl, role } = this.props; - const to = `${baseUrl}/${encodeURIComponent(role.name)}/edit`; + const singleRoleUrl = baseUrl.substring(0, baseUrl.length - 1); + const to = `${singleRoleUrl}/${encodeURIComponent(role.name)}`; return ( {this.renderLink(to, role.name)} diff --git a/scm-ui/src/config/containers/Config.js b/scm-ui/src/config/containers/Config.js index ee973cf64b..38b5401926 100644 --- a/scm-ui/src/config/containers/Config.js +++ b/scm-ui/src/config/containers/Config.js @@ -10,8 +10,9 @@ import type { Links } from "@scm-manager/ui-types"; import { Page, Navigation, NavLink, Section } from "@scm-manager/ui-components"; import { getLinks } from "../../modules/indexResource"; import GlobalConfig from "./GlobalConfig"; -import GlobalPermissionRoles from "./GlobalPermissionRoles"; -import GlobalPermissionRoleForm from "./GlobalPermissionRoleForm"; +import RepositoryRoles from "./RepositoryRoles"; +import RepositoryRoleForm from "./RepositoryRoleForm" +import SingleRepositoryRole from "./SingleRepositoryRole"; type Props = { links: Links, @@ -57,13 +58,9 @@ class Config extends React.Component { ( - - )} + render={() => } /> - + string, // dispatch functions - fetchAvailableVerbs: (link: string) => void + fetchAvailableVerbs: (link: string) => void, + addRole: (link: string, role: Role) => void }; type State = { role: Role }; -class GlobalPermissionRoleForm extends React.Component { +class RepositoryRoleForm extends React.Component { constructor(props: Props) { super(props); @@ -46,17 +48,8 @@ class GlobalPermissionRoleForm extends React.Component { } componentDidMount() { - const { fetchAvailableVerbs, verbsLink, role } = this.props; + const { fetchAvailableVerbs, verbsLink} = this.props; fetchAvailableVerbs(verbsLink); - - if (role) { - this.setState({ - role: { - ...role, - role: { verbs: role.verbs } - } - }); - } } isFalsy(value) { @@ -100,8 +93,7 @@ class GlobalPermissionRoleForm extends React.Component { submit = (event: Event) => { event.preventDefault(); if (this.isValid()) { - // this.props.submitForm(this.state.role); - //TODO ADD createRole here + this.props.addRole(this.props.repositoryRolesLink, this.state.role) } }; @@ -155,12 +147,14 @@ const mapStateToProps = (state, ownProps) => { const error = getFetchVerbsFailure(state); const verbsLink = getRepositoryVerbsLink(state); const availableVerbs = getVerbsFromState(state); + const repositoryRolesLink = getRepositoryRolesLink(state); return { loading, error, verbsLink, - availableVerbs + availableVerbs, + repositoryRolesLink }; }; @@ -168,6 +162,9 @@ const mapDispatchToProps = dispatch => { return { fetchAvailableVerbs: (link: string) => { dispatch(fetchAvailableVerbs(link)); + }, + addRole: (link: string, role: Role) => { + createRole(link, role) } }; }; @@ -175,4 +172,4 @@ const mapDispatchToProps = dispatch => { export default connect( mapStateToProps, mapDispatchToProps -)(translate("roles")(GlobalPermissionRoleForm)); +)(translate("roles")(RepositoryRoleForm)); diff --git a/scm-ui/src/config/containers/GlobalPermissionRoles.js b/scm-ui/src/config/containers/RepositoryRoles.js similarity index 96% rename from scm-ui/src/config/containers/GlobalPermissionRoles.js rename to scm-ui/src/config/containers/RepositoryRoles.js index 2691bf3988..41cbd11bf5 100644 --- a/scm-ui/src/config/containers/GlobalPermissionRoles.js +++ b/scm-ui/src/config/containers/RepositoryRoles.js @@ -41,7 +41,7 @@ type Props = { fetchRolesByPage: (link: string, page: number) => void }; -class GlobalPermissionRoles extends React.Component { +class RepositoryRoles extends React.Component { componentDidMount() { const { fetchRolesByPage, rolesLink, page } = this.props; fetchRolesByPage(rolesLink, page); @@ -119,4 +119,4 @@ const mapDispatchToProps = dispatch => { export default withRouter(connect( mapStateToProps, mapDispatchToProps -)(translate("config")(GlobalPermissionRoles))); +)(translate("config")(RepositoryRoles))); diff --git a/scm-ui/src/config/containers/SingleRepositoryRole.js b/scm-ui/src/config/containers/SingleRepositoryRole.js new file mode 100644 index 0000000000..dcdba90b31 --- /dev/null +++ b/scm-ui/src/config/containers/SingleRepositoryRole.js @@ -0,0 +1,121 @@ +//@flow +import React from "react"; +import { connect } from "react-redux"; +import { + Page, + Loading, + ErrorPage +} from "@scm-manager/ui-components"; +import { Route } from "react-router"; +import type { History } from "history"; +import { EditRepositoryRoleNavLink, RepositoryRoleDetailNavLink } from "./../components/navLinks"; +import { translate } from "react-i18next"; +import type { Role } from "@scm-manager/ui-types"; +import {getRepositoryRolesLink} from "../../modules/indexResource"; +import {ExtensionPoint} from "@scm-manager/ui-extensions"; +import {fetchRoleByName, getFetchRoleFailure, getRoleByName, isFetchRolePending} from "../modules/roles"; + +type Props = { + name: string, + role: Role, + loading: boolean, + error: Error, + repositoryRolesLink: string, + + // dispatcher function + fetchRoleByName: (string, string) => void, + + // context objects + t: string => string, + match: any, + history: History +}; + +class SingleRepositoryRole extends React.Component { + componentDidMount() { + this.props.fetchRoleByName(this.props.repositoryRolesLink, this.props.name); + } + + stripEndingSlash = (url: string) => { + if (url.endsWith("/")) { + return url.substring(0, url.length - 2); + } + return url; + }; + + matchedUrl = () => { + return this.stripEndingSlash(this.props.match.url); + }; + + render() { + const { t, loading, error, role } = this.props; + + if (error) { + return ( + + ); + } + + if (!role || loading) { + return ; + } + + const url = this.matchedUrl(); + + const extensionProps = { + role, + url + }; + + return ( + +
+
+ } /> + } + /> + +
+
+
+ ); + } +} + +const mapStateToProps = (state, ownProps) => { + const name = ownProps.match.params.name; + const role = getRoleByName(state, name); + const loading = isFetchRolePending(state, name); + const error = getFetchRoleFailure(state, name); + const repositoryRolesLink = getRepositoryRolesLink(state); + return { + repositoryRolesLink, + name, + role, + loading, + error + }; +}; + +const mapDispatchToProps = dispatch => { + return { + fetchRoleByName: (link: string, name: string) => { + dispatch(fetchRoleByName(link, name)); + } + }; +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(translate("users")(SingleRepositoryRole));