feat(A08): Ámbito dtic-NOTAS creado - Sistema web de notas/informes
Nuevo ámbito A08 para gestión de notas e informes formales: Arquitectura: - Separación contenido (archivos .md) de presentación (web HTML) - Plantillas configurables para diferentes tipos de notas - Vista previa con membrete institucional UTN-FRLR - Impresión/PDF via window.print() con CSS @media print Archivos creados: - docs/ambito/dtic-NOTAS/A08_dtic-NOTAS.md (manifiesto) - docs/ambito/dtic-NOTAS/A08.P001_Sistema-Web-Notas.md (plan) - docs/ambito/dtic-NOTAS/app/index.html (interfaz) - docs/ambito/dtic-NOTAS/app/styles.css (estilos institucionales) - docs/ambito/dtic-NOTAS/app/app.js (lógica + marked.js CDN) - docs/ambito/dtic-NOTAS/plantillas/nota-simple.md - docs/ambito/dtic-NOTAS/contenido/2026/ejemplo-nota.md Migración: - dtic-NOTAs/ movido a docs/ambito/dtic-NOTAS/dtic-NOTAs/ - Histórico 2019-2025 preservado en .Hist/ - Convención de nombres documentada: Nota-<AÑO><NUMERO>_<Asunto>.<ext> Uso: 1. Abrir docs/ambito/dtic-NOTAS/app/index.html en navegador 2. Seleccionar plantilla o cargar archivo .md 3. Completar datos de nota 4. Generar vista previa e imprimir Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
2ab51af7f1
commit
85645ce0b8
@@ -0,0 +1,175 @@
|
||||
# Plan: Sistema Web para Generación de Notas
|
||||
|
||||
> **Ámbito:** A08 — dtic-NOTAS
|
||||
|
||||
**Código:** A08.P001
|
||||
**Fecha:** 07 de abril de 2026
|
||||
**Autor:** Sistema ADN
|
||||
**Versión:** 1.0
|
||||
**Estado:** ✅ WEB CREADA (pendiente: numeración automática, exportación PDF)
|
||||
**Dependencia:** Ninguna
|
||||
|
||||
## 📋 Resumen Ejecutivo
|
||||
|
||||
Desarrollar un sistema web simple que permita generar notas e informes formales separando el **contenido** (archivos de texto/markdown) de la **presentación** (plantilla HTML institucional).
|
||||
|
||||
**Ventajas:**
|
||||
- Redacción en formato simple (markdown/txt)
|
||||
- Membrete institucional automático
|
||||
- Numeración consecutiva
|
||||
- Archivo organizado
|
||||
- Fácil mantenimiento
|
||||
|
||||
## 🎯 Objetivo
|
||||
|
||||
Crear una herramienta web que:
|
||||
1. Permita seleccionar una plantilla de nota
|
||||
2. Cargue el contenido desde un archivo `.md` o `.txt`
|
||||
3. Renderice el documento con membrete institucional
|
||||
4. Permita exportar a PDF o imprimir directamente
|
||||
|
||||
## 📅 Fases de Implementación
|
||||
|
||||
### ✅ **FASE 1: Diseño de la Arquitectura** - COMPLETADA
|
||||
|
||||
#### Componentes del Sistema
|
||||
|
||||
```
|
||||
dtic-NOTAs/
|
||||
├── app/ # Aplicación web
|
||||
│ ├── index.html # Interfaz principal
|
||||
│ ├── styles.css # Estilos institucionales
|
||||
│ └── app.js # Lógica de renderizado
|
||||
├── plantillas/ # Modelos de notas
|
||||
│ ├── nota-simple.md
|
||||
│ ├── informe-tecnico.md
|
||||
│ └── memorando.md
|
||||
├── contenido/ # Archivos con redacción
|
||||
│ └── 2026/
|
||||
│ └── nota-26XX.md
|
||||
└── output/ # Documentos generados
|
||||
└── 2026/
|
||||
└── Nota-26XX.pdf
|
||||
```
|
||||
|
||||
#### Estructura de Plantilla Markdown
|
||||
|
||||
```markdown
|
||||
---
|
||||
tipo: nota-simple
|
||||
numero: 26XX
|
||||
fecha: 2026-XX-XX
|
||||
destinatario: [Nombre/Cargo]
|
||||
remitente: DTIC - UTN FRLR
|
||||
asunto: [Descripción breve]
|
||||
---
|
||||
|
||||
[Cuerpo de la nota en formato markdown]
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
|
||||
---
|
||||
**Firma:** _________________________
|
||||
**Nombre:** [Nombre del Responsable]
|
||||
**Cargo:** [Cargo]
|
||||
```
|
||||
|
||||
### ✅ **FASE 2: Implementación de la Web** - COMPLETADA
|
||||
|
||||
#### Componentes desarrollados
|
||||
|
||||
1. **index.html** ✅ - Interfaz principal
|
||||
- Selector de plantillas
|
||||
- Carga de archivos .md
|
||||
- Formulario de datos de nota
|
||||
- Botones de acción
|
||||
|
||||
2. **styles.css** ✅ - Estilos institucionales
|
||||
- Membrete UTN-FRLR
|
||||
- Tipografía formal
|
||||
- Márgenes para impresión A4
|
||||
- CSS @media print configurado
|
||||
|
||||
3. **app.js** ✅ - Lógica
|
||||
- Carga de plantillas embebidas
|
||||
- Renderizado markdown→HTML (marked.js)
|
||||
- Impresión/PDF via window.print()
|
||||
- Extracción de metadatos frontmatter
|
||||
|
||||
**Archivos creados en `docs/ambito/dtic-NOTAS/app/`:**
|
||||
- `index.html` - Interfaz
|
||||
- `styles.css` - Estilos
|
||||
- `app.js` - Lógica
|
||||
|
||||
**Archivos de ejemplo:**
|
||||
- `plantillas/nota-simple.md` - Plantilla base
|
||||
- `contenido/2026/ejemplo-nota.md` - Nota DKIM de ejemplo
|
||||
|
||||
### ✅ **FASE 3: Integración con Archivo Histórico** - COMPLETADA
|
||||
|
||||
- [x] Directorio `dtic-NOTAs` migrado a `docs/ambito/dtic-NOTAS/dtic-NOTAs/`
|
||||
- [x] Histórico preservado en `.Hist/` con notas de 2024
|
||||
- [x] Convención de nombres documentada: `Nota-<AÑO><NUMERO>_<Asunto>.<ext>`
|
||||
|
||||
### ⏳ **FASE 4: Testing y Documentación**
|
||||
|
||||
- Probar con notas reales del histórico
|
||||
- Validar formato de impresión
|
||||
- Documentar uso para el equipo
|
||||
|
||||
## 🎯 Criterios de Éxito
|
||||
|
||||
| Criterio | Verificación |
|
||||
| :--- | :--- |
|
||||
| **Web funcional** | Carga plantillas y renderiza contenido |
|
||||
| **Membrete correcto** | Logo UTN-FRLR, datos institucionales |
|
||||
| **Exportación PDF** | Documento imprimible formato A4 |
|
||||
| **Archivo organizado** | Notas guardadas en `.Hist/<AÑO>/` |
|
||||
| **Numeración automática** | Consecutivo sin repetir |
|
||||
|
||||
## 📝 Notas Técnicas
|
||||
|
||||
### Stack Tecnológico Sugerido
|
||||
|
||||
**Mínimo viable (sin dependencias complejas):**
|
||||
- HTML5 + CSS3 + JavaScript vanilla
|
||||
- Markdown parser: `marked.js` (CDN)
|
||||
- PDF: `window.print()` con CSS `@media print`
|
||||
|
||||
**Opcional (más robusto):**
|
||||
- Node.js + Express para backend
|
||||
- Puppeteer para generación PDF
|
||||
- SQLite para registro de numeración
|
||||
|
||||
### Migración del Histórico - COMPLETADA
|
||||
|
||||
El directorio `dtic-NOTAs/` fue migrado exitosamente:
|
||||
1. ✅ Movido a `docs/ambito/dtic-NOTAS/dtic-NOTAs/`
|
||||
2. Histórico 2024 preservado en `.Hist/`
|
||||
3. El nuevo sistema convive con el histórico
|
||||
|
||||
### Convención de Nombres
|
||||
|
||||
```
|
||||
Nota-<AÑO><NUMERO>_<AsuntoCorto>.<ext>
|
||||
|
||||
Ejemplos:
|
||||
- Nota-2601_Nota_Horas_ServDASU_RRHH.docx
|
||||
- Nota-2412_GuardiasPasivas_0.docx
|
||||
- Nota-2409_GATICASolicitaDiasPorCapacitación_1.1.pdf
|
||||
```
|
||||
|
||||
## 🔄 Armonía Integral
|
||||
|
||||
| Documento | Estado | Notas |
|
||||
| :--- | :--- | :--- |
|
||||
| `A08_dtic-NOTAS.md` | ✅ Creado | Manifiesto del ámbito |
|
||||
| `A08.P001_Sistema-Web-Notas.md` | ✅ Web implementada | Sistema funcional (Fases 1-3 completas) |
|
||||
| `dtic-NOTAs/` | ✅ Migrado | Archivo histórico en `docs/ambito/dtic-NOTAS/dtic-NOTAs/` |
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- **Archivo histórico**: `dtic-NOTAs/.Hist/`
|
||||
- **Bitácoras**: `./adn/tools/run db evento:listar --ambito dtic-NOTAS`
|
||||
@@ -0,0 +1,111 @@
|
||||
# A08 - Ámbito dtic-NOTAS
|
||||
|
||||
> Manifiesto de Ámbito | Referencia: [`adn/01_ontologia.md`](../../../adn/01_ontologia.md)
|
||||
|
||||
## Identificación
|
||||
|
||||
| Campo | Valor |
|
||||
| :--- | :--- |
|
||||
| **Código** | A08 |
|
||||
| **Nombre** | Sistema de Notas e Informes Formales |
|
||||
| **Estado** | 🚧 En Implementación |
|
||||
| **Inicio** | 07/04/2026 |
|
||||
| **Fin Estimado** | Continuo (producción de documentos institucionales) |
|
||||
|
||||
## Objetivo
|
||||
|
||||
El ámbito **dtic-NOTAS** centraliza la producción, gestión y archivo de notas e informes formales de la DTIC.
|
||||
|
||||
Este ámbito cubre:
|
||||
|
||||
1. **Generación de notas** — Sistema web + archivos de texto para redacción separada.
|
||||
2. **Plantillas institucionales** — Modelos estandarizados para diferentes tipos de notas.
|
||||
3. **Archivo histórico** — Organización y resguardo de notas emitidas/recibidas.
|
||||
4. **Seguimiento** — Control de estado (borrador, enviada, respondida, archivada).
|
||||
|
||||
## Arquitectura del Sistema
|
||||
|
||||
### Separación Contenido/Presentación
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ CONTENIDO (archivos .md/.txt) │
|
||||
│ - Redacción en formato simple │
|
||||
│ - Fácil edición y versionado │
|
||||
│ - Independiente del formato final │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ MOTOR DE PLANTILLAS (web) │
|
||||
│ - HTML/CSS institucional │
|
||||
│ - Encabezado/membrete UTN-FRLR │
|
||||
│ - Numeración automática │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ SALIDA (PDF/DOCX/HTML) │
|
||||
│ - Documento formal listo para imprimir/firmar │
|
||||
│ - Copia digital para archivo │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Herramientas
|
||||
|
||||
| Herramienta | Uso |
|
||||
| :--- | :--- |
|
||||
| **Web de Notas** | Interfaz para redactar y generar documentos |
|
||||
| **Plantillas Markdown** | Archivos `.md` con estructura de nota |
|
||||
| **Conversor MD→PDF** | Generación de documentos formales |
|
||||
| **Archivo Histórico** | Directorio `dtic-NOTAs/.Hist/` organizado por año |
|
||||
|
||||
## Nodos Involucrados
|
||||
|
||||
| Nodo | IP / VMID | Rol en el Ámbito |
|
||||
| :--- | :--- | :--- |
|
||||
| **srv-ns8** | `10.0.10.8` | Host del sistema web de notas |
|
||||
| **dtic-NOTAs/** | (directorio) | Archivo de notas históricas y nuevas |
|
||||
|
||||
## Tipos de Notas
|
||||
|
||||
| Tipo | Descripción | Ejemplo de uso |
|
||||
| :--- | :--- | :--- |
|
||||
| **Nota simple** | Comunicación unilateral | Solicitud de materiales |
|
||||
| **Informe técnico** | Detalle de situación/problema | Informe de fallas |
|
||||
| **Memorando** | Comunicación interna | Curso fuera de horario |
|
||||
| **Nota de solicitud** | Pedido formal a otra área | Acceso a sistemas |
|
||||
| **Respuesta** | Contestación a nota recibida | Respuesta a RRHH |
|
||||
|
||||
## Flujo de Trabajo Típico
|
||||
|
||||
```
|
||||
1. Seleccionar tipo de nota (plantilla)
|
||||
2. Redactar contenido en archivo .md
|
||||
3. Previsualizar en web con membrete institucional
|
||||
4. Generar PDF/DOCX
|
||||
5. Imprimir y firmar (si corresponde)
|
||||
6. Enviar y archivar en dtic-NOTAs/.Hist/<AÑO>/
|
||||
```
|
||||
|
||||
## Planes Asociados
|
||||
|
||||
| Código | Nombre | Estado |
|
||||
| :--- | :--- | :--- |
|
||||
| [A08.P001](A08.P001_Sistema-Web-Notas.md) | Sistema Web para Generación de Notas | ✅ Web Funcional |
|
||||
|
||||
## 🔄 Armonía Integral
|
||||
|
||||
**Última actualización:** 2026-04-07 22:30 (Ámbito A08 creado - Web funcional implementada)
|
||||
|
||||
| Documento | Estado | Notas |
|
||||
| :--- | :--- | :--- |
|
||||
| `A08_dtic-NOTAS.md` | ✅ Creado | Manifiesto del ámbito |
|
||||
| `A08.P001_Sistema-Web-Notas.md` | 🚧 En implementación | Plan para web + plantillas |
|
||||
| `dtic-NOTAs/` | ✅ Migrado | Archivo histórico en `docs/ambito/dtic-NOTAS/dtic-NOTAs/` |
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- **Archivo histórico**: `dtic-NOTAs/.Hist/`
|
||||
- **ADN Ontología**: [`adn/01_ontologia.md`](../../../adn/01_ontologia.md)
|
||||
- **Bitácoras**: `./adn/tools/run db evento:listar --ambito dtic-NOTAS`
|
||||
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* Generador de Notas - DTIC UTN-FRLR
|
||||
* Lógica de la aplicación web
|
||||
*/
|
||||
|
||||
// Estado de la aplicación
|
||||
let estado = {
|
||||
plantillaCargada: null,
|
||||
contenidoCargado: null,
|
||||
datosNota: {}
|
||||
};
|
||||
|
||||
// Inicialización
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Establecer fecha actual por defecto
|
||||
document.getElementById('fecha').valueAsDate = new Date();
|
||||
|
||||
// Cargar último número disponible (simulado)
|
||||
document.getElementById('numero').placeholder = 'Ej: ' + generarNumeroSugerido();
|
||||
});
|
||||
|
||||
/**
|
||||
* Genera un número sugerido basado en la fecha
|
||||
* Formato: AAMM (ej: 2604 para abril 2026)
|
||||
*/
|
||||
function generarNumeroSugerido() {
|
||||
const fecha = new Date();
|
||||
const año = fecha.getFullYear() % 100;
|
||||
const mes = String(fecha.getMonth() + 1).padStart(2, '0');
|
||||
return `${año}${mes}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Carga la plantilla seleccionada
|
||||
*/
|
||||
function cargarPlantilla() {
|
||||
const plantilla = document.getElementById('plantilla').value;
|
||||
|
||||
if (!plantilla) {
|
||||
alert('Por favor seleccioná una plantilla');
|
||||
return;
|
||||
}
|
||||
|
||||
// Plantillas embebidas
|
||||
const plantillas = {
|
||||
'nota-simple': `---
|
||||
tipo: nota-simple
|
||||
numero: ${document.getElementById('numero').value || 'XXXX'}
|
||||
fecha: ${document.getElementById('fecha').value || '____'}
|
||||
destinatario: [Nombre del Destinatario]
|
||||
remitente: DTIC - UTN FRLR
|
||||
asunto: [Asunto de la nota]
|
||||
---
|
||||
|
||||
# Nota Simple
|
||||
|
||||
Estimado/a [Nombre]:
|
||||
|
||||
Por medio de la presente, me dirijo a usted para [propósito de la nota].
|
||||
|
||||
[Cuerpo principal de la nota - desarrollar el tema]
|
||||
|
||||
Sin otro particular, saludo a usted atentamente.
|
||||
|
||||
`,
|
||||
|
||||
'informe-tecnico': `---
|
||||
tipo: informe-tecnico
|
||||
numero: ${document.getElementById('numero').value || 'XXXX'}
|
||||
fecha: ${document.getElementById('fecha').value || '____'}
|
||||
destinatario: [Nombre del Destinatario]
|
||||
remitente: DTIC - UTN FRLR
|
||||
asunto: Informe Técnico sobre [tema]
|
||||
---
|
||||
|
||||
# Informe Técnico
|
||||
|
||||
## 1. Objeto del Informe
|
||||
|
||||
El presente informe tiene por objeto [describir el propósito].
|
||||
|
||||
## 2. Antecedentes
|
||||
|
||||
[Describir contexto y situación previa]
|
||||
|
||||
## 3. Análisis Técnico
|
||||
|
||||
[Desarrollar análisis detallado]
|
||||
|
||||
## 4. Conclusiones
|
||||
|
||||
[Conclusiones y recomendaciones]
|
||||
|
||||
## 5. Anexos
|
||||
|
||||
- Anexo A: [Descripción]
|
||||
- Anexo B: [Descripción]
|
||||
|
||||
`,
|
||||
|
||||
'memorando': `---
|
||||
tipo: memorando
|
||||
numero: ${document.getElementById('numero').value || 'XXXX'}
|
||||
fecha: ${document.getElementById('fecha').value || '____'}
|
||||
destinatario: [Personal de DTIC / Nombre]
|
||||
remitente: Dirección DTIC
|
||||
asunto: [Asunto del memorando]
|
||||
---
|
||||
|
||||
# Memorando
|
||||
|
||||
**PARA:** [Destinatario]
|
||||
|
||||
**DE:** [Remitente]
|
||||
|
||||
**FECHA:** [Fecha]
|
||||
|
||||
**ASUNTO:** [Asunto]
|
||||
|
||||
---
|
||||
|
||||
[Cuerpo del memorando]
|
||||
|
||||
Se comunica a todo el personal que [contenido].
|
||||
|
||||
Es importante destacar que [puntos clave].
|
||||
|
||||
Quedan a disposición para cualquier consulta.
|
||||
|
||||
`,
|
||||
|
||||
'solicitud': `---
|
||||
tipo: solicitud
|
||||
numero: ${document.getElementById('numero').value || 'XXXX'}
|
||||
fecha: ${document.getElementById('fecha').value || '____'}
|
||||
destinatario: [Autoridad/Área]
|
||||
remitente: DTIC - UTN FRLR
|
||||
asunto: Solicitud de [qué se solicita]
|
||||
---
|
||||
|
||||
# Nota de Solicitud
|
||||
|
||||
Por medio de la presente, me dirijo a usted con el fin de solicitar [describir lo que se solicita].
|
||||
|
||||
**Fundamentación:**
|
||||
|
||||
[Explicar razones y necesidad de lo solicitado]
|
||||
|
||||
**Especificaciones:**
|
||||
|
||||
- [Ítem 1]
|
||||
- [Ítem 2]
|
||||
- [Ítem 3]
|
||||
|
||||
Agradeciendo de antemano su atención, saludo a usted atentamente.
|
||||
|
||||
`
|
||||
};
|
||||
|
||||
const contenido = plantillas[plantilla];
|
||||
document.getElementById('editorTexto').value = contenido;
|
||||
estado.plantillaCargada = plantilla;
|
||||
|
||||
// Extraer metadatos del frontmatter
|
||||
extraerMetadatos(contenido);
|
||||
|
||||
alert('Plantilla "' + plantilla + '" cargada. Editá el contenido y generá la vista previa.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Carga contenido desde archivo .md
|
||||
*/
|
||||
function cargarContenido() {
|
||||
const input = document.getElementById('contenido');
|
||||
|
||||
if (!input.files || !input.files[0]) {
|
||||
alert('Por favor seleccioná un archivo .md');
|
||||
return;
|
||||
}
|
||||
|
||||
const archivo = input.files[0];
|
||||
const lector = new FileReader();
|
||||
|
||||
lector.onload = (e) => {
|
||||
document.getElementById('editorTexto').value = e.target.result;
|
||||
estado.contenidoCargado = archivo.name;
|
||||
extraerMetadatos(e.target.result);
|
||||
alert('Contenido cargado desde: ' + archivo.name);
|
||||
};
|
||||
|
||||
lector.readAsText(archivo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extrae metadatos del frontmatter (YAML entre ---)
|
||||
*/
|
||||
function extraerMetadatos(contenido) {
|
||||
const match = contenido.match(/^---\n([\s\S]*?)\n---/);
|
||||
|
||||
if (match) {
|
||||
const frontmatter = match[1];
|
||||
|
||||
// Extraer campos individuales
|
||||
const campos = {
|
||||
numero: frontmatter.match(/numero:\s*(.+)/)?.[1]?.trim(),
|
||||
fecha: frontmatter.match(/fecha:\s*(.+)/)?.[1]?.trim(),
|
||||
destinatario: frontmatter.match(/destinatario:\s*(.+)/)?.[1]?.trim(),
|
||||
asunto: frontmatter.match(/asunto:\s*(.+)/)?.[1]?.trim()
|
||||
};
|
||||
|
||||
// Completar formulario
|
||||
if (campos.numero && campos.numero !== 'XXXX') {
|
||||
document.getElementById('numero').value = campos.numero;
|
||||
}
|
||||
if (campos.fecha && campos.fecha !== '____') {
|
||||
document.getElementById('fecha').value = campos.fecha;
|
||||
}
|
||||
if (campos.destinatario && !campos.destinatario.includes('[')) {
|
||||
document.getElementById('destinatario').value = campos.destinatario;
|
||||
}
|
||||
if (campos.asunto && !campos.asunto.includes('[')) {
|
||||
document.getElementById('asunto').value = campos.asunto;
|
||||
}
|
||||
|
||||
estado.datosNota = { ...estado.datosNota, ...campos };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Genera la vista previa del documento
|
||||
*/
|
||||
function generarVistaPrevia() {
|
||||
const contenido = document.getElementById('editorTexto').value;
|
||||
|
||||
// Obtener datos del formulario
|
||||
const datos = {
|
||||
numero: document.getElementById('numero').value,
|
||||
fecha: formatearFecha(document.getElementById('fecha').value),
|
||||
destinatario: document.getElementById('destinatario').value,
|
||||
asunto: document.getElementById('asunto').value
|
||||
};
|
||||
|
||||
// Separar frontmatter del cuerpo
|
||||
const cuerpo = contenido.replace(/^---\n[\s\S]*?\n---\n/, '');
|
||||
|
||||
// Renderizar markdown a HTML
|
||||
const htmlCuerpo = marked.parse(cuerpo);
|
||||
|
||||
// Construir documento
|
||||
const template = document.getElementById('templateNota');
|
||||
const clone = template.content.cloneNode(true);
|
||||
|
||||
// Completar datos
|
||||
clone.querySelector('.campo-numero').textContent = datos.numero || '____';
|
||||
clone.querySelector('.campo-fecha').textContent = datos.fecha || '____';
|
||||
clone.querySelector('.campo-destinatario').textContent = datos.destinatario || '____';
|
||||
clone.querySelector('.campo-asunto').textContent = datos.asunto || '____';
|
||||
clone.querySelector('.cuerpo').innerHTML = htmlCuerpo;
|
||||
|
||||
// Actualizar vista previa
|
||||
const preview = document.getElementById('vistaPrevia');
|
||||
preview.innerHTML = '';
|
||||
preview.appendChild(clone);
|
||||
|
||||
// Scroll a la vista previa
|
||||
preview.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatea fecha de YYYY-MM-DD a DD/MM/YYYY
|
||||
*/
|
||||
function formatearFecha(fechaISO) {
|
||||
if (!fechaISO) return '____';
|
||||
const [año, mes, dia] = fechaISO.split('-');
|
||||
return `${dia}/${mes}/${año}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imprime o genera PDF del documento
|
||||
*/
|
||||
function imprimir() {
|
||||
const vistaPrevia = document.getElementById('vistaPrevia');
|
||||
|
||||
if (!vistaPrevia.innerHTML.trim() || vistaPrevia.querySelector('.placeholder')) {
|
||||
alert('Por favor generá primero la vista previa');
|
||||
return;
|
||||
}
|
||||
|
||||
// Crear ventana de impresión
|
||||
const contenido = vistaPrevia.innerHTML;
|
||||
|
||||
const ventana = window.open('', '_blank');
|
||||
ventana.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Nota ${document.getElementById('numero').value || '____'}</title>
|
||||
<style>
|
||||
${document.querySelector('style').innerHTML}
|
||||
body { background: white; }
|
||||
.sidebar, .editor { display: none; }
|
||||
.container { display: block; padding: 0; }
|
||||
.preview { position: absolute; width: 100%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${contenido}
|
||||
<script>
|
||||
window.onload = () => {
|
||||
window.print();
|
||||
window.onafterprint = () => window.close();
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
ventana.document.close();
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Generador de Notas - DTIC UTN-FRLR</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Panel de Control -->
|
||||
<aside class="sidebar">
|
||||
<h2>📝 Panel de Control</h2>
|
||||
|
||||
<div class="section">
|
||||
<label for="plantilla">Plantilla:</label>
|
||||
<select id="plantilla">
|
||||
<option value="">-- Seleccionar --</option>
|
||||
<option value="nota-simple">Nota Simple</option>
|
||||
<option value="informe-tecnico">Informe Técnico</option>
|
||||
<option value="memorando">Memorando</option>
|
||||
<option value="solicitud">Nota de Solicitud</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<label for="contenido">Archivo de contenido (.md):</label>
|
||||
<input type="file" id="contenido" accept=".md,.txt">
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Datos de la Nota</h3>
|
||||
<label>Número:</label>
|
||||
<input type="text" id="numero" placeholder="Ej: 2601">
|
||||
|
||||
<label>Fecha:</label>
|
||||
<input type="date" id="fecha">
|
||||
|
||||
<label>Destinatario:</label>
|
||||
<input type="text" id="destinatario" placeholder="Nombre/Cargo">
|
||||
|
||||
<label>Asunto:</label>
|
||||
<input type="text" id="asunto" placeholder="Descripción breve">
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button onclick="cargarPlantilla()">📄 Cargar Plantilla</button>
|
||||
<button onclick="cargarContenido()">📂 Cargar Contenido</button>
|
||||
<button onclick="generarVistaPrevia()">👁️ Vista Previa</button>
|
||||
<button onclick="imprimir()">🖨️ Imprimir / PDF</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Área de Edición -->
|
||||
<main class="editor">
|
||||
<h2>Editor de Contenido</h2>
|
||||
<textarea id="editorTexto" placeholder="Cargá una plantilla o escribí el contenido aquí..."></textarea>
|
||||
</main>
|
||||
|
||||
<!-- Vista Previa -->
|
||||
<aside class="preview">
|
||||
<h2>Vista Previa</h2>
|
||||
<div id="vistaPrevia" class="documento">
|
||||
<div class="placeholder">
|
||||
<p>La vista previa aparecerá aquí...</p>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<!-- Template de Nota (oculto) -->
|
||||
<template id="templateNota">
|
||||
<div class="nota">
|
||||
<header class="membrete">
|
||||
<div class="logo">
|
||||
<img src="../logo-utn.png" alt="UTN FRLR" onerror="this.style.display='none'">
|
||||
</div>
|
||||
<div class="datos-institucion">
|
||||
<h1>UNIVERSIDAD TECNOLÓGICA NACIONAL</h1>
|
||||
<h2>Facultad Regional La Rioja</h2>
|
||||
<p>Dirección de Tecnologías de la Información y Comunicación</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="datos-nota">
|
||||
<p><strong>Nota N°:</strong> <span class="campo-numero"></span></p>
|
||||
<p><strong>Fecha:</strong> <span class="campo-fecha"></span></p>
|
||||
</div>
|
||||
|
||||
<div class="destinatario">
|
||||
<p><strong>Destinatario:</strong> <span class="campo-destinatario"></span></p>
|
||||
<p><strong>Asunto:</strong> <span class="campo-asunto"></span></p>
|
||||
</div>
|
||||
|
||||
<div class="cuerpo">
|
||||
<!-- Contenido renderizado aquí -->
|
||||
</div>
|
||||
|
||||
<footer class="firma">
|
||||
<div class="espacio-firma"></div>
|
||||
<p><strong class="nombre-remitente">DTIC - UTN FRLR</strong></p>
|
||||
<p class="cargo-remitente">Dirección de Tecnologías de la Información y Comunicación</p>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,298 @@
|
||||
/* =============================================
|
||||
Estilos - Generador de Notas DTIC UTN-FRLR
|
||||
============================================= */
|
||||
|
||||
:root {
|
||||
--primary: #1a4d8f;
|
||||
--secondary: #2c5f2d;
|
||||
--accent: #97bc09;
|
||||
--light: #f5f5f5;
|
||||
--dark: #333;
|
||||
--border: #ddd;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: var(--light);
|
||||
color: var(--dark);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr 1fr;
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
max-width: 1800px;
|
||||
margin: 0 auto;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: var(--primary);
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 600;
|
||||
color: var(--dark);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.section select,
|
||||
.section input[type="text"],
|
||||
.section input[type="date"],
|
||||
.section input[type="file"] {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.section h3 {
|
||||
color: var(--primary);
|
||||
font-size: 1rem;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 2px solid var(--primary);
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.actions button {
|
||||
padding: 12px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.actions button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.actions button:nth(1) { background: var(--primary); color: white; }
|
||||
.actions button:nth(2) { background: var(--secondary); color: white; }
|
||||
.actions button:nth(3) { background: var(--accent); color: white; }
|
||||
.actions button:nth(4) { background: var(--dark); color: white; }
|
||||
|
||||
/* Editor */
|
||||
.editor {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.editor h2 {
|
||||
color: var(--primary);
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#editorTexto {
|
||||
width: 100%;
|
||||
min-height: 500px;
|
||||
padding: 15px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
font-family: 'Consolas', 'Monaco', monospace;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/* Preview */
|
||||
.preview {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 40px);
|
||||
}
|
||||
|
||||
.preview h2 {
|
||||
color: var(--primary);
|
||||
margin-bottom: 15px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: white;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid var(--border);
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
padding: 100px 20px;
|
||||
}
|
||||
|
||||
/* Documento */
|
||||
.documento {
|
||||
background: white;
|
||||
padding: 40px;
|
||||
border: 1px solid #eee;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.nota {
|
||||
max-width: 210mm; /* A4 width */
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Membrete */
|
||||
.membrete {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 3px solid var(--primary);
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
width: 100px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.datos-institucion h1 {
|
||||
font-size: 1.3rem;
|
||||
color: var(--primary);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.datos-institucion h2 {
|
||||
font-size: 1rem;
|
||||
color: var(--secondary);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.datos-institucion p {
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* Datos de la nota */
|
||||
.datos-nota,
|
||||
.destinatario {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.datos-nota p,
|
||||
.destinatario p {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* Cuerpo */
|
||||
.cuerpo {
|
||||
min-height: 300px;
|
||||
line-height: 1.8;
|
||||
font-size: 11pt;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.cuerpo p {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* Firma */
|
||||
.firma {
|
||||
margin-top: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.espacio-firma {
|
||||
height: 60px;
|
||||
border-bottom: 1px solid var(--dark);
|
||||
margin-bottom: 10px;
|
||||
width: 60%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.firma .nombre-remitente {
|
||||
display: block;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.firma .cargo-remitente {
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* =============================================
|
||||
Estilos para impresión
|
||||
============================================= */
|
||||
@media print {
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.sidebar,
|
||||
.editor,
|
||||
.preview h2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.preview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.documento {
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nota {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
@page {
|
||||
margin: 2.5cm;
|
||||
size: A4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
tipo: nota-simple
|
||||
numero: 2604
|
||||
fecha: 2026-04-07
|
||||
destinatario: Sr. Decano de la Facultad
|
||||
remitente: DTIC - UTN FRLR
|
||||
asunto: Implementación de autenticación DKIM para correos institucionales
|
||||
---
|
||||
|
||||
# Implementación de DKIM - Correo Institucional
|
||||
|
||||
Estimado Decano:
|
||||
|
||||
Por medio de la presente, me dirijo a usted para informar que se ha completado la implementación del sistema de autenticación **DKIM (DomainKeys Identified Mail)** para los correos electrónicos institucionales de la Facultad.
|
||||
|
||||
## Antecedentes
|
||||
|
||||
Los correos enviados desde cuentas @frlr.utn.edu.ar estaban siendo rechazados o marcados como spam por proveedores como Gmail, debido a la falta de autenticación adecuada.
|
||||
|
||||
## Acciones Realizadas
|
||||
|
||||
Se han configurado los siguientes registros DNS:
|
||||
|
||||
1. **SPF** - Ya existente, autoriza a Microsoft 365 a enviar correos
|
||||
2. **DKIM** - Dos registros CNAME para selectores de Microsoft 365
|
||||
3. **DMARC** - Política de monitoreo para seguimiento de autenticación
|
||||
|
||||
## Estado Actual
|
||||
|
||||
La autenticación DKIM ha sido habilitada exitosamente en Microsoft 365. Los correos salientes ahora incluyen firma digital que verifica:
|
||||
- Que el correo proviene del dominio legítimo
|
||||
- Que el contenido no fue alterado en tránsito
|
||||
|
||||
## Consideraciones
|
||||
|
||||
Gmail y otros proveedores pueden tardar 24-72 horas en actualizar la reputación del dominio. Durante este período, algunos correos podrían continuar siendo marcados como spam temporalmente.
|
||||
|
||||
Sin otro particular, saludo a usted atentamente.
|
||||
|
||||
---
|
||||
**Firma:** _________________________
|
||||
|
||||
**Nombre:** Responsable DTIC
|
||||
|
||||
**Cargo:** Director de Tecnologías de la Información y Comunicación
|
||||
|
||||
**Área:** DTIC - UTN FRLR
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+1368
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+2280
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
+10132
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3683
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user