diff --git a/web-v2/src/features/assets/AssetHierarchyView.tsx b/web-v2/src/features/assets/AssetHierarchyView.tsx index c5f092c..0d113bf 100644 --- a/web-v2/src/features/assets/AssetHierarchyView.tsx +++ b/web-v2/src/features/assets/AssetHierarchyView.tsx @@ -6,11 +6,13 @@ import { Icon } from '../../components/Icon'; import { getAssetLineage } from '../../lib/api'; import type { AssetLineageItem } from '../../lib/api'; import { - listInventoryAreas, + listInventoryCompanies, + listInventoryDepartments, listInventoryChildren, } from '../../lib/inventoryBrowserApi'; import type { - InventoryBrowserArea, + InventoryBrowserCompany, + InventoryBrowserDepartment, InventoryBrowserItem, InventoryQuery, } from '../../lib/inventoryBrowserApi'; @@ -26,28 +28,30 @@ function navigationHref(base: URLSearchParams, parentId?: string) { return `/inventarios${params.size ? `?${params}` : ''}`; } -function AreaCard({ area, href }: { area: InventoryBrowserArea; href: string }) { +function DepartmentCard({ department, href }: { department: InventoryBrowserDepartment; 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'} + {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 }) { - const structural = !item.isInventoryInstance; return - + {item.name} @@ -57,9 +61,10 @@ function InventoryCard({ item, href }: { item: InventoryBrowserItem; href: strin - {structural - ? <>Contexto{item.childrenCount} nivel{item.childrenCount === 1 ? '' : 'es'} inferior{item.childrenCount === 1 ? '' : 'es'} - : <>{assetStatusLabel(item.informationStatus)}{assetOperationalStatusLabel(item.operationalStatus)}} + {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'}} ; @@ -67,6 +72,7 @@ function InventoryCard({ item, href }: { item: InventoryBrowserItem; href: strin function nextLevelLabel(typeCode: string | undefined) { switch (typeCode?.toLowerCase()) { + case 'departamento': return 'Áreas'; case 'area': return 'Yacimientos'; case 'yacimiento': return 'Instalaciones'; case 'instalacion': return 'Subinstalaciones'; @@ -79,7 +85,8 @@ export function AssetHierarchyView({ filters }: { filters: InventoryQuery }) { const canCreate = hasPermission('assets.create'); const [searchParams] = useSearchParams(); const parentId = searchParams.get('parentId') ?? ''; - const [areas, setAreas] = useState([]); + const [departments, setDepartments] = useState([]); + const [companies, setCompanies] = useState([]); const [children, setChildren] = useState([]); const [lineage, setLineage] = useState([]); const [hasMore, setHasMore] = useState(false); @@ -88,66 +95,53 @@ export function AssetHierarchyView({ filters }: { filters: InventoryQuery }) { useEffect(() => { let active = true; - setLoading(true); - setError(''); - setAreas([]); - setChildren([]); - setLineage([]); - setHasMore(false); - + setLoading(true); setError(''); setDepartments([]); setCompanies([]); 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); + 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) => ['area','yacimiento','instalacion','subinstalacion'].includes(item.type.code.toLowerCase()))); - setChildren(response.data); - setHasMore(response.meta.hasMore); + 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)); + run().catch((requestError) => active && setError(errorMessage(requestError))).finally(() => active && setLoading(false)); return () => { active = false; }; - }, [parentId, filters.search, filters.operationalAreaId, filters.operatorCompanyId]); + }, [parentId, filters.search, filters.operatorCompanyId]); - if (loading) return ; + 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 -
+
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
- {areas.length === 0 - ? - :
{areas.map((area) => )}
} + {departments.length === 0 + ? + :
{departments.map((department) => )}
} +
-
1ÁreaAncla territorial
-
2YacimientoContexto dentro del Área
-
3InstalaciónInventario real
-
4SubinstalaciónInventario real
+
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) => )}
} +
; } @@ -156,10 +150,7 @@ export function AssetHierarchyView({ filters }: { filters: InventoryQuery }) { Inventarios {lineage.map((item,index) => { const isLast=index===lineage.length-1; - return - - {isLast ? {item.name} : {item.name}} - ; + return {isLast ? {item.name} : {item.name}}; })} ; @@ -168,31 +159,17 @@ export function AssetHierarchyView({ filters }: { filters: InventoryQuery }) { {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?.type.name ?? 'INVENTARIO'}

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

{current?.code ?? ''}

- {current && Ver ficha} + {current && Ver ficha{['instalacion','subinstalacion'].includes(current.type.code.toLowerCase()) ? ' y Hallazgos' : ''}} {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} -
+

{nextLevelLabel(current?.type.code)}

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

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