- Add ToolsPage for managing MCP tools activation and persistence - Centralize all tool handlers in services/tools/handlers/ - toolRegistry.ts is now the single source of truth for tool state - Add tools store for pinned tools (persisted in localStorage) - Tools can be pinned to stay active across page navigation - Remove old individual tool files, replaced by centralized handlers
215 lines
7.8 KiB
Vue
215 lines
7.8 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted } from 'vue'
|
|
import { RouterLink, useRoute } from 'vue-router'
|
|
import { useCanvasStore } from '../stores/canvas'
|
|
import { useProjectCanvasStore } from '../stores/projectCanvas'
|
|
|
|
const route = useRoute()
|
|
const canvasStore = useCanvasStore()
|
|
const projectCanvasStore = useProjectCanvasStore()
|
|
|
|
function clearCanvas() {
|
|
const container = document.getElementById('canvas-content')
|
|
if (container) {
|
|
container.innerHTML = `
|
|
<div class="canvas-placeholder">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
|
<path d="M3 9h18"/>
|
|
<path d="M9 21V9"/>
|
|
</svg>
|
|
<p>Canvas listo</p>
|
|
<span>Claude Code puede renderizar contenido aquí</span>
|
|
</div>
|
|
`
|
|
}
|
|
}
|
|
|
|
function toggleHistory() {
|
|
canvasStore.toggleHistoryPanel()
|
|
}
|
|
|
|
function isCanvasActive(canvasId: string) {
|
|
return route.path === `/canvas/${canvasId}`
|
|
}
|
|
|
|
onMounted(() => {
|
|
projectCanvasStore.fetchToolbarCanvases()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<aside class="toolbar">
|
|
<!-- Navegacion principal -->
|
|
<div class="toolbar-section nav-section">
|
|
<RouterLink to="/" class="toolbar-btn" :class="{ active: route.path === '/' }" title="Home">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
|
|
<polyline points="9 22 9 12 15 12 15 22"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<RouterLink to="/dynamic/canvas" class="toolbar-btn" :class="{ active: route.path === '/dynamic/canvas' }" title="Dynamic Canvas">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
|
<path d="M3 9h18"/>
|
|
<path d="M9 21V9"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<!-- Canvas dinamicos de la toolbar -->
|
|
<RouterLink
|
|
v-for="canvas in projectCanvasStore.toolbarCanvases"
|
|
:key="canvas.id"
|
|
:to="`/canvas/${canvas.id}`"
|
|
class="toolbar-btn"
|
|
:class="{ active: isCanvasActive(canvas.id) }"
|
|
:title="canvas.name"
|
|
>
|
|
<span v-if="canvas.toolbar_icon" class="toolbar-emoji">{{ canvas.toolbar_icon }}</span>
|
|
<svg v-else xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
|
<path d="M3 9h18"/>
|
|
<path d="M9 21V9"/>
|
|
</svg>
|
|
</RouterLink>
|
|
</div>
|
|
|
|
<div class="toolbar-divider"></div>
|
|
|
|
<!-- Gestion -->
|
|
<div class="toolbar-section">
|
|
<RouterLink to="/projects" class="toolbar-btn" :class="{ active: route.path === '/projects' }" title="Proyectos">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<RouterLink to="/components" class="toolbar-btn" :class="{ active: route.path === '/components' }" title="Componentes">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
|
|
<polyline points="3.29 7 12 12 20.71 7"/>
|
|
<line x1="12" y1="22" x2="12" y2="12"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<RouterLink to="/themes" class="toolbar-btn" :class="{ active: route.path === '/themes' }" title="Temas">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<circle cx="13.5" cy="6.5" r="2.5"/>
|
|
<circle cx="19" cy="11.5" r="2.5"/>
|
|
<circle cx="17" cy="18.5" r="2.5"/>
|
|
<circle cx="8.5" cy="17.5" r="2.5"/>
|
|
<circle cx="5" cy="10.5" r="2.5"/>
|
|
<path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.93 0 1.82-.13 2.67-.36"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<RouterLink to="/database" class="toolbar-btn" :class="{ active: route.path === '/database' }" title="Database">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<ellipse cx="12" cy="5" rx="9" ry="3"/>
|
|
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/>
|
|
<path d="M3 12c0 1.66 4 3 9 3s9-1.34 9-3"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<RouterLink to="/source" class="toolbar-btn" :class="{ active: route.path === '/source' }" title="Source Code">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<polyline points="16 18 22 12 16 6"/>
|
|
<polyline points="8 6 2 12 8 18"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<RouterLink to="/terminal" class="toolbar-btn" :class="{ active: route.path === '/terminal' }" title="Terminal">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<polyline points="4 17 10 11 4 5"/>
|
|
<line x1="12" y1="19" x2="20" y2="19"/>
|
|
</svg>
|
|
</RouterLink>
|
|
|
|
<RouterLink to="/tools" class="toolbar-btn" :class="{ active: route.path === '/tools' }" title="Tools">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
|
</svg>
|
|
</RouterLink>
|
|
</div>
|
|
|
|
<div class="toolbar-divider"></div>
|
|
|
|
<!-- Acciones -->
|
|
<div class="toolbar-section">
|
|
<button class="toolbar-btn" @click="clearCanvas" title="Limpiar canvas">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M3 6h18"/>
|
|
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
|
|
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
|
|
</svg>
|
|
</button>
|
|
|
|
<button class="toolbar-btn" @click="toggleHistory" title="Historial">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M12 8v4l3 3"/>
|
|
<circle cx="12" cy="12" r="10"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</aside>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.toolbar {
|
|
width: 56px;
|
|
background: var(--bg-secondary);
|
|
border-right: 1px solid var(--border-color);
|
|
padding: 0.75rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.toolbar-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.toolbar-divider {
|
|
height: 1px;
|
|
background: var(--border-color);
|
|
margin: 0.25rem 0;
|
|
}
|
|
|
|
.toolbar-btn {
|
|
width: 40px;
|
|
height: 40px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: transparent;
|
|
border: none;
|
|
border-radius: 8px;
|
|
color: var(--text-secondary);
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.toolbar-btn:hover {
|
|
background: var(--bg-hover);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.toolbar-btn:active {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
.toolbar-btn.active {
|
|
background: rgba(99, 102, 241, 0.15);
|
|
color: #6366f1;
|
|
}
|
|
|
|
.toolbar-emoji {
|
|
font-size: 1.25rem;
|
|
line-height: 1;
|
|
}
|
|
</style>
|