diff --git a/web-v2/src/features/assets/AssetHierarchyView.tsx b/web-v2/src/features/assets/AssetHierarchyView.tsx index 0d113bf..32c76fc 100644 --- a/web-v2/src/features/assets/AssetHierarchyView.tsx +++ b/web-v2/src/features/assets/AssetHierarchyView.tsx @@ -4,7 +4,7 @@ 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 type { AssetLineageItem, AssetType } from '../../lib/api'; import { listInventoryCompanies, listInventoryDepartments, @@ -18,16 +18,61 @@ import type { } from '../../lib/inventoryBrowserApi'; import { assetOperationalStatusLabel, assetStatusClass, assetStatusLabel } from './assetPresentation'; +const structuredInventorySections = [ + { + code: 'empresa', + label: 'Empresas', + description: 'Maestro de empresas operadoras. Se vinculan a una o más Áreas sin formar parte del árbol territorial.', + icon: 'users' as const, + }, + { + code: 'departamento', + label: 'Departamentos', + description: 'Primer nivel territorial. Desde cada Departamento se accede a sus Áreas.', + icon: 'map' as const, + }, + { + code: 'area', + label: 'Áreas', + description: 'Cada Área pertenece a un Departamento y puede tener una o más Empresas operadoras vinculadas.', + icon: 'map' as const, + }, + { + code: 'yacimiento', + label: 'Yacimientos', + description: 'Nivel operativo dentro de un Área. Organiza las Instalaciones que pertenecen a ese Yacimiento.', + icon: 'map' as const, + }, + { + code: 'instalacion', + label: 'Instalaciones', + description: 'Elementos técnicos ubicados dentro de un Yacimiento y clasificados por su familia de Inventario.', + icon: 'layers' as const, + }, + { + code: 'subinstalacion', + label: 'Subinstalaciones', + description: 'Último nivel estructural. Dependen de una Instalación y conservan su clasificación técnica.', + icon: 'layers' as const, + }, +] as const; + function navigationHref(base: URLSearchParams, parentId?: string) { const params = new URLSearchParams(base); params.delete('view'); params.delete('page'); params.delete('section'); params.delete('companyId'); + params.delete('typeId'); parentId ? params.set('parentId', parentId) : params.delete('parentId'); return `/inventarios${params.size ? `?${params}` : ''}`; } +function inventoryTypeForSection(types: AssetType[], code: string) { + if (code === 'empresa') return types.find((type) => type.operationalRole === 'COMPANY') ?? null; + return types.find((type) => type.code.toLowerCase() === code) ?? null; +} + function DepartmentCard({ department, href }: { department: InventoryBrowserDepartment; href: string }) { return @@ -80,7 +125,7 @@ function nextLevelLabel(typeCode: string | undefined) { } } -export function AssetHierarchyView({ filters }: { filters: InventoryQuery }) { +export function AssetHierarchyView({ filters, types }: { filters: InventoryQuery; types: AssetType[] }) { const { hasPermission } = useAuth(); const canCreate = hasPermission('assets.create'); const [searchParams] = useSearchParams(); @@ -123,24 +168,48 @@ export function AssetHierarchyView({ filters }: { filters: InventoryQuery }) { 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.

+
+ INVENTARIOS ESTRUCTURADOS +

Elegí qué querés administrar

+

La estructura queda fija y fácil de leer: Empresas como maestro de operadoras y, por separado, Departamento → Área → Yacimiento → Instalación → Subinstalación.

+
{departments.length} Departamentos{companies.length} Empresas
- {departments.length === 0 - ? - :
{departments.map((department) => )}
} -
+
+ {structuredInventorySections.map((section, index) => { + const assetType = inventoryTypeForSection(types, section.code); + const content = <> + + + {section.label} + {section.description} + + {section.code === 'empresa' ? 'Maestro independiente' : `Nivel ${index}`} + {assetType && } + ; + return assetType + ? {content} + :
{content}
; + })} +
+ +
1Departamentoraíz territorial
-
2Áreadentro del Departamento
+
2Áreaoperadoras vinculadas
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) => )}
} +
+

Recorrido por territorio

También podés navegar como árbol: entrá por un Departamento y descendé hasta la Instalación o Subinstalación concreta.

+ {departments.length} +
+ {departments.length === 0 + ? + :
{departments.map((department) => )}
}
; }