diff --git a/public/app/features/provisioning/Wizard/SynchronizeStep.tsx b/public/app/features/provisioning/Wizard/SynchronizeStep.tsx index f389351be27..ba03c07f630 100644 --- a/public/app/features/provisioning/Wizard/SynchronizeStep.tsx +++ b/public/app/features/provisioning/Wizard/SynchronizeStep.tsx @@ -1,5 +1,5 @@ import { skipToken } from '@reduxjs/toolkit/query'; -import { memo, useState } from 'react'; +import { memo, useEffect, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { Trans, t } from '@grafana/i18n'; @@ -37,7 +37,15 @@ export const SynchronizeStep = memo(function SynchronizeStep({ setStepStatusInfo, }); const [job, setJob] = useState(); - const repositoryStatusQuery = useGetRepositoryStatusQuery(repoName ? { name: repoName } : skipToken); + const [shouldEnablePolling, setShouldEnablePolling] = useState(true); + + const POLLING_INTERVAL_MS = 5000; + + const repositoryStatusQuery = useGetRepositoryStatusQuery(repoName ? { name: repoName } : skipToken, { + // Disable polling by setting interval to 0 when we should stop + pollingInterval: shouldEnablePolling ? POLLING_INTERVAL_MS : 0, + skipPollingIfUnfocused: true, + }); const { healthy: isRepositoryHealthy, @@ -45,9 +53,21 @@ export const SynchronizeStep = memo(function SynchronizeStep({ checked, } = repositoryStatusQuery?.data?.status?.health || {}; + // healthStatusNotReady: If the repository is not yet ready (e.g., initial setup), synchronization cannot be started. + // User can potentially fail at this step if they click too fast and repo is not ready. + const healthStatusNotReady = + isRepositoryHealthy === false && repositoryStatusQuery?.data?.status?.observedGeneration === 0; + + // Stop polling when repository becomes healthy + useEffect(() => { + if (!healthStatusNotReady) { + setShouldEnablePolling(false); + } + }, [healthStatusNotReady]); + const hasError = repositoryStatusQuery.isError; const isLoading = repositoryStatusQuery.isLoading || repositoryStatusQuery.isFetching; - const isButtonDisabled = hasError || (checked !== undefined && isRepositoryHealthy === false); + const isButtonDisabled = hasError || (checked !== undefined && isRepositoryHealthy === false) || healthStatusNotReady; const startSynchronization = async () => { const [history] = getValues(['migrate.history']); @@ -151,21 +171,43 @@ export const SynchronizeStep = memo(function SynchronizeStep({ )} - - {hasError || (checked !== undefined && isRepositoryHealthy === false) ? ( - - ) : ( - - )} - + {healthStatusNotReady ? ( + <> + + + Repository connecting, synchronize will be ready soon. + + + + + + + + + ) : ( + + {hasError || (checked !== undefined && isRepositoryHealthy === false) ? ( + + ) : ( + + )} + + )} ); }); diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 626aa4f41e7..e2a9045c77d 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -11692,6 +11692,8 @@ "button-cancelling": "Cancelling...", "button-next": "Finish", "button-start": "Begin synchronization", + "check-status-button": "Check repository status", + "check-status-message": "Repository connecting, synchronize will be ready soon.", "discard-modal": { "body": "This will delete the repository configuration and you will lose all progress. Are you sure you want to discard your changes?", "confirm": "Yes, discard",