diff --git a/web-v2/src/pages/InventoryCreatePage.tsx b/web-v2/src/pages/InventoryCreatePage.tsx index 0bfe037..c83a21e 100644 --- a/web-v2/src/pages/InventoryCreatePage.tsx +++ b/web-v2/src/pages/InventoryCreatePage.tsx @@ -18,22 +18,31 @@ import type { InventoryStructureParent, } from '../lib/inventoryStructureApi'; -const STRUCTURE_KINDS: Array<{ kind: InventoryStructureKind; label: string; help: string; step: number }> = [ - { kind: 'AREA', label: 'Área', help: 'Nivel territorial raíz.', step: 1 }, - { kind: 'YACIMIENTO', label: 'Yacimiento', help: 'Debe pertenecer a un Área.', step: 2 }, - { kind: 'INSTALACION', label: 'Instalación', help: 'Debe pertenecer a un Yacimiento.', step: 3 }, - { kind: 'SUBINSTALACION', label: 'Subinstalación', help: 'Debe pertenecer a una Instalación.', step: 4 }, +const KINDS: Array<{ kind: InventoryStructureKind; label: string }> = [ + { kind: 'DEPARTAMENTO', label: 'Departamento' }, + { kind: 'AREA', label: 'Área' }, + { kind: 'YACIMIENTO', label: 'Yacimiento' }, + { kind: 'INSTALACION', label: 'Instalación' }, + { kind: 'SUBINSTALACION', label: 'Subinstalación' }, + { kind: 'EMPRESA', label: 'Empresa' }, ]; const childKindByParentType: Record = { + departamento: 'AREA', area: 'YACIMIENTO', yacimiento: 'INSTALACION', instalacion: 'SUBINSTALACION', }; -function kindLabel(kind: InventoryStructureKind): string { - if (kind === 'EMPRESA') return 'Empresa'; - return STRUCTURE_KINDS.find((item) => item.kind === kind)?.label ?? kind; +const parentLabelByKind: Partial> = { + AREA:'Departamento', + YACIMIENTO:'Área', + INSTALACION:'Yacimiento', + SUBINSTALACION:'Instalación', +}; + +function kindLabel(kind: InventoryStructureKind) { + return KINDS.find((item) => item.kind===kind)?.label ?? kind; } export function InventoryCreatePage() { @@ -41,14 +50,14 @@ export function InventoryCreatePage() { const [searchParams] = useSearchParams(); const contextParentId = searchParams.get('parentId'); const [options, setOptions] = useState(null); - const [kind, setKind] = useState('AREA'); + const [kind, setKind] = useState('DEPARTAMENTO'); const [parents, setParents] = useState([]); const [parentSearch, setParentSearch] = useState(''); const [parentId, setParentId] = useState(''); const [familyId, setFamilyId] = useState(''); const [familyFindings, setFamilyFindings] = useState(null); - const [code, setCode] = useState(''); const [name, setName] = useState(''); + const [code, setCode] = useState(''); const [commonName, setCommonName] = useState(''); const [description, setDescription] = useState(''); const [loading, setLoading] = useState(true); @@ -62,224 +71,113 @@ export function InventoryCreatePage() { if (contextParentId) { const parent = await getAsset(contextParentId); const inferred = childKindByParentType[parent.type.code.toLowerCase()]; - if (inferred) { - setKind(inferred); - setParentId(parent.id); - } + if (inferred) { setKind(inferred); setParentId(parent.id); } } }) .catch((requestError) => setError(errorMessage(requestError))) .finally(() => setLoading(false)); }, [contextParentId]); + const requiresParent = Boolean(parentLabelByKind[kind]); + const requiresFamily = kind === 'INSTALACION' || kind === 'SUBINSTALACION'; + const parentLabel = parentLabelByKind[kind] ?? ''; + useEffect(() => { - if (kind === 'AREA' || kind === 'EMPRESA') { - setParents([]); - setParentId(''); - return; - } + if (!requiresParent) { setParents([]); setParentId(''); return; } const timer = window.setTimeout(() => { - listInventoryStructureParents(kind, parentSearch) + listInventoryStructureParents(kind,parentSearch) .then((loaded) => { setParents(loaded); - if (contextParentId && loaded.some((item) => item.id === contextParentId)) { - setParentId(contextParentId); - } + if (contextParentId && loaded.some((item) => item.id===contextParentId)) setParentId(contextParentId); }) .catch((requestError) => setError(errorMessage(requestError))); - }, 180); + },150); return () => window.clearTimeout(timer); - }, [kind, parentSearch, contextParentId]); + }, [kind,parentSearch,contextParentId,requiresParent]); - const selectedParent = parents.find((item) => item.id === parentId) ?? null; + const selectedParent = parents.find((item) => item.id===parentId) ?? null; const families = useMemo(() => { if (!options) return [] as InventoryFamily[]; - if (kind === 'INSTALACION') return options.installationFamilies; - if (kind === 'SUBINSTALACION') { - const parentFamilyId = selectedParent?.inventoryFamily?.id; - return parentFamilyId - ? options.subinstallationFamilies.filter((item) => item.parentFamilyId === parentFamilyId) - : []; + if (kind==='INSTALACION') return options.installationFamilies; + if (kind==='SUBINSTALACION') { + const parentFamilyId=selectedParent?.inventoryFamily?.id; + return parentFamilyId ? options.subinstallationFamilies.filter((item)=>item.parentFamilyId===parentFamilyId) : []; } return []; - }, [options, kind, selectedParent]); - const selectedFamily = families.find((item) => item.id === familyId) ?? null; + },[options,kind,selectedParent]); + const selectedFamily=families.find((item)=>item.id===familyId) ?? null; useEffect(() => { - if (!familyId) { - setFamilyFindings(null); - return; - } - getInventoryFamilyFindings(familyId) - .then(setFamilyFindings) - .catch((requestError) => setError(errorMessage(requestError))); - }, [familyId]); + if (!familyId) { setFamilyFindings(null); return; } + getInventoryFamilyFindings(familyId).then(setFamilyFindings).catch((requestError)=>setError(errorMessage(requestError))); + },[familyId]); useEffect(() => { - if (kind !== 'INSTALACION' && kind !== 'SUBINSTALACION') setFamilyId(''); - if (kind === 'SUBINSTALACION' && familyId && !families.some((item) => item.id === familyId)) setFamilyId(''); - }, [kind, familyId, families]); + if (!requiresFamily) setFamilyId(''); + if (kind==='SUBINSTALACION' && familyId && !families.some((item)=>item.id===familyId)) setFamilyId(''); + },[kind,requiresFamily,families,familyId]); - const chooseKind = (next: InventoryStructureKind) => { - setKind(next); - setParentId(''); - setParentSearch(''); - setFamilyId(''); - setFamilyFindings(null); - setError(''); + const changeKind=(next:InventoryStructureKind) => { + setKind(next); setParentId(''); setParentSearch(''); setFamilyId(''); setFamilyFindings(null); setError(''); }; - const save = async (event: FormEvent) => { + const save=async(event:FormEvent) => { event.preventDefault(); - const requiresParent = kind !== 'AREA' && kind !== 'EMPRESA'; - const requiresFamily = kind === 'INSTALACION' || kind === 'SUBINSTALACION'; - if (requiresParent && !parentId) { - setError(`Seleccioná el ${kind === 'YACIMIENTO' ? 'Área' : kind === 'INSTALACION' ? 'Yacimiento' : 'Instalación'} padre.`); - return; - } - if (requiresFamily && !familyId) { - setError(`Seleccioná la familia de ${kindLabel(kind).toLowerCase()}.`); - return; - } - setSaving(true); - setError(''); + if (requiresParent && !parentId) { setError(`Seleccioná ${parentLabel}.`); return; } + if (requiresFamily && !familyId) { setError(`Seleccioná el tipo de ${kindLabel(kind).toLowerCase()}.`); return; } + setSaving(true); setError(''); try { - const created = await createInventoryStructure({ - kind, - code: code.trim() || null, - name: name.trim(), - commonName: commonName.trim() || null, - parentId: parentId || null, - familyId: familyId || null, - description: description.trim() || null, + const created=await createInventoryStructure({ + kind,name:name.trim(),parentId:parentId || null,familyId:familyId || null, + code:code.trim() || null,commonName:commonName.trim() || null,description:description.trim() || null, }); - navigate(`/inventarios/${created.id}`, { replace: true }); - } catch (requestError) { - setError(errorMessage(requestError)); - } finally { - setSaving(false); - } + navigate(`/inventarios/${created.id}`,{replace:true}); + } catch(requestError) { setError(errorMessage(requestError)); } + finally { setSaving(false); } }; if (loading) return ; - const isIndependentCompany = kind === 'EMPRESA'; - const parentLabel = kind === 'YACIMIENTO' ? 'Área' : kind === 'INSTALACION' ? 'Yacimiento' : 'Instalación'; - const currentStep = STRUCTURE_KINDS.find((item) => item.kind === kind)?.step ?? 1; - const identificationStep = isIndependentCompany ? '2' : kind === 'AREA' ? '2' : kind === 'YACIMIENTO' ? '3' : '4'; - const requiresParent = kind !== 'AREA' && kind !== 'EMPRESA'; - return
- - +
-
- CONFIGURACIÓN E INVENTARIO -

Agregar registro

-

Empresa es un maestro independiente. La estructura física es Área → Yacimiento → Instalación → Subinstalación.

-
+
CARGA MANUAL

Nuevo registro

Elegí qué querés crear, dónde va y su nombre. El resto es opcional.

- {error && {error}} -
-
-

1. ¿Qué querés crear?

Creá una Empresa independiente o agregá un nivel a la estructura física.

-
- - {STRUCTURE_KINDS.map((item) => )} -
- {isIndependentCompany ?
- -

Empresa: no forma parte de la jerarquía física. Su vínculo con un Área se administra como relación temporal de operación/concesión.

-
:
- -

Ruta física: {STRUCTURE_KINDS.slice(0, currentStep).map((item) => item.label).join(' → ')}

-
} -
-
-
+
+

1. Tipo de registro

La estructura física es Departamento → Área → Yacimiento → Instalación → Subinstalación. Empresa es un maestro independiente.

+ +
+ {requiresParent &&
-

2. Ubicación en la estructura

Primero elegí el {parentLabel} al que pertenece este registro.

- - +

2. Ubicación

Elegí el {parentLabel.toLowerCase()} al que pertenece.

+ +
} - {(kind === 'INSTALACION' || kind === 'SUBINSTALACION') &&
-

3. Clasificación técnica

La clasificación no crea otro nivel: define el tipo de Instalación/Subinstalación y los Hallazgos aplicables.

- {kind === 'SUBINSTALACION' && !selectedParent?.inventoryFamily ? La Instalación seleccionada todavía no tiene una clasificación técnica. Revisala antes de crear una Subinstalación. : } - - {selectedFamily &&
- -
- Hallazgos asociados automáticamente - {familyFindings ? `${familyFindings.count} Hallazgos aplicables para ${selectedFamily.name}` : 'Cargando catálogo asociado…'} - {familyFindings && familyFindings.items.length > 0 &&
    - {familyFindings.items.slice(0, 7).map((item) =>
  • {item.title}
  • )} - {familyFindings.items.length > 7 &&
  • + {familyFindings.items.length - 7} Hallazgos más
  • } -
} -
-
} - - {selectedFamily && selectedFamily.informationLabels.length > 0 &&
- -

Información técnica esperada: {selectedFamily.informationLabels.join(' · ')}

-
} + {requiresFamily &&
+

{requiresParent ? '3' : '2'}. Clasificación

Define qué tipo de elemento es y qué Hallazgos le corresponden.

+ {kind==='SUBINSTALACION' && !selectedParent?.inventoryFamily + ? La Instalación elegida todavía no tiene clasificación. Asignala antes de crear una Subinstalación. + : } + {selectedFamily &&
{selectedFamily.name}{familyFindings ? `${familyFindings.count} Hallazgo${familyFindings.count===1?'':'s'} asociado${familyFindings.count===1?'':'s'}` : 'Cargando Hallazgos asociados…'}{familyFindings && familyFindings.items.length>0 &&
    {familyFindings.items.slice(0,6).map((item)=>
  • {item.title}
  • )}{familyFindings.items.length>6 &&
  • + {familyFindings.items.length-6} más
  • }
}
}
}
-

{identificationStep}. Identificación

{isIndependentCompany ? 'Registrá la denominación de la Empresa.' : 'Usá el nombre real de campo.'} El código DH puede generarse automáticamente.

-
- - - -
-