style(HistoriaClinica): Agrupar tabs en menu select unificado y mostrar botones de accion en linea

This commit is contained in:
2026-08-12 20:39:17 +00:00
parent 369112d384
commit fce539abc2
14 changed files with 747 additions and 110 deletions
+139 -101
View File
@@ -1,4 +1,5 @@
import { useState } from 'react';
import { createPortal } from 'react-dom';
import { toast } from 'sonner';
import { User } from 'lucide-react';
import { useHospitalStore } from '@/hooks/useHospitalStore';
@@ -249,6 +250,7 @@ export function HistoriaClinica({
canEdit,
}: HistoriaClinicaProps) {
const [tabActivo, setTabActivo] = useState('evoluciones');
const [portalNode, setPortalNode] = useState<HTMLDivElement | null>(null);
const { pendientes } = useHospitalStore();
const indicacionesActivas = (indicadores || []).filter(i => i.estado === 'Activa');
const pendientesActivos = (pendientes || []).filter(p => p.pacienteId === paciente.id && p.estado === 'pendiente');
@@ -536,81 +538,49 @@ export function HistoriaClinica({
<div className="grid grid-cols-1 w-full">
<div className="w-full overflow-x-auto rounded-md pb-2">
<Tabs className="w-full" value={tabActivo} onValueChange={setTabActivo}>
<ScrollArea className="w-full rounded-md border bg-background whitespace-nowrap">
<TabsList className="w-full">
<TabsTrigger value="evoluciones">
<FileText className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Evoluciones</span>
({evoluciones.length})
</TabsTrigger>
<TabsTrigger value="indicaciones">
<List className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Indicaciones</span>
({indicacionesActivas.length})
</TabsTrigger>
<TabsTrigger value="glucemias">
<Droplet className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Glucemias</span>
({glucemias.length})
</TabsTrigger>
<TabsTrigger value="laboratorios">
<FlaskConical className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Laboratorio</span>
({laboratorios.length})
</TabsTrigger>
<TabsTrigger value="acidobase">
<Activity className="h-3 w-3 sm:h-4 sm:w-4" />
<span>EAB</span>
({acidosBase.length})
</TabsTrigger>
<TabsTrigger value="cultivos">
<Microscope className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Cultivos</span>
({cultivos.length})
</TabsTrigger>
<TabsTrigger value="atb">
<Pill className="h-3 w-3 sm:h-4 sm:w-4" />
<span>ATB</span>
({atb.length})
</TabsTrigger>
<TabsTrigger value="estudios">
<ClipboardList className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Estudios</span>
({estudiosComplementarios.length})
</TabsTrigger>
<TabsTrigger value="interconsultas">
<Users className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Interconsultas</span>
({interconsultas.length})
</TabsTrigger>
<TabsTrigger value="pendientes">
<ListTodo className="h-3 w-3 sm:h-4 sm:w-4" />
<span>Pendientes</span>
({pendientesActivos.length})
</TabsTrigger>
</TabsList>
<ScrollBar orientation="horizontal" />
</ScrollArea>
<div className="flex flex-col sm:flex-row sm:items-center gap-4 mb-4">
<Select value={tabActivo} onValueChange={setTabActivo}>
<SelectTrigger className="w-full sm:w-[280px] font-semibold bg-gray-50 border-gray-300">
<SelectValue placeholder="Menú de Secciones" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Menú</SelectLabel>
<SelectItem value="evoluciones">Evoluciones ({evoluciones.length})</SelectItem>
<SelectItem value="indicaciones">Indicaciones ({indicacionesActivas.length})</SelectItem>
<SelectItem value="glucemias">Glucemias ({glucemias.length})</SelectItem>
<SelectItem value="laboratorios">Laboratorio ({laboratorios.length})</SelectItem>
<SelectItem value="acidobase">EAB ({acidosBase.length})</SelectItem>
<SelectItem value="cultivos">Cultivos ({cultivos.length})</SelectItem>
<SelectItem value="atb">ATB ({atb.length})</SelectItem>
<SelectItem value="estudios">Estudios ({estudiosComplementarios.length})</SelectItem>
<SelectItem value="interconsultas">Interconsultas ({interconsultas.length})</SelectItem>
<SelectItem value="pendientes">Pendientes ({pendientesActivos.length})</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<div ref={setPortalNode} id="menu-actions" className="flex flex-1 items-center gap-2 overflow-x-auto min-h-[40px]"></div>
</div>
<TabsContent value="glucemias" className="mt-4 min-w-0 w-full overflow-hidden">
<SeccionGlucemias glucemias={glucemias} patientId={paciente.id} internacionId={internacion.id} add={onAgregarGlucemia} update={onActualizarGlucemia} del={onEliminarGlucemia} canEdit={canEdit} />
<SeccionGlucemias portalNode={portalNode} glucemias={glucemias} patientId={paciente.id} internacionId={internacion.id} add={onAgregarGlucemia} update={onActualizarGlucemia} del={onEliminarGlucemia} canEdit={canEdit} />
</TabsContent>
<TabsContent value="laboratorios" className="mt-4 min-w-0 w-full overflow-hidden">
<SeccionLaboratorios lab={laboratorios} patientId={paciente.id} internacionId={internacion.id} add={onAgregarLaboratorio} update={onActualizarLaboratorio} del={onEliminarLaboratorio} addAcidoBase={onAgregarAcidoBase} canEdit={canEdit} />
<SeccionLaboratorios portalNode={portalNode} lab={laboratorios} patientId={paciente.id} internacionId={internacion.id} add={onAgregarLaboratorio} update={onActualizarLaboratorio} del={onEliminarLaboratorio} addAcidoBase={onAgregarAcidoBase} canEdit={canEdit} />
</TabsContent>
<TabsContent value="evoluciones" className="mt-4">
<SeccionEvoluciones evos={evoluciones} internacionId={internacion.id} add={onAgregarEvolucion} update={onActualizarEvolucion} del={onEliminarEvolucion} canEdit={canEdit} />
<SeccionEvoluciones portalNode={portalNode} evos={evoluciones} internacionId={internacion.id} add={onAgregarEvolucion} update={onActualizarEvolucion} del={onEliminarEvolucion} canEdit={canEdit} />
</TabsContent>
<TabsContent value="acidobase" className="mt-4">
<SeccionAcidosBase ab={acidosBase} patientId={paciente.id} internacionId={internacion.id} add={onAgregarAcidoBase} update={onActualizarAcidoBase} del={onEliminarAcidoBase} canEdit={canEdit} />
<SeccionAcidosBase portalNode={portalNode} ab={acidosBase} patientId={paciente.id} internacionId={internacion.id} add={onAgregarAcidoBase} update={onActualizarAcidoBase} del={onEliminarAcidoBase} canEdit={canEdit} />
</TabsContent>
<TabsContent value="cultivos" className="mt-4">
<SeccionCultivos cults={cultivos} patient={paciente} internacionId={internacion.id} add={onAgregarCultivo} update={onActualizarCultivo} del={onEliminarCultivo} canEdit={canEdit} />
<SeccionCultivos portalNode={portalNode} cults={cultivos} patient={paciente} internacionId={internacion.id} add={onAgregarCultivo} update={onActualizarCultivo} del={onEliminarCultivo} canEdit={canEdit} />
</TabsContent>
<TabsContent value="atb" className="mt-4">
@@ -680,7 +650,7 @@ export function HistoriaClinica({
);
}
function SeccionGlucemias({ glucemias, patientId, internacionId, add, update, del, canEdit }: {
function SeccionGlucemias({ glucemias, patientId, internacionId, add, update, del, canEdit, portalNode}: {
glucemias: Glucemia[];
patientId: string;
internacionId: string;
@@ -688,6 +658,7 @@ function SeccionGlucemias({ glucemias, patientId, internacionId, add, update, de
update: (id: string, data: Partial<Glucemia>) => void;
del: (id: string) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const [dialog, setDialog] = useState(false);
const [evolDialog, setEvolDialog] = useState(false);
@@ -768,8 +739,8 @@ function SeccionGlucemias({ glucemias, patientId, internacionId, add, update, de
return (
<div className="space-y-4 w-full max-w-full min-w-0">
<div className="flex justify-between">
<div className="flex gap-2">
{portalNode ? createPortal(
<>
{canEdit && (
<Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-2" />Nueva
@@ -778,8 +749,22 @@ function SeccionGlucemias({ glucemias, patientId, internacionId, add, update, de
<Button variant="outline" onClick={() => setEvolDialog(true)} disabled={listGlucemias.length === 0}>
<TrendingUp className="h-4 w-4 mr-2" />Evolución
</Button>
</>,
portalNode
) : (
<div className="flex justify-between mb-4">
<div className="flex gap-2">
{canEdit && (
<Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-2" />Nueva
</Button>
)}
<Button variant="outline" onClick={() => setEvolDialog(true)} disabled={listGlucemias.length === 0}>
<TrendingUp className="h-4 w-4 mr-2" />Evolución
</Button>
</div>
</div>
</div>
)}
<Dialog open={dialog} onOpenChange={setDialog}>
<DialogContent className="sm:max-w-md">
@@ -940,7 +925,7 @@ function SeccionGlucemias({ glucemias, patientId, internacionId, add, update, de
);
}
function SeccionLaboratorios({ lab, patientId, internacionId, add, update, del, addAcidoBase, canEdit }: {
function SeccionLaboratorios({ lab, patientId, internacionId, add, update, del, addAcidoBase, canEdit, portalNode}: {
lab: Laboratorio[];
patientId: string;
internacionId: string;
@@ -949,6 +934,7 @@ function SeccionLaboratorios({ lab, patientId, internacionId, add, update, del,
del: (id: string) => void;
addAcidoBase?: (a: Omit<AcidoBase, 'id'>) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const [dialog, setDialog] = useState(false);
const [obsDialog, setObsDialog] = useState(false);
@@ -1864,13 +1850,14 @@ function SeccionLaboratorios({ lab, patientId, internacionId, add, update, del,
);
}
function SeccionEvoluciones({ evos, internacionId, add, update, del, canEdit }: {
function SeccionEvoluciones({ evos, internacionId, add, update, del, canEdit, portalNode}: {
evos: Evolucion[];
internacionId: string;
add: (e: Omit<Evolucion, 'id'>) => void;
update: (id: string, data: Partial<Evolucion>) => void;
del: (id: string) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const { currentUser } = useHospitalStore();
const [dialog, setDialog] = useState(false);
@@ -1974,9 +1961,14 @@ function SeccionEvoluciones({ evos, internacionId, add, update, del, canEdit }:
return (
<div className="space-y-4">
<div className="flex">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Evolución</Button>}
</div>
{portalNode ? createPortal(
canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Evolución</Button>,
portalNode
) : (
<div className="flex mb-4">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Evolución</Button>}
</div>
)}
<Dialog open={dialog} onOpenChange={setDialog}>
<DialogContent className="sm:max-w-3xl max-h-[90vh] overflow-y-auto">
<DialogHeader><DialogTitle>{edit ? 'Editar' : 'Nueva'} Evolución</DialogTitle></DialogHeader>
@@ -2181,7 +2173,7 @@ function SeccionEvoluciones({ evos, internacionId, add, update, del, canEdit }:
);
}
function SeccionAcidosBase({ ab, patientId, internacionId, add, update, del, canEdit }: {
function SeccionAcidosBase({ ab, patientId, internacionId, add, update, del, canEdit, portalNode}: {
ab: AcidoBase[];
patientId: string;
internacionId: string;
@@ -2189,6 +2181,7 @@ function SeccionAcidosBase({ ab, patientId, internacionId, add, update, del, can
update: (id: string, datos: Partial<AcidoBase>) => void;
del: (id: string) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const [dialog, setDialog] = useState(false);
const [editDialog, setEditDialog] = useState(false);
@@ -2260,9 +2253,14 @@ function SeccionAcidosBase({ ab, patientId, internacionId, add, update, del, can
return (
<div className="space-y-4">
<div className="flex">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Gasometría</Button>}
</div>
{portalNode ? createPortal(
canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Gasometría</Button>,
portalNode
) : (
<div className="flex mb-4">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Gasometría</Button>}
</div>
)}
<Dialog open={dialog} onOpenChange={setDialog}>
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
<DialogHeader><DialogTitle>Nueva Gasometría Arterial</DialogTitle></DialogHeader>
@@ -2400,7 +2398,7 @@ function SeccionAcidosBase({ ab, patientId, internacionId, add, update, del, can
);
}
function SeccionCultivos({ cults, patient, internacionId, add, update, del, canEdit }: {
function SeccionCultivos({ cults, patient, internacionId, add, update, del, canEdit, portalNode}: {
cults: Cultivo[];
patient: Paciente;
internacionId: string;
@@ -2408,6 +2406,7 @@ function SeccionCultivos({ cults, patient, internacionId, add, update, del, canE
update: (id: string, data: Partial<Cultivo>) => void;
del: (id: string) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const [dialog, setDialog] = useState(false);
const [resDialog, setResDialog] = useState(false);
@@ -2505,9 +2504,14 @@ function SeccionCultivos({ cults, patient, internacionId, add, update, del, canE
return (
<div className="space-y-4">
<div className="flex">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nuevo Cultivo</Button>}
</div>
{portalNode ? createPortal(
canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nuevo Cultivo</Button>,
portalNode
) : (
<div className="flex mb-4">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nuevo Cultivo</Button>}
</div>
)}
<Dialog open={dialog} onOpenChange={setDialog}>
<DialogContent className="sm:max-w-lg">
<DialogHeader><DialogTitle>Nuevo Cultivo</DialogTitle></DialogHeader>
@@ -2698,7 +2702,7 @@ function SeccionCultivos({ cults, patient, internacionId, add, update, del, canE
);
}
function SeccionEstudiosComplementarios({ estudios, internacionId, pacienteId, add, update, del, canEdit }: {
function SeccionEstudiosComplementarios({ estudios, internacionId, pacienteId, add, update, del, canEdit, portalNode}: {
estudios: EstudioComplementario[];
internacionId: string;
pacienteId: string;
@@ -2706,6 +2710,7 @@ function SeccionEstudiosComplementarios({ estudios, internacionId, pacienteId, a
update: (id: string, datos: Partial<EstudioComplementario>) => void;
del: (id: string) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const [dialog, setDialog] = useState(false);
const [filtro, setFiltro] = useState<'todos' | 'internacion'>('internacion');
@@ -2847,7 +2852,7 @@ function SeccionEstudiosComplementarios({ estudios, internacionId, pacienteId, a
);
}
function SeccionInterconsultas({ interconsultas, pacienteId, internacionId, add, update, del, canEdit }: {
function SeccionInterconsultas({ interconsultas, pacienteId, internacionId, add, update, del, canEdit, portalNode}: {
interconsultas: Interconsulta[];
pacienteId: string;
internacionId: string;
@@ -2855,6 +2860,7 @@ function SeccionInterconsultas({ interconsultas, pacienteId, internacionId, add,
update: (id: string, datos: Partial<Interconsulta>) => void;
del: (id: string) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const [dialog, setDialog] = useState(false);
const [fecha, setFecha] = useState(getLocalToday());
@@ -2902,12 +2908,20 @@ function SeccionInterconsultas({ interconsultas, pacienteId, internacionId, add,
return (
<div className="space-y-4">
<div className="flex justify-between items-center">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
{portalNode ? createPortal(
canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-2" />
Nueva IC
</Button>}
</div>
</Button>,
portalNode
) : (
<div className="flex justify-between items-center mb-4">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-2" />
Nueva IC
</Button>}
</div>
)}
<Dialog open={dialog} onOpenChange={setDialog}>
<DialogContent className="sm:max-w-lg">
@@ -3020,7 +3034,7 @@ function SeccionInterconsultas({ interconsultas, pacienteId, internacionId, add,
);
}
function SeccionATB({ atb, internacionId, pacienteId, add, update, del, canEdit }: {
function SeccionATB({ atb, internacionId, pacienteId, add, update, del, canEdit, portalNode}: {
atb: ATB[];
internacionId: string;
pacienteId: string;
@@ -3028,6 +3042,7 @@ function SeccionATB({ atb, internacionId, pacienteId, add, update, del, canEdit
update: (id: string, data: Partial<ATB>) => void;
del: (id: string) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
}) {
const [dialog, setDialog] = useState(false);
const [edit, setEdit] = useState<ATB | null>(null);
@@ -3085,11 +3100,18 @@ function SeccionATB({ atb, internacionId, pacienteId, add, update, del, canEdit
return (
<div className="space-y-4">
<div className="flex justify-between">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
{portalNode ? createPortal(
canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-2" />Nuevo
</Button>}
</div>
</Button>,
portalNode
) : (
<div className="flex justify-between mb-4">
{canEdit && <Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-2" />Nuevo
</Button>}
</div>
)}
<Dialog open={dialog} onOpenChange={setDialog}>
<DialogContent className="sm:max-w-md">
@@ -3159,7 +3181,7 @@ function SeccionATB({ atb, internacionId, pacienteId, add, update, del, canEdit
);
}
function SeccionPendientes({ pacienteId, internacionId, canEdit }: { pacienteId: string; internacionId: string; canEdit: boolean }) {
function SeccionPendientes({ pacienteId, internacionId, canEdit, portalNode}: { pacienteId: string; internacionId: string; canEdit: boolean; portalNode?: HTMLDivElement | null; }) {
const { pendientes, agregarPendiente, actualizarPendiente, eliminarPendiente, currentUser } = useHospitalStore();
const [modalAbierto, setModalAbierto] = useState(false);
const [pendienteEditar, setPendienteEditar] = useState<Pendiente | null>(null);
@@ -3368,18 +3390,34 @@ function SeccionPendientes({ pacienteId, internacionId, canEdit }: { pacienteId:
</Select>
</div>
<div className="flex items-center gap-2 w-full sm:w-auto justify-end">
<Button variant="outline" size="sm" onClick={handleCopiarPendientes} title="Copiar pendientes activos">
<Copy className="h-4 w-4 mr-1.5" />
Copiar
</Button>
{canEdit && (
<Button size="sm" onClick={() => { resetForm(); setModalAbierto(true); }}>
<Plus className="h-4 w-4 mr-1.5" />
Nuevo Pendiente
{portalNode ? createPortal(
<>
<Button variant="outline" size="sm" onClick={handleCopiarPendientes} title="Copiar pendientes activos">
<Copy className="h-4 w-4 mr-1.5" />
Copiar
</Button>
)}
</div>
{canEdit && (
<Button size="sm" onClick={() => { resetForm(); setModalAbierto(true); }}>
<Plus className="h-4 w-4 mr-1.5" />
Nuevo Pendiente
</Button>
)}
</>,
portalNode
) : (
<div className="flex items-center gap-2 w-full sm:w-auto justify-end mb-4">
<Button variant="outline" size="sm" onClick={handleCopiarPendientes} title="Copiar pendientes activos">
<Copy className="h-4 w-4 mr-1.5" />
Copiar
</Button>
{canEdit && (
<Button size="sm" onClick={() => { resetForm(); setModalAbierto(true); }}>
<Plus className="h-4 w-4 mr-1.5" />
Nuevo Pendiente
</Button>
)}
</div>
)}
</div>
{/* List of Pendientes */}
+23 -9
View File
@@ -1,4 +1,5 @@
import { useState } from 'react';
import { createPortal } from 'react';
import { toast } from 'sonner';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
@@ -13,7 +14,7 @@ import type { Indicacion, IndicacionTipo, ViaAdministracion, TipoPlanHidratacion
import { useHospitalStore } from '@/hooks/useHospitalStore';
import { getNombreProfesional, getLocalToday } from '@/lib/utils';
export function SeccionIndicaciones({ recomendaciones, internacionId, pacienteId, add, update, del, movimientos, onAgregarMovimiento, canEdit, atbList = [], addATB, updateATB }: {
export function SeccionIndicaciones({ recomendaciones, internacionId, pacienteId, add, update, del, movimientos, onAgregarMovimiento, canEdit, atbList = [], addATB, updateATB, portalNode}: {
recomendaciones: Indicacion[];
internacionId: string;
pacienteId?: string;
@@ -23,6 +24,7 @@ export function SeccionIndicaciones({ recomendaciones, internacionId, pacienteId
movimientos?: unknown[];
onAgregarMovimiento?: (m: unknown) => void;
canEdit?: boolean;
portalNode?: HTMLDivElement | null;
atbList?: ATB[];
addATB?: (a: Omit<ATB, 'id'>) => Promise<unknown>;
updateATB?: (id: string, datos: Partial<ATB>) => void;
@@ -283,14 +285,26 @@ export function SeccionIndicaciones({ recomendaciones, internacionId, pacienteId
return (
<div className="space-y-2.5">
<div className="flex justify-between items-center">
{canEdit && <Button size="sm" variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-1.5" />Nueva Indicación
</Button>}
<Button size="sm" variant="ghost" onClick={() => setShowHistorial(!showHistorial)}>
{showHistorial ? 'Ocultar Historial' : `Ver Historial (${movs.length})`}
</Button>
</div>
{portalNode ? createPortal(
<>
{canEdit && <Button size="sm" variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-1.5" />Nueva Indicación
</Button>}
<Button size="sm" variant="ghost" onClick={() => setShowHistorial(!showHistorial)}>
{showHistorial ? 'Ocultar Historial' : `Ver Historial (${movs.length})`}
</Button>
</>,
portalNode
) : (
<div className="flex justify-between items-center mb-4">
{canEdit && <Button size="sm" variant="outline" onClick={() => { reset(); setDialog(true); }}>
<Plus className="h-4 w-4 mr-1.5" />Nueva Indicación
</Button>}
<Button size="sm" variant="ghost" onClick={() => setShowHistorial(!showHistorial)}>
{showHistorial ? 'Ocultar Historial' : `Ver Historial (${movs.length})`}
</Button>
</div>
)}
<Dialog open={dialog} onOpenChange={setDialog}>
<DialogContent className="sm:max-w-lg">