/* global React */ // Catálogos del sistema (HU súper admin) — gestión de listas maestras: // categorías (ejes temáticos), tipos de medida y niveles de prioridad. // Solo visible para el rol 'superadmin' (ver modules-config.jsx). // Persisten en localStorage (cat_ejes / cat_tipos / cat_prioridades) y se leen // en vivo desde window.cgrData.* en los formularios de la plataforma. const { useState: useStateCat, useEffect: useEffectCat } = React; function prioTone(p) { const s = (p || '').toLowerCase(); if (s.indexOf('alta') !== -1 || s.indexOf('crít') !== -1 || s.indexOf('crit') !== -1) return 'high'; if (s.indexOf('media') !== -1) return 'mid'; if (s.indexOf('baja') !== -1) return 'low'; return 'none'; } // Chevron para los botones subir/bajar. function CatChev({ dir }) { return ( ); } // Intercambia dos elementos del arreglo y devuelve una copia nueva. function moveItem(list, i, dir) { const j = i + dir; if (j < 0 || j >= list.length) return list; const c = list.slice(); const t = c[i]; c[i] = c[j]; c[j] = t; return c; } // Control compacto de reordenar (subir/bajar). function ReorderCtl({ i, total, onMove }) { return ( ); } // ---------- Catálogo de cadenas (ejes, prioridades) ---------- function StringCatalog({ titulo, sub, icon, items, setItems, placeholder, toneOf }) { const I = window.Icons; const Icon = I[icon] || I.ListChecks; const [nuevo, setNuevo] = useStateCat(''); const [editIdx, setEditIdx] = useStateCat(-1); const [editVal, setEditVal] = useStateCat(''); const dupe = (v, skip) => items.some((x, i) => i !== skip && x.toLowerCase() === v.toLowerCase()); const add = () => { const v = nuevo.trim(); if (!v || dupe(v, -1)) return; setItems(list => [...list, v]); setNuevo(''); }; const startEdit = (i) => { setEditIdx(i); setEditVal(items[i]); }; const saveEdit = () => { const v = editVal.trim(); if (!v || dupe(v, editIdx)) { setEditIdx(-1); return; } setItems(list => list.map((x, idx) => idx === editIdx ? v : x)); setEditIdx(-1); setEditVal(''); }; const del = (i) => setItems(list => list.filter((_, idx) => idx !== i)); const move = (i, dir) => setItems(list => moveItem(list, i, dir)); const sortAZ = () => setItems(list => list.slice().sort((a, b) => String(a).localeCompare(String(b), 'es', { sensitivity: 'base' }))); return (

{titulo}

{items.length}
{sub &&

{sub}

}
setNuevo(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') add(); }} />
); } // ---------- Catálogo de tipos de medida (nombre + descripción) ---------- function TipoCatalog({ items, setItems }) { const I = window.Icons; const [label, setLabel] = useStateCat(''); const [desc, setDesc] = useStateCat(''); const [editId, setEditId] = useStateCat(null); const [eLabel, setELabel] = useStateCat(''); const [eDesc, setEDesc] = useStateCat(''); const add = () => { const l = label.trim(); if (!l) return; const id = 'tm-' + Date.now().toString(36); setItems(list => [...list, { id, label: l, desc: desc.trim() }]); setLabel(''); setDesc(''); }; const startEdit = (it) => { setEditId(it.id); setELabel(it.label); setEDesc(it.desc || ''); }; const saveEdit = () => { setItems(list => list.map(x => x.id === editId ? { ...x, label: eLabel.trim() || x.label, desc: eDesc.trim() } : x)); setEditId(null); }; const del = (id) => setItems(list => list.filter(x => x.id !== id)); const move = (i, dir) => setItems(list => moveItem(list, i, dir)); const sortAZ = () => setItems(list => list.slice().sort((a, b) => String(a.label).localeCompare(String(b.label), 'es', { sensitivity: 'base' }))); return (

Tipos de medida

{items.length}

Naturaleza de la acción que exige una recomendación.

setLabel(e.target.value)} /> setDesc(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') add(); }} />
); } // ---------- Catálogo de mecanismos (sigla + organismo + descripción + color) ---------- function MecCatalog({ items, setItems }) { const I = window.Icons; const [label, setLabel] = useStateCat(''); const [org, setOrg] = useStateCat(''); const [desc, setDesc] = useStateCat(''); const [color, setColor] = useStateCat('#2d4a8a'); const [editId, setEditId] = useStateCat(null); const [ev, setEv] = useStateCat({}); const add = () => { const l = label.trim(); if (!l || items.some(m => (m.label || '').toLowerCase() === l.toLowerCase())) return; const id = l.toUpperCase().replace(/\s+/g, '-'); setItems(list => [...list, { id, label: l, org: org.trim(), desc: desc.trim(), color }]); setLabel(''); setOrg(''); setDesc(''); setColor('#2d4a8a'); }; const startEdit = (m) => { setEditId(m.id); setEv({ label: m.label, org: m.org || '', desc: m.desc || '', color: m.color || '#2d4a8a' }); }; const saveEdit = () => { setItems(list => list.map(m => m.id === editId ? { ...m, label: (ev.label || '').trim() || m.label, org: (ev.org || '').trim(), desc: (ev.desc || '').trim(), color: ev.color } : m)); setEditId(null); }; const del = (id) => setItems(list => list.filter(m => m.id !== id)); const move = (i, dir) => setItems(list => moveItem(list, i, dir)); const sortAZ = () => setItems(list => list.slice().sort((a, b) => String(a.label).localeCompare(String(b.label), 'es', { sensitivity: 'base' }))); return (

Mecanismos de origen

{items.length}

Organismos y convenciones que emiten recomendaciones. El color elegido se usa en la “burbuja” del mecanismo en todo el sistema.

setLabel(e.target.value)} /> setOrg(e.target.value)} /> setDesc(e.target.value)} />
); } function CatalogosScreen() { const I = window.Icons; const [ejes, setEjes] = window.usePersistentState('cat_ejes', () => (window.EJES_TEMATICOS || []).slice()); const [tiposInst, setTiposInst] = window.usePersistentState('cat_tipos_inst', () => (window.TIPOS_INSTITUCION || []).slice()); const [tipos, setTipos] = window.usePersistentState('cat_tipos', () => (window.TIPOS_MEDIDA || []).map(t => ({ ...t }))); const [prioridades, setPrioridades] = window.usePersistentState('cat_prioridades', () => (window.PRIORIDADES || []).slice()); const [mecanismos, setMecanismos] = window.usePersistentState('cat_mecanismos', () => (window.MECANISMOS_CAT || []).map(m => ({ ...m }))); // Al cambiar los mecanismos, re-aplicar sus colores en todo el sistema. useEffectCat(() => { if (window.cgrData) window.cgrData.applyMechStyles(mecanismos); }, [mecanismos]); return (
Configuración · Súper Administrador

Catálogos del sistema

Administra las listas maestras que alimentan los formularios de la plataforma. Los cambios se reflejan al instante al registrar o clasificar recomendaciones.

Solo Súper Administrador
); } Object.assign(window, { CatalogosScreen });