feat(ui): show read-only transcription header without an edit tab (#697)

TranscriptionPanelHeader gains a canEdit prop (default true). Editors keep
the Lesen/Bearbeiten segmented toggle; read-only users get a plain
"Transkription" heading instead of a lone single-option pill, while the
"N Abschnitte" status line stays visible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-31 12:19:36 +02:00
committed by marcel
parent f4f853be8b
commit 4bbdd33344
2 changed files with 65 additions and 31 deletions

View File

@@ -8,11 +8,20 @@ type Props = {
hasBlocks: boolean;
blockCount: number;
lastEditedAt: string | null;
canEdit?: boolean;
onModeChange: (mode: 'read' | 'edit') => void;
onClose: () => void;
};
let { mode, hasBlocks, blockCount, lastEditedAt, onModeChange, onClose }: Props = $props();
let {
mode,
hasBlocks,
blockCount,
lastEditedAt,
canEdit = true,
onModeChange,
onClose
}: Props = $props();
const formattedDate = $derived(
lastEditedAt
@@ -34,7 +43,8 @@ function handleReadClick() {
<div
class="flex h-[44px] items-center justify-between border-b border-line bg-surface px-3 font-sans"
>
<!-- Segmented toggle + help chip -->
<!-- Segmented toggle + help chip for editors; plain title for read-only users -->
{#if canEdit}
<div class="flex items-center gap-1.5">
<div class="flex h-9 items-center rounded-full border border-line bg-muted p-0.5 md:h-7">
<button
@@ -65,6 +75,9 @@ function handleReadClick() {
<p class="text-xs leading-relaxed">{m.transcription_mode_help_body()}</p>
</HelpPopover>
</div>
{:else}
<h2 class="text-[16px] font-semibold text-ink">{m.transcription_panel_title()}</h2>
{/if}
<!-- Status line (hidden on mobile to save space) -->
<p class="hidden text-xs text-ink-2 md:block">

View File

@@ -22,6 +22,27 @@ describe('TranscriptionPanelHeader', () => {
await expect.element(page.getByRole('button', { name: /bearbeiten/i })).toBeVisible();
});
it('renders both tabs when canEdit is true', async () => {
render(TranscriptionPanelHeader, { ...baseProps, canEdit: true });
await expect.element(page.getByTestId('mode-read')).toBeInTheDocument();
await expect.element(page.getByTestId('mode-edit')).toBeInTheDocument();
});
it('hides the edit tab and shows a plain title when canEdit is false', async () => {
render(TranscriptionPanelHeader, { ...baseProps, canEdit: false });
await expect.element(page.getByTestId('mode-edit')).not.toBeInTheDocument();
await expect.element(page.getByTestId('mode-read')).not.toBeInTheDocument();
await expect.element(page.getByRole('heading', { name: /^transkription$/i })).toBeVisible();
});
it('keeps the section status line visible for readers (canEdit false)', async () => {
render(TranscriptionPanelHeader, { ...baseProps, canEdit: false, blockCount: 3 });
await expect.element(page.getByText('3 Abschnitte')).toBeVisible();
});
it('marks the Lesen button as aria-disabled when hasBlocks is false', async () => {
render(TranscriptionPanelHeader, {
...baseProps,