Kairo-Jinkendo/frontend/src/components/FieldRenderer.jsx
Lars dbe6f4f684
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 2m13s
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 12s
AP1.10c: Profil-Modal mit Archetyp, EFS und Owner.
InitiativeForm laedt Felder nach gewaehltem Archetyp; Plan-Profil zeigt Standardfelder und Zusatzfelder; actor_ref und Owner-Auswahl.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 07:48:00 +02:00

130 lines
3.2 KiB
JavaScript

export function FieldRenderer({ definitions, values, onChange, disabled = false, actors = [] }) {
if (!definitions?.length) {
return null
}
return (
<fieldset className="field-renderer">
<legend className="field-renderer__legend">Zusatzfelder (Archetyp)</legend>
{definitions.map((def) => (
<DynamicField
key={def.field_key}
definition={def}
value={values?.[def.field_key]}
onChange={(next) => onChange(def.field_key, next)}
disabled={disabled}
actors={actors}
/>
))}
</fieldset>
)
}
function DynamicField({ definition, value, onChange, disabled, actors = [] }) {
const { field_key, field_type, label, required, validation_json: validation } = definition
const inputId = `field-${field_key}`
if (field_type === 'longtext') {
return (
<label htmlFor={inputId}>
{label}
{required && ' *'}
<textarea
id={inputId}
name={field_key}
rows={4}
value={value ?? ''}
onChange={(e) => onChange(e.target.value)}
required={required}
disabled={disabled}
/>
</label>
)
}
if (field_type === 'boolean') {
return (
<label className="checkbox-label" htmlFor={inputId}>
<input
id={inputId}
name={field_key}
type="checkbox"
checked={Boolean(value)}
onChange={(e) => onChange(e.target.checked)}
disabled={disabled}
/>
{label}
{required && ' *'}
</label>
)
}
if (field_type === 'enum') {
const options = validation?.options || []
return (
<label htmlFor={inputId}>
{label}
{required && ' *'}
<select
id={inputId}
name={field_key}
value={value ?? ''}
onChange={(e) => onChange(e.target.value)}
required={required}
disabled={disabled}
>
<option value=""></option>
{options.map((opt) => (
<option key={opt} value={opt}>
{opt}
</option>
))}
</select>
</label>
)
}
if (field_type === 'actor_ref') {
return (
<label htmlFor={inputId}>
{label}
{required && ' *'}
<select
id={inputId}
name={field_key}
value={value ?? ''}
onChange={(e) => onChange(e.target.value || null)}
required={required}
disabled={disabled}
>
<option value=""></option>
{actors.map((actor) => (
<option key={actor.id} value={actor.id}>
{actor.name}
</option>
))}
</select>
</label>
)
}
const inputType =
field_type === 'number' ? 'number' : field_type === 'date' ? 'date' : field_type === 'url' ? 'url' : 'text'
return (
<label htmlFor={inputId}>
{label}
{required && ' *'}
<input
id={inputId}
name={field_key}
type={inputType}
value={value ?? ''}
onChange={(e) => onChange(field_type === 'number' ? e.target.value : e.target.value)}
required={required}
disabled={disabled}
/>
</label>
)
}