Add Loading Spinner while waiting for repository import

This commit is contained in:
Eduard Heimbuch
2020-11-25 12:12:16 +01:00
parent 10ed51733c
commit 4e1e51d1b9
6 changed files with 75 additions and 37 deletions

View File

@@ -49,13 +49,17 @@
}, },
"create": { "create": {
"title": "Repository hinzufügen", "title": "Repository hinzufügen",
"createSubtitle": "Neues Repository erstellen", "subtitle": "Neues Repository erstellen"
"importSubtitle": "Bestehendes Repository importieren", },
"importUrl": "Remote repository url", "import": {
"subtitle": "Bestehendes Repository importieren",
"importUrl": "Remote Repository URL",
"username": "Benutzername", "username": "Benutzername",
"password": "Passwort", "password": "Passwort",
"createButton": "Neues Repository erstellen", "pending": {
"importButton": "Repository importieren" "subtitle": "Repository wird importiert...",
"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."
}
}, },
"branches": { "branches": {
"overview": { "overview": {
@@ -167,7 +171,9 @@
"submitCreate": "Speichern", "submitCreate": "Speichern",
"submitImport": "Importieren", "submitImport": "Importieren",
"initializeRepository": "Repository initiieren", "initializeRepository": "Repository initiieren",
"dangerZone": "Umbenennen und Löschen" "dangerZone": "Umbenennen und Löschen",
"createButton": "Neues Repository erstellen",
"importButton": "Repository importieren"
}, },
"sources": { "sources": {
"fileTree": { "fileTree": {

View File

@@ -45,17 +45,22 @@
"title": "Repositories", "title": "Repositories",
"subtitle": "Overview of available repositories", "subtitle": "Overview of available repositories",
"noRepositories": "No repositories found.", "noRepositories": "No repositories found.",
"createButton": "Add Repository" "createButton": "Add repository"
}, },
"create": { "create": {
"title": "Add Repository", "title": "Add Repository",
"createSubtitle": "Create a new repository", "subtitle": "Create a new repository",
"importSubtitle": "Import existing repository", "createButton": "Create new repository"
},
"import": {
"subtitle": "Import existing repository",
"importUrl": "Remote repository url", "importUrl": "Remote repository url",
"username": "Username", "username": "Username",
"password": "Password", "password": "Password",
"createButton": "Create new repository", "pending": {
"importButton": "Import repository" "subtitle": "Importing Repository...",
"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."
}
}, },
"branches": { "branches": {
"overview": { "overview": {
@@ -167,7 +172,9 @@
"submitCreate": "Save", "submitCreate": "Save",
"submitImport": "Import", "submitImport": "Import",
"initializeRepository": "Initialize repository", "initializeRepository": "Initialize repository",
"dangerZone": "Rename and delete" "dangerZone": "Rename and delete",
"createButton": "Create Repository",
"importButton": "Import repository"
}, },
"sources": { "sources": {
"fileTree": { "fileTree": {

View File

@@ -204,7 +204,7 @@ const RepositoryForm: FC<Props> = ({
<Columns className="columns is-multiline"> <Columns className="columns is-multiline">
<Column className="column is-full"> <Column className="column is-full">
<InputField <InputField
label={t("create.importUrl")} label={t("import.importUrl")}
onChange={handleImportUrlChange} onChange={handleImportUrlChange}
value={importUrl} value={importUrl}
helpText={t("help.importUrlHelpText")} helpText={t("help.importUrlHelpText")}
@@ -212,7 +212,7 @@ const RepositoryForm: FC<Props> = ({
</Column> </Column>
<Column className="column is-half"> <Column className="column is-half">
<InputField <InputField
label={t("create.username")} label={t("import.username")}
onChange={setUsername} onChange={setUsername}
value={username} value={username}
helpText={t("help.usernameHelpText")} helpText={t("help.usernameHelpText")}
@@ -220,7 +220,7 @@ const RepositoryForm: FC<Props> = ({
</Column> </Column>
<Column className="column is-half"> <Column className="column is-half">
<InputField <InputField
label={t("create.password")} label={t("import.password")}
onChange={setPassword} onChange={setPassword}
value={password} value={password}
type="password" type="password"

View File

@@ -59,9 +59,9 @@ const RepositoryFormSwitcher: FC<Props> = ({ repository, createMode }) => {
if (repository) { if (repository) {
subtitle = "repositoryForm.subtitle"; subtitle = "repositoryForm.subtitle";
} else if (isImportMode()) { } else if (isImportMode()) {
subtitle = "create.importSubtitle"; subtitle = "create.subtitle";
} else { } else {
subtitle = "create.createSubtitle"; subtitle = "import.subtitle";
} }
return <Subtitle subtitle={t(subtitle)} />; return <Subtitle subtitle={t(subtitle)} />;
@@ -73,13 +73,13 @@ const RepositoryFormSwitcher: FC<Props> = ({ repository, createMode }) => {
right={ right={
<ButtonAddons> <ButtonAddons>
<SmallButton <SmallButton
label={t("create.createButton")} label={t("repositoryForm.createButton")}
icon="fa fa-plus" 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}
/> />
<SmallButton <SmallButton
label={t("create.importButton")} label={t("repositoryForm.importButton")}
icon="fa fa-file-upload" 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}

View File

@@ -32,7 +32,7 @@ import {
RepositoryImport, RepositoryImport,
RepositoryType RepositoryType
} from "@scm-manager/ui-types"; } from "@scm-manager/ui-types";
import { Page } from "@scm-manager/ui-components"; import { Loading, Page, Notification, Subtitle } from "@scm-manager/ui-components";
import { import {
fetchRepositoryTypesIfNeeded, fetchRepositoryTypesIfNeeded,
getFetchRepositoryTypesFailure, getFetchRepositoryTypesFailure,
@@ -44,8 +44,10 @@ import {
createRepo, createRepo,
createRepoReset, createRepoReset,
getCreateRepoFailure, getCreateRepoFailure,
getImportRepoFailure,
importRepoFromUrl, importRepoFromUrl,
isCreateRepoPending isCreateRepoPending,
isImportRepoPending
} from "../modules/repos"; } from "../modules/repos";
import { getRepositoriesLink } from "../../modules/indexResource"; import { getRepositoriesLink } from "../../modules/indexResource";
import { import {
@@ -60,6 +62,7 @@ type Props = WithTranslation & {
namespaceStrategies: NamespaceStrategies; namespaceStrategies: NamespaceStrategies;
pageLoading: boolean; pageLoading: boolean;
createLoading: boolean; createLoading: boolean;
importLoading: boolean;
error: Error; error: Error;
repoLink: string; repoLink: string;
indexResources: any; indexResources: any;
@@ -97,6 +100,7 @@ class AddRepository extends React.Component<Props> {
const { const {
pageLoading, pageLoading,
createLoading, createLoading,
importLoading,
repositoryTypes, repositoryTypes,
namespaceStrategies, namespaceStrategies,
createRepo, createRepo,
@@ -109,18 +113,26 @@ class AddRepository extends React.Component<Props> {
return ( return (
<Page title={t("create.title")} loading={pageLoading} error={error} showContentOnError={true}> <Page title={t("create.title")} loading={pageLoading} error={error} showContentOnError={true}>
<RepositoryForm {importLoading ? (
repositoryTypes={repositoryTypes} <>
loading={createLoading} <Subtitle subtitle={t("import.pending.subtitle")}/>
namespaceStrategy={namespaceStrategies.current} <Notification type="info">{t("import.pending.infoText")}</Notification>
createRepository={(repo, initRepository) => { <Loading />
createRepo(repoLink, repo, initRepository, (repo: Repository) => this.repoCreated(repo)); </>
}} ) : (
importRepository={repo => { <RepositoryForm
importRepoFromUrl(repoLink, repo, (repo: Repository) => this.repoCreated(repo)); repositoryTypes={repositoryTypes}
}} loading={createLoading}
indexResources={indexResources} namespaceStrategy={namespaceStrategies.current}
/> createRepository={(repo, initRepository) => {
createRepo(repoLink, repo, initRepository, (repo: Repository) => this.repoCreated(repo));
}}
importRepository={repo => {
importRepoFromUrl(repoLink, repo, (repo: Repository) => this.repoCreated(repo));
}}
indexResources={indexResources}
/>
)}
</Page> </Page>
); );
} }
@@ -131,8 +143,12 @@ const mapStateToProps = (state: any) => {
const namespaceStrategies = getNamespaceStrategies(state); const namespaceStrategies = getNamespaceStrategies(state);
const pageLoading = isFetchRepositoryTypesPending(state) || isFetchNamespaceStrategiesPending(state); const pageLoading = isFetchRepositoryTypesPending(state) || isFetchNamespaceStrategiesPending(state);
const createLoading = isCreateRepoPending(state); const createLoading = isCreateRepoPending(state);
const importLoading = isImportRepoPending(state);
const error = const error =
getFetchRepositoryTypesFailure(state) || getCreateRepoFailure(state) || getFetchNamespaceStrategiesFailure(state); getFetchRepositoryTypesFailure(state) ||
getCreateRepoFailure(state) ||
getFetchNamespaceStrategiesFailure(state) ||
getImportRepoFailure(state);
const repoLink = getRepositoriesLink(state); const repoLink = getRepositoriesLink(state);
const indexResources = state?.indexResources; const indexResources = state?.indexResources;
@@ -141,6 +157,7 @@ const mapStateToProps = (state: any) => {
namespaceStrategies, namespaceStrategies,
pageLoading, pageLoading,
createLoading, createLoading,
importLoading,
error, error,
repoLink, repoLink,
indexResources indexResources

View File

@@ -268,19 +268,19 @@ export function importRepoFromUrl(link: string, repository: RepositoryImport, ca
export function importRepoPending(): Action { export function importRepoPending(): Action {
return { return {
type: CREATE_REPO_PENDING type: IMPORT_REPO_PENDING
}; };
} }
export function importRepoSuccess(): Action { export function importRepoSuccess(): Action {
return { return {
type: CREATE_REPO_SUCCESS type: IMPORT_REPO_SUCCESS
}; };
} }
export function importRepoFailure(err: Error): Action { export function importRepoFailure(err: Error): Action {
return { return {
type: CREATE_REPO_FAILURE, type: IMPORT_REPO_FAILURE,
payload: err payload: err
}; };
} }
@@ -643,6 +643,14 @@ export function isAbleToCreateRepos(state: object) {
return !!(state.repos && state.repos.list && state.repos.list._links && state.repos.list._links.create); return !!(state.repos && state.repos.list && state.repos.list._links && state.repos.list._links.create);
} }
export function isImportRepoPending(state: object) {
return isPending(state, IMPORT_REPO);
}
export function getImportRepoFailure(state: object) {
return getFailure(state, IMPORT_REPO);
}
export function isCreateRepoPending(state: object) { export function isCreateRepoPending(state: object) {
return isPending(state, CREATE_REPO); return isPending(state, CREATE_REPO);
} }