feat: Enhance Admin Activity Attribute Profiles UI and styling
- Introduced a new layout for the Admin Activity Attribute Profiles page, improving the user interface with a dedicated class for styling. - Added new CSS styles for input fields, labels, and layout structures to enhance the visual presentation and usability of the attribute profiles. - Updated the form structure to include clearer labels and organization for input fields, ensuring better accessibility and user experience. - Improved responsiveness of the layout for mobile devices, ensuring a consistent experience across different screen sizes.
This commit is contained in:
parent
bc8e9fb7fa
commit
92e334dcd2
|
|
@ -440,6 +440,141 @@ a.analysis-split__nav-item {
|
|||
}
|
||||
}
|
||||
|
||||
/* Admin: Session-Metriken / Attributprofile — volle Breite, linksbündig (nicht globale 90px-Zahlfelder) */
|
||||
.activity-attribute-profiles .aaf-stack {
|
||||
max-width: 42rem;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-field {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-label {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text1);
|
||||
text-align: left;
|
||||
margin-bottom: 6px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-sublabel {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--text2);
|
||||
text-align: left;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-hint {
|
||||
font-size: 12px;
|
||||
color: var(--text3);
|
||||
text-align: left;
|
||||
margin: 6px 0 0;
|
||||
line-height: 1.45;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-input,
|
||||
.activity-attribute-profiles textarea.aaf-input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 10px 12px;
|
||||
text-align: left;
|
||||
font-family: var(--font);
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: var(--text1);
|
||||
background: var(--surface2);
|
||||
border: 1.5px solid var(--border2);
|
||||
border-radius: 8px;
|
||||
transition: border-color 0.15s;
|
||||
}
|
||||
.activity-attribute-profiles textarea.aaf-input {
|
||||
resize: vertical;
|
||||
min-height: 4.5rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
.activity-attribute-profiles .aaf-split {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
@media (max-width: 560px) {
|
||||
.activity-attribute-profiles .aaf-split {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.activity-attribute-profiles .aaf-field-select {
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.activity-attribute-profiles .aaf-field-select:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-field-select .form-label {
|
||||
display: block;
|
||||
text-align: left;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
flex: unset;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-field-select .form-input,
|
||||
.activity-attribute-profiles .aaf-field-select select.form-input {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
min-width: 0;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
gap: 12px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.activity-attribute-profiles .aaf-toolbar .form-label {
|
||||
display: block;
|
||||
text-align: left;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
flex: unset;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-toolbar__grow {
|
||||
flex: 1 1 240px;
|
||||
min-width: 0;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-toolbar .form-input,
|
||||
.activity-attribute-profiles .aaf-toolbar select.form-input {
|
||||
width: 100%;
|
||||
min-width: 140px;
|
||||
max-width: none;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-toolbar__compact {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-toolbar__compact .form-input,
|
||||
.activity-attribute-profiles .aaf-toolbar__compact select.form-input {
|
||||
width: 100%;
|
||||
min-width: 5rem;
|
||||
}
|
||||
.activity-attribute-profiles .aaf-inline-edit .form-input,
|
||||
.activity-attribute-profiles .aaf-inline-edit select.form-input {
|
||||
text-align: left;
|
||||
min-width: 4.5rem;
|
||||
width: auto;
|
||||
max-width: none;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
/* Erfassung: Sub-Navigation (Mobil = Chips, Desktop = linke Spalte) */
|
||||
.capture-shell {
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="capture-page">
|
||||
<div className="capture-page activity-attribute-profiles">
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Link to="/admin/g/training" className="text-link" style={{ fontSize: 13 }}>
|
||||
← Training (Hub)
|
||||
|
|
@ -378,87 +378,151 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
style={{
|
||||
border: '1px solid var(--border)',
|
||||
borderRadius: 8,
|
||||
padding: 12,
|
||||
padding: 16,
|
||||
marginBottom: 12,
|
||||
background: 'var(--surface2)',
|
||||
}}
|
||||
>
|
||||
<div className="form-row">
|
||||
<label className="form-label">key</label>
|
||||
<input
|
||||
className="form-input"
|
||||
placeholder="z. B. avg_power"
|
||||
value={paramForm.key}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, key: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">name_de / name_en</label>
|
||||
<input
|
||||
className="form-input"
|
||||
value={paramForm.name_de}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, name_de: e.target.value }))}
|
||||
/>
|
||||
<input
|
||||
className="form-input"
|
||||
value={paramForm.name_en}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, name_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Beschreibung DE / EN (optional, für KI)</label>
|
||||
<textarea
|
||||
className="form-input"
|
||||
rows={2}
|
||||
placeholder="Was bedeutet der Wert? Einheit/Skala?"
|
||||
value={paramForm.description_de}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, description_de: e.target.value }))}
|
||||
/>
|
||||
<textarea
|
||||
className="form-input"
|
||||
rows={2}
|
||||
placeholder="Short meaning for prompts / EN users"
|
||||
value={paramForm.description_en}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, description_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Gruppe / Datentyp</label>
|
||||
<select
|
||||
className="form-input"
|
||||
value={paramForm.category}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, category: e.target.value }))}
|
||||
>
|
||||
{PARAM_GROUP.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
className="form-input"
|
||||
value={paramForm.data_type}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, data_type: e.target.value }))}
|
||||
>
|
||||
{DATA_TYPES.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Einheit / source_field</label>
|
||||
<input
|
||||
className="form-input"
|
||||
value={paramForm.unit}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, unit: e.target.value }))}
|
||||
/>
|
||||
<input
|
||||
className="form-input"
|
||||
value={paramForm.source_field}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, source_field: e.target.value }))}
|
||||
/>
|
||||
<div className="aaf-stack">
|
||||
<div className="aaf-field">
|
||||
<label className="aaf-label" htmlFor="aaf-new-key">
|
||||
Technischer Schlüssel (key)
|
||||
</label>
|
||||
<input
|
||||
id="aaf-new-key"
|
||||
className="aaf-input"
|
||||
placeholder="z. B. avg_power"
|
||||
value={paramForm.key}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, key: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<span className="aaf-label">Bezeichnung</span>
|
||||
<div className="aaf-split">
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-new-name-de">
|
||||
Deutsch
|
||||
</label>
|
||||
<input
|
||||
id="aaf-new-name-de"
|
||||
className="aaf-input"
|
||||
value={paramForm.name_de}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, name_de: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-new-name-en">
|
||||
English
|
||||
</label>
|
||||
<input
|
||||
id="aaf-new-name-en"
|
||||
className="aaf-input"
|
||||
value={paramForm.name_en}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, name_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<span className="aaf-label">Beschreibung (optional, für KI / Export)</span>
|
||||
<div className="aaf-split">
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-new-desc-de">
|
||||
Deutsch
|
||||
</label>
|
||||
<textarea
|
||||
id="aaf-new-desc-de"
|
||||
className="aaf-input"
|
||||
rows={3}
|
||||
placeholder="Was bedeutet der Wert? Einheit, Skala, Herkunft …"
|
||||
value={paramForm.description_de}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, description_de: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-new-desc-en">
|
||||
English
|
||||
</label>
|
||||
<textarea
|
||||
id="aaf-new-desc-en"
|
||||
className="aaf-input"
|
||||
rows={3}
|
||||
placeholder="Short meaning for prompts and EN contexts"
|
||||
value={paramForm.description_en}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, description_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<span className="aaf-label">Gruppe und Datentyp</span>
|
||||
<div className="aaf-split">
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-new-cat">
|
||||
Parameter-Gruppe
|
||||
</label>
|
||||
<select
|
||||
id="aaf-new-cat"
|
||||
className="aaf-input"
|
||||
value={paramForm.category}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, category: e.target.value }))}
|
||||
>
|
||||
{PARAM_GROUP.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-new-dtype">
|
||||
Datentyp
|
||||
</label>
|
||||
<select
|
||||
id="aaf-new-dtype"
|
||||
className="aaf-input"
|
||||
value={paramForm.data_type}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, data_type: e.target.value }))}
|
||||
>
|
||||
{DATA_TYPES.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<label className="aaf-label" htmlFor="aaf-new-unit">
|
||||
Einheit (optional)
|
||||
</label>
|
||||
<input
|
||||
id="aaf-new-unit"
|
||||
className="aaf-input"
|
||||
placeholder="z. B. W, bpm, min"
|
||||
value={paramForm.unit}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, unit: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<label className="aaf-label" htmlFor="aaf-new-source-field">
|
||||
Quell-Spalte in activity_log (source_field, optional)
|
||||
</label>
|
||||
<input
|
||||
id="aaf-new-source-field"
|
||||
className="aaf-input"
|
||||
placeholder="z. B. hr_avg — Spaltenname der Trainingseinheit"
|
||||
autoComplete="off"
|
||||
value={paramForm.source_field}
|
||||
onChange={(e) => setParamForm((f) => ({ ...f, source_field: e.target.value }))}
|
||||
/>
|
||||
<p className="aaf-hint">
|
||||
Wenn gesetzt, wird der Messwert beim Anzeigen und Zusammenführen mit EAV primär aus dieser
|
||||
Spalte der Einheit gelesen (nicht aus der EAV-Tabelle). Leer lassen, wenn der Wert nur über
|
||||
EAV oder Standard-Spalten kommt.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
|
||||
<button type="button" className="btn btn-primary" onClick={saveNewParameter}>
|
||||
|
|
@ -476,78 +540,138 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
style={{
|
||||
border: '1px solid var(--accent)',
|
||||
borderRadius: 8,
|
||||
padding: 12,
|
||||
padding: 16,
|
||||
marginBottom: 12,
|
||||
}}
|
||||
>
|
||||
<div className="card-title" style={{ fontSize: 14 }}>
|
||||
Bearbeiten: <code>{editParam.key}</code>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">name_de / name_en</label>
|
||||
<input
|
||||
className="form-input"
|
||||
value={editParam.name_de || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, name_de: e.target.value }))}
|
||||
/>
|
||||
<input
|
||||
className="form-input"
|
||||
value={editParam.name_en || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, name_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Beschreibung DE / EN (optional, für KI)</label>
|
||||
<textarea
|
||||
className="form-input"
|
||||
rows={2}
|
||||
value={editParam.description_de || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, description_de: e.target.value }))}
|
||||
/>
|
||||
<textarea
|
||||
className="form-input"
|
||||
rows={2}
|
||||
value={editParam.description_en || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, description_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Gruppe / Typ</label>
|
||||
<select
|
||||
className="form-input"
|
||||
value={editParam.category}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, category: e.target.value }))}
|
||||
>
|
||||
{PARAM_GROUP.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
className="form-input"
|
||||
value={editParam.data_type}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, data_type: e.target.value }))}
|
||||
>
|
||||
{DATA_TYPES.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Einheit / source_field</label>
|
||||
<input
|
||||
className="form-input"
|
||||
value={editParam.unit || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, unit: e.target.value }))}
|
||||
/>
|
||||
<input
|
||||
className="form-input"
|
||||
value={editParam.source_field || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, source_field: e.target.value }))}
|
||||
/>
|
||||
<div className="aaf-stack">
|
||||
<div className="aaf-field">
|
||||
<span className="aaf-label">Bezeichnung</span>
|
||||
<div className="aaf-split">
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-edit-name-de">
|
||||
Deutsch
|
||||
</label>
|
||||
<input
|
||||
id="aaf-edit-name-de"
|
||||
className="aaf-input"
|
||||
value={editParam.name_de || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, name_de: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-edit-name-en">
|
||||
English
|
||||
</label>
|
||||
<input
|
||||
id="aaf-edit-name-en"
|
||||
className="aaf-input"
|
||||
value={editParam.name_en || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, name_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<span className="aaf-label">Beschreibung (optional, für KI / Export)</span>
|
||||
<div className="aaf-split">
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-edit-desc-de">
|
||||
Deutsch
|
||||
</label>
|
||||
<textarea
|
||||
id="aaf-edit-desc-de"
|
||||
className="aaf-input"
|
||||
rows={3}
|
||||
value={editParam.description_de || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, description_de: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-edit-desc-en">
|
||||
English
|
||||
</label>
|
||||
<textarea
|
||||
id="aaf-edit-desc-en"
|
||||
className="aaf-input"
|
||||
rows={3}
|
||||
value={editParam.description_en || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, description_en: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<span className="aaf-label">Gruppe und Datentyp</span>
|
||||
<div className="aaf-split">
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-edit-cat">
|
||||
Parameter-Gruppe
|
||||
</label>
|
||||
<select
|
||||
id="aaf-edit-cat"
|
||||
className="aaf-input"
|
||||
value={editParam.category}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, category: e.target.value }))}
|
||||
>
|
||||
{PARAM_GROUP.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="aaf-sublabel" htmlFor="aaf-edit-dtype">
|
||||
Datentyp
|
||||
</label>
|
||||
<select
|
||||
id="aaf-edit-dtype"
|
||||
className="aaf-input"
|
||||
value={editParam.data_type}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, data_type: e.target.value }))}
|
||||
>
|
||||
{DATA_TYPES.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<label className="aaf-label" htmlFor="aaf-edit-unit">
|
||||
Einheit (optional)
|
||||
</label>
|
||||
<input
|
||||
id="aaf-edit-unit"
|
||||
className="aaf-input"
|
||||
placeholder="z. B. W, bpm, min"
|
||||
value={editParam.unit || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, unit: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="aaf-field">
|
||||
<label className="aaf-label" htmlFor="aaf-edit-source-field">
|
||||
Quell-Spalte in activity_log (source_field, optional)
|
||||
</label>
|
||||
<input
|
||||
id="aaf-edit-source-field"
|
||||
className="aaf-input"
|
||||
placeholder="z. B. hr_avg"
|
||||
autoComplete="off"
|
||||
value={editParam.source_field || ''}
|
||||
onChange={(e) => setEditParam((p) => ({ ...p, source_field: e.target.value }))}
|
||||
/>
|
||||
<p className="aaf-hint">
|
||||
Optional: Name der <code>activity_log</code>-Spalte, aus der dieser Parameter beim Lesen zuerst
|
||||
befüllt wird (kanonisch vor EAV). Leer, wenn nur EAV oder implizites Spalten-Mapping.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, marginBottom: 8 }}>
|
||||
<input
|
||||
|
|
@ -625,13 +749,15 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
{tab === 'category' && (
|
||||
<div className="card section-gap">
|
||||
<div className="card-title">Zuordnung: Trainings-Kategorie</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Kategorie</label>
|
||||
<div className="aaf-field-select">
|
||||
<label className="form-label" htmlFor="aaf-cat-pick">
|
||||
Kategorie
|
||||
</label>
|
||||
<select
|
||||
id="aaf-cat-pick"
|
||||
className="form-input"
|
||||
value={selCategory}
|
||||
onChange={(e) => setSelCategory(e.target.value)}
|
||||
style={{ maxWidth: 280 }}
|
||||
>
|
||||
{categoryKeys.map((k) => (
|
||||
<option key={k} value={k}>
|
||||
|
|
@ -640,10 +766,13 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-row" style={{ alignItems: 'flex-end', flexWrap: 'wrap', gap: 8 }}>
|
||||
<div style={{ flex: 1, minWidth: 200 }}>
|
||||
<label className="form-label">Parameter</label>
|
||||
<div className="aaf-toolbar">
|
||||
<div className="aaf-toolbar__grow">
|
||||
<label className="form-label" htmlFor="aaf-cat-param">
|
||||
Parameter
|
||||
</label>
|
||||
<select
|
||||
id="aaf-cat-param"
|
||||
className="form-input"
|
||||
value={catAdd.training_parameter_id}
|
||||
onChange={(e) => setCatAdd((a) => ({ ...a, training_parameter_id: e.target.value }))}
|
||||
|
|
@ -656,17 +785,22 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="form-label">sort</label>
|
||||
<div className="aaf-toolbar__compact">
|
||||
<label className="form-label" htmlFor="aaf-cat-sort">
|
||||
Sortierung
|
||||
</label>
|
||||
<input
|
||||
id="aaf-cat-sort"
|
||||
type="number"
|
||||
className="form-input"
|
||||
style={{ width: 80 }}
|
||||
value={catAdd.sort_order}
|
||||
onChange={(e) => setCatAdd((a) => ({ ...a, sort_order: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 13 }}>
|
||||
<label
|
||||
className="aaf-toolbar__compact"
|
||||
style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 14, paddingBottom: 4 }}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={catAdd.required}
|
||||
|
|
@ -674,11 +808,14 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
/>
|
||||
Pflicht
|
||||
</label>
|
||||
<div>
|
||||
<label className="form-label">ui_group</label>
|
||||
<div className="aaf-toolbar__compact">
|
||||
<label className="form-label" htmlFor="aaf-cat-uigroup">
|
||||
ui_group
|
||||
</label>
|
||||
<input
|
||||
id="aaf-cat-uigroup"
|
||||
className="form-input"
|
||||
style={{ width: 120 }}
|
||||
placeholder="optional"
|
||||
value={catAdd.ui_group}
|
||||
onChange={(e) => setCatAdd((a) => ({ ...a, ui_group: e.target.value }))}
|
||||
/>
|
||||
|
|
@ -698,21 +835,20 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
}}
|
||||
>
|
||||
{editingCatId === l.id ? (
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'flex-end' }}>
|
||||
<div className="aaf-inline-edit" style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'flex-end' }}>
|
||||
<span style={{ flex: '1 1 200px' }}>
|
||||
<strong>{l.parameter_key}</strong> · {l.parameter_name_de}
|
||||
</span>
|
||||
<div>
|
||||
<label className="form-label">sort</label>
|
||||
<label className="form-label">Sortierung</label>
|
||||
<input
|
||||
type="number"
|
||||
className="form-input"
|
||||
style={{ width: 72 }}
|
||||
value={catDraft.sort_order}
|
||||
onChange={(e) => setCatDraft((d) => ({ ...d, sort_order: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 14, paddingBottom: 4 }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={!!catDraft.required}
|
||||
|
|
@ -722,7 +858,6 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
</label>
|
||||
<input
|
||||
className="form-input"
|
||||
style={{ width: 100 }}
|
||||
placeholder="ui_group"
|
||||
value={catDraft.ui_group}
|
||||
onChange={(e) => setCatDraft((d) => ({ ...d, ui_group: e.target.value }))}
|
||||
|
|
@ -782,13 +917,15 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
{tab === 'type' && (
|
||||
<div className="card section-gap">
|
||||
<div className="card-title">Zuordnung: Trainingstyp (Zusatz / Override)</div>
|
||||
<div className="form-row">
|
||||
<label className="form-label">Trainingstyp</label>
|
||||
<div className="aaf-field-select">
|
||||
<label className="form-label" htmlFor="aaf-type-pick">
|
||||
Trainingstyp
|
||||
</label>
|
||||
<select
|
||||
id="aaf-type-pick"
|
||||
className="form-input"
|
||||
value={selTypeId}
|
||||
onChange={(e) => setSelTypeId(e.target.value)}
|
||||
style={{ maxWidth: 420 }}
|
||||
>
|
||||
{flatTypes.map((t) => (
|
||||
<option key={t.id} value={t.id}>
|
||||
|
|
@ -797,10 +934,13 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-row" style={{ alignItems: 'flex-end', flexWrap: 'wrap', gap: 8 }}>
|
||||
<div style={{ flex: 1, minWidth: 200 }}>
|
||||
<label className="form-label">Parameter</label>
|
||||
<div className="aaf-toolbar">
|
||||
<div className="aaf-toolbar__grow">
|
||||
<label className="form-label" htmlFor="aaf-type-param">
|
||||
Parameter
|
||||
</label>
|
||||
<select
|
||||
id="aaf-type-param"
|
||||
className="form-input"
|
||||
value={typeAdd.training_parameter_id}
|
||||
onChange={(e) => setTypeAdd((a) => ({ ...a, training_parameter_id: e.target.value }))}
|
||||
|
|
@ -813,21 +953,25 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="form-label">sort (leer=Erben)</label>
|
||||
<div className="aaf-toolbar__compact">
|
||||
<label className="form-label" htmlFor="aaf-type-sort">
|
||||
Sortierung (leer = erben)
|
||||
</label>
|
||||
<input
|
||||
id="aaf-type-sort"
|
||||
type="number"
|
||||
className="form-input"
|
||||
style={{ width: 80 }}
|
||||
value={typeAdd.sort_order}
|
||||
onChange={(e) => setTypeAdd((a) => ({ ...a, sort_order: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="form-label">Pflicht (leer=Erben)</label>
|
||||
<div className="aaf-toolbar__compact">
|
||||
<label className="form-label" htmlFor="aaf-type-req">
|
||||
Pflicht (leer = erben)
|
||||
</label>
|
||||
<select
|
||||
id="aaf-type-req"
|
||||
className="form-input"
|
||||
style={{ width: 100 }}
|
||||
value={typeAdd.required}
|
||||
onChange={(e) => setTypeAdd((a) => ({ ...a, required: e.target.value }))}
|
||||
>
|
||||
|
|
@ -836,11 +980,14 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
<option value="false">nein</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="form-label">ui_group</label>
|
||||
<div className="aaf-toolbar__compact">
|
||||
<label className="form-label" htmlFor="aaf-type-uigroup">
|
||||
ui_group
|
||||
</label>
|
||||
<input
|
||||
id="aaf-type-uigroup"
|
||||
className="form-input"
|
||||
style={{ width: 120 }}
|
||||
placeholder="optional"
|
||||
value={typeAdd.ui_group}
|
||||
onChange={(e) => setTypeAdd((a) => ({ ...a, ui_group: e.target.value }))}
|
||||
/>
|
||||
|
|
@ -860,23 +1007,21 @@ export default function AdminActivityAttributeProfilesPage() {
|
|||
}}
|
||||
>
|
||||
{editingTypeId === l.id ? (
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'flex-end' }}>
|
||||
<div className="aaf-inline-edit" style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'flex-end' }}>
|
||||
<span style={{ flex: '1 1 200px' }}>
|
||||
<strong>{l.parameter_key}</strong>
|
||||
</span>
|
||||
<div>
|
||||
<label className="form-label">sort</label>
|
||||
<label className="form-label">Sortierung</label>
|
||||
<input
|
||||
type="number"
|
||||
className="form-input"
|
||||
style={{ width: 72 }}
|
||||
value={typeDraft.sort_order}
|
||||
onChange={(e) => setTypeDraft((d) => ({ ...d, sort_order: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<select
|
||||
className="form-input"
|
||||
style={{ width: 100 }}
|
||||
value={typeDraft.required}
|
||||
onChange={(e) => setTypeDraft((d) => ({ ...d, required: e.target.value }))}
|
||||
>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user