Files
Investidor-V2/resources/js/components/technical-incident-handling.tsx
T

123 lines
4.6 KiB
TypeScript

import {
useTechnicalIncidentHandling,
type HandlingProps,
type Command,
} from '@/lib/technical-incident-handling';
import { button, control } from '@/pages/management/shared';
import { handlingLabels, commandLabels } from '@/lib/technical-incident-labels';
export default function TechnicalIncidentHandling(props: HandlingProps) {
const edit = useTechnicalIncidentHandling(props),
state = props.incident.handling;
const actions: Command[] =
state.status === 'resolved'
? ['note', 'reopen']
: [
'claim',
'note',
'resolve',
...(state.status === 'in_progress'
? ['release' as const]
: []),
];
return (
<section
className="space-y-3 rounded border p-4"
aria-label="Tratar incidente técnico"
>
<h2 className="text-xl font-semibold">Tratar incidente técnico</h2>
<p>
O tratamento é partilhado pela equipa autorizada neste âmbito.
Assumir um tratamento em curso substitui o responsável e
conserva o histórico.
</p>
<p>
Resolver este incidente não submete, publica ou aprova a
oportunidade.
</p>
{edit.notice && <p role="status">{edit.notice}</p>}
{edit.error && <p role="alert">{edit.error}</p>}
{edit.stale && (
<section
className="rounded border p-3"
aria-label="Comparar tratamento"
>
<p>
O incidente mudou. Compare antes de confirmar o estado
actual.
</p>
<p>
Analisado: {handlingLabels[edit.base.status]} ·
responsável {edit.base.assignee_name || 'por assumir'} ·
versão {edit.base.version}
</p>
<p>
Actual: {handlingLabels[state.status]} · responsável{' '}
{state.assignee_name || 'por assumir'} · versão{' '}
{state.version}
</p>
<button
type="button"
className={button}
disabled={!edit.canAdopt}
onClick={edit.adopt}
>
Confirmar leitura do estado actual
</button>
</section>
)}
<label className="block">
Nota interna do tratamento
<textarea
className={control}
value={edit.note}
maxLength={3000}
onChange={(event) => edit.change(event.target.value)}
/>
</label>
<p>
A nota é visível à equipa de suporte autorizada e fica no
histórico. O autor da tentativa acompanha apenas o estado
técnico.
</p>
<div className="flex flex-wrap gap-3">
{actions
.filter(
(action) =>
action !== 'claim' ||
state.assignee_user_id !== props.actorId,
)
.map((action) => (
<button
type="button"
key={action}
className={button}
disabled={edit.blocked}
onClick={() => void edit.send(action)}
>
{commandLabels[action]}
</button>
))}
{edit.canRetry && (
<button
type="button"
className={button}
onClick={() =>
void edit.send(edit.pendingAction ?? 'note', true)
}
>
Repetir o registo original
</button>
)}
<button
type="button"
className={button}
disabled={edit.refreshing}
onClick={edit.refresh}
>
Actualizar incidente
</button>
</div>
</section>
);
}