Enhance provisioning wizard with migration options
- Added a checkbox for migrating existing resources in the BootstrapStep component. - Updated the form context to track the new migration option. - Adjusted the SynchronizeStep and useCreateSyncJob hook to incorporate the migration logic. - Enhanced localization with new descriptions and labels for migration features.
This commit is contained in:
7 files changed
+67
-28
No files matched your search
@@ -14,7 +14,7 @@ import (
|
||||
//go:generate mockery --name FullSyncFn --structname MockFullSyncFn --inpackage --filename full_sync_fn_mock.go --with-expecter
|
||||
type FullSyncFn func(ctx context.Context, repo repository.Reader, compare CompareFn, clients resources.ResourceClients, currentRef string, repositoryResources resources.RepositoryResources, progress jobs.JobProgressRecorder, tracer tracing.Tracer, maxSyncWorkers int, metrics jobs.JobMetrics) error
|
||||
|
||||
//go:generate mockery --name CompareFn --structname MockCompareFn --inpackage --filename compare_fn_mock.go --with-expecter
|
||||
//go:generate mockery -name CompareFn --structname MockCompareFn --inpackage --filename compare_fn_mock.go --with-expecter
|
||||
type CompareFn func(ctx context.Context, repo repository.Reader, repositoryResources resources.RepositoryResources, ref string) ([]ResourceFileChange, error)
|
||||
|
||||
//go:generate mockery --name IncrementalSyncFn --structname MockIncrementalSyncFn --inpackage --filename incremental_sync_fn_mock.go --with-expecter
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { memo, useEffect } from 'react';
|
||||
import React, { memo, useEffect } from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { Box, Card, Field, Icon, Input, LoadingPlaceholder, Stack, Text, useStyles2 } from '@grafana/ui';
|
||||
import { Box, Card, Checkbox, Field, Icon, Input, LoadingPlaceholder, Stack, Text, useStyles2 } from '@grafana/ui';
|
||||
import { RepositoryViewList } from 'app/api/clients/provisioning/v0alpha1';
|
||||
import { generateRepositoryTitle } from 'app/features/provisioning/utils/data';
|
||||
|
||||
@@ -116,30 +116,56 @@ export const BootstrapStep = memo(function BootstrapStep({ settingsData, repoNam
|
||||
|
||||
{/* Only show title field if folder sync */}
|
||||
{selectedTarget === 'folder' && (
|
||||
<Field
|
||||
label={t('provisioning.bootstrap-step.label-display-name', 'Display name')}
|
||||
description={t(
|
||||
'provisioning.bootstrap-step.description-clear-repository-connection',
|
||||
'Add a clear name for this repository connection'
|
||||
)}
|
||||
error={errors.repository?.title?.message}
|
||||
invalid={!!errors.repository?.title}
|
||||
required
|
||||
noMargin
|
||||
>
|
||||
<Input
|
||||
id="repository-title"
|
||||
{...register('repository.title', {
|
||||
required: t('provisioning.bootstrap-step.error-field-required', 'This field is required.'),
|
||||
})}
|
||||
placeholder={t(
|
||||
'provisioning.bootstrap-step.placeholder-my-repository-connection',
|
||||
'My repository connection'
|
||||
<>
|
||||
<Field
|
||||
label={t('provisioning.bootstrap-step.label-display-name', 'Display name')}
|
||||
description={t(
|
||||
'provisioning.bootstrap-step.description-clear-repository-connection',
|
||||
'Add a clear name for this repository connection'
|
||||
)}
|
||||
error={errors.repository?.title?.message}
|
||||
invalid={!!errors.repository?.title}
|
||||
required
|
||||
noMargin
|
||||
>
|
||||
<Input
|
||||
id="repository-title"
|
||||
{...register('repository.title', {
|
||||
required: t('provisioning.bootstrap-step.error-field-required', 'This field is required.'),
|
||||
})}
|
||||
placeholder={t(
|
||||
'provisioning.bootstrap-step.placeholder-my-repository-connection',
|
||||
'My repository connection'
|
||||
)}
|
||||
// Autofocus the title field if it's the only available option
|
||||
autoFocus={enabledOptions?.length === 1 && enabledOptions[0]?.target === 'folder'}
|
||||
/>
|
||||
</Field>
|
||||
<Controller
|
||||
name="migrate.migrateExistingResources"
|
||||
control={control}
|
||||
render={({ field: { onChange, value, ...field } }) => (
|
||||
<Field
|
||||
description={t(
|
||||
'provisioning.bootstrap-step.description-migrate-existing-resources',
|
||||
'Migrate all existing resources into the repository and pull everything from there.'
|
||||
)}
|
||||
noMargin
|
||||
>
|
||||
<Checkbox
|
||||
id="migrate-existing-resources"
|
||||
{...field}
|
||||
value={value || false}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange(e.target.checked)}
|
||||
label={t(
|
||||
'provisioning.bootstrap-step.label-migrate-existing-resources',
|
||||
'Migrate all existing resources into this folder'
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
// Autofocus the title field if it's the only available option
|
||||
autoFocus={enabledOptions?.length === 1 && enabledOptions[0]?.target === 'folder'}
|
||||
/>
|
||||
</Field>
|
||||
</>
|
||||
)}
|
||||
|
||||
{disabledOptions?.length > 0 && (
|
||||
|
||||
@@ -114,7 +114,12 @@ export const ProvisioningWizard = memo(function ProvisioningWizard({
|
||||
handleSubmit,
|
||||
} = methods;
|
||||
|
||||
const [repoName = '', repoType, syncTarget] = watch(['repositoryName', 'repository.type', 'repository.sync.target']);
|
||||
const [repoName = '', repoType, syncTarget, migrateExistingResources] = watch([
|
||||
'repositoryName',
|
||||
'repository.type',
|
||||
'repository.sync.target',
|
||||
'migrate.migrateExistingResources',
|
||||
]);
|
||||
const [submitData] = useCreateOrUpdateRepository(repoName);
|
||||
const [deleteRepository] = useDeleteRepositoryMutation();
|
||||
const {
|
||||
@@ -125,6 +130,7 @@ export const ProvisioningWizard = memo(function ProvisioningWizard({
|
||||
const { createSyncJob, isLoading: isCreatingSkipJob } = useCreateSyncJob({
|
||||
repoName: repoName,
|
||||
requiresMigration,
|
||||
migrateExistingResources,
|
||||
setStepStatusInfo,
|
||||
});
|
||||
|
||||
|
||||
@@ -25,11 +25,12 @@ export const SynchronizeStep = memo(function SynchronizeStep({
|
||||
}: SynchronizeStepProps) {
|
||||
const { watch } = useFormContext<WizardFormData>();
|
||||
const { setStepStatusInfo } = useStepStatus();
|
||||
const [repoName = ''] = watch(['repositoryName']);
|
||||
const [repoName = '', migrateExistingResources] = watch(['repositoryName', 'migrate.migrateExistingResources']);
|
||||
const { requiresMigration } = useResourceStats(repoName);
|
||||
const { createSyncJob } = useCreateSyncJob({
|
||||
repoName,
|
||||
requiresMigration,
|
||||
migrateExistingResources,
|
||||
setStepStatusInfo,
|
||||
});
|
||||
const [job, setJob] = useState<Job>();
|
||||
|
||||
@@ -6,12 +6,14 @@ import { StepStatusInfo } from '../types';
|
||||
export interface UseCreateSyncJobParams {
|
||||
repoName: string;
|
||||
requiresMigration: boolean;
|
||||
migrateExistingResources?: boolean;
|
||||
setStepStatusInfo?: (info: StepStatusInfo) => void;
|
||||
}
|
||||
|
||||
export function useCreateSyncJob({
|
||||
repoName,
|
||||
requiresMigration,
|
||||
migrateExistingResources,
|
||||
setStepStatusInfo,
|
||||
}: UseCreateSyncJobParams) {
|
||||
const [createJob, { isLoading }] = useCreateRepositoryJobsMutation();
|
||||
@@ -28,7 +30,8 @@ export function useCreateSyncJob({
|
||||
try {
|
||||
setStepStatusInfo?.({ status: 'running' });
|
||||
|
||||
const jobSpec = requiresMigration
|
||||
const shouldMigrate = requiresMigration || migrateExistingResources === true;
|
||||
const jobSpec = shouldMigrate
|
||||
? {
|
||||
migrate: {},
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export type RepoType = RepositorySpec['type'];
|
||||
export interface MigrateFormData {
|
||||
history: boolean;
|
||||
identifier: boolean;
|
||||
migrateExistingResources?: boolean;
|
||||
}
|
||||
|
||||
export interface WizardFormData {
|
||||
|
||||
@@ -11668,6 +11668,7 @@
|
||||
"dashboards-count_one": "{{count}} dashboard",
|
||||
"dashboards-count_other": "{{count}} dashboard",
|
||||
"description-clear-repository-connection": "Add a clear name for this repository connection",
|
||||
"description-migrate-existing-resources": "Migrate all existing resources into the repository and pull everything from there.",
|
||||
"empty": "Empty",
|
||||
"error-field-required": "This field is required.",
|
||||
"external-storage-label": "External storage",
|
||||
@@ -11676,6 +11677,7 @@
|
||||
"folders-count_one": "{{count}} folder",
|
||||
"folders-count_other": "{{count}} folder",
|
||||
"label-display-name": "Display name",
|
||||
"label-migrate-existing-resources": "Migrate all existing resources into this folder",
|
||||
"placeholder-my-repository-connection": "My repository connection",
|
||||
"text-loading-resource-information": "Loading resource information...",
|
||||
"unavailable-options": {
|
||||
|
||||
Reference in new issue
Block a user