import { useEffect, useState } from 'react'; import { Link, useSearchParams } from 'react-router'; import { useAuth } from '../../auth/AuthContext'; import { Alert, EmptyState, LoadingBlock, errorMessage } from '../../components/Feedback'; import { Icon } from '../../components/Icon'; import { getAssetLineage } from '../../lib/api'; import type { AssetLineageItem } from '../../lib/api'; import { listInventoryAreas, listInventoryChildren, } from '../../lib/inventoryBrowserApi'; import type { InventoryBrowserArea, InventoryBrowserItem, InventoryQuery, } from '../../lib/inventoryBrowserApi'; import { assetOperationalStatusLabel, assetStatusClass, assetStatusLabel } from './assetPresentation'; function navigationHref(base: URLSearchParams, parentId?: string) { const params = new URLSearchParams(base); params.delete('view'); params.delete('page'); params.delete('section'); params.delete('companyId'); parentId ? params.set('parentId', parentId) : params.delete('parentId'); return `/inventarios${params.size ? `?${params}` : ''}`; } function AreaCard({ area, href }: { area: InventoryBrowserArea; href: string }) { return {area.name} {area.code} · {area.yacimientoCount} yacimiento{area.yacimientoCount === 1 ? '' : 's'} {area.currentOperator ? ` · Operadora vigente: ${area.currentOperator.name}` : ' · Sin operadora vigente'} {area.inventoryCount} instancia{area.inventoryCount === 1 ? '' : 's'} real{area.inventoryCount === 1 ? '' : 'es'} ; } function InventoryCard({ item, href }: { item: InventoryBrowserItem; href: string }) { const structural = !item.isInventoryInstance; return {item.name} {item.code} · {item.type.name} {item.inventoryFamily ? ` · ${item.inventoryFamily.name}` : ''} {item.commonName ? ` · ${item.commonName}` : ''} {structural ? <>Contexto{item.childrenCount} nivel{item.childrenCount === 1 ? '' : 'es'} inferior{item.childrenCount === 1 ? '' : 'es'} : <>{assetStatusLabel(item.informationStatus)}{assetOperationalStatusLabel(item.operationalStatus)}} ; } function nextLevelLabel(typeCode: string | undefined) { switch (typeCode?.toLowerCase()) { case 'area': return 'Yacimientos'; case 'yacimiento': return 'Instalaciones'; case 'instalacion': return 'Subinstalaciones'; default: return 'Niveles inferiores'; } } export function AssetHierarchyView({ filters }: { filters: InventoryQuery }) { const { hasPermission } = useAuth(); const canCreate = hasPermission('assets.create'); const [searchParams] = useSearchParams(); const parentId = searchParams.get('parentId') ?? ''; const [areas, setAreas] = useState([]); const [children, setChildren] = useState([]); const [lineage, setLineage] = useState([]); const [hasMore, setHasMore] = useState(false); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { let active = true; setLoading(true); setError(''); setAreas([]); setChildren([]); setLineage([]); setHasMore(false); const run = async () => { if (!parentId) { const response = await listInventoryAreas({ search: filters.search, operationalAreaId: filters.operationalAreaId, operatorCompanyId: filters.operatorCompanyId, }); if (active) setAreas(response.data); return; } const [loadedLineage, response] = await Promise.all([ getAssetLineage(parentId), listInventoryChildren(parentId, { search: filters.search }), ]); if (!active) return; setLineage(loadedLineage.filter((item) => ['area','yacimiento','instalacion','subinstalacion'].includes(item.type.code.toLowerCase()))); setChildren(response.data); setHasMore(response.meta.hasMore); }; run() .catch((requestError) => active && setError(errorMessage(requestError))) .finally(() => active && setLoading(false)); return () => { active = false; }; }, [parentId, filters.search, filters.operationalAreaId, filters.operatorCompanyId]); if (loading) return ; if (!parentId) { const realTotal = areas.reduce((sum, area) => sum + Number(area.inventoryCount ?? 0), 0); return
{error && {error}}
ESTRUCTURA TERRITORIAL

Áreas

Las Áreas y Yacimientos son contexto de navegación. El Inventario real comienza en las Instalaciones/Subinstalaciones efectivamente registradas.

{realTotal} Inventario real {areas.length} Áreas
{areas.length === 0 ? :
{areas.map((area) => )}
}
1ÁreaAncla territorial
2YacimientoContexto dentro del Área
3InstalaciónInventario real
4SubinstalaciónInventario real
; } const current = lineage.at(-1) ?? null; const breadcrumb = ; return
{breadcrumb} {error && {error}} {hasMore && Este nivel tiene más de 200 registros. Usá la búsqueda para acotar el resultado.}
{current?.type.name ?? 'INVENTARIO'}

{current?.name ?? 'Nivel de Inventario'}

{current?.code ?? ''}

{current && Ver ficha} {canCreate && current?.type.code.toLowerCase() !== 'subinstalacion' && Agregar aquí}

{nextLevelLabel(current?.type.code)}

La jerarquía permitida es Área → Yacimiento → Instalación → Subinstalación.

{children.length}
{children.length === 0 ? :
{children.map((item) => )}
}
; }