refactor: Separate concerns and add components dropdown
- Add ComponentsDropdown.vue with save/load/delete functionality - Create components store (Pinia) for state management - Extract WebMCP initialization to services/webmcp.ts - Extract MCP tools registration to services/canvasTools.ts - Simplify Canvas.vue (~340 lines -> ~105 lines) - Update App.vue header with components dropdown Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
124
frontend/src/stores/components.ts
Normal file
124
frontend/src/stores/components.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { componentsApi, type VueComponentDefinition } from '../services/dynamicComponents'
|
||||
|
||||
export interface ComponentState extends VueComponentDefinition {
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export const useComponentsStore = defineStore('components', () => {
|
||||
// State
|
||||
const savedComponents = ref<ComponentState[]>([])
|
||||
const currentComponent = ref<ComponentState | null>(null)
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
|
||||
// Getters
|
||||
const savedCount = computed(() => savedComponents.value.length)
|
||||
const hasCurrentComponent = computed(() => currentComponent.value !== null)
|
||||
|
||||
// Actions
|
||||
async function fetchComponents() {
|
||||
loading.value = true
|
||||
try {
|
||||
savedComponents.value = await componentsApi.getAll()
|
||||
} catch (e) {
|
||||
console.error('Error fetching components:', e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function saveComponent(component: ComponentState) {
|
||||
saving.value = true
|
||||
try {
|
||||
await componentsApi.save({
|
||||
id: component.id,
|
||||
name: component.name,
|
||||
template: component.template,
|
||||
setup: component.setup,
|
||||
style: component.style,
|
||||
props: component.props,
|
||||
imports: component.imports
|
||||
})
|
||||
await fetchComponents()
|
||||
return true
|
||||
} catch (e) {
|
||||
console.error('Error saving component:', e)
|
||||
return false
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function saveCurrentComponent() {
|
||||
if (!currentComponent.value) return false
|
||||
return saveComponent(currentComponent.value)
|
||||
}
|
||||
|
||||
async function deleteComponent(id: string) {
|
||||
try {
|
||||
await componentsApi.delete(id)
|
||||
await fetchComponents()
|
||||
return true
|
||||
} catch (e) {
|
||||
console.error('Error deleting component:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteAllComponents() {
|
||||
try {
|
||||
await componentsApi.deleteAll()
|
||||
savedComponents.value = []
|
||||
return true
|
||||
} catch (e) {
|
||||
console.error('Error deleting all components:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentComponent(component: ComponentState | null) {
|
||||
currentComponent.value = component
|
||||
}
|
||||
|
||||
function clearCurrentComponent() {
|
||||
currentComponent.value = null
|
||||
}
|
||||
|
||||
// Listener para cuando se renderiza un componente
|
||||
function handleComponentRendered(detail: any) {
|
||||
if (detail) {
|
||||
currentComponent.value = {
|
||||
id: detail.id || `comp-${Date.now()}`,
|
||||
name: detail.name || 'Unnamed',
|
||||
template: detail.template || '',
|
||||
setup: detail.setup || '',
|
||||
style: detail.style || '',
|
||||
props: detail.props || [],
|
||||
imports: detail.imports || []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
savedComponents,
|
||||
currentComponent,
|
||||
loading,
|
||||
saving,
|
||||
// Getters
|
||||
savedCount,
|
||||
hasCurrentComponent,
|
||||
// Actions
|
||||
fetchComponents,
|
||||
saveComponent,
|
||||
saveCurrentComponent,
|
||||
deleteComponent,
|
||||
deleteAllComponents,
|
||||
setCurrentComponent,
|
||||
clearCurrentComponent,
|
||||
handleComponentRendered
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user