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)

  1. Start Dev Server:

    nx serve gograb-space
    
  2. Navigate to Canvas Builder:

    • Open browser: http://localhost:5200
    • Go to Universe Canvas Builder
  3. 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
  4. Test Persistence:

    • Select a template
    • Add some modules/sections
    • Reload the page
    • Verify structure persists

Expected Results ✅

After completing these steps, you should have:

  1. ✅ All 6 templates registered and discoverable
  2. ✅ Layout selector showing templates from ModuleRegistryService
  3. ✅ Templates rendering correctly with proper regions
  4. ✅ JSON structure preserving template configuration
  5. ✅ Persistence working across page reloads

Troubleshooting

Templates Not Showing in Selector

Check:

Template Not Rendering

Check:

JSON Structure Issues

Check:


Next Steps After Integration

  1. Implement Region Module Containers:

    • Allow drag-drop of modules into template regions
    • Support nested sections within regions
  2. Create Template Marketplace:

    • Export templates as JSON packages
    • Import community templates
    • Share across universes
  3. 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! 🚀