feat(web): capture Yacimiento company and concession
This commit is contained in:
@@ -44,6 +44,8 @@ export function InventoryCreatePage() {
|
||||
const [parentSearch, setParentSearch] = useState('');
|
||||
const [parentId, setParentId] = useState('');
|
||||
const [familyId, setFamilyId] = useState('');
|
||||
const [operatorCompanyId, setOperatorCompanyId] = useState('');
|
||||
const [concessionTypeId, setConcessionTypeId] = useState('');
|
||||
const [familyFindings, setFamilyFindings] = useState<InventoryFamilyFindings | null>(null);
|
||||
const [name, setName] = useState('');
|
||||
const [code, setCode] = useState('');
|
||||
@@ -66,6 +68,7 @@ export function InventoryCreatePage() {
|
||||
|
||||
const requiresParent = Boolean(parentLabelByKind[kind]);
|
||||
const requiresFamily = kind === 'INSTALACION' || kind === 'SUBINSTALACION';
|
||||
const requiresYacimientoContext = kind === 'YACIMIENTO';
|
||||
const parentLabel = parentLabelByKind[kind] ?? '';
|
||||
|
||||
useEffect(() => {
|
||||
@@ -99,18 +102,25 @@ export function InventoryCreatePage() {
|
||||
if (!requiresFamily) setFamilyId('');
|
||||
if (kind==='SUBINSTALACION' && familyId && !families.some((item)=>item.id===familyId)) setFamilyId('');
|
||||
},[kind,requiresFamily,families,familyId]);
|
||||
useEffect(() => {
|
||||
if (!requiresYacimientoContext) { setOperatorCompanyId(''); setConcessionTypeId(''); }
|
||||
},[requiresYacimientoContext]);
|
||||
|
||||
const changeKind=(next:InventoryStructureKind) => {
|
||||
setKind(next); setParentId(''); setParentSearch(''); setFamilyId(''); setFamilyFindings(null); setError('');
|
||||
setKind(next); setParentId(''); setParentSearch(''); setFamilyId(''); setFamilyFindings(null);
|
||||
setOperatorCompanyId(''); setConcessionTypeId(''); setError('');
|
||||
};
|
||||
const save=async(event:FormEvent) => {
|
||||
event.preventDefault();
|
||||
if (requiresParent && !parentId) { setError(`Seleccioná ${parentLabel}.`); return; }
|
||||
if (requiresYacimientoContext && !operatorCompanyId) { setError('Seleccioná la Empresa relacionada del Yacimiento.'); return; }
|
||||
if (requiresYacimientoContext && !concessionTypeId) { setError('Seleccioná el Tipo de concesión del Yacimiento.'); return; }
|
||||
if (requiresFamily && !familyId) { setError(`Seleccioná el tipo de ${kindLabel(kind).toLowerCase()}.`); return; }
|
||||
setSaving(true); setError('');
|
||||
try {
|
||||
const created=await createInventoryStructure({
|
||||
kind,name:name.trim(),parentId:parentId || null,familyId:familyId || null,
|
||||
operatorCompanyId:operatorCompanyId || null,concessionTypeId:concessionTypeId || null,
|
||||
code:code.trim() || null,commonName:commonName.trim() || null,description:description.trim() || null,
|
||||
});
|
||||
navigate(`/inventarios/${created.id}`,{replace:true});
|
||||
@@ -121,14 +131,15 @@ export function InventoryCreatePage() {
|
||||
if (loading) return <LoadingBlock label="Preparando alta…" />;
|
||||
return <section className="narrow-section asset-detail-page">
|
||||
<nav className="breadcrumb asset-detail-breadcrumb" aria-label="Ruta del Inventario"><Link to="/inventarios">Inventarios</Link><span>›</span><strong>Nuevo registro</strong></nav>
|
||||
<div className="page-heading asset-editor-heading"><div><span className="eyebrow">CARGA MANUAL</span><h1>Nuevo registro</h1><p>Para crear sólo necesitás ubicación, clasificación cuando corresponda y nombre. DH genera el código automáticamente.</p></div></div>
|
||||
<div className="page-heading asset-editor-heading"><div><span className="eyebrow">CARGA MANUAL</span><h1>Nuevo registro</h1><p>Modelo fijo: Departamento → Área → Yacimiento → Instalación → Subinstalación. La Empresa y el Tipo de concesión pertenecen al Yacimiento.</p></div></div>
|
||||
{error && <Alert>{error}</Alert>}
|
||||
<form className="panel form-panel" onSubmit={save}>
|
||||
<div className="form-section"><div><h2>1. ¿Qué querés crear?</h2><p className="section-copy">Departamento → Área → Yacimiento → Instalación → Subinstalación. Empresa queda fuera del árbol físico.</p></div><label className="field"><span>Tipo</span><select value={kind} onChange={(event)=>changeKind(event.target.value as InventoryStructureKind)}>{KINDS.map((item)=><option key={item.kind} value={item.kind}>{item.label}</option>)}</select></label></div>
|
||||
<div className="form-section"><div><h2>1. ¿Qué querés crear?</h2><p className="section-copy">Área sólo depende de Departamento. Yacimiento define Área, Empresa relacionada y Tipo de concesión.</p></div><label className="field"><span>Tipo</span><select value={kind} onChange={(event)=>changeKind(event.target.value as InventoryStructureKind)}>{KINDS.map((item)=><option key={item.kind} value={item.kind}>{item.label}</option>)}</select></label></div>
|
||||
{requiresParent && <div className="form-section"><div><h2>2. Ubicación</h2><p className="section-copy">Elegí el {parentLabel.toLowerCase()} concreto.</p></div><label className="field"><span>Buscar {parentLabel.toLowerCase()}</span><input value={parentSearch} onChange={(event)=>setParentSearch(event.target.value)} placeholder={`Buscar ${parentLabel.toLowerCase()}…`} /></label><label className="field"><span>{parentLabel} <em>obligatorio</em></span><select value={parentId} onChange={(event)=>{setParentId(event.target.value);setFamilyId('');}} required><option value="">Seleccionar…</option>{parents.map((parent)=><option key={parent.id} value={parent.id}>{parent.name} · {parent.code}</option>)}</select></label></div>}
|
||||
{requiresFamily && <div className="form-section"><div><h2>3. Clasificación técnica</h2><p className="section-copy">Define los datos técnicos y Hallazgos aplicables. En Subinstalaciones sólo aparecen clasificaciones compatibles con la Instalación elegida.</p></div>{kind==='SUBINSTALACION' && !selectedParent?.inventoryFamily ? <Alert>La Instalación elegida todavía no tiene clasificación técnica.</Alert> : <label className="field"><span>Tipo de {kindLabel(kind).toLowerCase()} <em>obligatorio</em></span><select value={familyId} onChange={(event)=>setFamilyId(event.target.value)} required><option value="">Seleccionar…</option>{families.map((family)=><option key={family.id} value={family.id}>{family.name}</option>)}</select></label>}{kind==='SUBINSTALACION' && selectedParent?.inventoryFamily && families.length===0 && <Alert>No hay tipos de Subinstalación compatibles con {selectedParent.inventoryFamily.name}. Configuralos primero en Configuración de Inventarios.</Alert>}{selectedFamily && <div className="context-create-banner"><Icon name="alert" /><div><strong>{selectedFamily.name}</strong><span>{familyFindings ? `${familyFindings.count} Hallazgo${familyFindings.count===1?'':'s'} asociado${familyFindings.count===1?'':'s'}` : 'Cargando Hallazgos asociados…'}</span>{familyFindings && familyFindings.items.length>0 && <ul style={{margin:'8px 0 0',paddingLeft:18}}>{familyFindings.items.slice(0,6).map((item)=><li key={item.id}>{item.title}</li>)}{familyFindings.items.length>6 && <li>+ {familyFindings.items.length-6} más</li>}</ul>}</div></div>}</div>}
|
||||
<div className="form-section"><div><h2>{requiresFamily ? '4' : requiresParent ? '3' : '2'}. Nombre</h2><p className="section-copy">Los datos técnicos se completan después, en la ficha del elemento.</p></div><label className="field"><span>Nombre <em>obligatorio</em></span><input autoFocus value={name} onChange={(event)=>setName(event.target.value)} required maxLength={200} placeholder={`Nombre de ${kindLabel(kind).toLowerCase()}`} /></label><details style={{marginTop:12}}><summary style={{cursor:'pointer',fontWeight:700}}>Datos opcionales</summary><div style={{marginTop:14}}><div className="form-grid"><label className="field"><span>Código DH</span><input value={code} onChange={(event)=>setCode(event.target.value.toUpperCase())} maxLength={120} pattern="[A-Z0-9][A-Z0-9._/-]*" placeholder="Dejalo vacío para generar automáticamente" /></label><label className="field"><span>Nombre habitual</span><input value={commonName} onChange={(event)=>setCommonName(event.target.value)} maxLength={200} /></label></div><label className="field"><span>Descripción</span><textarea value={description} onChange={(event)=>setDescription(event.target.value)} rows={2} maxLength={4000} /></label></div></details></div>
|
||||
<div className="form-actions"><Link className="button secondary" to="/inventarios">Cancelar</Link><button className="button primary" disabled={saving || !name.trim() || (requiresParent && !parentId) || (requiresFamily && !familyId)}><Icon name="check" />{saving?'Creando…':`Crear ${kindLabel(kind)}`}</button></div>
|
||||
{requiresYacimientoContext && <div className="form-section"><div><h2>3. Contexto del Yacimiento</h2><p className="section-copy">Estas relaciones pertenecen directamente al Yacimiento y no al Área.</p></div><div className="form-grid"><label className="field"><span>Empresa relacionada <em>obligatorio</em></span><select value={operatorCompanyId} onChange={(event)=>setOperatorCompanyId(event.target.value)} required><option value="">Seleccionar…</option>{options?.companies.map((company)=><option key={company.id} value={company.id}>{company.name}</option>)}</select></label><label className="field"><span>Tipo de concesión <em>obligatorio</em></span><select value={concessionTypeId} onChange={(event)=>setConcessionTypeId(event.target.value)} required><option value="">Seleccionar…</option>{options?.concessionTypes.map((type)=><option key={type.id} value={type.id}>{type.name}</option>)}</select></label></div></div>}
|
||||
{requiresFamily && <div className="form-section"><div><h2>3. Clasificación técnica</h2><p className="section-copy">Define los datos técnicos y Hallazgos aplicables. En Subinstalaciones sólo aparecen clasificaciones compatibles con la Instalación elegida.</p></div>{kind==='SUBINSTALACION' && !selectedParent?.inventoryFamily ? <Alert>La Instalación elegida todavía no tiene clasificación técnica.</Alert> : <label className="field"><span>Tipo de {kindLabel(kind).toLowerCase()} <em>obligatorio</em></span><select value={familyId} onChange={(event)=>setFamilyId(event.target.value)} required><option value="">Seleccionar…</option>{families.map((family)=><option key={family.id} value={family.id}>{family.name}</option>)}</select></label>}{kind==='SUBINSTALACION' && selectedParent?.inventoryFamily && families.length===0 && <Alert>No hay tipos de Subinstalación compatibles con {selectedParent.inventoryFamily.name}.</Alert>}{selectedFamily && <div className="context-create-banner"><Icon name="alert" /><div><strong>{selectedFamily.name}</strong><span>{familyFindings ? `${familyFindings.count} Hallazgo${familyFindings.count===1?'':'s'} asociado${familyFindings.count===1?'':'s'}` : 'Cargando Hallazgos asociados…'}</span>{familyFindings && familyFindings.items.length>0 && <ul style={{margin:'8px 0 0',paddingLeft:18}}>{familyFindings.items.slice(0,6).map((item)=><li key={item.id}>{item.title}</li>)}{familyFindings.items.length>6 && <li>+ {familyFindings.items.length-6} más</li>}</ul>}</div></div>}</div>}
|
||||
<div className="form-section"><div><h2>{requiresYacimientoContext ? '4' : requiresFamily ? '4' : requiresParent ? '3' : '2'}. Nombre</h2><p className="section-copy">El nombre es el dato propio principal de este nivel. Los datos técnicos se completan después, cuando corresponda.</p></div><label className="field"><span>Nombre <em>obligatorio</em></span><input autoFocus value={name} onChange={(event)=>setName(event.target.value)} required maxLength={200} placeholder={`Nombre de ${kindLabel(kind).toLowerCase()}`} /></label><details style={{marginTop:12}}><summary style={{cursor:'pointer',fontWeight:700}}>Datos opcionales</summary><div style={{marginTop:14}}><div className="form-grid"><label className="field"><span>Código DH</span><input value={code} onChange={(event)=>setCode(event.target.value.toUpperCase())} maxLength={120} pattern="[A-Z0-9][A-Z0-9._/-]*" placeholder="Dejalo vacío para generar automáticamente" /></label><label className="field"><span>Nombre habitual</span><input value={commonName} onChange={(event)=>setCommonName(event.target.value)} maxLength={200} /></label></div><label className="field"><span>Descripción</span><textarea value={description} onChange={(event)=>setDescription(event.target.value)} rows={2} maxLength={4000} /></label></div></details></div>
|
||||
<div className="form-actions"><Link className="button secondary" to="/inventarios">Cancelar</Link><button className="button primary" disabled={saving || !name.trim() || (requiresParent && !parentId) || (requiresYacimientoContext && (!operatorCompanyId || !concessionTypeId)) || (requiresFamily && !familyId)}><Icon name="check" />{saving?'Creando…':`Crear ${kindLabel(kind)}`}</button></div>
|
||||
</form>
|
||||
</section>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user