Workers P2: Kennzahlen, Worker-Karte mit Spur und Worker-Liste
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
85b5f3cedb
commit
f2975e26f0
4 files changed
+226
No files matched your search
@@ -0,0 +1,62 @@
|
||||
import { workerStatusLabel } from '../../lib/workersView'
|
||||
import { FLOORS, FLOOR_TITLES, ROLES } from '../../lib/workersRoster'
|
||||
|
||||
// Statuspunkt je Dienst-Status (Wörterbuch statt zusammengesetzter Klasse: der CSS-Test in workers.css findet die Namen)
|
||||
const DOT = {
|
||||
arbeitet: 'wk-dot-arbeitet',
|
||||
wartet: 'wk-dot-wartet',
|
||||
leerlauf: 'wk-dot-leerlauf',
|
||||
grau: 'wk-dot-grau',
|
||||
fehler: 'wk-dot-fehler',
|
||||
}
|
||||
|
||||
// Etagen von oben nach unten mit ihren Workern; Etagen ohne Worker (Pult, Tresor) entfallen
|
||||
const GROUPS = FLOORS.map((floor) => ({ floor, roles: ROLES.filter((r) => r.floor === floor) })).filter((g) => g.roles.length > 0)
|
||||
|
||||
const isRecord = (v) => v !== null && typeof v === 'object' && !Array.isArray(v)
|
||||
|
||||
// workers = Tabelle nach workerId (indexWorkers/reduceEvents) oder die Liste aus state.workers; unbekannt -> null
|
||||
function entryOf(workers, workerId) {
|
||||
if (Array.isArray(workers)) return workers.find((w) => isRecord(w) && w.workerId === workerId) ?? null
|
||||
return isRecord(workers) && Object.hasOwn(workers, workerId) && isRecord(workers[workerId]) ? workers[workerId] : null
|
||||
}
|
||||
|
||||
// Status aus dem Eintrag; ein nicht angeschlossener Worker ist grau (wie in indexWorkers)
|
||||
function statusOf(entry) {
|
||||
if (!entry) return ''
|
||||
return entry.connected === false ? 'grau' : entry.status
|
||||
}
|
||||
|
||||
// Alle Worker je Etage als Knopfliste. Ein Klick meldet die workerId über onSelect, der gewählte Knopf ist aria-pressed.
|
||||
export default function WorkerList({ workers, selectedId, onSelect }) {
|
||||
return (
|
||||
<div className="wk-list">
|
||||
{GROUPS.map((group) => (
|
||||
<section key={group.floor}>
|
||||
<h3 className="wk-list-floor">{FLOOR_TITLES[group.floor]}</h3>
|
||||
<ul>
|
||||
{group.roles.map((role) => {
|
||||
const status = statusOf(entryOf(workers, role.workerId))
|
||||
const label = workerStatusLabel(status)
|
||||
return (
|
||||
<li key={role.workerId}>
|
||||
<button
|
||||
type="button"
|
||||
data-wk-worker={role.workerId}
|
||||
aria-pressed={selectedId === role.workerId}
|
||||
aria-label={`${role.name}, ${label}`}
|
||||
onClick={() => { if (onSelect) onSelect(role.workerId) }}
|
||||
>
|
||||
<span className={Object.hasOwn(DOT, status) ? `wk-dot ${DOT[status]}` : 'wk-dot'} aria-hidden="true" />
|
||||
<span>{role.name}</span>
|
||||
<span>{label}</span>
|
||||
</button>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user