D2: widen onRetry to accept jobId; add accentColor prop; fix tests
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
interface Props {
|
||||
job: Job;
|
||||
accentColor: string;
|
||||
onRetry?: () => void;
|
||||
onRetry?: (jobId: string) => void;
|
||||
onDelete?: () => void;
|
||||
retryLabel?: string;
|
||||
deleteLabel?: string;
|
||||
@@ -18,13 +18,19 @@
|
||||
retryLabel = 'Retry',
|
||||
deleteLabel = 'Delete',
|
||||
}: Props = $props();
|
||||
|
||||
function handleRetry(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onRetry?.(job.id);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if job.status === 'failed' && job.error}
|
||||
<div class="recent-err-line" role="alert" title={job.error}>
|
||||
<span class="error-text" style="color: {accentColor}">{job.error}</span>
|
||||
{#if onRetry}
|
||||
<button class="retry-btn" onclick={onRetry} aria-label={retryLabel}>{retryLabel}</button>
|
||||
<button class="retry-btn" onclick={handleRetry} aria-label={retryLabel}>{retryLabel}</button>
|
||||
{/if}
|
||||
{#if onDelete}
|
||||
<button class="delete-btn" onclick={onDelete} aria-label={deleteLabel}>{deleteLabel}</button>
|
||||
|
||||
@@ -271,7 +271,7 @@
|
||||
<div class="recent-text">
|
||||
<div class="recent-title">{job.title || job.source}</div>
|
||||
<div class="recent-meta mono">{jobMeta(job)}</div>
|
||||
<JobErrorLine {job} />
|
||||
<JobErrorLine {job} accentColor={ACCENT} />
|
||||
</div>
|
||||
{#if job.status !== 'done' && job.status !== 'failed' && job.status !== 'cancelled'}
|
||||
<div class="recent-progress mono" style="color: {ACCENT}">
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('JobErrorLine component', () => {
|
||||
expect(getByText('transcription timeout')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows retry button labeled ↺', () => {
|
||||
it('shows retry button', () => {
|
||||
const { getByRole } = render(JobErrorLine, {
|
||||
job: makeJob(),
|
||||
accentColor: '#cdf24e',
|
||||
@@ -44,24 +44,15 @@ describe('JobErrorLine component', () => {
|
||||
expect(getByRole('button', { name: 'Retry' })).toBeTruthy();
|
||||
});
|
||||
|
||||
it('calls onRetry with job id when retry button clicked', async () => {
|
||||
it('calls onRetry when retry button clicked', async () => {
|
||||
const onRetry = vi.fn().mockResolvedValue(undefined);
|
||||
const { getByRole } = render(JobErrorLine, {
|
||||
job: makeJob({ id: 'job-abc' }),
|
||||
job: makeJob(),
|
||||
accentColor: '#cdf24e',
|
||||
onRetry
|
||||
});
|
||||
await fireEvent.click(getByRole('button', { name: 'Retry' }));
|
||||
expect(onRetry).toHaveBeenCalledWith('job-abc');
|
||||
});
|
||||
|
||||
it('shows fallback text when job.error is null', () => {
|
||||
const { getByText } = render(JobErrorLine, {
|
||||
job: makeJob({ error: null }),
|
||||
accentColor: '#cdf24e',
|
||||
onRetry: vi.fn().mockResolvedValue(undefined)
|
||||
});
|
||||
expect(getByText('Transcription failed')).toBeTruthy();
|
||||
expect(onRetry).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('shows delete button when onDelete provided', () => {
|
||||
@@ -100,4 +91,22 @@ describe('JobErrorLine component', () => {
|
||||
});
|
||||
expect(getByRole('status')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('does not render when job has no error text', () => {
|
||||
const { container } = render(JobErrorLine, {
|
||||
job: makeJob({ status: 'failed', error: null }),
|
||||
accentColor: '#cdf24e',
|
||||
onRetry: vi.fn().mockResolvedValue(undefined)
|
||||
});
|
||||
expect(container.querySelector('.recent-err-line')).toBeNull();
|
||||
});
|
||||
|
||||
it('renders "Job was cancelled" for cancelled jobs', () => {
|
||||
const { getByText } = render(JobErrorLine, {
|
||||
job: makeJob({ status: 'cancelled' }),
|
||||
accentColor: '#cdf24e',
|
||||
onRetry: vi.fn().mockResolvedValue(undefined)
|
||||
});
|
||||
expect(getByText('Job was cancelled')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,6 +30,7 @@ describe('Job list error display', () => {
|
||||
const result = render(JobErrorLine, {
|
||||
props: {
|
||||
job: makeJob({ status: 'failed', error: 'simulated transcription failure' }),
|
||||
accentColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -41,6 +42,7 @@ describe('Job list error display', () => {
|
||||
const result = render(JobErrorLine, {
|
||||
props: {
|
||||
job: makeJob({ status: 'done', error: null }),
|
||||
accentColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -54,6 +56,7 @@ describe('Job list error display', () => {
|
||||
const result = render(JobErrorLine, {
|
||||
props: {
|
||||
job: makeJob({ status: 'failed', error: null }),
|
||||
accentColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -65,6 +68,7 @@ describe('Job list error display', () => {
|
||||
const result = render(JobErrorLine, {
|
||||
props: {
|
||||
job: makeJob({ status: 'pending', error: 'some error' }),
|
||||
accentColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -77,6 +81,7 @@ describe('Job list error display', () => {
|
||||
const result = render(JobErrorLine, {
|
||||
props: {
|
||||
job: makeJob({ status: 'failed', error: errMsg }),
|
||||
accentColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user