QUICK START INTEGRATION
Ecosistema completo para organización y gestión de contenido con interfaces espaciales
🚀 Quick Start: Integrating Template Modules
Goal: Get all 6 template modules working in the Universe Canvas Builder in under 30 minutes.
Step 1: Build All Template Modules (5 min)
cd /Users/fguijarro/developer/repos/editor
# Build all 6 templates
nx build @canvas-templates/split-sidebar
nx build @canvas-templates/two-column-equal
nx build @canvas-templates/three-column-equal
nx build @canvas-templates/header-content-footer
nx build @canvas-templates/dashboard
nx build @canvas-templates/custom
Expected Output: dist/modules/canvas-templates/ with all 6 modules built.
Step 2: Register Templates with Module Registry (10 min)
File: apps/gograb-space/src/app/app.config.ts
import { SplitSidebarTemplateModule } from '@canvas-templates/split-sidebar';
import { TwoColumnEqualTemplateModule } from '@canvas-templates/two-column-equal';
import { ThreeColumnEqualTemplateModule } from '@canvas-templates/three-column-equal';
import { HeaderContentFooterTemplateModule } from '@canvas-templates/header-content-footer';
import { DashboardTemplateModule } from '@canvas-templates/dashboard';
import { CustomTemplateModule } from '@canvas-templates/custom';
export const appConfig: ApplicationConfig = {
providers: [
// ... existing providers ...
// Register canvas template modules
SplitSidebarTemplateModule,
TwoColumnEqualTemplateModule,
ThreeColumnEqualTemplateModule,
HeaderContentFooterTemplateModule,
DashboardTemplateModule,
CustomTemplateModule,
// ... rest of providers ...
]
};
Step 3: Update Layout Selector Component (10 min)
File: libs/libs-structural/modular-universe/src/lib/universe-canvas-v3/components/layout-selector/layout-selector.component.ts
import { Component, inject, signal, computed, output, ChangeDetectionStrategy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ModuleRegistryService } from '@libs-core/module-base';
interface LayoutTemplate {
id: string;
name: string;
icon: string;
description: string;
preview: string; // SVG
responsive: boolean;
complexity: 'simple' | 'advanced';
}
@Component({
selector: 'lib-layout-selector',
standalone: true,
imports: [CommonModule],
templateUrl: './layout-selector.component.html',
styleUrl: './layout-selector.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LayoutSelectorComponent {
private readonly moduleRegistry = inject(ModuleRegistryService);
readonly templateSelected = output<string>();
// Dynamically load templates from ModuleRegistryService
readonly layouts = computed<LayoutTemplate[]>(() => {
const allModules = this.moduleRegistry.getAllModules();
return allModules
.filter(m => m.category === 'layout-template')
.map(manifest => ({
id: manifest.id,
name: manifest.displayName || manifest.name,
icon: manifest.icon || '📐',
description: manifest.description || '',
preview: this.generatePreview(manifest.id),
responsive: manifest.metadata?.responsive ?? true,
complexity: manifest.metadata?.complexity || 'simple'
}));
});
selectLayout(templateId: string): void {
this.templateSelected.emit(templateId);
}
private generatePreview(templateId: string): string {
// SVG previews for each template
const previews: Record<string, string> = {
'template-split-sidebar': `<svg viewBox="0 0 100 100"><rect x="10" y="10" width="25" height="80" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="45" y="10" width="45" height="80" fill="#7c4dff20" stroke="#7c4dff" stroke-width="2" rx="4"/></svg>`,
'template-two-column-equal': `<svg viewBox="0 0 100 100"><rect x="10" y="10" width="38" height="80" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="52" y="10" width="38" height="80" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/></svg>`,
'template-three-column-equal': `<svg viewBox="0 0 100 100"><rect x="10" y="10" width="23" height="80" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="38.5" y="10" width="23" height="80" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="67" y="10" width="23" height="80" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/></svg>`,
'template-header-content-footer': `<svg viewBox="0 0 100 100"><rect x="10" y="10" width="80" height="15" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="10" y="35" width="80" height="40" fill="#7c4dff20" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="10" y="82" width="80" height="8" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/></svg>`,
'template-dashboard': `<svg viewBox="0 0 100 100"><rect x="10" y="10" width="80" height="12" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="10" y="28" width="20" height="60" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="35" y="28" width="35" height="60" fill="#7c4dff20" stroke="#7c4dff" stroke-width="2" rx="4"/><rect x="75" y="28" width="15" height="60" fill="#7c4dff40" stroke="#7c4dff" stroke-width="2" rx="4"/></svg>`,
'template-custom': `<svg viewBox="0 0 100 100"><rect x="10" y="10" width="80" height="80" fill="#7c4dff10" stroke="#7c4dff" stroke-width="2" stroke-dasharray="5,5" rx="4"/><text x="50" y="55" text-anchor="middle" fill="#7c4dff" font-size="14">⚙️</text></svg>`
};
return previews[templateId] || '';
}
}
Step 4: Update Canvas Builder to Use Templates (5 min)
File: libs/libs-structural/modular-universe/src/lib/universe-canvas-v3/components/canvas-builder/canvas-builder.component.ts
Add import:
import { ModuleRegistryService } from '@libs-core/module-base';
In constructor, inject the service:
private readonly moduleRegistry = inject(ModuleRegistryService);
Update applyTemplate method:
async applyTemplate(templateId: string, targetSectionId?: string): Promise<void> {
const manifest = this.moduleRegistry.getModule(templateId);
if (!manifest) {
console.error(`Template ${templateId} not found in registry`);
return;
}
const targetId = targetSectionId || this.selectedSectionId() || 'root';
const template = manifest.metadata?.platforms?.web;
if (!template) {
console.error(`No web platform config for template ${templateId}`);
return;
}
// Apply template configuration
this.updateSection({
id: targetId,
updates: {
layout: 'template',
template: templateId,
regions: manifest.regions?.map(r => ({
...r,
children: []
}))
}
});
}
Step 5: Test in Browser (5 min)
Start Dev Server:
nx serve gograb-spaceNavigate to Canvas Builder:
- Open browser:
http://localhost:5200 - Go to Universe Canvas Builder
- Open browser:
Test Each Template:
- Click on each layout template in the selector
- Verify it renders correctly
- Check browser console for errors
- Verify JSON structure in the Tree View tab
Test Persistence:
- Select a template
- Add some modules/sections
- Reload the page
- Verify structure persists
Expected Results ✅
After completing these steps, you should have:
- ✅ All 6 templates registered and discoverable
- ✅ Layout selector showing templates from
ModuleRegistryService - ✅ Templates rendering correctly with proper regions
- ✅ JSON structure preserving template configuration
- ✅ Persistence working across page reloads
Troubleshooting
Templates Not Showing in Selector
Check:
- All templates built successfully (
dist/modules/canvas-templates/) - Modules registered in
app.config.ts -
ModuleRegistryServiceinjected inLayoutSelectorComponent - Filter
category === 'layout-template'is correct
Template Not Rendering
Check:
-
embeddableComponents['template-renderer']defined in manifest - Renderer component imported correctly
- Canvas section component knows how to render template modules
JSON Structure Issues
Check:
-
layout: 'template'is set when template applied -
template: 'template-id'is stored -
regionsarray is properly serialized - Flash persistence is working (check IndexedDB)
Next Steps After Integration
Implement Region Module Containers:
- Allow drag-drop of modules into template regions
- Support nested sections within regions
Create Template Marketplace:
- Export templates as JSON packages
- Import community templates
- Share across universes
Enable AI Generation:
- Train AI on template patterns
- Natural language template creation
- Auto-generate Flutter equivalents
Time to Complete: ~30 minutes Difficulty: Intermediate Prerequisites: Basic understanding of Angular, NX, and GoGrab module system
Let's integrate and test! 🚀