DECK frontend: data-driven category classification using hst_rules

- Add tableRules to State for caching hst_rules data
- Add getTableRules() API function to fetch hst_rules table
- Modify getCategory() to check if table has categories (hst_permitidos)
- Only use set_hst for sub-categorization on tables with non-empty hst_permitidos
- Tables without categories now correctly show base name as category
- Load tableRules once on first data load for performance

Fixes issue where all items were showing sub-categories even when the
table (like itm, flg, loc) doesn't have category restrictions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
ARCHITECT
2026-01-17 23:15:43 +00:00
parent 4546003ce7
commit bee5f9f939

View File

@@ -790,7 +790,7 @@ const State = {
base: "hst", view: "grid", lang: "es",
search: "", group: "all", library: "all", libraryMembers: new Set(),
selectionMode: false, selected: new Set(), selectedTag: null,
tags: [], hstTags: [], groups: [], libraries: [], edges: [], treeData: [],
tags: [], hstTags: [], groups: [], libraries: [], edges: [], treeData: [], tableRules: {},
graphFilters: { categories: new Set(Object.keys(CONFIG.CATEGORIES)), edgeTypes: new Set(Object.keys(CONFIG.EDGE_TYPES)) },
graphSettings: { ...CONFIG.GRAPH_DEFAULTS }
},
@@ -878,16 +878,27 @@ const Utils = {
},
getCategory(tag) {
// Category is determined by the tag's set_hst (parent category MRF)
const base = State.get("base");
const config = CONFIG.BASES[base];
if (!config) return base;
// Check tableRules to see if this table has categories
const tableKey = `${config.schema}.${config.table}`;
const tableRules = State.get("tableRules") || {};
const hasCategories = tableRules[tableKey];
// If table has no categories defined, use base name
if (!hasCategories) return base;
// Use set_hst to find category
const setHst = tag.set_hst;
if (!setHst) return State.get("base");
if (!setHst) return base;
// Look up the category tag in hstTags
const hstTags = State.get("hstTags");
const hstTags = State.get("hstTags") || [];
const categoryTag = hstTags.find(t => t.mrf === setHst);
const cat = categoryTag?.ref;
// Return the ref of the category tag, or fall back to base
return categoryTag?.ref || State.get("base");
return (cat && CONFIG.CATEGORIES[cat]) ? cat : base;
},
updateHash() {
@@ -938,6 +949,14 @@ const API = {
getHstTags() { return this.fetch("/hst?select=mrf,ref,name_es,name_en,alias", "tzzr_core_hst", { fallback: [] }); },
getGroups() { return this.fetch("/api_groups", "public", { fallback: [] }); },
async getTableRules() {
const rules = await this.fetch("/hst_rules?select=tabla,hst_permitidos", "tzzr_core_hst", { fallback: [] });
// Convert to map: "schema.table" -> has categories (hst_permitidos.length > 0)
const map = {};
rules.forEach(r => { map[r.tabla] = r.hst_permitidos && r.hst_permitidos.length > 0; });
return map;
},
async getLibraries(base) {
const config = CONFIG.BASES[base];
if (!config?.hasLibraries) return [];
@@ -1582,6 +1601,13 @@ const App = {
async loadData(base) {
Utils.$("#content-area").innerHTML = '<div class="loading">Cargando...</div>';
try {
// Load tableRules once (first load only)
let tableRules = State.get("tableRules");
if (!tableRules || Object.keys(tableRules).length === 0) {
tableRules = await API.getTableRules();
State.set({ tableRules });
}
const [tags, hstTags, groups, libraries, edges, treeData] = await Promise.all([
API.getTags(base), API.getHstTags(), API.getGroups(), API.getLibraries(base), API.getEdges(base), API.getTree(base)
]);