Tags are now categorized based on their set_hst field, which points to the parent category tag (e.g., hst, spe, vue, vsn, msn). This uses the actual semantic relationship defined in the database rather than inferring from ref prefix or using the base. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
DECK Frontend - Vite + TypeScript
Frontend modular para visualización de tags semánticos TZZR (HST/FLG/ITM/LOC/PLY).
Stack
- Vite - Bundler con HMR
- TypeScript - Tipado estático
- ES6 Modules - import/export
- D3.js - Lazy loading solo en GraphView
Estructura
src/
├── main.ts # Bootstrap y App principal
├── types/ # Interfaces TypeScript
│ ├── tag.ts # Tag, Group, Library, ChildTag, RelatedTag
│ ├── state.ts # AppState, ViewType, BaseType
│ └── graph.ts # GraphNode, GraphEdge, EdgeType
├── config/ # Constantes
│ ├── api.ts # API_BASE
│ ├── categories.ts # CATS (colores por categoría)
│ └── edges.ts # EDGE_COLORS
├── state/ # Store reactivo
│ ├── store.ts # createStore<T>()
│ └── index.ts # Estado inicial
├── api/ # Fetch tipado
│ ├── client.ts # apiClient<T>(), apiClientSafe<T>()
│ ├── tags.ts # fetchTags, fetchHstTags, fetchChildren, fetchRelated
│ ├── groups.ts # fetchGroups
│ ├── libraries.ts # fetchLibraries, fetchLibraryMembers
│ └── graph.ts # fetchGraphEdges, fetchTreeEdges
├── utils/ # Helpers puros
│ ├── dom.ts # $, $$, createElement, delegateEvent
│ ├── i18n.ts # getName, getImg, createNameMap, resolveGroupName
│ ├── filters.ts # filterTags
│ ├── clipboard.ts # copyToClipboard, copyMrf
│ └── toast.ts # toast()
├── components/ # Componentes reutilizables
│ ├── Component.ts # Clase base
│ ├── Card/
│ ├── TagChip/
│ └── Toast/
├── views/ # Vistas principales
│ ├── View.ts # Clase base
│ ├── GridView/ # Vista de tarjetas
│ ├── TreeView/ # Vista de árbol agrupado
│ ├── GraphView/ # Grafo D3 (lazy load)
│ └── DetailPanel/ # Panel lateral de detalle
├── router/ # Hash routing
│ └── index.ts # Router con parseHash/updateHash
└── styles/
└── main.css # Estilos globales
Resolución de Nombres
Prioridad de campos para mostrar nombres
name_es/name_en/name_ch(según idioma)aliasrefmrf.slice(0, 8)(fallback a hash truncado)
Resolución de grupos (set_hst)
El campo set_hst contiene el MRF de un tag HST que representa la categoría.
Para resolver el nombre del grupo:
- Se cargan siempre los tags de HST (
fetchHstTags) - Se crea un mapa
mrf → nombreconcreateNameMap(hstTags, lang) - Se resuelve el nombre con
resolveGroupName(set_hst, nameMap)
Esto permite que al ver cualquier base (flg, itm, loc, ply), los grupos muestren nombres legibles en lugar de hashes.
API Endpoints
| Endpoint | Descripción |
|---|---|
GET /api/{base} |
Lista tags (hst, flg, itm, loc, ply) |
GET /api/hst?select=... |
Tags HST para resolver nombres |
POST /api/rpc/api_children |
Hijos de un tag |
POST /api/rpc/api_related |
Tags relacionados |
GET /api/graph_hst |
Relaciones del grafo |
GET /api/tree_hst |
Jerarquías |
GET /api/groups |
Grupos disponibles |
GET /api/library_hst |
Bibliotecas |
POST /api/rpc/library_members |
Miembros de biblioteca |
Comandos
# Desarrollo
npm run dev
# Build producción
npm run build
# Preview build
npm run preview
# Lint
npm run lint
Despliegue
# Build
npm run build
# Deploy a DECK
scp -r dist/* root@72.62.1.113:/opt/hst/web/
URLs
- DECK: https://tzzrdeck.me
- HST: https://hst.tzzrdeck.me
- API: https://tzzrdeck.me/api/
Layout
┌─────────────────────────────────────────────────────────────┐
│ TOPBAR: Logo | Lang | API | SEL | GET | Bases | Search | View │
├─────────────────────────────────────────────────────────────┤
│ GROUPS BAR: Todos | Grupo1 | Grupo2 | ... │
├────────┬────────────────────────────────────┬───────────────┤
│ │ │ │
│ LEFT │ CONTENT AREA │ DETAIL │
│ PANEL │ (Grid / Tree / Graph) │ PANEL │
│ │ │ │
│ Libs │ │ (slide-in) │
│ │ │ │
└────────┴────────────────────────────────────┴───────────────┘
State
interface AppState {
// Navegación
base: 'hst' | 'flg' | 'itm' | 'loc' | 'ply';
lang: 'es' | 'en' | 'ch';
view: 'grid' | 'tree' | 'graph';
// Filtros
search: string;
group: string; // MRF del grupo o 'all'
library: string; // MRF de biblioteca o 'all'
libraryMembers: Set<string>;
// Selección
selectionMode: boolean;
selected: Set<string>;
selectedTag: Tag | null;
// Datos
tags: Tag[]; // Tags de la base actual
hstTags: Tag[]; // Tags HST para resolver nombres de grupos
groups: Group[];
libraries: Library[];
graphEdges: GraphEdge[];
treeEdges: TreeEdge[];
// Grafo
graphFilters: { cats: Set, edges: Set };
graphSettings: { nodeSize, linkDist, showImg, showLbl };
}
Changelog
2026-01-13
- Migrado de vanilla JS a Vite + TypeScript
- Añadido panel izquierdo de bibliotecas
- Implementada resolución de nombres para grupos (set_hst → nombre)
- Prioridad de nombres: name_es → alias → ref → hash
- D3 lazy loading en GraphView
- Layout de 3 paneles (left, center, detail)