83 lines
3.4 KiB
React
83 lines
3.4 KiB
React
import { useState } from 'react'
|
|
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
|
|
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)
|
|
|
|
const toggle = (checked) => {
|
|
setEnabled(checked)
|
|
onChange(checked ? [{ employeeId: '', name: '', task: '' }] : [])
|
|
}
|
|
const update = (index, patch) => onChange(value.map((row, i) => (i === index ? { ...row, ...patch } : row)))
|
|
const pick = (index, userId) => {
|
|
const employee = choices.find((e) => e.userId === userId)
|
|
update(index, { employeeId: userId, name: employee?.displayName || '' })
|
|
}
|
|
const remove = (index) => {
|
|
const next = value.filter((_, i) => i !== index)
|
|
onChange(next)
|
|
if (!next.length) setEnabled(false)
|
|
}
|
|
|
|
return (
|
|
<div className="field supporters-editor">
|
|
<label className="check">
|
|
<input type="checkbox" checked={enabled} onChange={(e) => toggle(e.target.checked)} />
|
|
Unterstützung
|
|
</label>
|
|
{enabled && (
|
|
<>
|
|
{!loading && (error || !choices.length) && (
|
|
<div className="hint">Mitarbeiterliste konnte nicht geladen werden.</div>
|
|
)}
|
|
{value.map((row, index) => (
|
|
<div key={index} className="supporter-row">
|
|
<select
|
|
className="select"
|
|
aria-label="Mitarbeiter"
|
|
value={row.employeeId}
|
|
onChange={(e) => pick(index, e.target.value)}
|
|
>
|
|
<option value="">Person wählen …</option>
|
|
{choices
|
|
.filter((e) => e.userId === row.employeeId || !value.some((r) => r.employeeId === e.userId))
|
|
.map((e) => <option key={e.userId} value={e.userId}>{e.displayName}</option>)}
|
|
</select>
|
|
<input
|
|
className="input"
|
|
aria-label="Wobei?"
|
|
placeholder="Wobei?"
|
|
maxLength={200}
|
|
value={row.task}
|
|
onChange={(e) => update(index, { task: e.target.value })}
|
|
/>
|
|
<div className="sup-meta">
|
|
<span>= {perPerson}</span>
|
|
<button type="button" className="link" aria-label="Zeile entfernen" onClick={() => remove(index)}>
|
|
Entfernen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
))}
|
|
<div>
|
|
<button type="button" className="link" onClick={() => onChange([...value, { employeeId: '', name: '', task: '' }])}>
|
|
+ weitere Person
|
|
</button>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|