feat: expand admin and data sync workflows
This commit is contained in:
@@ -27,6 +27,8 @@ import type {
|
||||
OpsJobKind,
|
||||
} from "@/lib/types";
|
||||
|
||||
const INGEST_MAX_BYTES = 2 * 1024 * 1024 * 1024;
|
||||
|
||||
export default function OperacionesPage() {
|
||||
return (
|
||||
<AppShell>
|
||||
@@ -37,6 +39,7 @@ export default function OperacionesPage() {
|
||||
|
||||
type ConfirmState =
|
||||
| { kind: "REIMPORT" }
|
||||
| { kind: "SYNC" }
|
||||
| { kind: "RESTORE"; file: string }
|
||||
| null;
|
||||
|
||||
@@ -176,6 +179,7 @@ function Operaciones() {
|
||||
const c = confirm;
|
||||
setConfirm(null);
|
||||
if (c.kind === "REIMPORT") await start("REIMPORT");
|
||||
else if (c.kind === "SYNC") await start("SYNC");
|
||||
else await start("RESTORE", c.file);
|
||||
}
|
||||
|
||||
@@ -224,7 +228,7 @@ function Operaciones() {
|
||||
<h2 className="section-title">Carpeta de ingesta</h2>
|
||||
<p className="inline-form-note">
|
||||
Los cuatro archivos originales de Access. La reimportación y la
|
||||
sincronización leen de aquí.
|
||||
sincronización leen de aquí. Tamaño máximo por archivo: {formatBytes(INGEST_MAX_BYTES)}.
|
||||
</p>
|
||||
<div className="tx-scroll">
|
||||
<table className="tx-table">
|
||||
@@ -306,11 +310,11 @@ function Operaciones() {
|
||||
/>
|
||||
<OpTile
|
||||
title="Sincronizar"
|
||||
desc="Conserva los datos actuales e importa solo lo nuevo del legado. Disponible en la Fase B."
|
||||
action="Próximamente"
|
||||
tone="muted"
|
||||
disabled
|
||||
onClick={() => {}}
|
||||
desc="Respalda, luego importa lo nuevo del legado. Borra del sistema los registros del legado que ya no aparecen en los archivos de ingesta. Se conservan los datos capturados a mano."
|
||||
action="Sincronizar"
|
||||
tone="primary"
|
||||
disabled={jobRunning || starting || !ingestReady}
|
||||
onClick={() => askConfirm({ kind: "SYNC" })}
|
||||
/>
|
||||
</div>
|
||||
{!ingestReady && (
|
||||
@@ -446,12 +450,18 @@ function Operaciones() {
|
||||
<div className="modal-backdrop" role="dialog" aria-modal="true">
|
||||
<div className="card" style={{ padding: 24, maxWidth: 480 }}>
|
||||
<h2 className="section-title" style={{ marginTop: 0 }}>
|
||||
{confirm.kind === "REIMPORT" ? "Confirmar reimportación" : "Confirmar restauración"}
|
||||
{confirm.kind === "REIMPORT"
|
||||
? "Confirmar reimportación"
|
||||
: confirm.kind === "SYNC"
|
||||
? "Confirmar sincronización"
|
||||
: "Confirmar restauración"}
|
||||
</h2>
|
||||
<p className="inline-form-note">
|
||||
{confirm.kind === "REIMPORT"
|
||||
? "Esto BORRA todos los datos actuales (incluidos los capturados a mano) y reconstruye desde los archivos de ingesta. Se creará un respaldo previo automático."
|
||||
: `Esto sobreescribe la base de datos completa con “${confirm.file}”. Se recomienda crear un respaldo antes.`}
|
||||
: confirm.kind === "SYNC"
|
||||
? "Se creará un respaldo previo automático. Luego se importarán al sistema los registros nuevos del legado y se eliminarán los del legado que ya no aparezcan en los archivos de ingesta. Los datos capturados a mano NO se borran."
|
||||
: `Esto sobreescribe la base de datos completa con “${confirm.file}”. Se recomienda crear un respaldo antes.`}
|
||||
</p>
|
||||
<label className="field">
|
||||
<span className="field-label">Escriba CONFIRMAR para continuar</span>
|
||||
@@ -464,12 +474,16 @@ function Operaciones() {
|
||||
</label>
|
||||
<div className="form-actions">
|
||||
<button
|
||||
className="btn btn-danger"
|
||||
className={confirm.kind === "SYNC" ? "btn btn-primary" : "btn btn-danger"}
|
||||
type="button"
|
||||
disabled={confirmText !== "CONFIRMAR" || starting}
|
||||
onClick={runConfirmed}
|
||||
>
|
||||
{confirm.kind === "REIMPORT" ? "Reimportar" : "Restaurar"}
|
||||
{confirm.kind === "REIMPORT"
|
||||
? "Reimportar"
|
||||
: confirm.kind === "SYNC"
|
||||
? "Sincronizar"
|
||||
: "Restaurar"}
|
||||
</button>
|
||||
<button className="btn btn-outline" type="button" onClick={() => setConfirm(null)}>
|
||||
Cancelar
|
||||
|
||||
Reference in New Issue
Block a user