const { Card, Button, Icon, IconButton, Input, Select, Modal, Badge, Tag, SectorTag, SearchField, EmptyState, Switch, DataTable, StatCard } = window.ACRFlowDesignSystem_ba1e9c; const slug = (s) => s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, ""); function TaxonomyScreen({ onToast }) { const D = window.useStore(); const S = window.ACRStore; const sectors = D.sectorsCfg || []; const [selected, setSelected] = React.useState((sectors[0] || {}).id); const [salvando, setSalvando] = React.useState(false); React.useEffect(() => { if (!sectors.some((x) => x.id === selected)) setSelected((sectors[0] || {}).id); }, [sectors.length]); const catId = (sectorId, name) => ((D.catIds || {})[sectorId] || {})[name]; const falhou = (r) => { if (!r.ok) { onToast({ tone: "danger", title: "Não foi possível gravar", message: r.error }); return true; } return false; }; const [sectorForm, setSectorForm] = React.useState(null); const [removeSector, setRemoveSector] = React.useState(null); const [catForm, setCatForm] = React.useState(null); const [removeCat, setRemoveCat] = React.useState(null); const [q, setQ] = React.useState(""); const sector = sectors.find((s) => s.id === selected) || sectors[0]; const cats = sector ? sector.categories.filter((c) => c.toLowerCase().includes(q.toLowerCase())) : []; const demandsOf = (id, cat) => D.demands.filter((d) => d.sector === id && (!cat || d.category === cat)).length; const saveSector = async () => { const f = sectorForm; setSalvando(true); const r = await S.salvarArea(f); setSalvando(false); if (falhou(r)) return; if (!f.id) setSelected(slug(f.name)); onToast({ tone: "success", title: f.id ? "Área atualizada" : "Área cadastrada", message: f.name }); setSectorForm(null); }; const saveCat = async () => { const { target, name, original } = catForm; setSalvando(true); const r = await S.salvarAtividade({ sectorId: target, name, catId: original ? catId(target, original) : null }); setSalvando(false); if (falhou(r)) return; onToast({ tone: "success", title: original ? "Atividade renomeada" : "Atividade criada", message: name + " · " + (sectors.find((x) => x.id === target) || {}).name }); setCatForm(null); }; return (

Áreas e Atividades

Cadastro dos setores da empresa e das categorias de atividade de cada um. Novos setores ficam disponíveis imediatamente.
s.active).length} tone="brand" icon={} /> n + s.categories.length, 0)} icon={} /> } />
{sectors.map((s) => (
setSelected(s.id)} style={{ display: "flex", alignItems: "center", gap: 10, padding: "12px 14px", cursor: "pointer", borderLeft: "3px solid " + (s.id === selected ? "var(--accent-primary)" : "transparent"), background: s.id === selected ? "var(--surface-sunken)" : "transparent", borderBottom: "1px solid var(--border-subtle)" }}> {s.name} {!s.active ? Inativo : null} {s.categories.length} categorias · {demandsOf(s.id)} demandas } onClick={(e) => { e.stopPropagation(); setSectorForm({ ...s }); }} /> } onClick={(e) => { e.stopPropagation(); setRemoveSector(s); }} />
))}
setQ(e.target.value)} />
}> {cats.length ? ( ({ name: c }))} columns={[ { key: "name", label: "Categoria", render: (r) => {r.name} }, { key: "sector", label: "Setor", width: 200, render: () => }, { key: "uso", label: "Demandas", width: 110, render: (r) => {demandsOf(sector.id, r.name)} }, { key: "acoes", label: "", width: 92, render: (r) => ( } onClick={() => setCatForm({ target: sector.id, name: r.name, original: r.name })} /> } onClick={() => setRemoveCat(r.name)} /> ) }, ]} /> ) : ( } title="Nenhuma categoria neste setor." description="Cadastre as atividades que este setor executa — elas aparecem na abertura da demanda." action={} /> )}
{sectorForm ? ( setSectorForm(null)} footer={<>}> setSectorForm({ ...sectorForm, name: e.target.value })} /> setSectorForm({ ...sectorForm, active: !sectorForm.active })} label="Setor ativo" description="Setores inativos não recebem novas demandas." /> ) : null} {removeSector ? ( setRemoveSector(null)} footer={<> }> {demandsOf(removeSector.id) > 0 ? ( Este setor possui {demandsOf(removeSector.id)} demandas vinculadas. Encaminhe-as para outro setor antes de remover — ou desative o setor para bloquear novas aberturas. ) : ( As {removeSector.categories.length} categorias deste setor também serão removidas. )} ) : null} {catForm ? ( s.id === catForm.target) || {}).name} tone="info" width={520} onClose={() => setCatForm(null)} footer={<>}> setCatForm({ ...catForm, name: e.target.value })} />