diff --git a/.betterer.results b/.betterer.results index ee807040ee7..027526239f6 100644 --- a/.betterer.results +++ b/.betterer.results @@ -5900,14 +5900,14 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "21"], [0, 0, 0, "No untranslated strings. Wrap text with ", "22"] ], - "public/app/features/provisioning/Wizard/JobStep.tsx:5381": [ - [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] - ], "public/app/features/provisioning/Wizard/MigrateStep.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], [0, 0, 0, "No untranslated strings. Wrap text with ", "2"] ], + "public/app/features/provisioning/Wizard/PullStep.tsx:5381": [ + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] + ], "public/app/features/provisioning/Wizard/Stepper.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], diff --git a/public/app/features/provisioning/JobStatus.tsx b/public/app/features/provisioning/JobStatus.tsx index 15faee89603..823bcd473e6 100644 --- a/public/app/features/provisioning/JobStatus.tsx +++ b/public/app/features/provisioning/JobStatus.tsx @@ -39,7 +39,7 @@ export function JobStatus({ name, onStatusChange, onRunningChange, onErrorChange } }, [job, onStatusChange, onErrorChange, onRunningChange]); - if (jobQuery.isLoading || !job) { + if (!name || jobQuery.isLoading || !job) { return ( diff --git a/public/app/features/provisioning/Wizard/JobStep.tsx b/public/app/features/provisioning/Wizard/JobStep.tsx index 73c60755e55..554806679f8 100644 --- a/public/app/features/provisioning/Wizard/JobStep.tsx +++ b/public/app/features/provisioning/Wizard/JobStep.tsx @@ -1,11 +1,10 @@ -import { skipToken } from '@reduxjs/toolkit/query'; -import { ReactNode, useEffect, useRef, useState } from 'react'; +import { ReactNode, useState } from 'react'; import { useFormContext } from 'react-hook-form'; +import { useAsync } from 'react-use'; -import { Box, Spinner, Stack, Text } from '@grafana/ui'; +import { Stack, Text } from '@grafana/ui'; import { JobStatus } from '../JobStatus'; -import { useListJobQuery } from '../api'; import { StepStatus, useStepStatus } from '../hooks/useStepStatus'; import { WizardFormData } from './types'; @@ -20,92 +19,59 @@ interface JobStepProps { export type { JobStepProps }; export function JobStep({ onStepUpdate, description, startJob, children }: JobStepProps) { - const hasInitialized = useRef(false); const { watch } = useFormContext(); const repositoryName = watch('repositoryName'); const stepStatus = useStepStatus({ onStepUpdate }); const [jobName, setJobName] = useState(); - // Query the job status if we have a job name - const jobQuery = useListJobQuery(jobName ? { watch: true, fieldSelector: `metadata.name=${jobName}` } : skipToken); - - useEffect(() => { - if (!repositoryName || hasInitialized.current) { + useAsync(async () => { + if (!repositoryName) { return; } - hasInitialized.current = true; - let isMounted = true; + try { + stepStatus.setRunning(); + const response = await startJob(repositoryName); - const executeJob = async () => { - try { - if (!isMounted) { - return; - } - - stepStatus.setRunning(); - const response = await startJob(repositoryName); - - if (!response?.metadata?.name) { - stepStatus.setError('Invalid response from operation'); - return; - } - setJobName(response.metadata.name); - } catch (error) { - if (!isMounted) { - return; - } - stepStatus.setError(error instanceof Error ? error.message : 'Failed to start operation'); + if (!response?.metadata?.name) { + stepStatus.setError('Invalid response from operation'); + throw new Error('Invalid response from operation'); } - }; - executeJob(); - return () => { - isMounted = false; - }; + setJobName(response.metadata.name); + } catch (error) { + stepStatus.setError(error instanceof Error ? error.message : 'Failed to start operation'); + throw error; // Re-throw to mark the async operation as failed + } }, [repositoryName, startJob, stepStatus]); - const job = jobQuery.data?.items?.[0]; - const showSpinner = !job; - return ( {description && {description}} {children} - - {showSpinner && ( - - - - Starting... - - - )} - - {job && ( - { - if (success) { - stepStatus.setSuccess(); - } else { - stepStatus.setError('Job failed'); - } - }} - onRunningChange={(isRunning) => { - if (isRunning) { - stepStatus.setRunning(); - } - }} - onErrorChange={(error) => { - if (error) { - stepStatus.setError(error); - } - }} - /> - )} - + {jobName && ( + { + if (success) { + stepStatus.setSuccess(); + } else { + stepStatus.setError('Job failed'); + } + }} + onRunningChange={(isRunning) => { + if (isRunning) { + stepStatus.setRunning(); + } + }} + onErrorChange={(error) => { + if (error) { + stepStatus.setError(error); + } + }} + /> + )} ); } diff --git a/public/app/features/provisioning/Wizard/PullStep.tsx b/public/app/features/provisioning/Wizard/PullStep.tsx index 3d7f1d1791a..34fda60bdab 100644 --- a/public/app/features/provisioning/Wizard/PullStep.tsx +++ b/public/app/features/provisioning/Wizard/PullStep.tsx @@ -1,5 +1,3 @@ -import { ReactNode } from 'react'; - import { useCreateRepositorySyncMutation } from '../api'; import { StepStatus } from '../hooks/useStepStatus'; @@ -7,10 +5,9 @@ import { JobStep } from './JobStep'; interface PullStepProps { onStepUpdate: (status: StepStatus, error?: string) => void; - description?: ReactNode; } -export function PullStep({ onStepUpdate, description }: PullStepProps) { +export function PullStep({ onStepUpdate }: PullStepProps) { const [syncRepo] = useCreateRepositorySyncMutation(); const startSync = async (repositoryName: string) => { @@ -24,7 +21,7 @@ export function PullStep({ onStepUpdate, description }: PullStepProps) { return ( );