494 lines
13 KiB
Markdown
494 lines
13 KiB
Markdown
|
|
# 🚀 Nuevas Funcionalidades de AEditor
|
|||
|
|
|
|||
|
|
## 📋 Sistema de Registro de Actividad
|
|||
|
|
|
|||
|
|
### Descripción
|
|||
|
|
Un sistema completo de **registro de operaciones** que mantiene un historial detallado de todas las acciones realizadas en el editor, permitiendo auditar y revisar cambios.
|
|||
|
|
|
|||
|
|
### Características
|
|||
|
|
- ✅ **Timeline de Actividad**: Visualiza cronológicamente todas las operaciones
|
|||
|
|
- ✅ **Filtros por Tipo**: Separar entre crear, editar, guardar, eliminar, abrir
|
|||
|
|
- ✅ **Detalles Completos**: Archivo afectado, líneas modificadas, timestamp
|
|||
|
|
- ✅ **Exportación**: Guarda el log completo en JSON
|
|||
|
|
- ✅ **Persistencia**: Mantiene historial entre sesiones
|
|||
|
|
|
|||
|
|
### Tipos de Eventos Rastreados
|
|||
|
|
- 🟢 **Crear** - Nuevos archivos/comandos/eventos
|
|||
|
|
- 🟡 **Editar** - Modificaciones de código
|
|||
|
|
- 🔵 **Guardar** - Guardado de cambios
|
|||
|
|
- 🔴 **Eliminar** - Borrado de archivos
|
|||
|
|
- 📂 **Abrir** - Apertura de archivos
|
|||
|
|
|
|||
|
|
### Uso en el Código
|
|||
|
|
```typescript
|
|||
|
|
// En cualquier componente
|
|||
|
|
import { invoke } from '@tauri-apps/api/core';
|
|||
|
|
|
|||
|
|
// Registrar una operación
|
|||
|
|
await invoke('save_activity_log', {
|
|||
|
|
entry: {
|
|||
|
|
type: 'edit',
|
|||
|
|
action: 'Modificado comando de ayuda',
|
|||
|
|
file: 'src/commands/help.ts',
|
|||
|
|
lines: 45,
|
|||
|
|
details: 'Actualizada descripción del comando'
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Obtener historial
|
|||
|
|
const logs = await invoke('get_activity_logs');
|
|||
|
|
console.log(logs);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🐛 Sistema de Diagnóstico de Errores
|
|||
|
|
|
|||
|
|
### Descripción
|
|||
|
|
Panel de **detección de errores** integrado que identifica problemas en tiempo real mientras editas, similar al panel de problemas de VS Code.
|
|||
|
|
|
|||
|
|
### Características
|
|||
|
|
- ✅ **Detección en Tiempo Real**: Analiza el código mientras escribes
|
|||
|
|
- ✅ **Tres Niveles de Severidad**: Error, Advertencia, Información
|
|||
|
|
- ✅ **Sugerencias Inteligentes**: Propone soluciones automáticas
|
|||
|
|
- ✅ **Quick Fixes**: Correcciones con un clic
|
|||
|
|
- ✅ **Estadísticas**: Conteo de errores por tipo
|
|||
|
|
- ✅ **Navegación**: Click para ir directamente al error
|
|||
|
|
|
|||
|
|
### Tipos de Errores Detectados
|
|||
|
|
```typescript
|
|||
|
|
// ❌ Errores (Severity: error)
|
|||
|
|
// - Sintaxis inválida
|
|||
|
|
// - Variables no definidas
|
|||
|
|
// - Imports faltantes
|
|||
|
|
|
|||
|
|
// ⚠️ Advertencias (Severity: warning)
|
|||
|
|
// - Uso de 'var' en lugar de 'let/const'
|
|||
|
|
// - Uso de '==' en lugar de '==='
|
|||
|
|
// - console.log() en producción
|
|||
|
|
// - Variables no usadas
|
|||
|
|
|
|||
|
|
// ℹ️ Información (Severity: info)
|
|||
|
|
// - Falta punto y coma
|
|||
|
|
// - Comentarios TODO/FIXME
|
|||
|
|
// - Código no alcanzable
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Reglas Implementadas
|
|||
|
|
1. **no-console** - Detecta `console.log()` y sugiere usar un logger
|
|||
|
|
2. **no-var** - Detecta `var` y sugiere `const` o `let`
|
|||
|
|
3. **eqeqeq** - Detecta `==` y sugiere `===`
|
|||
|
|
4. **semi** - Detecta falta de punto y coma
|
|||
|
|
5. **no-warning-comments** - Detecta TODO/FIXME
|
|||
|
|
|
|||
|
|
### Uso del Panel
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<ErrorPanel
|
|||
|
|
ref="errorPanelRef"
|
|||
|
|
@navigateToError="handleErrorNavigation"
|
|||
|
|
/>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import ErrorPanel from '@/components/ErrorPanel.vue';
|
|||
|
|
|
|||
|
|
// Navegar al error
|
|||
|
|
const handleErrorNavigation = (error) => {
|
|||
|
|
openFile(error.file);
|
|||
|
|
goToLine(error.line);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Añadir error manualmente
|
|||
|
|
errorPanelRef.value?.addError({
|
|||
|
|
severity: 'error',
|
|||
|
|
message: 'Variable "x" no está definida',
|
|||
|
|
file: 'src/commands/test.ts',
|
|||
|
|
line: 45,
|
|||
|
|
column: 10,
|
|||
|
|
code: 'no-undef',
|
|||
|
|
suggestion: 'Declara la variable antes de usarla',
|
|||
|
|
fixable: false
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Integración con Monaco Editor
|
|||
|
|
```typescript
|
|||
|
|
// En MonacoEditor.vue
|
|||
|
|
import { invoke } from '@tauri-apps/api/core';
|
|||
|
|
|
|||
|
|
// Analizar archivo al cambiar
|
|||
|
|
editor.onDidChangeModelContent(() => {
|
|||
|
|
const content = editor.getValue();
|
|||
|
|
const filePath = currentFile.value;
|
|||
|
|
|
|||
|
|
invoke('analyze_file_diagnostics', {
|
|||
|
|
filePath,
|
|||
|
|
content
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Obtener errores
|
|||
|
|
const errors = await invoke('get_diagnostics');
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💾 Sistema de Respaldo Automático
|
|||
|
|
|
|||
|
|
### Descripción
|
|||
|
|
Sistema de **snapshots automáticos** que guarda versiones del proyecto, permitiendo recuperar código anterior y comparar cambios.
|
|||
|
|
|
|||
|
|
### Características
|
|||
|
|
- ✅ **Auto-respaldo Configurable**: 1, 5, 10 o 30 minutos
|
|||
|
|
- ✅ **Respaldos Manuales**: Crear snapshot con nombre y descripción
|
|||
|
|
- ✅ **Comparación Visual**: Ver diferencias entre versiones
|
|||
|
|
- ✅ **Restauración**: Volver a cualquier punto anterior
|
|||
|
|
- ✅ **Gestión Inteligente**: Limita cantidad de respaldos automáticos
|
|||
|
|
- ✅ **Metadatos**: Muestra fecha, archivos, tamaño
|
|||
|
|
|
|||
|
|
### Configuración
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<BackupManager />
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- Configuración del componente -->
|
|||
|
|
<script>
|
|||
|
|
// Intervalo de respaldo: 1, 5, 10, 30 minutos
|
|||
|
|
const backupInterval = ref('5');
|
|||
|
|
|
|||
|
|
// Máximo de respaldos a mantener
|
|||
|
|
const maxBackups = ref(20);
|
|||
|
|
|
|||
|
|
// Auto-respaldo activado
|
|||
|
|
const autoBackupEnabled = ref(true);
|
|||
|
|
</script>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Tipos de Respaldo
|
|||
|
|
1. **Manual** 💾 - Creado por el usuario con nombre personalizado
|
|||
|
|
2. **Automático** 🔄 - Creado según el intervalo configurado
|
|||
|
|
|
|||
|
|
### API de Respaldos
|
|||
|
|
```typescript
|
|||
|
|
// Crear respaldo manual
|
|||
|
|
const backup = await invoke('create_backup', {
|
|||
|
|
name: 'Versión estable v1.0',
|
|||
|
|
description: 'Antes de refactorizar comandos',
|
|||
|
|
type: 'manual'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Obtener lista de respaldos
|
|||
|
|
const backups = await invoke('get_backups');
|
|||
|
|
|
|||
|
|
// Restaurar respaldo
|
|||
|
|
await invoke('restore_backup', {
|
|||
|
|
backupId: 'backup_1699234567890'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Comparar con versión actual
|
|||
|
|
const { current, backup } = await invoke('compare_backup', {
|
|||
|
|
backupId: 'backup_1699234567890'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Eliminar respaldo
|
|||
|
|
await invoke('delete_backup', {
|
|||
|
|
backupId: 'backup_1699234567890'
|
|||
|
|
});
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Estructura de Backup
|
|||
|
|
```typescript
|
|||
|
|
interface Backup {
|
|||
|
|
id: string;
|
|||
|
|
name?: string;
|
|||
|
|
description?: string;
|
|||
|
|
timestamp: number;
|
|||
|
|
type: 'manual' | 'auto';
|
|||
|
|
fileCount: number;
|
|||
|
|
size: number; // en bytes
|
|||
|
|
files: Array<{
|
|||
|
|
path: string;
|
|||
|
|
content: string;
|
|||
|
|
hash: string; // SHA-256
|
|||
|
|
}>;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Almacenamiento
|
|||
|
|
Los respaldos se guardan en:
|
|||
|
|
```
|
|||
|
|
C:\Users\[TU_USUARIO]\AppData\Local\AEditor\backups\
|
|||
|
|
├── backup_1699234567890.json
|
|||
|
|
├── backup_1699234568123.json
|
|||
|
|
└── backup_1699234569456.json
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Estrategia de Limpieza
|
|||
|
|
- Respaldos manuales: **Se mantienen siempre** hasta eliminación manual
|
|||
|
|
- Respaldos automáticos: **Máximo 50% del límite configurado**
|
|||
|
|
- Si `maxBackups = 20`, mantiene máximo 10 auto-respaldos
|
|||
|
|
- Elimina los más antiguos primero
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📁 Estructura de Archivos
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
AEditor/
|
|||
|
|
├── src/
|
|||
|
|
│ ├── components/
|
|||
|
|
│ │ ├── ActivityLog.vue # Nuevo ✨
|
|||
|
|
│ │ ├── ErrorPanel.vue # Nuevo ✨
|
|||
|
|
│ │ ├── BackupManager.vue # Nuevo ✨
|
|||
|
|
│ │ ├── MonacoEditor.vue
|
|||
|
|
│ │ ├── Sidebar.vue
|
|||
|
|
│ │ └── ...
|
|||
|
|
│ ├── App.vue
|
|||
|
|
│ └── main.ts
|
|||
|
|
├── src-tauri/
|
|||
|
|
│ ├── src/
|
|||
|
|
│ │ ├── lib.rs
|
|||
|
|
│ │ ├── activity_log.rs # Nuevo ✨
|
|||
|
|
│ │ ├── diagnostics.rs # Nuevo ✨
|
|||
|
|
│ │ ├── backup.rs # Nuevo ✨
|
|||
|
|
│ │ └── main.rs
|
|||
|
|
│ └── Cargo.toml
|
|||
|
|
└── package.json
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 Instalación y Configuración
|
|||
|
|
|
|||
|
|
### 1. Instalar Dependencias de Rust
|
|||
|
|
Las dependencias ya están en `Cargo.toml`:
|
|||
|
|
```toml
|
|||
|
|
[dependencies]
|
|||
|
|
sha2 = "0.10"
|
|||
|
|
serde = { version = "1", features = ["derive"] }
|
|||
|
|
serde_json = "1"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Inicializar Managers
|
|||
|
|
En `App.vue` o al inicio de la aplicación:
|
|||
|
|
```typescript
|
|||
|
|
import { invoke } from '@tauri-apps/api/core';
|
|||
|
|
import { appDataDir } from '@tauri-apps/api/path';
|
|||
|
|
|
|||
|
|
// Al montar la aplicación
|
|||
|
|
onMounted(async () => {
|
|||
|
|
const dataDir = await appDataDir();
|
|||
|
|
|
|||
|
|
// Inicializar todos los managers
|
|||
|
|
await invoke('init_managers', { appDataDir: dataDir });
|
|||
|
|
|
|||
|
|
console.log('✅ Managers inicializados');
|
|||
|
|
});
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. Usar Componentes
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<div class="app">
|
|||
|
|
<!-- Sidebar con nuevas opciones -->
|
|||
|
|
<Sidebar @view-changed="handleViewChange" />
|
|||
|
|
|
|||
|
|
<!-- Contenido principal -->
|
|||
|
|
<div class="main-content">
|
|||
|
|
<!-- Editor de código -->
|
|||
|
|
<MonacoEditor v-if="currentView === 'editor'" />
|
|||
|
|
|
|||
|
|
<!-- Nuevo: Registro de Actividad -->
|
|||
|
|
<ActivityLog v-if="currentView === 'activity'" />
|
|||
|
|
|
|||
|
|
<!-- Nuevo: Panel de Errores -->
|
|||
|
|
<ErrorPanel
|
|||
|
|
v-if="currentView === 'errors'"
|
|||
|
|
@navigateToError="goToError"
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<!-- Nuevo: Gestor de Respaldos -->
|
|||
|
|
<BackupManager v-if="currentView === 'backups'" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎨 Personalización de Estilos
|
|||
|
|
|
|||
|
|
Todos los componentes usan el tema oscuro de VS Code:
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
/* Variables de color */
|
|||
|
|
:root {
|
|||
|
|
--bg-primary: #1e1e1e;
|
|||
|
|
--bg-secondary: #252525;
|
|||
|
|
--bg-tertiary: #2d2d2d;
|
|||
|
|
--border-color: #333;
|
|||
|
|
--text-primary: #d4d4d4;
|
|||
|
|
--text-secondary: #858585;
|
|||
|
|
--accent-blue: #007acc;
|
|||
|
|
--error-red: #d32f2f;
|
|||
|
|
--warning-orange: #ff9800;
|
|||
|
|
--success-green: #4caf50;
|
|||
|
|
--info-blue: #2196f3;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 Ejemplos de Uso Completos
|
|||
|
|
|
|||
|
|
### Ejemplo 1: Rastrear Edición de Archivo
|
|||
|
|
```typescript
|
|||
|
|
// En MonacoEditor.vue
|
|||
|
|
const saveFile = async () => {
|
|||
|
|
const content = editor.getValue();
|
|||
|
|
const filePath = currentFile.value;
|
|||
|
|
|
|||
|
|
// Guardar archivo
|
|||
|
|
await invoke('write_file_content', { filePath, content });
|
|||
|
|
|
|||
|
|
// Registrar en Activity Log
|
|||
|
|
await invoke('save_activity_log', {
|
|||
|
|
entry: {
|
|||
|
|
type: 'save',
|
|||
|
|
action: 'Archivo guardado',
|
|||
|
|
file: filePath,
|
|||
|
|
lines: content.split('\n').length,
|
|||
|
|
details: `Guardado exitoso de ${filePath}`
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Crear respaldo si es importante
|
|||
|
|
if (isImportantFile(filePath)) {
|
|||
|
|
await invoke('create_backup', {
|
|||
|
|
name: `Respaldo: ${fileName}`,
|
|||
|
|
description: 'Guardado automático de archivo importante',
|
|||
|
|
type: 'auto'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Ejemplo 2: Detectar y Corregir Errores
|
|||
|
|
```typescript
|
|||
|
|
// En MonacoEditor.vue
|
|||
|
|
const analyzeCode = async () => {
|
|||
|
|
const content = editor.getValue();
|
|||
|
|
const filePath = currentFile.value;
|
|||
|
|
|
|||
|
|
// Analizar con backend
|
|||
|
|
await invoke('analyze_file_diagnostics', { filePath, content });
|
|||
|
|
|
|||
|
|
// Obtener errores
|
|||
|
|
const errors = await invoke('get_diagnostics');
|
|||
|
|
|
|||
|
|
// Mostrar en Monaco Editor
|
|||
|
|
const markers = errors.map(error => ({
|
|||
|
|
severity: error.severity === 'error' ? 8 :
|
|||
|
|
error.severity === 'warning' ? 4 : 1,
|
|||
|
|
startLineNumber: error.line,
|
|||
|
|
startColumn: error.column,
|
|||
|
|
endLineNumber: error.line,
|
|||
|
|
endColumn: error.column + 10,
|
|||
|
|
message: error.message
|
|||
|
|
}));
|
|||
|
|
|
|||
|
|
monaco.editor.setModelMarkers(model, 'aeditor', markers);
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Ejemplo 3: Sistema de Recuperación
|
|||
|
|
```typescript
|
|||
|
|
// En BackupManager.vue
|
|||
|
|
const recoverFromCrash = async () => {
|
|||
|
|
// Obtener último respaldo
|
|||
|
|
const backups = await invoke('get_backups');
|
|||
|
|
const latest = backups.sort((a, b) => b.timestamp - a.timestamp)[0];
|
|||
|
|
|
|||
|
|
if (latest) {
|
|||
|
|
const confirmed = confirm(
|
|||
|
|
`Se detectó un respaldo reciente de hace ${timeAgo(latest.timestamp)}.\n` +
|
|||
|
|
`¿Deseas restaurarlo?`
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (confirmed) {
|
|||
|
|
await invoke('restore_backup', { backupId: latest.id });
|
|||
|
|
alert('✅ Proyecto restaurado exitosamente');
|
|||
|
|
location.reload();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 Próximas Mejoras
|
|||
|
|
|
|||
|
|
### Registro de Actividad
|
|||
|
|
- [ ] Filtrar por rango de fechas
|
|||
|
|
- [ ] Buscar en el historial
|
|||
|
|
- [ ] Ver diff de cambios específicos
|
|||
|
|
- [ ] Agrupar por sesión de trabajo
|
|||
|
|
|
|||
|
|
### Panel de Errores
|
|||
|
|
- [ ] Integración con ESLint
|
|||
|
|
- [ ] Integración con TypeScript compiler
|
|||
|
|
- [ ] Reglas personalizables
|
|||
|
|
- [ ] Quick fixes más sofisticados
|
|||
|
|
- [ ] Soporte para Prettier
|
|||
|
|
|
|||
|
|
### Respaldos
|
|||
|
|
- [ ] Compresión de respaldos (gzip)
|
|||
|
|
- [ ] Respaldo incremental (solo cambios)
|
|||
|
|
- [ ] Sincronización con la nube
|
|||
|
|
- [ ] Respaldo selectivo (solo ciertos archivos)
|
|||
|
|
- [ ] Notificaciones de respaldo completado
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 Notas Importantes
|
|||
|
|
|
|||
|
|
1. **Rendimiento**: Los respaldos pueden ser pesados si el proyecto es grande. Considera excluir `node_modules`, `dist`, `build`.
|
|||
|
|
|
|||
|
|
2. **Privacidad**: Los respaldos se almacenan localmente. No se envía nada a servidores externos.
|
|||
|
|
|
|||
|
|
3. **Compatibilidad**: Requiere Tauri 2.0+ y Rust 1.70+.
|
|||
|
|
|
|||
|
|
4. **Límites**: Por defecto, el sistema mantiene máximo 20 respaldos. Ajusta según tu espacio disponible.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🐛 Solución de Problemas
|
|||
|
|
|
|||
|
|
### Error: "Backup manager no inicializado"
|
|||
|
|
**Solución**: Llama a `invoke('init_managers')` al inicio de la app.
|
|||
|
|
|
|||
|
|
### Error: "Permission denied"
|
|||
|
|
**Solución**: Ejecuta AEditor como administrador en Windows.
|
|||
|
|
|
|||
|
|
### Los respaldos no se crean automáticamente
|
|||
|
|
**Solución**: Verifica que `autoBackupEnabled` esté en `true` y el intervalo configurado.
|
|||
|
|
|
|||
|
|
### Panel de errores no muestra nada
|
|||
|
|
**Solución**: Asegúrate de llamar a `analyze_file_diagnostics` después de cada cambio.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📞 Soporte
|
|||
|
|
|
|||
|
|
Si encuentras problemas o tienes sugerencias:
|
|||
|
|
- 📧 Email: soporte@amayo.dev
|
|||
|
|
- 🐛 Issues: [GitHub Issues](https://github.com/ShniCorp/amayo/issues)
|
|||
|
|
- 💬 Discord: [Servidor de Amayo](https://discord.gg/amayo)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**¡Disfruta de las nuevas funcionalidades de AEditor!** 🎉
|