- Migrated vanilla JS frontend to Vite + TypeScript - Modular architecture: views, components, utils, api, state - Three-panel layout: libraries (left), content (center), detail (right) - Group name resolution via hstTags (set_hst -> readable name) - Name priority: name_es -> alias -> ref -> hash truncated - D3.js lazy loading in GraphView - Hash-based routing - Deployed to tzzrdeck.me Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
185 lines
6.4 KiB
Markdown
185 lines
6.4 KiB
Markdown
# 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
|
|
|
|
1. `name_es` / `name_en` / `name_ch` (según idioma)
|
|
2. `alias`
|
|
3. `ref`
|
|
4. `mrf.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:
|
|
|
|
1. Se cargan siempre los tags de HST (`fetchHstTags`)
|
|
2. Se crea un mapa `mrf → nombre` con `createNameMap(hstTags, lang)`
|
|
3. 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
|
|
|
|
```bash
|
|
# Desarrollo
|
|
npm run dev
|
|
|
|
# Build producción
|
|
npm run build
|
|
|
|
# Preview build
|
|
npm run preview
|
|
|
|
# Lint
|
|
npm run lint
|
|
```
|
|
|
|
## Despliegue
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```typescript
|
|
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)
|