mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 06:55:47 +01:00
fix form validation after refactoring
This commit is contained in:
@@ -61,6 +61,7 @@ const MarginLeft = styled.div`
|
|||||||
const FlexContainer = styled.div`
|
const FlexContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
height: 2.25rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default class Page extends React.Component<Props> {
|
export default class Page extends React.Component<Props> {
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
"infoText": "Ihr Repository wird gerade importiert. Dies kann einen Moment dauern. Sie werden weitergeleitet, sobald der Import abgeschlossen ist. Wenn Sie diese Seite verlassen, können Sie nicht zurückkehren, um den Import-Status zu erfahren."
|
"infoText": "Ihr Repository wird gerade importiert. Dies kann einen Moment dauern. Sie werden weitergeleitet, sobald der Import abgeschlossen ist. Wenn Sie diese Seite verlassen, können Sie nicht zurückkehren, um den Import-Status zu erfahren."
|
||||||
},
|
},
|
||||||
"importTypes": {
|
"importTypes": {
|
||||||
|
"label": "Import Modus",
|
||||||
"url": {
|
"url": {
|
||||||
"label": "Import via URL",
|
"label": "Import via URL",
|
||||||
"helpText": "Das Repository wird über eine URL importiert."
|
"helpText": "Das Repository wird über eine URL importiert."
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"infoText": "Your repository is currently being imported. This may take a moment. You will be forwarded as soon as the import is finished. If you leave this page you cannot return to find out the import status."
|
"infoText": "Your repository is currently being imported. This may take a moment. You will be forwarded as soon as the import is finished. If you leave this page you cannot return to find out the import status."
|
||||||
},
|
},
|
||||||
"importTypes": {
|
"importTypes": {
|
||||||
|
"label": "Import Mode",
|
||||||
"url": {
|
"url": {
|
||||||
"label": "Import via URL",
|
"label": "Import via URL",
|
||||||
"helpText": "The Repository will be imported via the provided URL."
|
"helpText": "The Repository will be imported via the provided URL."
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type Props = {
|
|||||||
repository: RepositoryUrlImport;
|
repository: RepositoryUrlImport;
|
||||||
onChange: (repository: RepositoryUrlImport) => void;
|
onChange: (repository: RepositoryUrlImport) => void;
|
||||||
setValid: (valid: boolean) => void;
|
setValid: (valid: boolean) => void;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Column = styled.div`
|
const Column = styled.div`
|
||||||
@@ -42,7 +43,7 @@ const Columns = styled.div`
|
|||||||
padding: 0.75rem 0 0;
|
padding: 0.75rem 0 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ImportFromUrlForm: FC<Props> = ({ repository, onChange, setValid }) => {
|
const ImportFromUrlForm: FC<Props> = ({ repository, onChange, setValid, disabled }) => {
|
||||||
const [t] = useTranslation("repos");
|
const [t] = useTranslation("repos");
|
||||||
const [urlValidationError, setUrlValidationError] = useState(false);
|
const [urlValidationError, setUrlValidationError] = useState(false);
|
||||||
|
|
||||||
@@ -72,6 +73,7 @@ const ImportFromUrlForm: FC<Props> = ({ repository, onChange, setValid }) => {
|
|||||||
helpText={t("help.importUrlHelpText")}
|
helpText={t("help.importUrlHelpText")}
|
||||||
validationError={urlValidationError}
|
validationError={urlValidationError}
|
||||||
errorMessage={t("validation.url-invalid")}
|
errorMessage={t("validation.url-invalid")}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
<Column className="column is-half">
|
<Column className="column is-half">
|
||||||
@@ -80,6 +82,7 @@ const ImportFromUrlForm: FC<Props> = ({ repository, onChange, setValid }) => {
|
|||||||
onChange={username => onChange({ ...repository, username })}
|
onChange={username => onChange({ ...repository, username })}
|
||||||
value={repository.username}
|
value={repository.username}
|
||||||
helpText={t("help.usernameHelpText")}
|
helpText={t("help.usernameHelpText")}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
<Column className="column is-half">
|
<Column className="column is-half">
|
||||||
@@ -89,6 +92,7 @@ const ImportFromUrlForm: FC<Props> = ({ repository, onChange, setValid }) => {
|
|||||||
value={repository.password}
|
value={repository.password}
|
||||||
type="password"
|
type="password"
|
||||||
helpText={t("help.passwordHelpText")}
|
helpText={t("help.passwordHelpText")}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
</Columns>
|
</Columns>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import React, { FC, useState } from "react";
|
import React, { FC, FormEvent, useState } from "react";
|
||||||
import NamespaceAndNameFields from "./NamespaceAndNameFields";
|
import NamespaceAndNameFields from "./NamespaceAndNameFields";
|
||||||
import { Repository, RepositoryUrlImport } from "@scm-manager/ui-types";
|
import { Repository, RepositoryUrlImport } from "@scm-manager/ui-types";
|
||||||
import ImportFromUrlForm from "./ImportFromUrlForm";
|
import ImportFromUrlForm from "./ImportFromUrlForm";
|
||||||
@@ -62,7 +62,9 @@ const ImportRepositoryFromUrl: FC<Props> = ({ url, setImportPending }) => {
|
|||||||
setImportPending(loading);
|
setImportPending(loading);
|
||||||
};
|
};
|
||||||
|
|
||||||
const submit = () => {
|
const submit = (event: FormEvent<HTMLFormElement>) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const currentPath = history.location.pathname;
|
||||||
handleImportLoading(true);
|
handleImportLoading(true);
|
||||||
apiClient
|
apiClient
|
||||||
.post(url, repo, "application/vnd.scmm-repository+json;v=2")
|
.post(url, repo, "application/vnd.scmm-repository+json;v=2")
|
||||||
@@ -72,7 +74,11 @@ const ImportRepositoryFromUrl: FC<Props> = ({ url, setImportPending }) => {
|
|||||||
return apiClient.get(location);
|
return apiClient.get(location);
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(repo => history.push(`/repo/${repo.namespace}/${repo.name}/code/sources`))
|
.then(repo => {
|
||||||
|
if (history.location.pathname === currentPath) {
|
||||||
|
history.push(`/repo/${repo.namespace}/${repo.name}/code/sources`);
|
||||||
|
}
|
||||||
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
setError(error);
|
setError(error);
|
||||||
handleImportLoading(false);
|
handleImportLoading(false);
|
||||||
@@ -81,22 +87,24 @@ const ImportRepositoryFromUrl: FC<Props> = ({ url, setImportPending }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={submit}>
|
<form onSubmit={submit}>
|
||||||
<ErrorNotification error={error} />
|
|
||||||
<ImportFromUrlForm
|
<ImportFromUrlForm
|
||||||
repository={repo}
|
repository={repo}
|
||||||
onChange={setRepo}
|
onChange={setRepo}
|
||||||
setValid={(importUrl: boolean) => setValid({ ...valid, importUrl })}
|
setValid={(importUrl: boolean) => setValid({ ...valid, importUrl })}
|
||||||
|
disabled={loading}
|
||||||
/>
|
/>
|
||||||
|
<ErrorNotification error={error} />
|
||||||
<hr />
|
<hr />
|
||||||
<NamespaceAndNameFields
|
<NamespaceAndNameFields
|
||||||
repository={repo}
|
repository={repo}
|
||||||
onChange={setRepo as React.Dispatch<React.SetStateAction<Repository>>}
|
onChange={setRepo as React.Dispatch<React.SetStateAction<Repository>>}
|
||||||
setValid={(namespaceAndName: boolean) => setValid({ ...valid, namespaceAndName })}
|
setValid={(namespaceAndName: boolean) => setValid({ ...valid, namespaceAndName })}
|
||||||
|
disabled={loading}
|
||||||
/>
|
/>
|
||||||
<RepositoryInformationForm
|
<RepositoryInformationForm
|
||||||
repository={repo}
|
repository={repo}
|
||||||
onChange={setRepo as React.Dispatch<React.SetStateAction<Repository>>}
|
onChange={setRepo as React.Dispatch<React.SetStateAction<Repository>>}
|
||||||
disabled={false}
|
disabled={loading}
|
||||||
setValid={(contact: boolean) => setValid({ ...valid, contact })}
|
setValid={(contact: boolean) => setValid({ ...valid, contact })}
|
||||||
/>
|
/>
|
||||||
<Level
|
<Level
|
||||||
|
|||||||
@@ -30,18 +30,21 @@ type Props = {
|
|||||||
repositoryTypes: RepositoryType[];
|
repositoryTypes: RepositoryType[];
|
||||||
repositoryType?: RepositoryType;
|
repositoryType?: RepositoryType;
|
||||||
setRepositoryType: (repositoryType: RepositoryType) => void;
|
setRepositoryType: (repositoryType: RepositoryType) => void;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ImportRepositoryTypeSelect: FC<Props> = ({ repositoryTypes, repositoryType, setRepositoryType }) => {
|
const ImportRepositoryTypeSelect: FC<Props> = ({ repositoryTypes, repositoryType, setRepositoryType, disabled }) => {
|
||||||
const [t] = useTranslation("repos");
|
const [t] = useTranslation("repos");
|
||||||
|
|
||||||
const createSelectOptions = () => {
|
const createSelectOptions = () => {
|
||||||
const options = repositoryTypes.filter(repoType => !!repoType._links.import).map(repositoryType => {
|
const options = repositoryTypes
|
||||||
return {
|
.filter(repoType => !!repoType._links.import)
|
||||||
label: repositoryType.displayName,
|
.map(repositoryType => {
|
||||||
value: repositoryType.name
|
return {
|
||||||
};
|
label: repositoryType.displayName,
|
||||||
});
|
value: repositoryType.name
|
||||||
|
};
|
||||||
|
});
|
||||||
options.unshift({ label: "", value: "" });
|
options.unshift({ label: "", value: "" });
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
@@ -52,13 +55,14 @@ const ImportRepositoryTypeSelect: FC<Props> = ({ repositoryTypes, repositoryType
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
label={t("repository.type")}
|
label={t("repository.type")}
|
||||||
onChange={onChangeType}
|
onChange={onChangeType}
|
||||||
value={repositoryType ? repositoryType.name : ""}
|
value={repositoryType ? repositoryType.name : ""}
|
||||||
options={createSelectOptions()}
|
options={createSelectOptions()}
|
||||||
helpText={t("help.typeHelpText")}
|
helpText={t("help.typeHelpText")}
|
||||||
/>
|
disabled={disabled}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,17 +22,18 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import React, { FC } from "react";
|
import React, { FC } from "react";
|
||||||
import { RepositoryType, Link } from "@scm-manager/ui-types";
|
import { Link, RepositoryType } from "@scm-manager/ui-types";
|
||||||
import { Radio } from "@scm-manager/ui-components";
|
import { LabelWithHelpIcon, Radio } from "@scm-manager/ui-components";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
repositoryType: RepositoryType;
|
repositoryType: RepositoryType;
|
||||||
importType: string;
|
importType: string;
|
||||||
setImportType: (type: string) => void;
|
setImportType: (type: string) => void;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ImportTypeSelect: FC<Props> = ({ repositoryType, importType, setImportType }) => {
|
const ImportTypeSelect: FC<Props> = ({ repositoryType, importType, setImportType, disabled }) => {
|
||||||
const [t] = useTranslation("repos");
|
const [t] = useTranslation("repos");
|
||||||
|
|
||||||
const changeImportType = (checked: boolean, name?: string) => {
|
const changeImportType = (checked: boolean, name?: string) => {
|
||||||
@@ -43,6 +44,7 @@ const ImportTypeSelect: FC<Props> = ({ repositoryType, importType, setImportType
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<LabelWithHelpIcon label={t("import.importTypes.label")} key="import.importTypes.label" />
|
||||||
{(repositoryType._links.import as Link[]).map((type, index) => (
|
{(repositoryType._links.import as Link[]).map((type, index) => (
|
||||||
<Radio
|
<Radio
|
||||||
name={type.name}
|
name={type.name}
|
||||||
@@ -52,6 +54,7 @@ const ImportTypeSelect: FC<Props> = ({ repositoryType, importType, setImportType
|
|||||||
helpText={t(`import.importTypes.${type.name}.helpText`)}
|
helpText={t(`import.importTypes.${type.name}.helpText`)}
|
||||||
onChange={changeImportType}
|
onChange={changeImportType}
|
||||||
key={index}
|
key={index}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -36,45 +36,45 @@ type Props = {
|
|||||||
onChange: (repository: Repository) => void;
|
onChange: (repository: Repository) => void;
|
||||||
namespaceStrategy: string;
|
namespaceStrategy: string;
|
||||||
setValid: (valid: boolean) => void;
|
setValid: (valid: boolean) => void;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const NamespaceAndNameFields: FC<Props> = ({ repository, onChange, namespaceStrategy, setValid }) => {
|
const NamespaceAndNameFields: FC<Props> = ({ repository, onChange, namespaceStrategy, setValid, disabled }) => {
|
||||||
const [t] = useTranslation("repos");
|
const [t] = useTranslation("repos");
|
||||||
const [namespaceValidationError, setNamespaceValidationError] = useState(false);
|
const [namespaceValidationError, setNamespaceValidationError] = useState(false);
|
||||||
const [nameValidationError, setNameValidationError] = useState(false);
|
const [nameValidationError, setNameValidationError] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//TODO fix validation
|
|
||||||
if (repository.name) {
|
if (repository.name) {
|
||||||
const valid = validator.isNameValid(repository.name);
|
const nameValid = validator.isNameValid(repository.name);
|
||||||
setNameValidationError(!valid);
|
setNameValidationError(!nameValid);
|
||||||
onFieldChange();
|
if (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY) {
|
||||||
|
if (repository.namespace) {
|
||||||
|
const namespaceValid = validator.isNamespaceValid(repository.namespace);
|
||||||
|
setValid(!(!namespaceValid || !nameValid));
|
||||||
|
} else {
|
||||||
|
setValid(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setValid(nameValid);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setValid(false);
|
||||||
}
|
}
|
||||||
}, [repository.name]);
|
}, [repository.name, repository.namespace]);
|
||||||
|
|
||||||
const handleNamespaceChange = (namespace: string) => {
|
const handleNamespaceChange = (namespace: string) => {
|
||||||
const valid = validator.isNamespaceValid(namespace);
|
const valid = validator.isNamespaceValid(namespace);
|
||||||
setNamespaceValidationError(!valid);
|
setNamespaceValidationError(!valid);
|
||||||
onFieldChange(valid);
|
|
||||||
onChange({ ...repository, namespace });
|
onChange({ ...repository, namespace });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNameChange = (name: string) => {
|
const handleNameChange = (name: string) => {
|
||||||
const valid = validator.isNameValid(name);
|
const valid = validator.isNameValid(name);
|
||||||
setNameValidationError(!valid);
|
setNameValidationError(!valid);
|
||||||
onFieldChange();
|
|
||||||
onChange({ ...repository, name });
|
onChange({ ...repository, name });
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO fix validation
|
|
||||||
const onFieldChange = (namespaceValid?: boolean) => {
|
|
||||||
if (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY && !validator.isNamespaceValid(repository.namespace)) {
|
|
||||||
setValid(false);
|
|
||||||
} else {
|
|
||||||
setValid(!nameValidationError && !namespaceValidationError);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderNamespaceField = () => {
|
const renderNamespaceField = () => {
|
||||||
const props = {
|
const props = {
|
||||||
label: t("repository.namespace"),
|
label: t("repository.namespace"),
|
||||||
@@ -82,7 +82,8 @@ const NamespaceAndNameFields: FC<Props> = ({ repository, onChange, namespaceStra
|
|||||||
value: repository ? repository.namespace : "",
|
value: repository ? repository.namespace : "",
|
||||||
onChange: handleNamespaceChange,
|
onChange: handleNamespaceChange,
|
||||||
errorMessage: t("validation.namespace-invalid"),
|
errorMessage: t("validation.namespace-invalid"),
|
||||||
validationError: namespaceValidationError
|
validationError: namespaceValidationError,
|
||||||
|
disabled: disabled
|
||||||
};
|
};
|
||||||
|
|
||||||
if (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY) {
|
if (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY) {
|
||||||
@@ -102,6 +103,7 @@ const NamespaceAndNameFields: FC<Props> = ({ repository, onChange, namespaceStra
|
|||||||
validationError={nameValidationError}
|
validationError={nameValidationError}
|
||||||
errorMessage={t("validation.name-invalid")}
|
errorMessage={t("validation.name-invalid")}
|
||||||
helpText={t("help.nameHelpText")}
|
helpText={t("help.nameHelpText")}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ const RepositoryForm: FC<Props> = ({
|
|||||||
});
|
});
|
||||||
const [initRepository, setInitRepository] = useState(false);
|
const [initRepository, setInitRepository] = useState(false);
|
||||||
const [contextEntries, setContextEntries] = useState({});
|
const [contextEntries, setContextEntries] = useState({});
|
||||||
//TODO fix validation
|
|
||||||
const [valid, setValid] = useState({ namespaceAndName: false, contact: true });
|
const [valid, setValid] = useState({ namespaceAndName: false, contact: true });
|
||||||
const [t] = useTranslation("repos");
|
const [t] = useTranslation("repos");
|
||||||
|
|
||||||
@@ -194,7 +193,7 @@ const RepositoryForm: FC<Props> = ({
|
|||||||
<RepositoryInformationForm
|
<RepositoryInformationForm
|
||||||
repository={repo}
|
repository={repo}
|
||||||
onChange={setRepo}
|
onChange={setRepo}
|
||||||
disabled={!createRepository}
|
disabled={!(isModifiable() || createRepository)}
|
||||||
setValid={contact => setValid({ ...valid, contact })}
|
setValid={contact => setValid({ ...valid, contact })}
|
||||||
/>
|
/>
|
||||||
{submitButton()}
|
{submitButton()}
|
||||||
|
|||||||
@@ -25,12 +25,16 @@
|
|||||||
import React, { FC } from "react";
|
import React, { FC } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Button, ButtonAddons, Level } from "@scm-manager/ui-components";
|
import { Button, ButtonAddons, Icon, Level } from "@scm-manager/ui-components";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
creationMode: "CREATE" | "IMPORT";
|
creationMode: "CREATE" | "IMPORT";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MarginIcon = styled(Icon)`
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
`;
|
||||||
|
|
||||||
const SmallButton = styled(Button)`
|
const SmallButton = styled(Button)`
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
@@ -38,9 +42,14 @@ const SmallButton = styled(Button)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const TopLevel = styled(Level)`
|
const TopLevel = styled(Level)`
|
||||||
margin-top: -2.75rem;
|
margin-top: 1.5rem;
|
||||||
margin-bottom: 2.75rem !important; //TODO Try to remove important
|
margin-bottom: -1.5rem !important;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
@media (max-width: 785px) {
|
||||||
|
margin-top: 4.5rem;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RepositoryFormSwitcher: FC<Props> = ({ creationMode }) => {
|
const RepositoryFormSwitcher: FC<Props> = ({ creationMode }) => {
|
||||||
@@ -59,17 +68,20 @@ const RepositoryFormSwitcher: FC<Props> = ({ creationMode }) => {
|
|||||||
right={
|
right={
|
||||||
<ButtonAddons>
|
<ButtonAddons>
|
||||||
<SmallButton
|
<SmallButton
|
||||||
label={t("repositoryForm.createButton")}
|
|
||||||
icon="fa fa-plus"
|
|
||||||
color={isCreateMode() ? "link is-selected" : undefined}
|
color={isCreateMode() ? "link is-selected" : undefined}
|
||||||
link={isImportMode() ? "/repos/create" : undefined}
|
link={isImportMode() ? "/repos/create" : undefined}
|
||||||
/>
|
>
|
||||||
|
<MarginIcon name="fa fa-plus" color={isCreateMode() ? "white" : "default"} />{" "}
|
||||||
|
<p className="is-hidden-mobile is-hidden-tablet-only">{t("repositoryForm.createButton")}</p>
|
||||||
|
</SmallButton>
|
||||||
<SmallButton
|
<SmallButton
|
||||||
label={t("repositoryForm.importButton")}
|
|
||||||
icon="fa fa-file-upload"
|
|
||||||
color={isImportMode() ? "link is-selected" : undefined}
|
color={isImportMode() ? "link is-selected" : undefined}
|
||||||
link={isCreateMode() ? "/repos/import" : undefined}
|
link={isCreateMode() ? "/repos/import" : undefined}
|
||||||
/>
|
className="has-text-left-desktop"
|
||||||
|
>
|
||||||
|
<MarginIcon name="fa fa-file-upload" color={isImportMode() ? "white" : "default"} />
|
||||||
|
<p className="is-hidden-mobile is-hidden-tablet-only">{t("repositoryForm.importButton")}</p>
|
||||||
|
</SmallButton>
|
||||||
</ButtonAddons>
|
</ButtonAddons>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -35,12 +35,7 @@ import {
|
|||||||
} from "../modules/repositoryTypes";
|
} from "../modules/repositoryTypes";
|
||||||
import RepositoryForm from "../components/form";
|
import RepositoryForm from "../components/form";
|
||||||
import RepositoryFormSwitcher from "../components/form/RepositoryFormSwitcher";
|
import RepositoryFormSwitcher from "../components/form/RepositoryFormSwitcher";
|
||||||
import {
|
import { createRepo, createRepoReset, getCreateRepoFailure, isCreateRepoPending } from "../modules/repos";
|
||||||
createRepo,
|
|
||||||
createRepoReset,
|
|
||||||
getCreateRepoFailure,
|
|
||||||
isCreateRepoPending
|
|
||||||
} from "../modules/repos";
|
|
||||||
import { getRepositoriesLink } from "../../modules/indexResource";
|
import { getRepositoriesLink } from "../../modules/indexResource";
|
||||||
import {
|
import {
|
||||||
fetchNamespaceStrategiesIfNeeded,
|
fetchNamespaceStrategiesIfNeeded,
|
||||||
@@ -77,7 +72,19 @@ type Props = WithTranslation &
|
|||||||
history: History;
|
history: History;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddRepository extends React.Component<Props> {
|
type State = {
|
||||||
|
importPending: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddRepository extends React.Component<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
importPending: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.resetForm();
|
this.props.resetForm();
|
||||||
this.props.fetchRepositoryTypesIfNeeded();
|
this.props.fetchRepositoryTypesIfNeeded();
|
||||||
@@ -102,6 +109,16 @@ class AddRepository extends React.Component<Props> {
|
|||||||
isImportPage = () => this.resolveLocation() === "import";
|
isImportPage = () => this.resolveLocation() === "import";
|
||||||
isCreatePage = () => this.resolveLocation() === "create";
|
isCreatePage = () => this.resolveLocation() === "create";
|
||||||
|
|
||||||
|
getSubtitle = () => {
|
||||||
|
if (this.isCreatePage()) {
|
||||||
|
return "create.subtitle";
|
||||||
|
} else if (this.isImportPage() && this.state.importPending) {
|
||||||
|
return "import.pending.subtitle";
|
||||||
|
} else {
|
||||||
|
return "import.subtitle";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
pageLoading,
|
pageLoading,
|
||||||
@@ -118,13 +135,18 @@ class AddRepository extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<Page
|
<Page
|
||||||
title={t("create.title")}
|
title={t("create.title")}
|
||||||
subtitle={t("create.subtitle")}
|
subtitle={t(this.getSubtitle())}
|
||||||
|
afterTitle={<RepositoryFormSwitcher creationMode={this.isImportPage() ? "IMPORT" : "CREATE"} />}
|
||||||
loading={pageLoading}
|
loading={pageLoading}
|
||||||
error={error}
|
error={error}
|
||||||
showContentOnError={true}
|
showContentOnError={true}
|
||||||
>
|
>
|
||||||
{!error && <RepositoryFormSwitcher creationMode={this.isImportPage() ? "IMPORT" : "CREATE"} />}
|
{this.isImportPage() && (
|
||||||
{this.isImportPage() && <ImportRepository repositoryTypes={repositoryTypes} />}
|
<ImportRepository
|
||||||
|
repositoryTypes={repositoryTypes}
|
||||||
|
setPending={(importPending: boolean) => this.setState({ importPending })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{this.isCreatePage() && (
|
{this.isCreatePage() && (
|
||||||
<RepositoryForm
|
<RepositoryForm
|
||||||
repositoryTypes={repositoryTypes}
|
repositoryTypes={repositoryTypes}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { FC, useState } from "react";
|
import React, { FC, useEffect, useState } from "react";
|
||||||
import { RepositoryType, Link } from "@scm-manager/ui-types";
|
import { Link, RepositoryType } from "@scm-manager/ui-types";
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import ImportRepositoryTypeSelect from "../components/ImportRepositoryTypeSelect";
|
import ImportRepositoryTypeSelect from "../components/ImportRepositoryTypeSelect";
|
||||||
@@ -33,14 +33,19 @@ import { Loading, Notification } from "@scm-manager/ui-components";
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
repositoryTypes: RepositoryType[];
|
repositoryTypes: RepositoryType[];
|
||||||
|
setPending: (pending: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ImportRepository: FC<Props> = ({ repositoryTypes }) => {
|
const ImportRepository: FC<Props> = ({ repositoryTypes, setPending }) => {
|
||||||
const [importPending, setImportPending] = useState(false);
|
const [importPending, setImportPending] = useState(false);
|
||||||
const [repositoryType, setRepositoryType] = useState<RepositoryType | undefined>();
|
const [repositoryType, setRepositoryType] = useState<RepositoryType | undefined>();
|
||||||
const [importType, setImportType] = useState("");
|
const [importType, setImportType] = useState("");
|
||||||
const [t] = useTranslation("repos");
|
const [t] = useTranslation("repos");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPending(importPending);
|
||||||
|
}, [importPending]);
|
||||||
|
|
||||||
const changeRepositoryType = (repositoryType: RepositoryType) => {
|
const changeRepositoryType = (repositoryType: RepositoryType) => {
|
||||||
setRepositoryType(repositoryType);
|
setRepositoryType(repositoryType);
|
||||||
setImportType(repositoryType?._links ? ((repositoryType!._links?.import as Link[])[0] as Link).name! : "");
|
setImportType(repositoryType?._links ? ((repositoryType!._links?.import as Link[])[0] as Link).name! : "");
|
||||||
@@ -72,11 +77,17 @@ const ImportRepository: FC<Props> = ({ repositoryTypes }) => {
|
|||||||
repositoryTypes={repositoryTypes}
|
repositoryTypes={repositoryTypes}
|
||||||
repositoryType={repositoryType}
|
repositoryType={repositoryType}
|
||||||
setRepositoryType={changeRepositoryType}
|
setRepositoryType={changeRepositoryType}
|
||||||
|
disabled={importPending}
|
||||||
/>
|
/>
|
||||||
{repositoryType && (
|
{repositoryType && (
|
||||||
<>
|
<>
|
||||||
<hr />
|
<hr />
|
||||||
<ImportTypeSelect repositoryType={repositoryType} importType={importType} setImportType={setImportType} />
|
<ImportTypeSelect
|
||||||
|
repositoryType={repositoryType}
|
||||||
|
importType={importType}
|
||||||
|
setImportType={setImportType}
|
||||||
|
disabled={importPending}
|
||||||
|
/>
|
||||||
<hr />
|
<hr />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user