From cd8a9873a957da545a5bca6f8045891e33038e93 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Thu, 25 Jun 2020 09:16:19 +0200 Subject: [PATCH] - add global rename repositories permission - add api call on rename action --- .../repository/RepositoryRenamedEvent.java | 37 ++++++++++++++++ .../src/repos/containers/RenameRepository.tsx | 44 ++++++++++++++----- .../src/repos/containers/RepositoryRoot.tsx | 7 +++ scm-ui/ui-webapp/src/repos/modules/repos.ts | 2 +- .../api/v2/resources/RepositoryResource.java | 27 ++++++++---- .../resources/META-INF/scm/permissions.xml | 3 ++ .../main/resources/locales/de/plugins.json | 4 ++ .../main/resources/locales/en/plugins.json | 10 +++++ 8 files changed, 113 insertions(+), 21 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/RepositoryRenamedEvent.java diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryRenamedEvent.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryRenamedEvent.java new file mode 100644 index 0000000000..4c68b6b332 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryRenamedEvent.java @@ -0,0 +1,37 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository; + +import sonia.scm.HandlerEventType; +import sonia.scm.event.AbstractHandlerEvent; +import sonia.scm.event.Event; + +@Event +public class RepositoryRenamedEvent extends AbstractHandlerEvent { + + public RepositoryRenamedEvent(HandlerEventType eventType, Repository item, Repository oldItem) { + super(eventType, item, oldItem); + } +} diff --git a/scm-ui/ui-webapp/src/repos/containers/RenameRepository.tsx b/scm-ui/ui-webapp/src/repos/containers/RenameRepository.tsx index 16ff616798..5209d68f61 100644 --- a/scm-ui/ui-webapp/src/repos/containers/RenameRepository.tsx +++ b/scm-ui/ui-webapp/src/repos/containers/RenameRepository.tsx @@ -23,7 +23,8 @@ */ import React, { FC, useState } from "react"; -import { Repository } from "@scm-manager/ui-types"; +import { Repository, Link } from "@scm-manager/ui-types"; +import { CONTENT_TYPE } from "../modules/repos"; import { ErrorNotification, Level, @@ -35,6 +36,8 @@ import { ButtonGroup } from "@scm-manager/ui-components"; import { useTranslation } from "react-i18next"; +import { apiClient } from "@scm-manager/ui-components/src"; +import { useHistory } from "react-router-dom"; type Props = { repository: Repository; @@ -42,12 +45,13 @@ type Props = { }; const RenameRepository: FC = ({ repository, renameNamespace }) => { + let history = useHistory(); const [t] = useTranslation("repos"); const [error, setError] = useState(undefined); const [loading, setLoading] = useState(false); const [showModal, setShowModal] = useState(false); - const [repositoryName, setRepositoryName] = useState(repository.name); - const [repositoryNamespace, setRepositoryNamespace] = useState(repository.namespace); + const [name, setName] = useState(repository.name); + const [namespace, setNamespace] = useState(repository.namespace); if (error) { return ; @@ -58,24 +62,37 @@ const RenameRepository: FC = ({ repository, renameNamespace }) => { } const isValid = - validation.isNameValid(repositoryName) && - validation.isNameValid(repositoryNamespace) && - (repository.name !== repositoryName || repository.namespace !== repositoryNamespace); + validation.isNameValid(name) && + validation.isNameValid(namespace) && + (repository.name !== name || repository.namespace !== namespace); + + const rename = () => { + setLoading(true); + const url = renameNamespace + ? (repository?._links?.renameWithNamespace as Link).href + : (repository?._links?.rename as Link).href; + + apiClient + .post(url, { name, namespace }, CONTENT_TYPE) + .then(() => setLoading(false)) + .then(() => history.push(`/repo/${namespace}/${name}`)) + .catch(setError); + }; const modalBody = (
{renameNamespace && ( )}
@@ -90,8 +107,13 @@ const RenameRepository: FC = ({ repository, renameNamespace }) => { label={t("renameRepo.modal.button.rename")} disabled={!isValid} title={t("renameRepo.modal.button.rename")} + action={rename} + /> +