Skip to content

Plataforma técnica · Sevastopol

Ingresos View Island

Ingresos Islands Sevastopol

IngresosViewIsland es una island dispatcher: no consulta datos ni guarda estado de negocio. Renderiza una barra de pestañas con dos opciones — Operaciones (vista de ventas/boletas) y PPM anual (actualización por corrección monetaria) — y decide cuál de los dos componentes hijos mostrar. La pestaña inicial puede provenir de otra island vía sessionStorage.

  • Directorysevastopol/src/components/islands/contabilidad/
    • IngresosViewIsland.tsx — componente único, ~40 líneas
  • Directorysevastopol/src/components/islands/accounting/
    • OperationsViewIsland.tsx — pestaña Operaciones
  • Directorysevastopol/src/components/islands/contabilidad/
    • PpmActualizacionAnualIsland.tsx — pestaña PPM
type IngresosTab = "operaciones" | "ppm";
const [tab, setTab] = createSignal<IngresosTab>("operaciones");

Una única signal local — tab — controla qué componente hijo se monta. El switch usa <Show> con fallback:

<Show when={tab() === "operaciones"} fallback={<PpmActualizacionAnualIsland />}>
<OperacionesIngresosIsland />
</Show>
PestañaComponenteEndpoint base
operacionesOperacionesIngresosIsland (alias de IngresosViewIsland exportado desde OperationsViewIsland.tsx)/api/operaciones
ppmPpmActualizacionAnualIsland/api/reportes/ppm-actualizacion-anual

onMount lee sessionStorage.ingresos.activeTab para permitir abrir directamente una pestaña específica desde un origen externo:

onMount(() => {
const requestedTab = window.sessionStorage.getItem("ingresos.activeTab");
if (requestedTab === "operaciones" || requestedTab === "ppm") {
setTab(requestedTab);
window.sessionStorage.removeItem("ingresos.activeTab");
}
});

Tres detalles:

  1. Valida la clave — solo acepta "operaciones" o "ppm"; cualquier otra cosa la ignora.
  2. Borra la clave después de leerla — si no se borrara, navegar a Ingresos por el sidebar después de un deep-link forzaría la misma pestaña accidentalmente.
  3. Se ejecuta una sola vez en mount — cambiar de pestaña posteriormente con el sidebar global no escribe la clave.
OrigenAcciónCódigo
CicloContableIsland paso ppmBotón Abrir PPM anualsessionStorage.setItem("ingresos.activeTab", "ppm") + CustomEvent("sidebar:navigate", { detail: "IngresosView" })

Cualquier island futura puede usar el mismo mecanismo para llevar al operador a una pestaña específica.

Los botones usan clases inline derivadas de tab():

const tabClass = (value: IngresosTab) =>
`px-3 py-1 text-xs font-semibold rounded-md transition-colors ${
tab() === value
? "bg-white dark:bg-zinc-700 shadow text-black dark:text-white"
: "text-zinc-500 hover:text-black dark:hover:text-white"
}`;

No usa WorkspaceTabBar (el componente compartido de finanzas) porque la island está en contabilidad/ y predates ese token visual. Mantenerlo inline también deja la island liviana — sin imports adicionales del workspace.

ReglaMotivo
Sin fetch en el dispatcherEl contenedor no debe acoplarse al ciclo de datos de las hijas; cada pestaña gestiona su propio fetch y caché.
Validar la clave de sessionStorage antes de aplicarUna clave corrupta o legacy no debería forzar un crash al hacer setTab("foo").
Borrar la clave después de leerEvita que una navegación posterior herede la pestaña forzada.
Dos pestañas explícitas (sin opción “ambos”)Operaciones es mensual; PPM es anual. Mezclarlas confunde al operador.
<Show fallback> en vez de <Switch> con dos <Match>Hay solo dos opciones; el Show con fallback es más compacto.
Sin persistir la pestaña activaCambiar de pestaña no se guarda — al volver a la island, siempre arranca en Operaciones (el caso más común).