diff --git a/CLAUDE.md b/CLAUDE.md index e109126..f2bec1b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -115,6 +115,11 @@ Normalisierung: `admin-ui/src/components/ReferenceOrInlineField.tsx` via `normal - **Scroll**: `html, body { height: 100%; overflow: hidden }` — Sidebar scrollt unabhängig von der Seite - **Neue Komponente**: immer prüfen ob Übersetzungs-Namespace in beiden Message-Dateien vorhanden +### Asset-/Bild-URL-Felder (generisch halten) +- **Keine Heuristik**: Die Admin-UI soll String-Felder nicht anhand von Feldname oder Beschreibung (z. B. „Image URL“) als Bild-URL interpretieren. Das wäre nicht generisch. +- **Explizites Widget**: Bildvorschau + Asset-Picker nur anzeigen, wenn im Schema für das Feld **explizit** `widget: "imageUrl"` (oder `"assetUrl"`) gesetzt ist. Implementierung: `ContentForm.tsx` – Entscheidung nur über `def.widget === "imageUrl"`, nicht über `isImageUrlField()` mit Name/Description. +- **Typ `img`**: Bleibt generisch (kein Widget auf `src`) → normales Textfeld. Wo gewollt, kann ein eigener Typ oder ein Feld mit `widget: "imageUrl"` die Bild-UI bekommen. + ## Axum Routing Literale Routen haben Vorrang vor Wildcard-Routen — Reihenfolge egal, Axum löst korrekt auf: diff --git a/admin-ui/messages/de.json b/admin-ui/messages/de.json index db860a5..621f930 100644 --- a/admin-ui/messages/de.json +++ b/admin-ui/messages/de.json @@ -245,6 +245,7 @@ "stringWidgetSingleline": "Einzeilig", "stringWidgetTextarea": "Mehrzeilig (Textbereich)", "stringWidgetCode": "Code (Syntax-Hervorhebung)", + "stringWidgetImageUrl": "Bild- / Asset-URL (Vorschau + Picker)", "codeLanguageLabel": "Code-Sprache", "codeLanguageCss": "CSS", "codeLanguageJavascript": "JavaScript", @@ -280,8 +281,18 @@ "tagsLabel": "Tags (kommagetrennt)", "tagsPlaceholder": "z.\u00a0B. inhalt, blog", "strictLabel": "Strikt (unbekannte Felder ablehnen)", + "extendsLabel": "Erweitert", + "extendsDescription": "Dieser Typ erbt Felder von diesen Typen. Gehe zum jeweiligen Typ, um geerbte Felder zu bearbeiten.", + "extendsPlaceholder": "Typ zum Erweitern wählen", + "extendsNoneAvailable": "Keine weiteren Typen zum Hinzufügen", + "addExtend": "Hinzufügen", + "removeExtend": "Aus Erweiterungen entfernen", "fieldsLabel": "Felder", "addField": "Feld hinzuf\u00fcgen", + "moveFieldUp": "Feld nach oben", + "moveFieldDown": "Feld nach unten", + "moveFieldToTop": "Ganz nach oben", + "moveFieldToBottom": "Ganz nach unten", "fieldNamePlaceholder": "Feldname", "fieldTypeLabel": "Feldtyp", "required": "Pflichtfeld", @@ -289,6 +300,10 @@ "collectionPlaceholder": "Sammlung (z.\u00a0B. seite)", "allowedSlugsPlaceholder": "Erlaubte Slugs (kommagetrennt, optional)", "allowedCollectionsPlaceholder": "Erlaubte Inhaltstypen (kommagetrennt, optional)", + "patternLabel": "Pattern (Regex)", + "patternPlaceholder": "z. B. ^[A-Z]{2,4}-\\d{3,6}$", + "minLengthLabel": "Min. Länge", + "maxLengthLabel": "Max. Länge", "arrayItemType": "Array-Elementtyp", "itemTypePlaceholder": "z.\u00a0B. string, reference", "arrayExplain": "Dieses Feld ist in JSON eine Liste [ ]. Jeder Eintrag hat denselben Typ—w\u00e4hle unten, was ein Element ist.", @@ -308,6 +323,7 @@ "stringWidgetSingleline": "Einzeilig", "stringWidgetTextarea": "Mehrzeilig (Textbereich)", "stringWidgetCode": "Code (Syntax-Hervorhebung)", + "stringWidgetImageUrl": "Bild- / Asset-URL (Vorschau + Picker)", "codeLanguageLabel": "Code-Sprache", "codeLanguageCss": "CSS", "codeLanguageJavascript": "JavaScript", @@ -379,6 +395,8 @@ "searchPlaceholder": "Nach Dateiname suchen…", "dateFrom": "Von Datum", "dateTo": "Bis Datum", + "mimeFilter": "Typ", + "mimeFilterAll": "Alle Typen", "upload": "Hochladen", "uploading": "Wird hochgeladen…", "uploadedCount": "{count} Datei(en) hochgeladen.", diff --git a/admin-ui/messages/en.json b/admin-ui/messages/en.json index 92cfe27..c897232 100644 --- a/admin-ui/messages/en.json +++ b/admin-ui/messages/en.json @@ -245,6 +245,7 @@ "stringWidgetSingleline": "Single line", "stringWidgetTextarea": "Multi-line (textarea)", "stringWidgetCode": "Code (syntax highlighting)", + "stringWidgetImageUrl": "Image / asset URL (preview + picker)", "codeLanguageLabel": "Code language", "codeLanguageCss": "CSS", "codeLanguageJavascript": "JavaScript", @@ -280,8 +281,18 @@ "tagsLabel": "Tags (comma-separated)", "tagsPlaceholder": "e.g. content, blog", "strictLabel": "Strict (reject unknown fields)", + "extendsLabel": "Extends", + "extendsDescription": "This type inherits fields from these types. Edit the type there to change inherited fields.", + "extendsPlaceholder": "Select type to extend", + "extendsNoneAvailable": "No other types to add", + "addExtend": "Add", + "removeExtend": "Remove from extends", "fieldsLabel": "Fields", "addField": "Add field", + "moveFieldUp": "Move field up", + "moveFieldDown": "Move field down", + "moveFieldToTop": "Move to top", + "moveFieldToBottom": "Move to bottom", "fieldNamePlaceholder": "Field name", "fieldTypeLabel": "Field type", "required": "Required", @@ -289,6 +300,10 @@ "collectionPlaceholder": "Collection (e.g. page)", "allowedSlugsPlaceholder": "Allowed slugs (comma-separated, optional)", "allowedCollectionsPlaceholder": "Allowed content types (comma-separated, optional)", + "patternLabel": "Pattern (regex)", + "patternPlaceholder": "e.g. ^[A-Z]{2,4}-\\d{3,6}$", + "minLengthLabel": "Min length", + "maxLengthLabel": "Max length", "arrayItemType": "Array item type", "itemTypePlaceholder": "e.g. string, reference", "arrayExplain": "This field is a list [ ] in JSON. Every position in the list has the same type—pick what one entry is below.", @@ -308,6 +323,7 @@ "stringWidgetSingleline": "Single line", "stringWidgetTextarea": "Multi-line (textarea)", "stringWidgetCode": "Code (syntax highlighting)", + "stringWidgetImageUrl": "Image / asset URL (preview + picker)", "codeLanguageLabel": "Code language", "codeLanguageCss": "CSS", "codeLanguageJavascript": "JavaScript", @@ -379,6 +395,8 @@ "searchPlaceholder": "Search by filename…", "dateFrom": "From date", "dateTo": "To date", + "mimeFilter": "Type", + "mimeFilterAll": "All types", "upload": "Upload", "uploading": "Uploading…", "uploadedCount": "Uploaded {count} file(s).", diff --git a/admin-ui/src/app/admin/new-type/page.tsx b/admin-ui/src/app/admin/new-type/page.tsx index 08952db..3a65654 100644 --- a/admin-ui/src/app/admin/new-type/page.tsx +++ b/admin-ui/src/app/admin/new-type/page.tsx @@ -184,7 +184,7 @@ export default function NewTypePage() { }; return ( -
{t("description", { path: "types/ {t("missingName")} {t("loading")} {t("loading")} {t("errorLoading", { error: String(fetchError) })} {t("description")} {t("extendsDescription")}{t("title", { name })}
+ {extendsList.map((typeName) => (
+
+ )}
+ {t("title")}