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:
@@ -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)
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user