Provisioning: Consolidate status display (#108589)
* Provisioning: Centralize wizard errors * Move alert to shared * Update pull status * betterer * Update warning * Fix i18n * Format * Format[2] * Extract MessageList * Add fallback status
This commit is contained in:
@@ -2653,18 +2653,6 @@ exports[`better eslint`] = {
|
||||
"public/app/features/provisioning/GettingStarted/SidebarItem.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Job/RecentJobs.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Repository/RepositoryCard.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Repository/RepositoryOverview.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "2"],
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "3"]
|
||||
],
|
||||
"public/app/features/query/components/QueryEditorRow.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Alert, Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { useGetRepositoryJobsWithPathQuery } from 'app/api/clients/provisioning/v0alpha1';
|
||||
|
||||
import { useStepStatus } from '../Wizard/StepStatusContext';
|
||||
@@ -36,15 +36,26 @@ export function FinishedJobStatus({ jobUid, repositoryName }: FinishedJobProps)
|
||||
}
|
||||
|
||||
if (finishedQuery.isSuccess && job?.status) {
|
||||
if (job.status.state === 'error') {
|
||||
const { state, message, errors } = job.status;
|
||||
|
||||
if (state === 'error') {
|
||||
setStepStatusInfo({
|
||||
status: 'error',
|
||||
error: {
|
||||
title: t('provisioning.job-status.status.title-error-running-job', 'Error running job'),
|
||||
message: errors?.length ? errors : message,
|
||||
},
|
||||
});
|
||||
} else if (job.status.state === 'success') {
|
||||
setStepStatusInfo({ status: 'success' });
|
||||
} else if (job.status.state === 'warning') {
|
||||
// We treat warnings as success for now, but this could be changed later
|
||||
} else if (state === 'success') {
|
||||
setStepStatusInfo({ status: 'success' });
|
||||
} else if (state === 'warning') {
|
||||
setStepStatusInfo({
|
||||
status: 'warning',
|
||||
warning: {
|
||||
title: t('provisioning.job-status.status.title-warning-running-job', 'Job completed with warnings'),
|
||||
message: errors?.length ? errors : message,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,14 +67,17 @@ export function FinishedJobStatus({ jobUid, repositoryName }: FinishedJobProps)
|
||||
}, [finishedQuery, job, setStepStatusInfo]);
|
||||
|
||||
if (retryFailed) {
|
||||
setStepStatusInfo({ status: 'error' });
|
||||
return (
|
||||
<Alert severity="error" title={t('provisioning.job-status.no-job-found', 'No job found')}>
|
||||
<Trans i18nKey="provisioning.job-status.no-job-found-message">
|
||||
The job may have been deleted or could not be retrieved. Cancel the current process and start again.
|
||||
</Trans>
|
||||
</Alert>
|
||||
);
|
||||
setStepStatusInfo({
|
||||
status: 'error',
|
||||
error: {
|
||||
title: t('provisioning.job-status.no-job-found', 'No job found'),
|
||||
message: t(
|
||||
'provisioning.job-status.no-job-found-message',
|
||||
'The job may have been deleted or could not be retrieved. Cancel the current process and start again.'
|
||||
),
|
||||
},
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!job || finishedQuery.isLoading || finishedQuery.isFetching) {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Alert, ControlledCollapse, Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { ControlledCollapse, Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { Job } from 'app/api/clients/provisioning/v0alpha1';
|
||||
|
||||
import { RepositoryLink } from '../Repository/RepositoryLink';
|
||||
import ProgressBar from '../Shared/ProgressBar';
|
||||
import { useStepStatus } from '../Wizard/StepStatusContext';
|
||||
|
||||
import { JobSummary } from './JobSummary';
|
||||
|
||||
@@ -13,6 +16,9 @@ export interface JobContentProps {
|
||||
}
|
||||
|
||||
export function JobContent({ job, isFinishedJob = false }: JobContentProps) {
|
||||
const { setStepStatusInfo } = useStepStatus();
|
||||
const errorSetRef = useRef(false);
|
||||
|
||||
if (!job?.status) {
|
||||
return null;
|
||||
}
|
||||
@@ -20,48 +26,60 @@ export function JobContent({ job, isFinishedJob = false }: JobContentProps) {
|
||||
const { state, message, progress, summary, errors } = job.status;
|
||||
const repoName = job.metadata?.labels?.['provisioning.grafana.app/repository'];
|
||||
|
||||
const getStatusDisplay = () => {
|
||||
// Update step status based on job state
|
||||
useEffect(() => {
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 'success':
|
||||
return (
|
||||
<Alert
|
||||
severity="success"
|
||||
title={t('provisioning.job-status.status.title-job-completed-successfully', 'Job completed successfully')}
|
||||
/>
|
||||
);
|
||||
setStepStatusInfo({ status: 'success' });
|
||||
break;
|
||||
case 'warning':
|
||||
return (
|
||||
<Alert
|
||||
severity="warning"
|
||||
title={t('provisioning.job-status.status.title-warning-running-job', 'Job completed with warnings')}
|
||||
>
|
||||
{errors?.length ? errors?.join('\n') : message}
|
||||
</Alert>
|
||||
);
|
||||
if (!errorSetRef.current) {
|
||||
setStepStatusInfo({
|
||||
status: 'warning',
|
||||
warning: {
|
||||
title: t('provisioning.job-status.status.title-warning-running-job', 'Job completed with warnings'),
|
||||
message: errors?.length ? errors : message,
|
||||
},
|
||||
});
|
||||
errorSetRef.current = true;
|
||||
}
|
||||
break;
|
||||
case 'error':
|
||||
return (
|
||||
<Alert
|
||||
severity="error"
|
||||
title={t('provisioning.job-status.status.title-error-running-job', 'Error running job')}
|
||||
>
|
||||
{errors?.length ? errors?.join('\n') : message}
|
||||
</Alert>
|
||||
);
|
||||
if (!errorSetRef.current) {
|
||||
setStepStatusInfo({
|
||||
status: 'error',
|
||||
error: {
|
||||
title: t('provisioning.job-status.status.title-error-running-job', 'Error running job'),
|
||||
message: errors?.length ? errors : message,
|
||||
},
|
||||
});
|
||||
errorSetRef.current = true;
|
||||
}
|
||||
break;
|
||||
case 'working':
|
||||
case 'pending':
|
||||
setStepStatusInfo({ status: 'running' });
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (
|
||||
<Stack direction="row" alignItems="center" justifyContent="center" gap={2}>
|
||||
{['working', 'pending'].includes(state ?? '') && <Spinner size={24} />}
|
||||
<Text element="h4" color="secondary">
|
||||
{message ?? state ?? ''}
|
||||
</Text>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
}, [state, message, errors, setStepStatusInfo]);
|
||||
|
||||
return (
|
||||
<Stack direction="column" gap={2}>
|
||||
<Stack direction="column" gap={2}>
|
||||
{getStatusDisplay()}
|
||||
{['working', 'pending'].includes(state ?? '') && (
|
||||
<Stack direction="row" alignItems="center" justifyContent="center" gap={2}>
|
||||
<Spinner size={24} />
|
||||
<Text element="h4" color="secondary">
|
||||
{message ?? state ?? t('provisioning.job-status.starting', 'Starting...')}
|
||||
</Text>
|
||||
</Stack>
|
||||
)}
|
||||
{state && !['success', 'error'].includes(state) && (
|
||||
<Stack direction="row" alignItems="center" justifyContent="center" gap={2}>
|
||||
<ProgressBar progress={progress ?? 0} />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { Job, useListJobQuery } from 'app/api/clients/provisioning/v0alpha1';
|
||||
|
||||
@@ -36,7 +36,12 @@ export function JobStatus({ watch }: JobStatusProps) {
|
||||
}
|
||||
|
||||
if (activeQuery.isError) {
|
||||
setStepStatusInfo({ status: 'error', error: 'Error fetching active job' });
|
||||
setStepStatusInfo({
|
||||
status: 'error',
|
||||
error: {
|
||||
title: t('provisioning.job-status.title.error-fetching-active-job', 'Error fetching active job'),
|
||||
},
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@ import { useMemo } from 'react';
|
||||
|
||||
import { intervalToAbbreviatedDurationString, TraceKeyValuePair } from '@grafana/data';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Alert, Badge, Box, Card, Icon, InteractiveTable, Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { Alert, Badge, Box, Card, InteractiveTable, Spinner, Stack, Text } from '@grafana/ui';
|
||||
import { Job, Repository, SyncStatus } from 'app/api/clients/provisioning/v0alpha1';
|
||||
import KeyValuesTable from 'app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/KeyValuesTable';
|
||||
|
||||
import { ProvisioningAlert } from '../Shared/ProvisioningAlert';
|
||||
import { useRepositoryAllJobs } from '../hooks/useRepositoryAllJobs';
|
||||
import { formatTimestamp } from '../utils/time';
|
||||
|
||||
@@ -126,21 +127,7 @@ function ExpandedRow({ row }: ExpandedRowProps) {
|
||||
<KeyValuesTable data={data} />
|
||||
</Stack>
|
||||
)}
|
||||
{hasErrors && (
|
||||
<Stack direction="column">
|
||||
{row.status?.errors?.map(
|
||||
(error, index) =>
|
||||
error.trim() && (
|
||||
<Alert key={index} severity="error" title={t('provisioning.expanded-row.title-error', 'Error')}>
|
||||
<Stack alignItems="center" gap={1}>
|
||||
<Icon name="exclamation-circle" size="sm" />
|
||||
{error}
|
||||
</Stack>
|
||||
</Alert>
|
||||
)
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
{hasErrors && <ProvisioningAlert error={{ message: row.status?.errors }} />}
|
||||
{hasSummary && (
|
||||
<Stack direction="column" gap={2}>
|
||||
<Text variant="body" color="secondary">
|
||||
@@ -212,7 +199,7 @@ export function RecentJobs({ repo }: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<Card noMargin>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="provisioning.recent-jobs.jobs">Jobs</Trans>
|
||||
</Card.Heading>
|
||||
|
||||
@@ -58,7 +58,7 @@ export function RepositoryCard({ repository }: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Card key={name}>
|
||||
<Card noMargin key={name}>
|
||||
<Card.Figure>
|
||||
<Icon name={getRepositoryIcon()} size="xxl" />
|
||||
</Card.Figure>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Box, Card, CellProps, Grid, InteractiveTable, LinkButton, Stack, Text,
|
||||
import { Repository, ResourceCount } from 'app/api/clients/provisioning/v0alpha1';
|
||||
|
||||
import { RecentJobs } from '../Job/RecentJobs';
|
||||
import { MessageList } from '../Shared/MessageList';
|
||||
import { formatTimestamp } from '../utils/time';
|
||||
|
||||
import { CheckRepository } from './CheckRepository';
|
||||
@@ -51,7 +52,7 @@ export function RepositoryOverview({ repo }: { repo: Repository }) {
|
||||
<Stack direction="column" gap={2}>
|
||||
<Grid columns={columns} gap={2}>
|
||||
<div className={styles.cardContainer}>
|
||||
<Card className={styles.card}>
|
||||
<Card noMargin className={styles.card}>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="provisioning.repository-overview.resources">Resources</Trans>
|
||||
</Card.Heading>
|
||||
@@ -73,7 +74,7 @@ export function RepositoryOverview({ repo }: { repo: Repository }) {
|
||||
</div>
|
||||
{repo.status?.health && (
|
||||
<div className={styles.cardContainer}>
|
||||
<Card className={styles.card}>
|
||||
<Card noMargin className={styles.card}>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="provisioning.repository-overview.health">Health</Trans>
|
||||
</Card.Heading>
|
||||
@@ -129,7 +130,7 @@ export function RepositoryOverview({ repo }: { repo: Repository }) {
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.cardContainer}>
|
||||
<Card className={styles.card}>
|
||||
<Card className={styles.card} noMargin>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="provisioning.repository-overview.pull-status">Pull status</Trans>
|
||||
</Card.Heading>
|
||||
@@ -192,13 +193,7 @@ export function RepositoryOverview({ repo }: { repo: Repository }) {
|
||||
</Text>
|
||||
</div>
|
||||
<div className={styles.valueColumn}>
|
||||
<Stack gap={1}>
|
||||
{status.sync.message.map((msg, idx) => (
|
||||
<Text key={idx} variant="body">
|
||||
{msg}
|
||||
</Text>
|
||||
))}
|
||||
</Stack>
|
||||
<MessageList messages={status.sync.message} variant="body" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@@ -211,7 +206,7 @@ export function RepositoryOverview({ repo }: { repo: Repository }) {
|
||||
</div>
|
||||
{repo.status?.webhook && (
|
||||
<div className={styles.cardContainer}>
|
||||
<Card className={styles.card}>
|
||||
<Card noMargin className={styles.card}>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="provisioning.repository-overview.webhook">Webhook</Trans>
|
||||
</Card.Heading>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Text, useStyles2 } from '@grafana/ui';
|
||||
|
||||
interface MessageListProps {
|
||||
messages: string[];
|
||||
variant?: 'body' | 'bodySmall';
|
||||
}
|
||||
|
||||
export function MessageList({ messages, variant }: MessageListProps) {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<ul className={styles.messageList}>
|
||||
{messages.map((msg, index) => (
|
||||
<li key={index}>{variant ? <Text variant={variant}>{msg}</Text> : msg}</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
messageList: css({
|
||||
margin: 0,
|
||||
paddingLeft: theme.spacing(3),
|
||||
}),
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import { t } from '@grafana/i18n';
|
||||
import { Alert } from '@grafana/ui';
|
||||
|
||||
import { ProvisioningErrorInfo } from '../types';
|
||||
|
||||
import { MessageList } from './MessageList';
|
||||
|
||||
interface ProvisioningAlertProps {
|
||||
error?: string | ProvisioningErrorInfo;
|
||||
warning?: string | ProvisioningErrorInfo;
|
||||
}
|
||||
|
||||
const getTitle = (alert: string | ProvisioningErrorInfo, isWarning = false) => {
|
||||
if (typeof alert === 'string') {
|
||||
return alert;
|
||||
}
|
||||
|
||||
if (isWarning) {
|
||||
return alert.title || t('provisioning.warning-title-default', 'Warning');
|
||||
} else {
|
||||
return alert.title || t('provisioning.error-title-default', 'Error');
|
||||
}
|
||||
};
|
||||
|
||||
const getMessage = (alert: string | ProvisioningErrorInfo) => {
|
||||
if (typeof alert === 'string' || !alert.message) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Array.isArray(alert.message)) {
|
||||
return <MessageList messages={alert.message} />;
|
||||
}
|
||||
|
||||
return alert.message;
|
||||
};
|
||||
|
||||
export function ProvisioningAlert({ error, warning }: ProvisioningAlertProps) {
|
||||
const alertData = error || warning;
|
||||
const isWarning = Boolean(warning);
|
||||
const severity = isWarning ? 'warning' : 'error';
|
||||
|
||||
if (!alertData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Alert severity={severity} title={getTitle(alertData, isWarning)}>
|
||||
{getMessage(alertData)}
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
@@ -30,7 +30,7 @@ export function RepositoryList({ items }: Props) {
|
||||
<ConnectRepositoryButton items={items} />
|
||||
</Stack>
|
||||
)}
|
||||
<Stack direction={'column'}>
|
||||
<Stack direction={'column'} gap={2}>
|
||||
{filteredItems.length ? (
|
||||
filteredItems.map((item) => <RepositoryCard key={item.metadata?.name} repository={item} />)
|
||||
) : (
|
||||
|
||||
@@ -6,11 +6,12 @@ import { useNavigate } from 'react-router-dom-v5-compat';
|
||||
import { AppEvents, GrafanaTheme2 } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { getAppEvents, isFetchError } from '@grafana/runtime';
|
||||
import { Alert, Box, Button, Stack, Text, useStyles2 } from '@grafana/ui';
|
||||
import { Box, Button, Stack, Text, useStyles2 } from '@grafana/ui';
|
||||
import { useDeleteRepositoryMutation, useGetFrontendSettingsQuery } from 'app/api/clients/provisioning/v0alpha1';
|
||||
import { FormPrompt } from 'app/core/components/FormPrompt/FormPrompt';
|
||||
|
||||
import { getDefaultValues } from '../Config/defaults';
|
||||
import { ProvisioningAlert } from '../Shared/ProvisioningAlert';
|
||||
import { PROVISIONING_URL } from '../constants';
|
||||
import { useCreateOrUpdateRepository } from '../hooks/useCreateOrUpdateRepository';
|
||||
import { dataToSpec } from '../utils/data';
|
||||
@@ -64,7 +65,8 @@ export function ProvisioningWizard({ type }: { type: RepoType }) {
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [isCancelling, setIsCancelling] = useState(false);
|
||||
|
||||
const { stepStatusInfo, setStepStatusInfo, isStepSuccess, isStepRunning, hasStepError } = useStepStatus();
|
||||
const { stepStatusInfo, setStepStatusInfo, isStepSuccess, isStepRunning, hasStepError, hasStepWarning } =
|
||||
useStepStatus();
|
||||
|
||||
const { data } = useGetFrontendSettingsQuery();
|
||||
const isLegacyStorage = Boolean(data?.legacyStorage);
|
||||
@@ -250,8 +252,8 @@ export function ProvisioningWizard({ type }: { type: RepoType }) {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
} else {
|
||||
// only proceed if the job was successful
|
||||
if (isStepSuccess) {
|
||||
// proceed if the job was successful or had warnings
|
||||
if (isStepSuccess || hasStepWarning) {
|
||||
handleNext();
|
||||
}
|
||||
}
|
||||
@@ -262,9 +264,9 @@ export function ProvisioningWizard({ type }: { type: RepoType }) {
|
||||
if (activeStep !== 'connection' && hasStepError) {
|
||||
return true;
|
||||
}
|
||||
// Synchronize step requires success to proceed
|
||||
// Synchronize step requires success or warning to proceed
|
||||
if (activeStep === 'synchronize') {
|
||||
return !isStepSuccess; // Disable next button if the step is not successful
|
||||
return !(isStepSuccess || hasStepWarning); // Disable next button if the step is not successful or has warnings
|
||||
}
|
||||
return isSubmitting || isCancelling || isStepRunning || isCreatingSkipJob;
|
||||
};
|
||||
@@ -283,9 +285,8 @@ export function ProvisioningWizard({ type }: { type: RepoType }) {
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
{hasStepError && 'error' in stepStatusInfo && stepStatusInfo.error && (
|
||||
<Alert severity="error" title={stepStatusInfo.error} />
|
||||
)}
|
||||
{hasStepError && 'error' in stepStatusInfo && <ProvisioningAlert error={stepStatusInfo.error} />}
|
||||
{hasStepWarning && 'warning' in stepStatusInfo && <ProvisioningAlert warning={stepStatusInfo.warning} />}
|
||||
|
||||
<div className={styles.content}>
|
||||
{activeStep === 'connection' && <ConnectStep />}
|
||||
|
||||
@@ -11,6 +11,7 @@ interface StepStatusContextData {
|
||||
|
||||
// Computed status checks
|
||||
hasStepError: boolean;
|
||||
hasStepWarning: boolean;
|
||||
isStepRunning: boolean;
|
||||
isStepSuccess: boolean;
|
||||
isStepIdle: boolean;
|
||||
@@ -29,6 +30,7 @@ export const StepStatusProvider = ({ children }: PropsWithChildren) => {
|
||||
stepStatusInfo,
|
||||
setStepStatusInfo,
|
||||
hasStepError: stepStatusInfo.status === 'error',
|
||||
hasStepWarning: stepStatusInfo.status === 'warning',
|
||||
isStepRunning: stepStatusInfo.status === 'running',
|
||||
isStepSuccess: stepStatusInfo.status === 'success',
|
||||
isStepIdle: stepStatusInfo.status === 'idle',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RepositorySpec, SyncOptions } from 'app/api/clients/provisioning/v0alpha1';
|
||||
|
||||
import { RepositoryFormData } from '../types';
|
||||
import { ProvisioningErrorInfo, RepositoryFormData } from '../types';
|
||||
|
||||
export type WizardStep = 'connection' | 'bootstrap' | 'finish' | 'synchronize';
|
||||
|
||||
@@ -26,5 +26,7 @@ export interface ModeOption {
|
||||
subtitle: string;
|
||||
}
|
||||
|
||||
export type StepStatus = 'idle' | 'running' | 'error' | 'success';
|
||||
export type StepStatusInfo = { status: StepStatus } | { status: 'error'; error: string };
|
||||
export type StepStatusInfo =
|
||||
| { status: 'idle' | 'running' | 'success' }
|
||||
| { status: 'error'; error: string | ProvisioningErrorInfo }
|
||||
| { status: 'warning'; warning: string | ProvisioningErrorInfo };
|
||||
|
||||
@@ -89,3 +89,8 @@ export type HistoryListResponse = {
|
||||
metadata?: Record<string, unknown>;
|
||||
items?: HistoryItem[];
|
||||
};
|
||||
|
||||
export interface ProvisioningErrorInfo {
|
||||
title?: string;
|
||||
message?: string | string[];
|
||||
}
|
||||
|
||||
@@ -11070,10 +11070,10 @@
|
||||
"title-instant-updates-requests-webhooks": "Instant updates and pull requests with webhooks.",
|
||||
"title-visual-previews-in-pull-requests": "Visual previews in pull requests with image rendering"
|
||||
},
|
||||
"error-title-default": "Error",
|
||||
"expanded-row": {
|
||||
"job-specification": "Job Specification",
|
||||
"summary": "Summary",
|
||||
"title-error": "Error"
|
||||
"summary": "Summary"
|
||||
},
|
||||
"features-list": {
|
||||
"actions": {
|
||||
@@ -11218,10 +11218,12 @@
|
||||
"starting": "Starting...",
|
||||
"status": {
|
||||
"title-error-running-job": "Error running job",
|
||||
"title-job-completed-successfully": "Job completed successfully",
|
||||
"title-warning-running-job": "Job completed with warnings"
|
||||
},
|
||||
"summary": "Summary"
|
||||
"summary": "Summary",
|
||||
"title": {
|
||||
"error-fetching-active-job": "Error fetching active job"
|
||||
}
|
||||
},
|
||||
"local": {
|
||||
"path-description": "Local file system path to the repository",
|
||||
@@ -11387,6 +11389,7 @@
|
||||
"go-to": "Go to",
|
||||
"make-sure": "Make sure to include these permissions"
|
||||
},
|
||||
"warning-title-default": "Warning",
|
||||
"wizard": {
|
||||
"alert-point-1": "Resources won't be able to be created, edited, or deleted during this process. In the last step, they will disappear.",
|
||||
"alert-point-2": "Once provisioning is complete, resources will reappear and be managed through external storage.",
|
||||
|
||||
Reference in New Issue
Block a user