mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-08 06:25:45 +01:00
Archive repository (#1477)
This adds a flag "archived" to repositories. Repositories marked with this can no longer be modified in any way. To do this, we switch to a new version of Shiro Static Permissions (sdorra/shiro-static-permissions#4) and specify a permission guard to check for every permission request, whether the repository in question is archived or not. Further we implement checks in stores and other activies so that no writing request may be executed by mistake. Co-authored-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
This commit is contained in:
@@ -50505,6 +50505,162 @@ exports[`Storyshots Popover Link 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Storyshots RepositoryEntry Archived 1`] = `
|
||||
<div
|
||||
className="RepositoryEntrystories__Spacing-toppdg-0 iIzVNZ box box-link-shadow"
|
||||
>
|
||||
<a
|
||||
className="overlay-column"
|
||||
href="/repo/hitchhiker/heartOfGold"
|
||||
onClick={[Function]}
|
||||
/>
|
||||
<article
|
||||
className="CardColumn__NoEventWrapper-sc-1w6lsih-0 eUWboI media"
|
||||
>
|
||||
<figure
|
||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||
>
|
||||
<p
|
||||
className="image is-64x64"
|
||||
>
|
||||
<img
|
||||
alt="Logo"
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</p>
|
||||
</figure>
|
||||
<div
|
||||
className="CardColumn__FlexFullHeight-sc-1w6lsih-2 hWRPir media-content text-box is-flex"
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
>
|
||||
<div
|
||||
className="CardColumn__ContentLeft-sc-1w6lsih-4 iRVRBC content"
|
||||
>
|
||||
<p
|
||||
className="shorten-text is-marginless"
|
||||
>
|
||||
|
||||
<strong>
|
||||
heartOfGold
|
||||
</strong>
|
||||
|
||||
|
||||
<i
|
||||
className="fas fa-archive has-text-grey-light"
|
||||
/>
|
||||
|
||||
<span
|
||||
className="RepositoryEntry__Smaller-sc-6jys82-0 lpzPr"
|
||||
>
|
||||
repository.archived
|
||||
</span>
|
||||
</p>
|
||||
<p
|
||||
className="shorten-text"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="CardColumn__FooterWrapper-sc-1w6lsih-3 hzknmV level is-flex"
|
||||
>
|
||||
<div
|
||||
className="CardColumn__RightMarginDiv-sc-1w6lsih-6 bnJfDV level-left is-hidden-mobile"
|
||||
>
|
||||
<a
|
||||
className="RepositoryEntryLink__PointerEventsLink-sc-1hpqj0w-0 iZuqoP level-item"
|
||||
href="/repo/hitchhiker/heartOfGold/branches/"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="tooltip has-tooltip-top"
|
||||
data-tooltip="repositoryRoot.tooltip.branches"
|
||||
>
|
||||
<i
|
||||
className="fas fa-code-branch has-text-inherit fa-lg"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
className="RepositoryEntryLink__PointerEventsLink-sc-1hpqj0w-0 iZuqoP level-item"
|
||||
href="/repo/hitchhiker/heartOfGold/tags/"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="tooltip has-tooltip-top"
|
||||
data-tooltip="repositoryRoot.tooltip.tags"
|
||||
>
|
||||
<i
|
||||
className="fas fa-tags has-text-inherit fa-lg"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
className="RepositoryEntryLink__PointerEventsLink-sc-1hpqj0w-0 iZuqoP level-item"
|
||||
href="/repo/hitchhiker/heartOfGold/code/changesets/"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="tooltip has-tooltip-top"
|
||||
data-tooltip="repositoryRoot.tooltip.commits"
|
||||
>
|
||||
<i
|
||||
className="fas fa-exchange-alt has-text-inherit fa-lg"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
className="RepositoryEntryLink__PointerEventsLink-sc-1hpqj0w-0 iZuqoP level-item"
|
||||
href="/repo/hitchhiker/heartOfGold/code/sources/"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="tooltip has-tooltip-top"
|
||||
data-tooltip="repositoryRoot.tooltip.sources"
|
||||
>
|
||||
<i
|
||||
className="fas fa-code has-text-inherit fa-lg"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
className="RepositoryEntryLink__PointerEventsLink-sc-1hpqj0w-0 iZuqoP level-item"
|
||||
href="/repo/hitchhiker/heartOfGold/settings/general"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="tooltip has-tooltip-top"
|
||||
data-tooltip="repositoryRoot.tooltip.settings"
|
||||
>
|
||||
<i
|
||||
className="fas fa-cog has-text-inherit fa-lg"
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="CardColumn__InheritFlexShrinkDiv-sc-1w6lsih-7 kdhCxo level-right is-block is-mobile is-marginless shorten-text"
|
||||
>
|
||||
<small
|
||||
className="level-item"
|
||||
>
|
||||
<time
|
||||
className="DateElement-sc-1schp8c-0 IMGpa"
|
||||
title="2020-03-23 09:26:01"
|
||||
>
|
||||
3 days ago
|
||||
</time>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Storyshots RepositoryEntry Avatar EP 1`] = `
|
||||
<div
|
||||
className="RepositoryEntrystories__Spacing-toppdg-0 iIzVNZ box box-link-shadow"
|
||||
@@ -50545,6 +50701,7 @@ exports[`Storyshots RepositoryEntry Avatar EP 1`] = `
|
||||
<strong>
|
||||
heartOfGold
|
||||
</strong>
|
||||
|
||||
</p>
|
||||
<p
|
||||
className="shorten-text"
|
||||
@@ -50693,6 +50850,7 @@ exports[`Storyshots RepositoryEntry Before Title EP 1`] = `
|
||||
<strong>
|
||||
heartOfGold
|
||||
</strong>
|
||||
|
||||
</p>
|
||||
<p
|
||||
className="shorten-text"
|
||||
@@ -50838,6 +50996,7 @@ exports[`Storyshots RepositoryEntry Default 1`] = `
|
||||
<strong>
|
||||
heartOfGold
|
||||
</strong>
|
||||
|
||||
</p>
|
||||
<p
|
||||
className="shorten-text"
|
||||
@@ -50983,6 +51142,7 @@ exports[`Storyshots RepositoryEntry Quick Link EP 1`] = `
|
||||
<strong>
|
||||
heartOfGold
|
||||
</strong>
|
||||
|
||||
</p>
|
||||
<p
|
||||
className="shorten-text"
|
||||
|
||||
@@ -74,9 +74,11 @@ const QuickLink = (
|
||||
</a>
|
||||
);
|
||||
|
||||
const archivedRepository = { ...repository, archived: true };
|
||||
|
||||
storiesOf("RepositoryEntry", module)
|
||||
.addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||
.addDecorator(storyFn => <Container>{storyFn()}</Container>)
|
||||
.addDecorator((story) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||
.addDecorator((storyFn) => <Container>{storyFn()}</Container>)
|
||||
.add("Default", () => {
|
||||
return <RepositoryEntry repository={repository} baseDate={baseDate} />;
|
||||
})
|
||||
@@ -94,4 +96,9 @@ storiesOf("RepositoryEntry", module)
|
||||
const binder = new Binder("title");
|
||||
bindQuickLink(binder, QuickLink);
|
||||
return withBinder(binder, repository);
|
||||
})
|
||||
.add("Archived", () => {
|
||||
const binder = new Binder("title");
|
||||
bindAvatar(binder, Git);
|
||||
return withBinder(binder, archivedRepository);
|
||||
});
|
||||
|
||||
@@ -28,6 +28,7 @@ import RepositoryEntryLink from "./RepositoryEntryLink";
|
||||
import RepositoryAvatar from "./RepositoryAvatar";
|
||||
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
||||
import { withTranslation, WithTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
|
||||
type DateProp = Date | string;
|
||||
|
||||
@@ -38,6 +39,18 @@ type Props = WithTranslation & {
|
||||
baseDate?: DateProp;
|
||||
};
|
||||
|
||||
const ArchiveTag = styled.span`
|
||||
margin-left: 0.2rem;
|
||||
background-color: #9a9a9a;
|
||||
padding: 0.25rem;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
overflow: visible;
|
||||
pointer-events: all;
|
||||
font-weight: bold;
|
||||
font-size: 0.7rem;
|
||||
`;
|
||||
|
||||
class RepositoryEntry extends React.Component<Props> {
|
||||
createLink = (repository: Repository) => {
|
||||
return `/repo/${repository.namespace}/${repository.name}`;
|
||||
@@ -131,10 +144,14 @@ class RepositoryEntry extends React.Component<Props> {
|
||||
};
|
||||
|
||||
createTitle = () => {
|
||||
const { repository } = this.props;
|
||||
const { repository, t } = this.props;
|
||||
const archivedFlag = repository.archived && (
|
||||
<ArchiveTag title={t("archive.tooltip")}>{t("repository.archived")}</ArchiveTag>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ExtensionPoint name="repository.card.beforeTitle" props={{ repository }} /> <strong>{repository.name}</strong>
|
||||
<ExtensionPoint name="repository.card.beforeTitle" props={{ repository }} />
|
||||
<strong>{repository.name}</strong> {archivedFlag}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user