diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json index 14fb1908d9..e425f54eb9 100644 --- a/scm-ui/ui-webapp/public/locales/de/repos.json +++ b/scm-ui/ui-webapp/public/locales/de/repos.json @@ -22,7 +22,10 @@ "typeHelpText": "Der Typ des Repository (Mercurial, Git oder Subversion).", "contactHelpText": "E-Mail Adresse der Person, die für das Repository verantwortlich ist.", "descriptionHelpText": "Eine kurze Beschreibung des Repository.", - "initializeRepository": "Erstellt einen ersten Branch und committet eine README.md." + "initializeRepository": "Erstellt einen ersten Branch und committet eine README.md.", + "importUrlHelpText": "Importiert das gesamte Repository inkl. aller Branches und Tags über die Remote URL.", + "usernameHelpText": "Benutzername könnte für den Import benötigt werden. Wird ignoriert, falls nicht gesetzt.", + "passwordHelpText": "Password könnte für den Import benötigt werden. Wird ignoriert, falls nicht gesetzt." }, "repositoryRoot": { "errorTitle": "Fehler", @@ -46,7 +49,13 @@ }, "create": { "title": "Repository hinzufügen", - "subtitle": "Erstellen eines neuen Repository" + "createSubtitle": "Neues Repository erstellen", + "importSubtitle": "Bestehendes Repository importieren", + "importUrl": "Remote repository url", + "username": "Benutzername", + "password": "Passwort", + "createButton": "Neues Repository erstellen", + "importButton": "Repository importieren" }, "branches": { "overview": { @@ -155,7 +164,8 @@ }, "repositoryForm": { "subtitle": "Repository bearbeiten", - "submit": "Speichern", + "submitCreate": "Speichern", + "submitImport": "Importieren", "initializeRepository": "Repository initiieren", "dangerZone": "Umbenennen und Löschen" }, diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index 8341137236..362a5e7241 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -22,7 +22,10 @@ "typeHelpText": "The type of the repository (e.g. Mercurial, Git or Subversion).", "contactHelpText": "Email address of the person who is responsible for this repository.", "descriptionHelpText": "A short description of the repository.", - "initializeRepository": "Creates an initial branch and commits a basic README.md." + "initializeRepository": "Creates an initial branch and commits a basic README.md.", + "importUrlHelpText": "Import the whole repository including all branches and tags via remote url", + "usernameHelpText": "Username may be required to import the remote repository. Will be ignored if not provided.", + "passwordHelpText": "Password may be required to import the remote repository. Will be ignored if not provided." }, "repositoryRoot": { "errorTitle": "Error", @@ -46,7 +49,13 @@ }, "create": { "title": "Add Repository", - "subtitle": "Create a new repository" + "createSubtitle": "Create a new repository", + "importSubtitle": "Import existing repository", + "importUrl": "Remote repository url", + "username": "Username", + "password": "Password", + "createButton": "Create new repository", + "importButton": "Import repository" }, "branches": { "overview": { @@ -155,7 +164,8 @@ }, "repositoryForm": { "subtitle": "Edit Repository", - "submit": "Save", + "submitCreate": "Save", + "submitImport": "Import", "initializeRepository": "Initialize repository", "dangerZone": "Rename and delete" }, diff --git a/scm-ui/ui-webapp/src/containers/Main.tsx b/scm-ui/ui-webapp/src/containers/Main.tsx index e0af6ee867..73b5c9370e 100644 --- a/scm-ui/ui-webapp/src/containers/Main.tsx +++ b/scm-ui/ui-webapp/src/containers/Main.tsx @@ -78,6 +78,7 @@ class Main extends React.Component { + diff --git a/scm-ui/ui-webapp/src/repos/components/form/RepositoryForm.tsx b/scm-ui/ui-webapp/src/repos/components/form/RepositoryForm.tsx index a841715104..1166049614 100644 --- a/scm-ui/ui-webapp/src/repos/components/form/RepositoryForm.tsx +++ b/scm-ui/ui-webapp/src/repos/components/form/RepositoryForm.tsx @@ -21,14 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import React from "react"; +import React, { FC, useEffect, useState } from "react"; import styled from "styled-components"; -import { WithTranslation, withTranslation } from "react-i18next"; +import { useTranslation } from "react-i18next"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import { Repository, RepositoryCreation, RepositoryType } from "@scm-manager/ui-types"; -import { Checkbox, InputField, Level, Select, SubmitButton, Subtitle, Textarea } from "@scm-manager/ui-components"; +import { Repository, RepositoryType } from "@scm-manager/ui-types"; +import { Checkbox, InputField, Level, Select, SubmitButton, Textarea } from "@scm-manager/ui-components"; import * as validator from "./repositoryValidation"; import { CUSTOM_NAMESPACE_STRATEGY } from "../../modules/repos"; +import { useLocation } from "react-router-dom"; +import RepositoryFormSwitcher from "./RepositoryFormSwitcher"; const CheckboxWrapper = styled.div` margin-top: 2em; @@ -44,8 +46,18 @@ const SpaceBetween = styled.div` justify-content: space-between; `; -type Props = WithTranslation & { - submitForm: (repo: RepositoryCreation, shouldInit: boolean) => void; +const Column = styled.div` + padding: 0 0.75rem; +`; + +const Columns = styled.div` + padding: 0.75rem 0 0; +`; + +type Props = { + createRepository?: (repo: RepositoryCreation, shouldInit: boolean) => void; + modifyRepository?: (repo: RepositoryCreation) => void; + importRepository?: (repo: RepositoryCreation) => void; repository?: Repository; repositoryTypes?: RepositoryType[]; namespaceStrategy?: string; @@ -53,141 +65,117 @@ type Props = WithTranslation & { indexResources: any; }; -type State = { - repository: RepositoryCreation; - initRepository: boolean; - namespaceValidationError: boolean; - nameValidationError: boolean; - contactValidationError: boolean; +type RepositoryCreation = Repository & { + contextEntries: object; }; -class RepositoryForm extends React.Component { - constructor(props: Props) { - super(props); +const RepositoryForm: FC = ({ + createRepository, + modifyRepository, + importRepository, + repository, + repositoryTypes, + namespaceStrategy, + loading, + indexResources +}) => { + const [repo, setRepo] = useState({ + name: "", + namespace: "", + type: "", + contact: "", + description: "", + contextEntries: {}, + _links: {} + }); + const [initRepository, setInitRepository] = useState(false); + const [namespaceValidationError, setNamespaceValidationError] = useState(false); + const [nameValidationError, setNameValidationError] = useState(false); + const [contactValidationError, setContactValidationError] = useState(false); + const [importUrl, setImportUrl] = useState(""); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); - this.state = { - repository: { - name: "", - namespace: "", - type: "", - contact: "", - description: "", - contextEntries: {}, - _links: {} - }, - initRepository: false, - namespaceValidationError: false, - nameValidationError: false, - contactValidationError: false - }; - } + const location = useLocation(); + const [t] = useTranslation("repos"); - componentDidMount() { - const { repository } = this.props; + useEffect(() => { if (repository) { - this.setState({ - repository: { - ...repository, - contextEntries: {} - } - }); + setRepo({ ...repository, contextEntries: {} }); } - } + }, [repository]); - isFalsy(value: string) { - return !value; - } - - isValid = () => { - const { namespaceStrategy } = this.props; - const { repository } = this.state; + const isValid = () => { return !( - this.state.namespaceValidationError || - this.state.nameValidationError || - this.state.contactValidationError || - this.isFalsy(repository.name) || - (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY && this.isFalsy(repository.namespace)) + namespaceValidationError || + nameValidationError || + contactValidationError || + !repo.name || + (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY && !repo.namespace) || + (isImportPage() && !importUrl) ); }; - submit = (event: React.FormEvent) => { + const submit = (event: React.FormEvent) => { event.preventDefault(); - if (this.isValid()) { - this.props.submitForm(this.state.repository, this.state.initRepository); + const submitForm = evaluateSubmit(); + if (isValid() && submitForm) { + submitForm(repo, initRepository); } }; - isCreateMode = () => { - return !this.props.repository; + const evaluateSubmit = () => { + if (isImportPage()) { + return importRepository; + } else if (isCreatePage()) { + return createRepository; + } else { + return modifyRepository; + } }; - isModifiable = () => { - return !!this.props.repository && !!this.props.repository._links.update; + const isEditMode = () => { + return !!repository; }; - toggleInitCheckbox = () => { - this.setState({ - initRepository: !this.state.initRepository - }); + const isModifiable = () => { + return !!repository && !!repository._links.update; }; - setCreationContextEntry = (key: string, value: any) => { - this.setState({ - repository: { - ...this.state.repository, - contextEntries: { - ...this.state.repository.contextEntries, - [key]: value - } + const toggleInitCheckbox = () => { + setInitRepository(!initRepository); + }; + + const setCreationContextEntry = (key: string, value: any) => { + setRepo({ + ...repo, + contextEntries: { + ...repo.contextEntries, + [key]: value } }); }; - render() { - const { loading, t } = this.props; - const repository = this.state.repository; - - const disabled = !this.isModifiable() && !this.isCreateMode(); - - const submitButton = disabled ? null : ( - } /> - ); - - let subtitle = null; - if (this.props.repository) { - // edit existing repo - subtitle = ; + const resolveLocation = () => { + const currentUrl = location.pathname; + if (currentUrl.includes("/repos/create")) { + return "create"; } + if (currentUrl.includes("/repos/import")) { + return "import"; + } + return ""; + }; - return ( - <> - {subtitle} -
- {this.renderCreateOnlyFields()} - + const isImportPage = () => { + return resolveLocation() === "import"; + }; -