Web: eigene Felder nachträglich bearbeiten
Backend und API-Client konnten Felddefinitionen laengst aendern (PATCH), nur die Oberflaeche bot bisher nur Anlegen und Loeschen. In der Felder-Verwaltung einer Kategorie gibt es jetzt je Feld einen Bearbeiten-Knopf: er laedt Name, Typ, Einheit, Auswahlmoeglichkeiten und Pflicht ins Formular; Speichern aktualisiert das Feld (oder Abbrechen). Geerbte und eingebaute Felder bleiben unveraendert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -287,6 +287,7 @@ function CategoryFields({ category, isAdmin, onClose }) {
|
||||
const confirm = useConfirm();
|
||||
const [fields, setFields] = useState([]);
|
||||
const [form, setForm] = useState(EMPTY_FIELD);
|
||||
const [editId, setEditId] = useState(null); // null = neues Feld, sonst bearbeiten
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
async function load() {
|
||||
@@ -298,12 +299,29 @@ function CategoryFields({ category, isAdmin, onClose }) {
|
||||
}
|
||||
useEffect(() => { load(); }, [category.id]);
|
||||
|
||||
async function add(e) {
|
||||
// Ein bestehendes Feld in das Formular laden (mehrfach getrennte Optionen
|
||||
// wieder als Komma-Liste).
|
||||
function startEdit(f) {
|
||||
setEditId(f.id);
|
||||
setForm({
|
||||
label: f.label,
|
||||
field_type: f.field_type,
|
||||
unit: f.unit || "",
|
||||
options: (f.options || []).join(", "),
|
||||
required: f.required,
|
||||
});
|
||||
setError(null);
|
||||
}
|
||||
|
||||
function cancelEdit() {
|
||||
setEditId(null);
|
||||
setForm(EMPTY_FIELD);
|
||||
}
|
||||
|
||||
async function submit(e) {
|
||||
e.preventDefault();
|
||||
setError(null);
|
||||
try {
|
||||
await api.createFieldDefinition({
|
||||
category_id: category.id,
|
||||
const body = {
|
||||
label: form.label,
|
||||
field_type: form.field_type,
|
||||
unit: form.field_type === "number" ? (form.unit || null) : null,
|
||||
@@ -311,8 +329,15 @@ function CategoryFields({ category, isAdmin, onClose }) {
|
||||
? form.options.split(",").map((o) => o.trim()).filter(Boolean)
|
||||
: null,
|
||||
required: form.required,
|
||||
});
|
||||
};
|
||||
try {
|
||||
if (editId) {
|
||||
await api.updateFieldDefinition(editId, body);
|
||||
} else {
|
||||
await api.createFieldDefinition({ category_id: category.id, ...body });
|
||||
}
|
||||
setForm(EMPTY_FIELD);
|
||||
setEditId(null);
|
||||
load();
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
@@ -351,7 +376,7 @@ function CategoryFields({ category, isAdmin, onClose }) {
|
||||
) : (
|
||||
<ul className="clean-list">
|
||||
{fields.map((f) => (
|
||||
<li key={f.id} className="cell-row">
|
||||
<li key={f.id} className={`cell-row ${editId === f.id ? "row-active" : ""}`}>
|
||||
<span className="strong">{f.label}</span>
|
||||
<span className="badge nowrap">{fieldTypeLabel(f.field_type)}</span>
|
||||
{f.field_type === "number" && f.unit && <span className="muted small">{f.unit}</span>}
|
||||
@@ -360,10 +385,16 @@ function CategoryFields({ category, isAdmin, onClose }) {
|
||||
<span className="badge nowrap" title="stammt aus einer Oberkategorie">geerbt</span>
|
||||
) : (
|
||||
isAdmin && (
|
||||
<button className="btn-icon danger" style={{ marginLeft: "auto" }}
|
||||
title="Feld löschen" onClick={() => remove(f)}>
|
||||
<span style={{ marginLeft: "auto", display: "flex", gap: 4 }}>
|
||||
{!f.is_builtin && (
|
||||
<button className="btn-icon" title="Feld bearbeiten" onClick={() => startEdit(f)}>
|
||||
<Icon name="edit" size={15} />
|
||||
</button>
|
||||
)}
|
||||
<button className="btn-icon danger" title="Feld löschen" onClick={() => remove(f)}>
|
||||
<Icon name="trash" size={15} />
|
||||
</button>
|
||||
</span>
|
||||
)
|
||||
)}
|
||||
</li>
|
||||
@@ -372,7 +403,12 @@ function CategoryFields({ category, isAdmin, onClose }) {
|
||||
)}
|
||||
|
||||
{isAdmin && (
|
||||
<form onSubmit={add} className="stack" style={{ marginTop: "var(--sp-3)" }}>
|
||||
<form onSubmit={submit} className="stack" style={{ marginTop: "var(--sp-3)" }}>
|
||||
{editId && (
|
||||
<div className="muted small" style={{ display: "flex", alignItems: "center", gap: 6 }}>
|
||||
<Icon name="edit" size={14} />Feld bearbeiten
|
||||
</div>
|
||||
)}
|
||||
<label>
|
||||
Feldname
|
||||
<input value={form.label} placeholder="z.B. Kapazität"
|
||||
@@ -406,7 +442,15 @@ function CategoryFields({ category, isAdmin, onClose }) {
|
||||
onChange={(e) => setForm({ ...form, required: e.target.checked })} />
|
||||
<span>Pflichtfeld</span>
|
||||
</label>
|
||||
<button className="btn primary"><Icon name="plus" size={16} />Feld hinzufügen</button>
|
||||
<div className="field-inline">
|
||||
<button className="btn primary">
|
||||
<Icon name={editId ? "check" : "plus"} size={16} />
|
||||
{editId ? "Änderungen speichern" : "Feld hinzufügen"}
|
||||
</button>
|
||||
{editId && (
|
||||
<button type="button" className="btn ghost" onClick={cancelEdit}>Abbrechen</button>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user