mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-26 17:29:12 +01:00
added delete group function
This commit is contained in:
@@ -31,5 +31,14 @@
|
||||
},
|
||||
"group-form": {
|
||||
"submit": "Submit"
|
||||
},
|
||||
"delete-group-button": {
|
||||
"label": "Delete",
|
||||
"confirm-alert": {
|
||||
"title": "Delete Group",
|
||||
"message": "Do you really want to delete the group?",
|
||||
"submit": "Yes",
|
||||
"cancel": "No"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
scm-ui/src/groups/components/navLinks/DeleteGroupNavLink.js
Normal file
57
scm-ui/src/groups/components/navLinks/DeleteGroupNavLink.js
Normal file
@@ -0,0 +1,57 @@
|
||||
// @flow
|
||||
import React from "react";
|
||||
import { translate } from "react-i18next";
|
||||
import type { Group } from "../../types/Group";
|
||||
import { confirmAlert } from "../../../components/modals/ConfirmAlert";
|
||||
import { NavAction } from "../../../components/navigation";
|
||||
|
||||
type Props = {
|
||||
group: Group,
|
||||
confirmDialog?: boolean,
|
||||
t: string => string,
|
||||
deleteGroup: (group: Group) => void
|
||||
};
|
||||
|
||||
export class DeleteGroupNavLink extends React.Component<Props> {
|
||||
static defaultProps = {
|
||||
confirmDialog: true
|
||||
};
|
||||
|
||||
deleteGroup = () => {
|
||||
this.props.deleteGroup(this.props.group);
|
||||
};
|
||||
|
||||
confirmDelete = () => {
|
||||
const { t } = this.props;
|
||||
confirmAlert({
|
||||
title: t("delete-group-button.confirm-alert.title"),
|
||||
message: t("delete-group-button.confirm-alert.message"),
|
||||
buttons: [
|
||||
{
|
||||
label: t("delete-group-button.confirm-alert.submit"),
|
||||
onClick: () => this.deleteGroup()
|
||||
},
|
||||
{
|
||||
label: t("delete-group-button.confirm-alert.cancel"),
|
||||
onClick: () => null
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
isDeletable = () => {
|
||||
return this.props.group._links.delete;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { confirmDialog, t } = this.props;
|
||||
const action = confirmDialog ? this.confirmDelete : this.deleteGroup;
|
||||
|
||||
if (!this.isDeletable()) {
|
||||
return null;
|
||||
}
|
||||
return <NavAction label={t("delete-group-button.label")} action={action} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default translate("groups")(DeleteGroupNavLink);
|
||||
@@ -0,0 +1,79 @@
|
||||
import React from "react";
|
||||
import { mount, shallow } from "enzyme";
|
||||
import "../../../tests/enzyme";
|
||||
import "../../../tests/i18n";
|
||||
import DeleteGroupNavLink from "./DeleteGroupNavLink";
|
||||
|
||||
import { confirmAlert } from "../../../components/modals/ConfirmAlert";
|
||||
jest.mock("../../../components/modals/ConfirmAlert");
|
||||
|
||||
describe("DeleteGroupNavLink", () => {
|
||||
it("should render nothing, if the delete link is missing", () => {
|
||||
const group = {
|
||||
_links: {}
|
||||
};
|
||||
|
||||
const navLink = shallow(
|
||||
<DeleteGroupNavLink group={group} deleteGroup={() => {}} />
|
||||
);
|
||||
expect(navLink.text()).toBe("");
|
||||
});
|
||||
|
||||
it("should render the navLink", () => {
|
||||
const group = {
|
||||
_links: {
|
||||
delete: {
|
||||
href: "/groups"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const navLink = mount(
|
||||
<DeleteGroupNavLink group={group} deleteGroup={() => {}} />
|
||||
);
|
||||
expect(navLink.text()).not.toBe("");
|
||||
});
|
||||
|
||||
it("should open the confirm dialog on navLink click", () => {
|
||||
const group = {
|
||||
_links: {
|
||||
delete: {
|
||||
href: "/groups"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const navLink = mount(
|
||||
<DeleteGroupNavLink group={group} deleteGroup={() => {}} />
|
||||
);
|
||||
navLink.find("a").simulate("click");
|
||||
|
||||
expect(confirmAlert.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should call the delete group function with delete url", () => {
|
||||
const group = {
|
||||
_links: {
|
||||
delete: {
|
||||
href: "/groups"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let calledUrl = null;
|
||||
function capture(group) {
|
||||
calledUrl = group._links.delete.href;
|
||||
}
|
||||
|
||||
const navLink = mount(
|
||||
<DeleteGroupNavLink
|
||||
group={group}
|
||||
confirmDialog={false}
|
||||
deleteGroup={capture}
|
||||
/>
|
||||
);
|
||||
navLink.find("a").simulate("click");
|
||||
|
||||
expect(calledUrl).toBe("/groups");
|
||||
});
|
||||
});
|
||||
2
scm-ui/src/groups/components/navLinks/index.js
Normal file
2
scm-ui/src/groups/components/navLinks/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as DeleteGroupNavLink } from "./DeleteGroupNavLink";
|
||||
export { default as EditGroupNavLink } from "./EditGroupNavLink";
|
||||
@@ -4,20 +4,23 @@ import { connect } from "react-redux";
|
||||
import { Page } from "../../components/layout";
|
||||
import { Route } from "react-router";
|
||||
import { Details } from "./../components/table";
|
||||
import { DeleteGroupNavLink, EditGroupNavLink } from "./../components/navLinks";
|
||||
import type { Group } from "../types/Group";
|
||||
import type { History } from "history";
|
||||
import {
|
||||
deleteGroup,
|
||||
fetchGroup,
|
||||
getGroupByName,
|
||||
isFetchGroupPending,
|
||||
getFetchGroupFailure,
|
||||
getDeleteGroupFailure,
|
||||
isDeleteGroupPending,
|
||||
} from "../modules/groups";
|
||||
import Loading from "../../components/Loading";
|
||||
|
||||
import { Navigation, Section, NavLink } from "../../components/navigation";
|
||||
import ErrorPage from "../../components/ErrorPage";
|
||||
import { translate } from "react-i18next";
|
||||
import EditGroupNavLink from "../components/navLinks/EditGroupNavLink";
|
||||
|
||||
type Props = {
|
||||
name: string,
|
||||
@@ -26,6 +29,7 @@ type Props = {
|
||||
error: Error,
|
||||
|
||||
// dispatcher functions
|
||||
deleteGroup: (group: Group, callback?: () => void) => void,
|
||||
fetchGroup: string => void,
|
||||
|
||||
// context objects
|
||||
@@ -46,6 +50,14 @@ class SingleGroup extends React.Component<Props> {
|
||||
return url;
|
||||
};
|
||||
|
||||
deleteGroup = (group: Group) => {
|
||||
this.props.deleteGroup(group, this.groupDeleted);
|
||||
};
|
||||
|
||||
groupDeleted = () => {
|
||||
this.props.history.push("/groups");
|
||||
};
|
||||
|
||||
matchedUrl = () => {
|
||||
return this.stripEndingSlash(this.props.match.url);
|
||||
};
|
||||
@@ -84,6 +96,7 @@ class SingleGroup extends React.Component<Props> {
|
||||
/>
|
||||
</Section>
|
||||
<Section label={t("single-group.actions-label")}>
|
||||
<DeleteGroupNavLink group={group} deleteGroup={this.deleteGroup} />
|
||||
<EditGroupNavLink group={group} editUrl={`${url}/edit`}/>
|
||||
<NavLink to="/groups" label={t("single-group.back-label")} />
|
||||
</Section>
|
||||
@@ -99,9 +112,9 @@ const mapStateToProps = (state, ownProps) => {
|
||||
const name = ownProps.match.params.name;
|
||||
const group = getGroupByName(state, name);
|
||||
const loading =
|
||||
isFetchGroupPending(state, name);
|
||||
isFetchGroupPending(state, name) || isDeleteGroupPending(state, name);
|
||||
const error =
|
||||
getFetchGroupFailure(state, name);
|
||||
getFetchGroupFailure(state, name) || getDeleteGroupFailure(state, name);
|
||||
|
||||
return {
|
||||
name,
|
||||
@@ -116,6 +129,9 @@ const mapDispatchToProps = dispatch => {
|
||||
fetchGroup: (name: string) => {
|
||||
dispatch(fetchGroup(name));
|
||||
},
|
||||
deleteGroup: (group: Group, callback?: () => void) => {
|
||||
dispatch(deleteGroup(group, callback));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user