Keep the landing editor off the .legal-editor class
All checks were successful
CD / Deploy to Test (push) Successful in 10s
CD / Build and push images (push) Successful in 1m10s
CD / Smoke tests against Test (push) Successful in 1m10s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m10s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m37s
CI / Import/export fidelity gate (push) Successful in 48s
Release / Build release images and notes (push) Successful in 1m6s
Release / Release-candidate operations QA (push) Successful in 41s
Prod deploy / Deploy the released images to Prod (push) Successful in 15s

The landing form reused LegalTextField, whose .legal-editor wrapper the
legal e2e selects by index (nth(1) = privacy policy). Placed before the
legal form it shifted those indices, so the test drove the imprint field
and the published privacy text never appeared. Generalize the component
to MarkdownTextField with a wrapperClass prop: legal keeps .legal-editor,
the landing editor uses .markdown-field. Verified locally: legal,
admin-users, admin-quotas packs green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
This commit is contained in:
Claude Fable 5 2026-07-13 00:14:03 +02:00
parent abf49c7c0e
commit 04abda5724
2 changed files with 25 additions and 10 deletions

View File

@ -274,7 +274,12 @@ function LandingSettingsForm({ settings }: { settings: InstanceSettings }): Reac
<form onSubmit={(event) => void onSubmit(event)} noValidate>
<FormError error={error} />
<FormSuccess message={saved ? t('landing.saved') : null} />
<LegalTextField label={t('landing.label')} value={content} onChange={setContent} />
<MarkdownTextField
wrapperClass="markdown-field"
label={t('landing.label')}
value={content}
onChange={setContent}
/>
<button type="submit" className="button" disabled={busy}>
{t('landing.save')}
</button>
@ -325,8 +330,8 @@ function LegalSettingsForm({ settings }: { settings: InstanceSettings }): React.
<form onSubmit={(event) => void onSubmit(event)} noValidate>
<FormError error={error} />
<FormSuccess message={saved ? t('admin.save') : null} />
<LegalTextField label={t('admin.imprint')} value={imprint} onChange={setImprint} />
<LegalTextField label={t('admin.privacyPolicy')} value={privacy} onChange={setPrivacy} />
<MarkdownTextField label={t('admin.imprint')} value={imprint} onChange={setImprint} />
<MarkdownTextField label={t('admin.privacyPolicy')} value={privacy} onChange={setPrivacy} />
<button type="submit" className="button" disabled={busy}>
{t('admin.save')}
</button>
@ -335,20 +340,27 @@ function LegalSettingsForm({ settings }: { settings: InstanceSettings }): React.
);
}
/** One Markdown textarea with a toggleable rendered preview. */
function LegalTextField({
/**
* One Markdown textarea with a toggleable rendered preview. `wrapperClass`
* distinguishes instances on the page: the legal editors keep `legal-editor`
* (the legal e2e selects them by that class and index), the landing editor
* gets its own so it does not shift those indices.
*/
function MarkdownTextField({
label,
value,
onChange,
wrapperClass = 'legal-editor',
}: {
label: string;
value: string;
onChange: (value: string) => void;
wrapperClass?: string;
}): React.JSX.Element {
const { t } = useTranslation('legal');
const [preview, setPreview] = useState(false);
return (
<div className="legal-editor">
<div className={wrapperClass}>
<Field label={label}>
<textarea
rows={10}
@ -363,7 +375,7 @@ function LegalTextField({
{preview && (
// Same sanitizing pipeline as the api's public rendering — safe.
<div
className="legal-editor__preview legal-page__body"
className={`${wrapperClass}__preview legal-page__body`}
dangerouslySetInnerHTML={{ __html: docToHtml(markdownToDoc(value)) }}
/>
)}

View File

@ -530,17 +530,20 @@ button {
color: var(--color-text-muted);
}
.legal-editor {
.legal-editor,
.markdown-field {
margin-bottom: var(--space-4);
}
.legal-editor textarea {
.legal-editor textarea,
.markdown-field textarea {
width: 100%;
font-family: var(--font-mono);
font-size: 0.9rem;
}
.legal-editor__preview {
.legal-editor__preview,
.markdown-field__preview {
margin-top: var(--space-3);
padding: var(--space-3);
border: 1px dashed var(--color-border);