diff --git a/.betterer.results b/.betterer.results index 8a8733abfa2..688fbc27b6d 100644 --- a/.betterer.results +++ b/.betterer.results @@ -5766,8 +5766,7 @@ exports[`better eslint`] = { "public/app/features/provisioning/JobStatus.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "2"] ], "public/app/features/provisioning/MigrateToRepository.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], @@ -5785,7 +5784,8 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "5"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "6"] ], "public/app/features/provisioning/RecentJobs.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], @@ -5905,10 +5905,12 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "6"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "6"], [0, 0, 0, "No untranslated strings. Wrap text with ", "7"], [0, 0, 0, "No untranslated strings. Wrap text with ", "8"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "9"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "9"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "10"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "11"] ], "public/app/features/provisioning/Wizard/ProvisioningWizard.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] @@ -5927,7 +5929,11 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "10"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "11"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "12"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "13"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "13"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "14"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "15"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "16"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "17"] ], "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/ConfigForm.tsx b/public/app/features/provisioning/ConfigForm.tsx index 005a2cb1bd3..f64a2d344c6 100644 --- a/public/app/features/provisioning/ConfigForm.tsx +++ b/public/app/features/provisioning/ConfigForm.tsx @@ -55,7 +55,7 @@ export function getDefaultValues(repository?: RepositorySpec): RepositoryFormDat generateDashboardPreviews: true, workflows: ['write', 'branch'], sync: { - enabled: false, + enabled: true, target: 'instance', intervalSeconds: 60, }, diff --git a/public/app/features/provisioning/JobStatus.tsx b/public/app/features/provisioning/JobStatus.tsx index 6e4ca58efc2..d3042dc32e6 100644 --- a/public/app/features/provisioning/JobStatus.tsx +++ b/public/app/features/provisioning/JobStatus.tsx @@ -4,6 +4,7 @@ import { Box, ControlledCollapse, Stack, Text, TextLink } from '@grafana/ui'; import ProgressBar from './ProgressBar'; import { useGetRepositoryQuery, useListJobQuery } from './api'; +import { getRemoteURL } from './utils/git'; export function JobStatus({ name }: { name: string }) { const jobQuery = useListJobQuery({ watch: true, fieldSelector: `metadata.name=${name}` }); @@ -18,8 +19,8 @@ export function JobStatus({ name }: { name: string }) { {job.status && ( - - {job.status.message} // {job.status.state} + + {job.status.message ?? ''} @@ -46,10 +47,15 @@ function RepositoryLink({ name }: RepositoryLinkProps) { return null; } + const href = getRemoteURL(repo); + + if (!href) { + return null; + } return ( Your dashboards and folders are now in your repository. - + View repository diff --git a/public/app/features/provisioning/MigrateToRepository.tsx b/public/app/features/provisioning/MigrateToRepository.tsx index 0f241ec8c43..29356713b18 100644 --- a/public/app/features/provisioning/MigrateToRepository.tsx +++ b/public/app/features/provisioning/MigrateToRepository.tsx @@ -15,6 +15,7 @@ export function MigrateToRepository({ repo }: Props) { const { register, formState, handleSubmit } = useForm({ defaultValues: { + identifier: true, // Keep URLs the same history: true, prefix: '', }, diff --git a/public/app/features/provisioning/OnboardingPage.tsx b/public/app/features/provisioning/OnboardingPage.tsx index dc1f30473dd..b9cedcd3cbc 100644 --- a/public/app/features/provisioning/OnboardingPage.tsx +++ b/public/app/features/provisioning/OnboardingPage.tsx @@ -4,9 +4,9 @@ import { EmptyState, LinkButton, Alert, Stack, Text } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; import { SetupWarnings } from './SetupWarnings'; -import { MIGRATE_URL } from './constants'; +import { NEW_URL, MIGRATE_URL } from './constants'; -export default function OnboardingPage() { +export default function OnboardingPage({ legacyStorage }: { legacyStorage?: boolean }) { return ( - - When you connect your whole instance, dashboards will be unavailable while running the migration. We recommend - warning your users before starting the process. - - } - button={ - - Connect Grafana to repository - - } - > - - Store and provision your Grafana resources externally by connecting to a repository. - We currently support GitHub and local storage. - - Learn more - - - + {legacyStorage ? ( + <> + + When you connect your whole instance, dashboards will be unavailable while running the migration. We + recommend warning your users before starting the process. + + } + button={ + + Connect Grafana to repository + + } + > + + Store and provision your Grafana resources externally by connecting to a repository. + We currently support GitHub and local storage. + + Learn more + + + + + ) : ( + + Create repository config + + } + /> + )} ); diff --git a/public/app/features/provisioning/RepositoryListPage.tsx b/public/app/features/provisioning/RepositoryListPage.tsx index 4aff01663d4..715b9977cc3 100644 --- a/public/app/features/provisioning/RepositoryListPage.tsx +++ b/public/app/features/provisioning/RepositoryListPage.tsx @@ -45,7 +45,7 @@ export default function RepositoryListPage() { }, [deleteAllResult.isSuccess]); if (!items?.length && !isLoading) { - return ; + return ; } const onConfirmDelete = () => { diff --git a/public/app/features/provisioning/RepositoryStatusPage.tsx b/public/app/features/provisioning/RepositoryStatusPage.tsx index dc41260c768..4f5194c72bd 100644 --- a/public/app/features/provisioning/RepositoryStatusPage.tsx +++ b/public/app/features/provisioning/RepositoryStatusPage.tsx @@ -42,6 +42,7 @@ import { } from './api'; import { FileDetails } from './api/types'; import { PROVISIONING_URL } from './constants'; +import { getRemoteURL } from './utils/git'; enum TabSelection { Overview = 'overview', @@ -253,15 +254,3 @@ function FilesView({ repo }: RepoProps) { ); } - -function getRemoteURL(repo: Repository) { - if (repo.spec?.type === 'github') { - const spec = repo.spec.github; - let url = spec?.url || ''; - if (spec?.branch) { - url += `/tree/${spec.branch}`; - } - return url; - } - return undefined; -} diff --git a/public/app/features/provisioning/Wizard/MigrateStep.tsx b/public/app/features/provisioning/Wizard/MigrateStep.tsx index c4c158749e7..f134c87c276 100644 --- a/public/app/features/provisioning/Wizard/MigrateStep.tsx +++ b/public/app/features/provisioning/Wizard/MigrateStep.tsx @@ -2,11 +2,12 @@ import { skipToken } from '@reduxjs/toolkit/query/react'; import { useState } from 'react'; import { useFormContext } from 'react-hook-form'; -import { Button, FieldSet, Stack, Text, Switch, Field, Alert } from '@grafana/ui'; +import { Alert, Button, FieldSet, Stack, Text, Switch, Field } from '@grafana/ui'; import { JobStatus } from '../JobStatus'; import { useCreateRepositoryMigrateMutation, useGetRepositoryQuery } from '../api'; +import { RequestErrorAlert } from './RequestErrorAlert'; import { WizardFormData } from './types'; export interface MigrateStepProps { @@ -58,6 +59,13 @@ export function MigrateStep({ onMigrationStatusChange }: MigrateStepProps) { updates will be automatically saved to the repository. + {!repositoryName && ( + + Repository name is required to migrate dashboards. Please complete the repository configuration step first. + + )} + + Dashboards will be unavailable while running this process. diff --git a/public/app/features/provisioning/Wizard/ProvisioningWizard.tsx b/public/app/features/provisioning/Wizard/ProvisioningWizard.tsx index 30eda9ea5fa..e5c49f7619c 100644 --- a/public/app/features/provisioning/Wizard/ProvisioningWizard.tsx +++ b/public/app/features/provisioning/Wizard/ProvisioningWizard.tsx @@ -35,11 +35,12 @@ export function ProvisioningWizard() { const navigate = useNavigate(); const [activeStep, setActiveStep] = useState('connection'); const [completedSteps, setCompletedSteps] = useState([]); - const [migrationSuccess, setMigrationSuccess] = useState(false); + const [stepSuccess, setStepSuccess] = useState(false); const [submitData, request] = useCreateOrUpdateRepository(); const methods = useForm({ defaultValues: { repository: getDefaultValues(), + migrate: { history: true, identifier: false, @@ -51,19 +52,20 @@ export function ProvisioningWizard() { useEffect(() => { if (request.isSuccess) { - appEvents.publish({ - type: AppEvents.alertSuccess.name, - payload: ['Repository settings saved'], - }); - if (request.data?.metadata?.name) { methods.setValue('repositoryName', request.data.metadata.name); } + if (activeStep === 'repository') { + appEvents.publish({ + type: AppEvents.alertSuccess.name, + payload: ['Repository settings saved'], + }); - const currentStepIndex = steps.findIndex((s) => s.id === activeStep); - if (currentStepIndex < steps.length - 1) { - setCompletedSteps([...completedSteps, activeStep]); - setActiveStep(steps[currentStepIndex + 1].id); + const currentStepIndex = steps.findIndex((s) => s.id === activeStep); + if (currentStepIndex < steps.length - 1) { + setCompletedSteps((prev) => [...prev, activeStep]); + setActiveStep(steps[currentStepIndex + 1].id); + } } } else if (request.isError) { appEvents.publish({ @@ -71,7 +73,7 @@ export function ProvisioningWizard() { payload: ['Failed to save repository settings', request.error], }); } - }, [request.isSuccess, request.isError, request.data, request.error, activeStep, completedSteps, methods]); + }, [request.isSuccess, request.isError, request.data, request.error, activeStep, methods]); const handleNext = async () => { const currentStepIndex = steps.findIndex((s) => s.id === activeStep); @@ -90,9 +92,12 @@ export function ProvisioningWizard() { } } - setCompletedSteps([...completedSteps, activeStep]); + if (activeStep === 'migrate') { + setCompletedSteps((prev) => [...prev, activeStep]); + } setActiveStep(steps[currentStepIndex + 1].id); - } else if (activeStep === 'migrate' && migrationSuccess) { + setStepSuccess(false); + } else if (activeStep === 'migrate') { navigate('/dashboards'); } }; @@ -101,6 +106,9 @@ export function ProvisioningWizard() { const currentStepIndex = steps.findIndex((s) => s.id === activeStep); if (currentStepIndex > 0) { setActiveStep(steps[currentStepIndex - 1].id); + setStepSuccess(false); + // Remove the last completed step when going back + setCompletedSteps((prev) => prev.slice(0, -1)); } }; @@ -117,19 +125,18 @@ export function ProvisioningWizard() { {}} + visitedSteps={completedSteps} validationResults={{ connection: { valid: true }, repository: { valid: true }, migrate: { valid: true }, }} - getNextUrl={() => ''} />
{activeStep === 'connection' && } - {activeStep === 'repository' && } - {activeStep === 'migrate' && } + {activeStep === 'repository' && } + {activeStep === 'migrate' && }
@@ -140,7 +147,11 @@ export function ProvisioningWizard() { )}