From 5a115d634cd6588a5cbdb050d91d1ccec9e4df2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maren=20S=C3=BCwer?= Date: Thu, 30 Aug 2018 09:49:36 +0200 Subject: [PATCH] user can be deleted now --- scm-ui/public/locales/en/permissions.json | 9 ++ .../buttons/DeletePermissionButton.js | 59 +++++++++++++ .../buttons/DeletePermissionButton.test.js | 88 +++++++++++++++++++ .../containers/SinglePermission.js | 43 +++++++-- 4 files changed, 191 insertions(+), 8 deletions(-) create mode 100644 scm-ui/src/permissions/components/buttons/DeletePermissionButton.js create mode 100644 scm-ui/src/permissions/components/buttons/DeletePermissionButton.test.js diff --git a/scm-ui/public/locales/en/permissions.json b/scm-ui/public/locales/en/permissions.json index 686a01156d..70185f95aa 100644 --- a/scm-ui/public/locales/en/permissions.json +++ b/scm-ui/public/locales/en/permissions.json @@ -11,5 +11,14 @@ "edit-permission": { "delete-button": "Delete", "save-button": "Save Changes" + }, + "delete-permission-button": { + "label": "Delete", + "confirm-alert": { + "title": "Delete permission", + "message": "Do you really want to delete the permission?", + "submit": "Yes", + "cancel": "No" + } } } diff --git a/scm-ui/src/permissions/components/buttons/DeletePermissionButton.js b/scm-ui/src/permissions/components/buttons/DeletePermissionButton.js new file mode 100644 index 0000000000..15954ea069 --- /dev/null +++ b/scm-ui/src/permissions/components/buttons/DeletePermissionButton.js @@ -0,0 +1,59 @@ +// @flow +import React from "react"; +import { translate } from "react-i18next"; +import type { Permission } from "../../types/Permissions"; +import { confirmAlert } from "../../../components/modals/ConfirmAlert"; +import {DeleteButton} from "../../../components/buttons/index"; + +type Props = { + permission: Permission, + namespace: string, + name: string, + confirmDialog?: boolean, + t: string => string, + deletePermission: (permission: Permission, namespace: string, name: string) => void +}; + +class DeletePermissionButton extends React.Component { + static defaultProps = { + confirmDialog: true + }; + + deletePermission = () => { + this.props.deletePermission(this.props.permission, this.props.namespace, this.props.name); + }; + + confirmDelete = () => { + const { t } = this.props; + confirmAlert({ + title: t("delete-permission-button.confirm-alert.title"), + message: t("delete-permission-button.confirm-alert.message"), + buttons: [ + { + label: t("delete-permission-button.confirm-alert.submit"), + onClick: () => this.deletePermission() + }, + { + label: t("delete-permission-button.confirm-alert.cancel"), + onClick: () => null + } + ] + }); + }; + + isDeletable = () => { + return this.props.permission._links.delete; + }; + + render() { + const { confirmDialog, t } = this.props; + const action = confirmDialog ? this.confirmDelete : this.deletePermission; + + if (!this.isDeletable()) { + return null; + } + return ; + } +} + +export default translate("permissions")(DeletePermissionButton); diff --git a/scm-ui/src/permissions/components/buttons/DeletePermissionButton.test.js b/scm-ui/src/permissions/components/buttons/DeletePermissionButton.test.js new file mode 100644 index 0000000000..d86f15604d --- /dev/null +++ b/scm-ui/src/permissions/components/buttons/DeletePermissionButton.test.js @@ -0,0 +1,88 @@ +import React from "react"; +import { mount, shallow } from "enzyme"; +import "../../../tests/enzyme"; +import "../../../tests/i18n"; +import DeletePermissionButton from "./DeletePermissionButton"; + +import { confirmAlert } from "../../../components/modals/ConfirmAlert"; +jest.mock("../../../components/modals/ConfirmAlert"); + +describe("DeletePermissionButton", () => { + it("should render nothing, if the delete link is missing", () => { + const permission = { + _links: {} + }; + + const navLink = shallow( + {}} + /> + ); + expect(navLink.text()).toBe(""); + }); + + it("should render the navLink", () => { + const permission = { + _links: { + delete: { + href: "/permission" + } + } + }; + + const navLink = mount( + {}} + /> + ); + expect(navLink.text()).not.toBe(""); + }); + + it("should open the confirm dialog on button click", () => { + const permission = { + _links: { + delete: { + href: "/permission" + } + } + }; + + const button = mount( + {}} + /> + ); + button.find("button").simulate("click"); + + expect(confirmAlert.mock.calls.length).toBe(1); + }); + + it("should call the delete permission function with delete url", () => { + const permission = { + _links: { + delete: { + href: "/permission" + } + } + }; + + let calledUrl = null; + function capture(permission) { + calledUrl = permission._links.delete.href; + } + + const button = mount( + + ); + button.find("button").simulate("click"); + + expect(calledUrl).toBe("/permission"); + }); +}); diff --git a/scm-ui/src/permissions/containers/SinglePermission.js b/scm-ui/src/permissions/containers/SinglePermission.js index f125d4025b..6bcf060b72 100644 --- a/scm-ui/src/permissions/containers/SinglePermission.js +++ b/scm-ui/src/permissions/containers/SinglePermission.js @@ -2,19 +2,20 @@ import React from "react"; import type { Permission } from "../types/Permissions"; import { Checkbox } from "../../components/forms/index"; -import { DeleteButton } from "../../components/buttons/index"; import { translate } from "react-i18next"; import { Select } from "../../components/forms/index"; import { modifyPermission, isModifyPermissionPending, getModifyPermissionFailure, - modifyPermissionReset + modifyPermissionReset, + deletePermission } from "../modules/permissions"; import connect from "react-redux/es/connect/connect"; import { withRouter } from "react-router-dom"; import type { History } from "history"; import ErrorNotification from "../../components/ErrorNotification"; +import DeletePermissionButton from "../components/buttons/DeletePermissionButton"; type Props = { submitForm: Permission => void, @@ -27,7 +28,8 @@ type Props = { history: History, loading: boolean, error: Error, - permissionReset: (string, string, string) => void + permissionReset: (string, string, string) => void, + deletePermission: (Permission, string, string, (void) => void) => void }; type State = { @@ -67,13 +69,25 @@ class SinglePermission extends React.Component { } } + permissionDeleted = () => { + this.props.history.push( + "/repo/" + this.props.namespace + "/" + this.props.name + "/permissions" + ); + }; + + deletePermission = () => { + this.props.deletePermission( + this.props.permission, + this.props.namespace, + this.props.name, + this.permissionDeleted + ); + }; + render() { const { permission } = this.state; - const { t, loading, error } = this.props; + const { t, loading, error, namespace, name } = this.props; const types = ["READ", "OWNER", "WRITE"]; - const deleteButton = this.props.permission._links.delete ? ( - - ) : null; const typeSelector = this.props.permission._links.update ? ( @@ -100,7 +114,12 @@ class SinglePermission extends React.Component { {typeSelector} - {deleteButton} + {errorNotification} @@ -170,6 +189,14 @@ const mapDispatchToProps = dispatch => { permissionname: string ) => { dispatch(modifyPermissionReset(namespace, name, permissionname)); + }, + deletePermission: ( + permission: Permission, + namespace: string, + name: string, + callback: () => void + ) => { + dispatch(deletePermission(permission, namespace, name, callback)); } }; };