From 4c61e876518d488b3a3cbe0abb490d4a7553765e Mon Sep 17 00:00:00 2001 From: Viktor Vorona Date: Wed, 18 Oct 2023 13:33:44 +0200 Subject: [PATCH] SONAR-20708 Handle failed imports --- .../create/project/components/AlmRepoItem.tsx | 4 +- .../components/NewCodeDefinitionSelection.tsx | 42 +++++++++++++------ .../resources/org/sonar/l10n/core.properties | 1 + 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/create/project/components/AlmRepoItem.tsx b/server/sonar-web/src/main/js/apps/create/project/components/AlmRepoItem.tsx index f604a644227..efbb949f15b 100644 --- a/server/sonar-web/src/main/js/apps/create/project/components/AlmRepoItem.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/components/AlmRepoItem.tsx @@ -92,7 +92,7 @@ export default function AlmRepoItem({ /> )}
-
+
)}
-
+
{secondaryTextNode}
diff --git a/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx b/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx index 521fb01226c..ad08108944f 100644 --- a/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx @@ -25,7 +25,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; import { useNavigate, unstable_usePrompt as usePrompt } from 'react-router-dom'; import NewCodeDefinitionSelector from '../../../../components/new-code-definition/NewCodeDefinitionSelector'; import { useDocUrl } from '../../../../helpers/docs'; -import { addGlobalSuccessMessage } from '../../../../helpers/globalMessages'; +import { addGlobalErrorMessage, addGlobalSuccessMessage } from '../../../../helpers/globalMessages'; import { translate } from '../../../../helpers/l10n'; import { getProjectUrl, queryToSearch } from '../../../../helpers/urls'; import { @@ -48,13 +48,15 @@ export default function NewCodeDefinitionSelection(props: Props) { const { importProjects } = props; const [selectedDefinition, selectDefinition] = React.useState(); - const { mutate, isLoading, data, reset } = useImportProjectMutation(); + const [failedImports, setFailedImports] = React.useState(0); + const { mutateAsync, data, reset, isIdle } = useImportProjectMutation(); const mutateCount = useImportProjectProgress(); + const isImporting = mutateCount > 0; const intl = useIntl(); const navigate = useNavigate(); const getDocUrl = useDocUrl(); usePrompt({ - when: isLoading, + when: isImporting, message: translate('onboarding.create_project.please_dont_leave'), }); @@ -62,7 +64,7 @@ export default function NewCodeDefinitionSelection(props: Props) { const isMultipleProjects = projectCount > 1; useEffect(() => { - if (mutateCount > 0 || !data) { + if (mutateCount > 0 || isIdle) { return; } reset(); @@ -70,28 +72,40 @@ export default function NewCodeDefinitionSelection(props: Props) { intl.formatMessage( { id: 'onboarding.create_project.success' }, { - count: projectCount, + count: projectCount - failedImports, }, ), ); + if (failedImports > 0) { + addGlobalErrorMessage( + intl.formatMessage( + { id: 'onboarding.create_project.failure' }, + { + count: failedImports, + }, + ), + ); + } if (projectCount === 1) { - navigate(getProjectUrl(data.project.key)); + if (data) { + navigate(getProjectUrl(data.project.key)); + } } else { navigate({ pathname: '/projects', search: queryToSearch({ sort: '-creation_date' }), }); } - }, [data, projectCount, mutateCount, reset, intl, navigate]); + }, [data, projectCount, failedImports, mutateCount, reset, intl, navigate, isIdle]); React.useEffect(() => { - if (isLoading) { + if (isImporting) { window.addEventListener('beforeunload', listener); } return () => window.removeEventListener('beforeunload', listener); - }, [isLoading]); + }, [isImporting]); const handleProjectCreation = () => { if (selectedDefinition) { @@ -101,10 +115,12 @@ export default function NewCodeDefinitionSelection(props: Props) { ...omit(importProjects, 'projects'), ...p, } as MutationArg; - mutate({ + mutateAsync({ newCodeDefinitionType: selectedDefinition.type, newCodeDefinitionValue: selectedDefinition.value, ...arg, + }).catch(() => { + setFailedImports((prev) => prev + 1); }); }); } @@ -151,7 +167,7 @@ export default function NewCodeDefinitionSelection(props: Props) { navigate(-1)}>{translate('back')} - + - {isLoading && ( + {isImporting && projectCount > 1 && (