From d1dc2e04e2a864211e531ac58adbe4696845f75f Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Wed, 25 Nov 2020 15:08:30 +0100 Subject: [PATCH] refactor UI --- .../repos/components/form/RepositoryForm.tsx | 41 ++---- .../form/RepositoryFormSwitcher.tsx | 36 ++--- .../src/repos/containers/AddRepository.tsx | 125 ++++++++++++------ .../src/repos/containers/EditRepo.tsx | 29 ++-- scm-ui/ui-webapp/src/repos/modules/repos.ts | 6 + 5 files changed, 132 insertions(+), 105 deletions(-) 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 55375768db..428e6e4c50 100644 --- a/scm-ui/ui-webapp/src/repos/components/form/RepositoryForm.tsx +++ b/scm-ui/ui-webapp/src/repos/components/form/RepositoryForm.tsx @@ -25,12 +25,10 @@ import React, { FC, useEffect, useState } from "react"; import styled from "styled-components"; import { useTranslation } from "react-i18next"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import { Repository, RepositoryType, RepositoryImport } from "@scm-manager/ui-types"; +import { Repository, RepositoryImport, 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; @@ -63,6 +61,7 @@ type Props = { namespaceStrategy?: string; loading?: boolean; indexResources?: any; + creationMode?: "CREATE" | "IMPORT"; }; type RepositoryCreation = Repository & { @@ -77,7 +76,8 @@ const RepositoryForm: FC = ({ repositoryTypes, namespaceStrategy, loading, - indexResources + indexResources, + creationMode }) => { const [repo, setRepo] = useState({ name: "", @@ -96,7 +96,6 @@ const RepositoryForm: FC = ({ const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); - const location = useLocation(); const [t] = useTranslation("repos"); useEffect(() => { @@ -105,6 +104,9 @@ const RepositoryForm: FC = ({ } }, [repository]); + const isImportMode = () => creationMode === "IMPORT"; + const isCreateMode = () => creationMode === "CREATE"; + const isValid = () => { return !( namespaceValidationError || @@ -112,16 +114,16 @@ const RepositoryForm: FC = ({ contactValidationError || !repo.name || (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY && !repo.namespace) || - (isImportPage() && !importUrl) + (isImportMode() && !importUrl) ); }; const submit = (event: React.FormEvent) => { event.preventDefault(); if (isValid()) { - if (importRepository && isImportPage()) { + if (importRepository && isImportMode()) { importRepository({ ...repo, url: importUrl, username, password }); - } else if (createRepository && isCreatePage()) { + } else if (createRepository && isCreateMode()) { createRepository(repo, initRepository); } else if (modifyRepository) { modifyRepository(repo); @@ -151,20 +153,6 @@ const RepositoryForm: FC = ({ }); }; - const resolveLocation = () => { - const currentUrl = location.pathname; - if (currentUrl.includes("/repos/create")) { - return "create"; - } - if (currentUrl.includes("/repos/import")) { - return "import"; - } - return ""; - }; - - const isImportPage = () => resolveLocation() === "import"; - const isCreatePage = () => resolveLocation() === "create"; - const createSelectOptions = (repositoryTypes?: RepositoryType[]) => { if (repositoryTypes) { return repositoryTypes.map(repositoryType => { @@ -195,7 +183,7 @@ const RepositoryForm: FC = ({ }; const renderUrlImportFields = () => { - if (!isImportPage()) { + if (!isImportMode()) { return null; } @@ -264,7 +252,7 @@ const RepositoryForm: FC = ({ helpText={t("help.typeHelpText")} /> - {!isImportPage() && ( + {!isImportMode() && ( = ({ const disabled = !isModifiable() && isEditMode(); const getSubmitButtonTranslationKey = () => - isImportPage() ? "repositoryForm.submitImport" : "repositoryForm.submitCreate"; + isImportMode() ? "repositoryForm.submitImport" : "repositoryForm.submitCreate"; const submitButton = disabled ? null : ( = ({ return ( <> - {!isEditMode() && ( - - )}
{renderCreateOnlyFields()} = ({ repository, createMode }) => { +const TopLevel = styled(Level)` + margin-top: -2.75rem; + margin-bottom: 2.75rem !important; //TODO Try to remove important + height: 0; +`; + +const RepositoryFormSwitcher: FC = ({ creationMode }) => { const [t] = useTranslation("repos"); const isImportMode = () => { - return createMode === "IMPORT"; + return creationMode === "IMPORT"; }; const isCreateMode = () => { - return createMode === "CREATE"; - }; - - const renderSubtitle = () => { - let subtitle; - if (repository) { - subtitle = "repositoryForm.subtitle"; - } else if (isImportMode()) { - subtitle = "create.subtitle"; - } else { - subtitle = "import.subtitle"; - } - - return ; + return creationMode === "CREATE"; }; return ( void; - fetchRepositoryTypesIfNeeded: () => void; - createRepo: ( - link: string, - repository: RepositoryCreation, - initRepository: boolean, - callback: (repo: Repository) => void - ) => void; - importRepoFromUrl: (link: string, repository: RepositoryImport, callback: (repo: Repository) => void) => void; - resetForm: () => void; + // dispatch functions + fetchNamespaceStrategiesIfNeeded: () => void; + fetchRepositoryTypesIfNeeded: () => void; + createRepo: ( + link: string, + repository: RepositoryCreation, + initRepository: boolean, + callback: (repo: Repository) => void + ) => void; + importRepoFromUrl: (link: string, repository: RepositoryImport, callback: (repo: Repository) => void) => void; + resetForm: () => void; - // context props - history: History; -}; + // context props + history: History; + }; class AddRepository extends React.Component { componentDidMount() { @@ -96,6 +101,34 @@ class AddRepository extends React.Component { history.push("/repo/" + repo.namespace + "/" + repo.name); }; + resolveLocation = () => { + const currentUrl = this.props.location.pathname; + if (currentUrl.includes("/repos/create")) { + return "create"; + } + if (currentUrl.includes("/repos/import")) { + return "import"; + } + return ""; + }; + + isImportPage = () => this.resolveLocation() === "import"; + isCreatePage = () => this.resolveLocation() === "create"; + + getSubtitle = () => { + const { importLoading, t } = this.props; + let subtitle; + if (this.isCreatePage()) { + subtitle = t("create.subtitle"); + } else if (!importLoading) { + subtitle = t("import.subtitle"); + } else { + subtitle = t("import.pending.subtitle"); + } + + return subtitle; + }; + render() { const { pageLoading, @@ -112,26 +145,35 @@ class AddRepository extends React.Component { } = this.props; return ( - + {importLoading ? ( <> - {t("import.pending.infoText")} ) : ( - { - createRepo(repoLink, repo, initRepository, (repo: Repository) => this.repoCreated(repo)); - }} - importRepository={repo => { - importRepoFromUrl(repoLink, repo, (repo: Repository) => this.repoCreated(repo)); - }} - indexResources={indexResources} - /> + <> + {!error && } + { + createRepo(repoLink, repo, initRepository, (repo: Repository) => this.repoCreated(repo)); + }} + importRepository={repo => { + importRepoFromUrl(repoLink, repo, (repo: Repository) => this.repoCreated(repo)); + }} + indexResources={indexResources} + creationMode={this.isImportPage() ? "IMPORT" : "CREATE"} + /> + )} ); @@ -180,8 +222,13 @@ const mapDispatchToProps = (dispatch: any) => { }, resetForm: () => { dispatch(createRepoReset()); + dispatch(importRepoReset()); } }; }; -export default connect(mapStateToProps, mapDispatchToProps)(withTranslation("repos")(AddRepository)); +export default compose( + withRouter, + withTranslation("repos"), + connect(mapStateToProps, mapDispatchToProps) +)(AddRepository); diff --git a/scm-ui/ui-webapp/src/repos/containers/EditRepo.tsx b/scm-ui/ui-webapp/src/repos/containers/EditRepo.tsx index 2c56dc612b..4928ee8703 100644 --- a/scm-ui/ui-webapp/src/repos/containers/EditRepo.tsx +++ b/scm-ui/ui-webapp/src/repos/containers/EditRepo.tsx @@ -28,25 +28,27 @@ import RepositoryForm from "../components/form"; import { Repository, Links } from "@scm-manager/ui-types"; import { getModifyRepoFailure, isModifyRepoPending, modifyRepo, modifyRepoReset } from "../modules/repos"; import { History } from "history"; -import { ErrorNotification } from "@scm-manager/ui-components"; +import { ErrorNotification, Subtitle } from "@scm-manager/ui-components"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; import { compose } from "redux"; import RepositoryDangerZone from "./RepositoryDangerZone"; import { getLinks } from "../../modules/indexResource"; import { urls } from "@scm-manager/ui-components"; +import { TranslationProps, withTranslation } from "react-i18next"; -type Props = RouteComponentProps & { - loading: boolean; - error: Error; - indexLinks: Links; +type Props = TranslationProps & + RouteComponentProps & { + loading: boolean; + error: Error; + indexLinks: Links; - modifyRepo: (p1: Repository, p2: () => void) => void; - modifyRepoReset: (p: Repository) => void; + modifyRepo: (p1: Repository, p2: () => void) => void; + modifyRepoReset: (p: Repository) => void; - // context props - repository: Repository; - history: History; -}; + // context props + repository: Repository; + history: History; + }; class EditRepo extends React.Component { componentDidMount() { @@ -60,7 +62,7 @@ class EditRepo extends React.Component { }; render() { - const { loading, error, repository, indexLinks } = this.props; + const { loading, error, repository, indexLinks, t } = this.props; const url = urls.matchedUrl(this.props); @@ -71,6 +73,7 @@ class EditRepo extends React.Component { return ( <> + { }; }; -export default compose(connect(mapStateToProps, mapDispatchToProps), withRouter)(EditRepo); +export default compose(connect(mapStateToProps, mapDispatchToProps), withRouter)(withTranslation("repos")(EditRepo)); diff --git a/scm-ui/ui-webapp/src/repos/modules/repos.ts b/scm-ui/ui-webapp/src/repos/modules/repos.ts index 10ff216558..fa0aa0a92e 100644 --- a/scm-ui/ui-webapp/src/repos/modules/repos.ts +++ b/scm-ui/ui-webapp/src/repos/modules/repos.ts @@ -285,6 +285,12 @@ export function importRepoFailure(err: Error): Action { }; } +export function importRepoReset(): Action { + return { + type: IMPORT_REPO_RESET + }; +} + // create repo export function createRepo(