Tickets: vier Ticket-Dialoge auf Dialog (Esc, Sperre beim Speichern), Unterstuetzung als Feldblock
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
39dfb386ac
commit
200d68f20d
6 files changed
+439
-436
No files matched your search
@@ -1,14 +1,16 @@
|
||||
import { useState } from 'react'
|
||||
import { FaTimes } from 'react-icons/fa'
|
||||
import { useEmployees } from '../hooks/useEmployees'
|
||||
import { supportMinutes } from '../lib/support'
|
||||
import { stepLabel } from '../lib/timeSteps'
|
||||
|
||||
// Stabile Vorgabe, damit `choices` und die Effekte der Aufrufer nicht bei jedem Render neu entstehen
|
||||
const NO_EMPLOYEES_STATE = { employees: [], loading: false, error: null }
|
||||
|
||||
/* Haken "Unterstuetzung" mit Zeilen Mitarbeiter + "Wobei?". Nur fuer die Person, die das
|
||||
Arbeitsblatt angelegt hat (sie selbst steht nicht in der Auswahl). Die Mitarbeiterliste
|
||||
laedt erst hier, damit nicht jede Ticket-Karte sie abruft. */
|
||||
export default function SupportersEditor({ value, onChange, excludeUserId, minutes }) {
|
||||
const { employees, loading, error } = useEmployees()
|
||||
kommt von der Seite (employeesState = Werte von useEmployees, dort einmal geladen),
|
||||
der Editor ruft den Hook nicht selbst auf. */
|
||||
export default function SupportersEditor({ value, onChange, excludeUserId, minutes, employeesState = NO_EMPLOYEES_STATE }) {
|
||||
const { employees, loading, error } = employeesState
|
||||
const [enabled, setEnabled] = useState(value.length > 0)
|
||||
const perPerson = stepLabel(supportMinutes(minutes))
|
||||
const choices = employees.filter((e) => e.userId && e.userId !== excludeUserId)
|
||||
@@ -29,20 +31,20 @@ export default function SupportersEditor({ value, onChange, excludeUserId, minut
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="form-group supporters-editor">
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<div className="field supporters-editor">
|
||||
<label className="check">
|
||||
<input type="checkbox" checked={enabled} onChange={(e) => toggle(e.target.checked)} />
|
||||
Unterstützung
|
||||
</label>
|
||||
{enabled && (
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<>
|
||||
{!loading && (error || !choices.length) && (
|
||||
<p className="text-grey" style={{ fontSize: 13 }}>Mitarbeiterliste konnte nicht geladen werden.</p>
|
||||
<div className="hint">Mitarbeiterliste konnte nicht geladen werden.</div>
|
||||
)}
|
||||
{value.map((row, index) => (
|
||||
<div key={index} className="flex gap-2" style={{ marginBottom: 8, alignItems: 'center' }}>
|
||||
<div key={index} className="supporter-row">
|
||||
<select
|
||||
className="form-control"
|
||||
className="select"
|
||||
aria-label="Mitarbeiter"
|
||||
value={row.employeeId}
|
||||
onChange={(e) => pick(index, e.target.value)}
|
||||
@@ -53,23 +55,27 @@ export default function SupportersEditor({ value, onChange, excludeUserId, minut
|
||||
.map((e) => <option key={e.userId} value={e.userId}>{e.displayName}</option>)}
|
||||
</select>
|
||||
<input
|
||||
className="form-control"
|
||||
className="input"
|
||||
aria-label="Wobei?"
|
||||
placeholder="Wobei?"
|
||||
maxLength={200}
|
||||
value={row.task}
|
||||
onChange={(e) => update(index, { task: e.target.value })}
|
||||
/>
|
||||
<span className="text-grey" style={{ whiteSpace: 'nowrap', fontSize: 13 }}>= {perPerson}</span>
|
||||
<button type="button" className="btn btn-sm" aria-label="Zeile entfernen" onClick={() => remove(index)}>
|
||||
<FaTimes />
|
||||
</button>
|
||||
<div className="sup-meta">
|
||||
<span>= {perPerson}</span>
|
||||
<button type="button" className="link" aria-label="Zeile entfernen" onClick={() => remove(index)}>
|
||||
Entfernen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<button type="button" className="btn btn-sm" onClick={() => onChange([...value, { employeeId: '', name: '', task: '' }])}>
|
||||
+ weitere Person
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" className="link" onClick={() => onChange([...value, { employeeId: '', name: '', task: '' }])}>
|
||||
+ weitere Person
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user