Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die README; an keiner Stelle Bedeutung, nur Zeichensetzung.
109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useTransition } from 'react'
|
|
import { assignmentText } from '@/lib/i18n/people'
|
|
import { participantText } from '@/lib/i18n/cases'
|
|
import { ASSIGNMENT_ROLES } from '@/lib/personnel/terms'
|
|
import { AddPanel, PanelSelect } from '@/components/AddPanel'
|
|
import { addAssignmentAction, removeAssignmentAction } from '../actions'
|
|
|
|
type Zuordnung = {
|
|
id: string
|
|
role: string
|
|
user: { id: string; displayName: string }
|
|
}
|
|
|
|
/**
|
|
* Mitglieder der Abteilung, die an dieser Personalakte hängen.
|
|
*
|
|
* Wie die Beteiligten einer Fallakte ist das zugleich der Weg zum
|
|
* ausnahmsweisen Zugang - der Hinweis steht deshalb direkt am Formular.
|
|
*/
|
|
export function Assignments({
|
|
personnelFileId,
|
|
assignments,
|
|
members,
|
|
canEdit,
|
|
}: {
|
|
personnelFileId: string
|
|
assignments: Zuordnung[]
|
|
members: { id: string; displayName: string }[]
|
|
canEdit: boolean
|
|
}) {
|
|
const [role, setRole] = useState<string>('HANDLER')
|
|
const [userId, setUserId] = useState('')
|
|
const [fehler, setFehler] = useState<string | null>(null)
|
|
const [pending, startTransition] = useTransition()
|
|
|
|
return (
|
|
<div>
|
|
{assignments.length === 0 ? (
|
|
<p className="text-text-dim">{assignmentText.empty}</p>
|
|
) : (
|
|
<ul className="border-t border-line">
|
|
{assignments.map((zuordnung) => (
|
|
<li
|
|
key={zuordnung.id}
|
|
className="record-row border-b border-line py-2"
|
|
>
|
|
<span className="record-label">
|
|
{assignmentText.roles[zuordnung.role] ?? zuordnung.role}
|
|
</span>
|
|
<span className="record-title text-sm">{zuordnung.user.displayName}</span>
|
|
{canEdit ? (
|
|
<button
|
|
type="button"
|
|
disabled={pending}
|
|
onClick={() =>
|
|
startTransition(async () => {
|
|
const ergebnis = await removeAssignmentAction({
|
|
personnelFileId,
|
|
assignmentId: zuordnung.id,
|
|
})
|
|
if (!ergebnis.ok) setFehler(ergebnis.error)
|
|
})
|
|
}
|
|
className="btn btn-sm"
|
|
>
|
|
{assignmentText.remove}
|
|
</button>
|
|
) : null}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
|
|
{fehler ? <p className="mt-2 font-condensed text-2xs text-stamp-4">{fehler}</p> : null}
|
|
|
|
{canEdit ? (
|
|
<AddPanel
|
|
label={assignmentText.add}
|
|
hint={assignmentText.hint}
|
|
disabled={!userId}
|
|
onSubmit={async () => {
|
|
const ergebnis = await addAssignmentAction({ personnelFileId, userId, role })
|
|
if (ergebnis.ok) setUserId('')
|
|
return ergebnis
|
|
}}
|
|
>
|
|
<PanelSelect value={role} onChange={setRole} label={participantText.role}>
|
|
{ASSIGNMENT_ROLES.map((value) => (
|
|
<option key={value} value={value}>
|
|
{assignmentText.roles[value] ?? value}
|
|
</option>
|
|
))}
|
|
</PanelSelect>
|
|
<PanelSelect value={userId} onChange={setUserId} label={participantText.pickUser}>
|
|
<option value="">-</option>
|
|
{members.map((member) => (
|
|
<option key={member.id} value={member.id}>
|
|
{member.displayName}
|
|
</option>
|
|
))}
|
|
</PanelSelect>
|
|
</AddPanel>
|
|
) : null}
|
|
</div>
|
|
)
|
|
}
|