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 { listInventoryCompanies, listInventoryDepartments, listInventoryChildren, } from '../../lib/inventoryBrowserApi'; import type { InventoryBrowserCompany, InventoryBrowserDepartment, 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 DepartmentCard({ department, href }: { department: InventoryBrowserDepartment; href: string }) { return {department.name} {department.code} · {department.areaCount} Área{department.areaCount === 1 ? '' : 's'} {assetStatusLabel(department.informationStatus)} ; } function CompanyCard({ company }: { company: InventoryBrowserCompany }) { return {company.name}{company.code} · {company.areaCount} Área{company.areaCount === 1 ? '' : 's'} operada{company.areaCount === 1 ? '' : 's'} {assetStatusLabel(company.informationStatus)} ; } function InventoryCard({ item, href }: { item: InventoryBrowserItem; href: string }) { return {item.name} {item.code} · {item.type.name} {item.inventoryFamily ? ` · ${item.inventoryFamily.name}` : ''} {item.commonName ? ` · ${item.commonName}` : ''} {assetStatusLabel(item.informationStatus)} {item.inventoryFamily ? {item.findingCount} Hallazgo{item.findingCount === 1 ? '' : 's'} asociado{item.findingCount === 1 ? '' : 's'} : {item.childrenCount} registro{item.childrenCount === 1 ? '' : 's'} inferior{item.childrenCount === 1 ? '' : 'es'}} ; } function nextLevelLabel(typeCode: string | undefined) { switch (typeCode?.toLowerCase()) { case 'departamento': return 'Áreas'; 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 [departments, setDepartments] = useState([]); const [companies, setCompanies] = 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(''); setDepartments([]); setCompanies([]); setChildren([]); setLineage([]); setHasMore(false); const run = async () => { if (!parentId) { const [loadedDepartments, loadedCompanies] = await Promise.all([ listInventoryDepartments({ search: filters.search, operatorCompanyId: filters.operatorCompanyId }), listInventoryCompanies({ search: filters.search }), ]); if (active) { setDepartments(loadedDepartments.data); setCompanies(loadedCompanies.data); } return; } const [loadedLineage, response] = await Promise.all([ getAssetLineage(parentId), listInventoryChildren(parentId, { search: filters.search }), ]); if (!active) return; setLineage(loadedLineage.filter((item) => ['departamento','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.operatorCompanyId]); if (loading) return ; if (!parentId) { return
{error && {error}}
INVENTARIO COMPLETO

Departamentos

Entrá por Departamento y navegá Área → Yacimiento → Instalación → Subinstalación hasta llegar a su clasificación y Hallazgos asociados.

{departments.length} Departamentos{companies.length} Empresas
{departments.length === 0 ? :
{departments.map((department) => )}
}
1Departamentoraíz territorial
2Áreadentro del Departamento
3Yacimientodentro del Área
4Instalaciónclasificación técnica
5Subinstalaciónclasificación técnica

Empresas

Maestro independiente. La Empresa se vincula al Área como operadora sin alterar la estructura física.

{companies.length}
{companies.length === 0 ?
Todavía no hay Empresas cargadas.
:
{companies.map((company) => )}
}
; } 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{['instalacion','subinstalacion'].includes(current.type.code.toLowerCase()) ? ' y Hallazgos' : ''}} {canCreate && current?.type.code.toLowerCase() !== 'subinstalacion' && Agregar aquí}

{nextLevelLabel(current?.type.code)}

Jerarquía: Departamento → Área → Yacimiento → Instalación → Subinstalación.

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