add frontend for deleting tags

This commit is contained in:
Konstantin Schaper
2020-11-25 15:51:44 +01:00
parent 84ea159741
commit e3170543cb
7 changed files with 104 additions and 16 deletions

View File

@@ -24,14 +24,15 @@
import React, { FC } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { Tag } from "@scm-manager/ui-types";
import { Link as RouterLink } from "react-router-dom";
import { Tag, Link } from "@scm-manager/ui-types";
import styled from "styled-components";
import { DateFromNow } from "@scm-manager/ui-components";
import { DateFromNow, Icon } from "@scm-manager/ui-components";
type Props = {
tag: Tag;
baseUrl: string;
onDelete: (tag: Tag) => void;
};
const Created = styled.span`
@@ -39,20 +40,32 @@ const Created = styled.span`
font-size: 0.8rem;
`;
const TagRow: FC<Props> = ({ tag, baseUrl }) => {
const TagRow: FC<Props> = ({ tag, baseUrl, onDelete }) => {
const [t] = useTranslation("repos");
let deleteButton;
if ((tag?._links?.delete as Link)?.href) {
deleteButton = (
<a className="level-item" onClick={() => onDelete(tag)}>
<span className="icon is-small">
<Icon name="trash" className="fas" title={t("tag.delete.button")} />
</span>
</a>
);
}
const to = `${baseUrl}/${encodeURIComponent(tag.name)}/info`;
return (
<tr>
<td>
<Link to={to} title={tag.name}>
<RouterLink to={to} title={tag.name}>
{tag.name}
<Created className="has-text-grey is-ellipsis-overflow">
{t("tags.overview.created")} <DateFromNow date={tag.date} />
</Created>
</Link>
</RouterLink>
</td>
<td className="is-darker">{deleteButton}</td>
</tr>
);
};

View File

@@ -22,30 +22,74 @@
* SOFTWARE.
*/
import React, { FC } from "react";
import { Tag } from "@scm-manager/ui-types";
import React, {FC, useState} from "react";
import {Link, Tag} from "@scm-manager/ui-types";
import { useTranslation } from "react-i18next";
import TagRow from "./TagRow";
import {apiClient, ConfirmAlert, ErrorNotification} from "@scm-manager/ui-components";
type Props = {
baseUrl: string;
tags: Tag[];
fetchTags: () => void;
};
const TagTable: FC<Props> = ({ baseUrl, tags }) => {
const TagTable: FC<Props> = ({ baseUrl, tags, fetchTags }) => {
const [t] = useTranslation("repos");
const [showConfirmAlert, setShowConfirmAlert] = useState(false);
const [error, setError] = useState<Error | undefined>();
const [tagToBeDeleted, setTagToBeDeleted] = useState<Tag | undefined>();
const onDelete = (tag: Tag) => {
setTagToBeDeleted(tag);
setShowConfirmAlert(true);
};
const abortDelete = () => {
setTagToBeDeleted(undefined);
setShowConfirmAlert(false);
};
const deleteTag = () => {
apiClient
.delete((tagToBeDeleted?._links.delete as Link).href)
.then(() => fetchTags())
.catch(setError);
};
const renderRow = () => {
let rowContent = null;
if (tags) {
rowContent = tags.map((tag, index) => {
return <TagRow key={index} baseUrl={baseUrl} tag={tag} />;
return <TagRow key={index} baseUrl={baseUrl} tag={tag} onDelete={onDelete} />;
});
}
return rowContent;
};
const confirmAlert = (
<ConfirmAlert
title={t("tag.delete.confirmAlert.title")}
message={t("tag.delete.confirmAlert.message", { tag: tagToBeDeleted?.name })}
buttons={[
{
className: "is-outlined",
label: t("tag.delete.confirmAlert.submit"),
onClick: () => deleteTag()
},
{
label: t("tag.delete.confirmAlert.cancel"),
onClick: () => abortDelete()
}
]}
close={() => abortDelete()}
/>
);
return (
<>
{showConfirmAlert && confirmAlert}
{error && <ErrorNotification error={error} />}
<table className="card-table table is-hoverable is-fullwidth is-word-break">
<thead>
<tr>
@@ -54,7 +98,7 @@ const TagTable: FC<Props> = ({ baseUrl, tags }) => {
</thead>
<tbody>{renderRow()}</tbody>
</table>
);
</>);
};
export default TagTable;

View File

@@ -40,7 +40,7 @@ const TagsOverview: FC<Props> = ({ repository, baseUrl }) => {
const [error, setError] = useState<Error | undefined>(undefined);
const [tags, setTags] = useState<Tag[]>([]);
useEffect(() => {
const fetchTags = () => {
const link = (repository._links?.tags as Link)?.href;
if (link) {
setLoading(true);
@@ -51,12 +51,16 @@ const TagsOverview: FC<Props> = ({ repository, baseUrl }) => {
.then(() => setLoading(false))
.catch(setError);
}
};
useEffect(() => {
fetchTags();
}, [repository]);
const renderTagsTable = () => {
if (!loading && tags?.length > 0) {
orderTags(tags);
return <TagTable baseUrl={baseUrl} tags={tags} />;
return <TagTable baseUrl={baseUrl} tags={tags} fetchTags={() => fetchTags()} />;
}
return <Notification type="info">{t("tags.overview.noTags")}</Notification>;
};