Volver a la wiki

Rack Editor

Rack Editor

Qué es

Interfaz visual principal para diseñar y mantener el contenido físico de un rack de red. Permite arrastrar dispositivos (stencils) desde biblioteca lateral, posicionarlos en unidades U y guardar estado completo automáticamente. Vista servida desde racks/views.py (rack_editor) en racks/editor/<rack_id>/ renderizando editor.html.

Por qué existe

Reemplaza la lógica equivalente en Flask (routes/main.py). Ofrece edición visual en tiempo real sin recargas manteniendo integridad vía transacciones atómicas en backend. Separa explícitamente presentación (canvas Konva en navegador) de negocio (Django Ninja API + RackService), facilitando tests y evolución independiente.

Componentes

Canvas Konva.js (static/js/editor/): frontend inicializa Konva.Stage en #canvas-container (konva_setup.js, initKonvaStage). Cada rack se dibuja como Konva.Group (STATE.rackGroup) con rectángulo de cabinete, líneas separadoras por U y etiquetas de numeración. Dispositivos como nodos Konva con drag-and-drop. Vista ajustada automáticamente con fitView() calculando escala óptima según paneles laterales. Zoom vía wheel event.

PersistenceManager (static/js/state_core/PersistenceManager.js): centraliza operaciones de guardado. scheduleSave(key, config) con debounce configurable. editor_api.js invoca PERSISTENCE.scheduleSave('rack-main', { endpoint: '/api/racks/{id}/devices', method: 'PUT', debounceMs: 1000 }). Si hay pendiente para la misma key, timer se reinicia evitando llamadas redundantes.

API REST (Django Ninja, racks/api/racks.py): CRUD del rack + endpoint clave PUT /{rack_id}/devices que recibe payload completo y delega en RackService.bulk_update_devices. Orden de rutas estáticas (/groups, /templates, /list, /bulk-update) antes de dinámicas (/{rack_id}) es intencional y está documentado para evitar conflictos de matching.

RackService.bulk_update_devices (racks/services/racks.py): decorado con @transaction.atomic, ejecuta reconciliación completa entre estado actual y payload en una sola transacción:

Vista Django (racks/views.py): rack_editor serializa dispositivos del rack a JSON (devices_json) y stencils por categoría (stencil_categories). Inyecta en contexto de editor.html. Frontend lee desde atributos data-* de #rack-data sin llamada inicial a API, minimizando tiempo de carga.

Flujos

Abrir el editor: usuario navega a /racks/editor/<rack_id>/. Django ejecuta rack_editor, recupera rack y dispositivos con query values(), serializa JSON, renderiza. Cliente: DOMContentLoaded dispara initEditor() en main.js, parsea #rack-data, inicializa stage Konva, carga dispositivos pre-renderizando imágenes en paralelo con preloadDeviceImages.

Editar dispositivos: usuario arrastra stencils al canvas. Drop listener en devices.js registra nuevo dispositivo en STATE.devices. Al mover/modificar, triggerAutoSave() activa debounce 500ms (procesamiento) + 1000ms (PersistenceManager) antes de enviar HTTP.

Guardar atómicamente: saveRackState() serializa nodos Konva a objetos planos (calcula u_position desde Y del canvas y altura del rack), construye payload { devices: [...] }, llama PERSISTENCE.scheduleSave. PersistenceManager ejecuta fetch PUT /api/racks/{id}/devices. Servidor: bulk_update_devices procesa en @transaction.atomic. Si falla validación (IP duplicada, datos inválidos), se revierte todo y devuelve 400.

Véase también

Subir