fix(f4): use locked sealed lifecycle in act detail
This commit is contained in:
@@ -9,14 +9,15 @@ import {
|
|||||||
} from '../features/inspections/inspectionActPresentation';
|
} from '../features/inspections/inspectionActPresentation';
|
||||||
import { InspectionClosurePanel } from '../features/inspections/InspectionClosurePanel';
|
import { InspectionClosurePanel } from '../features/inspections/InspectionClosurePanel';
|
||||||
import { InspectionFindingsPanel } from '../features/inspections/InspectionFindingsPanel';
|
import { InspectionFindingsPanel } from '../features/inspections/InspectionFindingsPanel';
|
||||||
import { getInspectionAct, getInspectionVisit } from '../lib/api';
|
import { getInspectionVisit } from '../lib/api';
|
||||||
import type { InspectionAct, InspectionVisit } from '../lib/api';
|
import type { InspectionVisit } from '../lib/api';
|
||||||
|
import { getInspectionActF4, type InspectionActF4 } from '../lib/inspectionActF4Api';
|
||||||
import { formatDate } from '../lib/format';
|
import { formatDate } from '../lib/format';
|
||||||
|
|
||||||
export function InspectionActEditorPage() {
|
export function InspectionActEditorPage() {
|
||||||
const { actId } = useParams();
|
const { actId } = useParams();
|
||||||
const [visit, setVisit] = useState<InspectionVisit | null>(null);
|
const [visit, setVisit] = useState<InspectionVisit | null>(null);
|
||||||
const [act, setAct] = useState<InspectionAct | null>(null);
|
const [act, setAct] = useState<InspectionActF4 | null>(null);
|
||||||
const [loading, setLoading] = useState(Boolean(actId));
|
const [loading, setLoading] = useState(Boolean(actId));
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ export function InspectionActEditorPage() {
|
|||||||
if (!actId) return;
|
if (!actId) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError('');
|
setError('');
|
||||||
getInspectionAct(actId)
|
getInspectionActF4(actId)
|
||||||
.then(async (value) => {
|
.then(async (value) => {
|
||||||
setAct(value);
|
setAct(value);
|
||||||
setVisit(await getInspectionVisit(value.visitId));
|
setVisit(await getInspectionVisit(value.visitId));
|
||||||
@@ -36,22 +37,24 @@ export function InspectionActEditorPage() {
|
|||||||
if (!actId) {
|
if (!actId) {
|
||||||
return <section className="survey-editor inspection-act-editor">
|
return <section className="survey-editor inspection-act-editor">
|
||||||
<div className="breadcrumb"><Link to="/inspecciones">Inspecciones</Link><span>/</span><span>Acta</span></div>
|
<div className="breadcrumb"><Link to="/inspecciones">Inspecciones</Link><span>/</span><span>Acta</span></div>
|
||||||
<div className="page-heading"><div><span className="eyebrow">OPERACIÓN EXCLUSIVA EN APK</span><h1>Crear acta de inspección</h1><p>Las actas sólo pueden generarse durante la visita física desde la aplicación móvil.</p></div></div>
|
<div className="page-heading"><div><span className="eyebrow">OPERACIÓN EXCLUSIVA EN APK</span><h1>Crear acta de inspección</h1><p>Las actas sólo pueden generarse durante la inspección física desde la aplicación móvil.</p></div></div>
|
||||||
<div className="temporal-notice"><Icon name="clipboard" /><p><strong>Usá la APK con un usuario inspector.</strong> El dashboard recibirá el acta, sus hallazgos y firmas cuando la aplicación sincronice.</p></div>
|
<div className="temporal-notice"><Icon name="clipboard" /><p><strong>Usá la APK con un usuario inspector.</strong> El dashboard recibirá el Acta, sus Hallazgos y constancias cuando la aplicación sincronice.</p></div>
|
||||||
<Link className="button secondary" to="/inspecciones">Volver a inspecciones</Link>
|
<Link className="button secondary" to="/inspecciones">Volver a inspecciones</Link>
|
||||||
</section>;
|
</section>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading) return <LoadingBlock label="Cargando acta…" />;
|
if (loading) return <LoadingBlock label="Cargando acta…" />;
|
||||||
|
|
||||||
|
const isSealed = act?.status === 'SEALED' || act?.status === 'CLOSED';
|
||||||
|
|
||||||
return <section className="survey-editor inspection-act-editor">
|
return <section className="survey-editor inspection-act-editor">
|
||||||
<div className="breadcrumb"><Link to="/inspecciones">Inspecciones</Link><span>/</span>{visit && <><Link to={`/inspecciones/${visit.id}`}>{visit.code}</Link><span>/</span></>}<span>{act?.code ?? 'Acta'}</span></div>
|
<div className="breadcrumb"><Link to="/inspecciones">Inspecciones</Link><span>/</span>{visit && <><Link to={`/inspecciones/${visit.id}`}>{visit.code}</Link><span>/</span></>}<span>{act?.code ?? 'Acta'}</span></div>
|
||||||
<div className="page-heading survey-editor-heading"><div><span className="eyebrow">ACTA DE INSPECCIÓN · SÓLO LECTURA</span><h1>{act?.title ?? 'Acta'}</h1><p>{act ? `${act.code} · versión ${act.currentVersion}` : 'Consulta del documento sincronizado desde la APK.'}</p></div>{act && <span className={`status-badge large ${inspectionActStatusClass(act.status)}`}>{inspectionActStatusLabel(act.status)}</span>}</div>
|
<div className="page-heading survey-editor-heading"><div><span className="eyebrow">ACTA DE INSPECCIÓN · SÓLO LECTURA</span><h1>{act?.title ?? 'Acta'}</h1><p>{act ? `${act.code} · versión ${act.currentVersion}` : 'Consulta del documento sincronizado desde la APK.'}</p></div>{act && <span className={`status-badge large ${inspectionActStatusClass(act.status)}`}>{inspectionActStatusLabel(act.status)}</span>}</div>
|
||||||
|
|
||||||
{error && <Alert>{error}</Alert>}
|
{error && <Alert>{error}</Alert>}
|
||||||
{visit && <div className="temporal-notice"><Icon name="clipboard" /><p><strong>{visit.code}</strong> El contenido constatado, los hallazgos y el cierre se registran exclusivamente desde la APK. Este dashboard permite consultarlos y gestionar el seguimiento posterior.</p></div>}
|
{visit && <div className="temporal-notice"><Icon name="clipboard" /><p><strong>{visit.code}</strong> El contenido constatado y los Hallazgos se registran desde la APK. Una vez bloqueada, el Acta ya no vuelve a borrador; la manifestación de empresa puede completarse posteriormente por enlace seguro.</p></div>}
|
||||||
{act?.report && <div className="temporal-notice"><Icon name="clipboard" /><p><strong>Informe relacionado: <Link to={`/informes/${act.report.id}`}>{act.report.code}</Link>.</strong> {act.report.pdfStatus === 'READY' ? 'El documento PDF está disponible.' : 'El contenido está congelado y el PDF continúa pendiente de composición.'}</p></div>}
|
{act?.report && <div className="temporal-notice"><Icon name="clipboard" /><p><strong>Informe relacionado: <Link to={`/informes/${act.report.id}`}>{act.report.code}</Link>.</strong> {act.report.pdfStatus === 'READY' ? 'El documento PDF está disponible.' : 'El contenido está congelado y el PDF continúa pendiente de composición.'}</p></div>}
|
||||||
{act?.status === 'CLOSED' && !act.report && <div className="temporal-notice"><Icon name="clipboard" /><p><strong>Informe pendiente de emisión.</strong> La solicitud se realiza desde la APK por un inspector asignado a la visita.</p></div>}
|
{isSealed && act && !act.report && <div className="temporal-notice"><Icon name="clipboard" /><p><strong>Informe pendiente de emisión.</strong> El Acta ya está sellada y habilita el circuito documental del INF.</p></div>}
|
||||||
{act?.status === 'CANCELLED' && <Alert>Cancelada: {act.cancellationReason}</Alert>}
|
{act?.status === 'CANCELLED' && <Alert>Cancelada: {act.cancellationReason}</Alert>}
|
||||||
|
|
||||||
{act && <section className="panel inspection-act-form">
|
{act && <section className="panel inspection-act-form">
|
||||||
@@ -59,7 +62,7 @@ export function InspectionActEditorPage() {
|
|||||||
<div className="responsible-summary">
|
<div className="responsible-summary">
|
||||||
<div><small>Fecha y hora</small><strong>{formatDate(act.occurredAt)}</strong></div>
|
<div><small>Fecha y hora</small><strong>{formatDate(act.occurredAt)}</strong></div>
|
||||||
<div><small>Título</small><strong>{act.title}</strong></div>
|
<div><small>Título</small><strong>{act.title}</strong></div>
|
||||||
<div><small>Registros</small><strong>{act.assets.length}</strong></div>
|
<div><small>Urgencia</small><strong>{act.urgency === 'URGENT' ? 'Urgente' : 'No urgente'}</strong></div>
|
||||||
<div><small>Hallazgos</small><strong>{act.findingCount}</strong></div>
|
<div><small>Hallazgos</small><strong>{act.findingCount}</strong></div>
|
||||||
</div>
|
</div>
|
||||||
<div className="closure-section"><span className="eyebrow">DESCRIPCIÓN DE LO ACTUADO</span><p>{act.summary}</p>{act.observations && <><span className="eyebrow">OBSERVACIONES</span><p>{act.observations}</p></>}</div>
|
<div className="closure-section"><span className="eyebrow">DESCRIPCIÓN DE LO ACTUADO</span><p>{act.summary}</p>{act.observations && <><span className="eyebrow">OBSERVACIONES</span><p>{act.observations}</p></>}</div>
|
||||||
@@ -71,7 +74,7 @@ export function InspectionActEditorPage() {
|
|||||||
{act && <InspectionClosurePanel act={act} />}
|
{act && <InspectionClosurePanel act={act} />}
|
||||||
|
|
||||||
{act && <section className="panel survey-report-history">
|
{act && <section className="panel survey-report-history">
|
||||||
<div className="panel-heading"><div><span className="eyebrow">VERSIONES INMUTABLES</span><h2>Historial exacto del acta</h2><p className="section-copy">Cada sincronización conserva el contenido y las versiones de los registros referenciados.</p></div><span className="count-pill">{act.versions.length}</span></div>
|
<div className="panel-heading"><div><span className="eyebrow">VERSIONES INMUTABLES</span><h2>Historial exacto del acta</h2><p className="section-copy">Cada transición conserva el contenido y las versiones de los registros referenciados.</p></div><span className="count-pill">{act.versions.length}</span></div>
|
||||||
<div className="survey-version-list">{act.versions.map((version) => <details key={version.id}><summary><span className="count-pill">v{version.versionNumber}</span><strong>{inspectionActVersionEventLabel(version.event)}</strong><small>{formatDate(version.createdAt)} · {version.actorUsername ?? 'sistema'}</small></summary><pre>{JSON.stringify(version.snapshot, null, 2)}</pre></details>)}</div>
|
<div className="survey-version-list">{act.versions.map((version) => <details key={version.id}><summary><span className="count-pill">v{version.versionNumber}</span><strong>{inspectionActVersionEventLabel(version.event)}</strong><small>{formatDate(version.createdAt)} · {version.actorUsername ?? 'sistema'}</small></summary><pre>{JSON.stringify(version.snapshot, null, 2)}</pre></details>)}</div>
|
||||||
</section>}
|
</section>}
|
||||||
</section>;
|
</section>;
|
||||||
|
|||||||
Reference in New Issue
Block a user