QUICK REFERENCE

Ecosistema completo para organización y gestión de contenido con interfaces espaciales

Widget System - Quick Reference Card 🚀

Last Updated: December 9, 2025 (Session 9)


🎯 Quick Navigation

Task Route Component
Browse Widgets /space/:spaceId/widgets/ WidgetGuideComponent
Create Widget (AI) /space/:spaceId/widgets/builder/ WidgetBuilderWorkspaceComponent
Create Widget (Template) /space/:spaceId/widgets/builder/ WidgetBuilderWorkspaceComponent
Create Widget (Component) /space/:spaceId/widgets/builder/ WidgetBuilderWorkspaceComponent
Edit Widget /space/:spaceId/widgets/builder/workspace/edit/:widgetId WidgetBuilderWorkspaceComponent
Manage Widgets /space/:spaceId/widgets/manager/ WidgetsManagerComponent
Create Variant /space/:spaceId/widgets/variant-editor/:componentId SmartVariantCreatorComponent
Edit Variant /space/:spaceId/widgets/variant-editor/:componentId/:variantId SmartVariantCreatorComponent
Widget Detail /space/:spaceId/widgets/:componentId CoreComponentDetailComponent

🛠️ Widget Creation Methods

Method 1: AI Generation ✨

// User Flow
1. Navigate to /space/:spaceId/widgets/builder/
2. Click "AI Generate" tab
3. Describe widget: "A pricing card with plan name, price, features list, and CTA button"
4. Click "Generate"
5. Customize properties
6. Finalize (name, description, category)
7. Save

// Technical
- Service: IntelligentWidgetGeneratorService
- Endpoint: POST /api/ai/generate-widget
- Result: GeneratedWidget with property groups

Method 2: Template Selection 📦

// User Flow
1. Navigate to /space/:spaceId/widgets/builder/
2. Click "Templates" tab
3. Select template (Button, Card, Form, etc.)
4. Customize properties
5. Finalize (name, description, category)
6. Save

// Technical
- Templates: Defined in widget-builder-workspace.component.ts
- Property Groups: From PropertyRegistryService
- Result: Widget with template defaults

Method 3: Component Selection 🧩

// User Flow
1. Navigate to /space/:spaceId/widgets/builder/
2. Click "From Component" tab
3. Browse categories
4. Select component (e.g., Button, Card)
5. Properties auto-load
6. Customize properties
7. Finalize (name, description, category)
8. Save

// Technical
- Service: WidgetsEmbeddableRegistryService
- Method: generatePropertyGroups(embeddableId)
- Result: Widget with embeddable properties

🎨 Variant Creation

Create New Variant

// User Flow
1. Navigate to widget detail page
2. Click "Create Variant" button
3. Visual property editor opens
4. Modify properties (colors, sizes, config)
5. Name variant (e.g., "Primary", "Outline", "Large")
6. Save

// Technical
- Route: /space/:spaceId/widgets/variant-editor/:componentId
- Component: SmartVariantCreatorComponent
- Result: Variant added to widget.variants[]

Edit Existing Variant

// User Flow
1. Navigate to widget detail page
2. Find variant in list
3. Click "Edit" button
4. Modify properties
5. Save

// Technical
- Route: /space/:spaceId/widgets/variant-editor/:componentId/:variantId
- Component: SmartVariantCreatorComponent
- Result: Variant updated in widget.variants[]

🔌 Backend API Endpoints

Space-Level Widgets

// Create Widget
POST /api/spaces/:spaceId/widgets
Body: CreateWidgetDto
Response: WidgetResponse

// List Widgets
GET /api/spaces/:spaceId/widgets
Response: WidgetResponse[]

// Get Widget
GET /api/spaces/:spaceId/widgets/:id
Response: WidgetResponse

// Update Widget
PUT /api/spaces/:spaceId/widgets/:id
Body: UpdateWidgetDto
Response: WidgetResponse

// Delete Widget
DELETE /api/spaces/:spaceId/widgets/:id
Response: { success: boolean }

Global Widgets

// Create Global Widget
POST /api/global-resources/widgets
Body: CreateWidgetDto
Response: GlobalWidgetResponse

// List Global Widgets
GET /api/global-resources/widgets
Response: GlobalWidgetResponse[]

// Get Global Widget
GET /api/global-resources/widgets/:id
Response: GlobalWidgetResponse

// Update Global Widget
PUT /api/global-resources/widgets/:id
Body: UpdateWidgetDto
Response: GlobalWidgetResponse

// Delete Global Widget
DELETE /api/global-resources/widgets/:id
Response: { success: boolean }

📦 Data Models

Widget

interface Widget {
  _id: string;
  name: string;
  type: string; // 'button', 'card', 'form', etc.
  category: string; // 'input', 'display', 'layout', etc.
  variants: WidgetVariant[];
  defaultConfig: Record<string, any>;
  propertyConfig: PropertyConfig[];
  metadata: WidgetMetadata;
  createdAt: Date;
  updatedAt: Date;
}

WidgetVariant

interface WidgetVariant {
  id: string;
  name: string;
  description?: string;
  properties: Record<string, any>;
  isDefault?: boolean;
  isStatic?: boolean; // Cannot be edited
}

PropertyConfig

interface PropertyConfig {
  key: string;
  label: string;
  type: 'string' | 'number' | 'boolean' | 'select' | 'color' | 'array';
  defaultValue?: any;
  description?: string;
  options?: string[]; // For select type
  min?: number; // For number type
  max?: number; // For number type
  step?: number; // For number type
}

🔧 Key Services

WidgetsEmbeddableRegistryService

// Get all embeddables
embeddables = computed(() => this.registry.embeddables());

// Get categories
categories = computed(() => this.registry.categories());

// Generate property groups
propertyGroups = this.registry.generatePropertyGroups(embeddableId);

WidgetStorageService

// Save widget
await this.widgetStorage.saveWidget(widget);

// Get widget
const widget = await this.widgetStorage.getWidget(widgetId);

// Delete widget
await this.widgetStorage.deleteWidget(widgetId);

IntelligentWidgetGeneratorService

// Generate widget from prompt
const result = await this.generator.generateWidget(prompt);

// Result contains:
// - name, description, type, category
// - propertyGroups with intelligent defaults
// - metadata

🎨 Styling Guidelines

Widget Cards

.widget-card {
  padding: 20px;
  background: rgba(var(--ux-surface-rgb), 0.9);
  border: 2px solid transparent;
  border-radius: 16px;
  transition: all 150ms ease;

  &:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
    border-color: rgba(var(--ux-primary-rgb), 0.3);
  }

  &.selected {
    border-color: var(--ux-primary);
    background: rgba(var(--ux-primary-rgb), 0.08);
  }
}

Creation Method Tabs

.method-tab {
  flex: 1;
  padding: 12px 24px;
  background: transparent;
  border: 2px solid transparent;
  border-radius: 12px;
  transition: all 150ms ease;

  &.active {
    background: var(--ux-primary);
    color: white;
    box-shadow: 0 4px 16px rgba(var(--ux-primary-rgb), 0.3);
  }
}

⚡ Common Tasks

Add New Widget Template

// In widget-builder-workspace.component.ts
readonly templates: WidgetTemplate[] = [
  // ... existing templates
  {
    id: 'my-new-template',
    name: 'My New Template',
    icon: 'widgets',
    description: 'Description of template',
    type: WidgetTypeEnum.CUSTOM,
    defaultProperties: { /* defaults */ },
    propertyGroups: [
      {
        id: 'content',
        title: 'Content',
        icon: 'edit',
        properties: [
          { key: 'title', label: 'Title', type: 'string', defaultValue: '' }
        ]
      }
    ]
  }
];

Register New Embeddable

// In embeddable component
@Component({
  selector: 'my-embeddable',
  standalone: true,
  // ... other config
})
export class MyEmbeddableComponent {
  // Component implementation
}

// Register in WidgetsEmbeddableRegistryService
const definition: EmbeddableDefinition = {
  id: 'my-embeddable',
  name: 'My Embeddable',
  description: 'Description',
  category: 'display',
  context: 'universal',
  icon: 'widgets',
  component: MyEmbeddableComponent,
  inputs: [
    { name: 'title', type: 'string', required: true }
  ]
};

🐛 Troubleshooting

Widget Not Appearing in Showcase

// Check:
1. Widget saved to MongoDB? (check backend logs)
2. Widget in correct collection? (space_widgets vs widgets)
3. Widget has correct context? (page, structural, universal)
4. Embeddable registered? (check WidgetsEmbeddableRegistryService)

Variant Not Saving

// Check:
1. Variant has unique ID? (auto-generated if missing)
2. Widget exists in database?
3. Backend endpoint responding? (check network tab)
4. Properties valid? (check console for errors)

Property Groups Not Loading

// Check:
1. PropertyRegistryService initialized?
2. Embeddable ID correct?
3. Property definitions valid?
4. Console errors? (check browser console)

📚 Documentation Links


🎯 Next Steps

Priority 5: NX Library Generation (Critical)

// Goal: Enable widget builder to generate NX libraries

// Implementation:
1. Add "Generate Library" checkbox in finalize step
2. Call NX generator: nx g @nx/angular:library my-widget
3. Generate files:
   - src/lib/my-widget.manifest.ts
   - src/lib/my-widget.component.ts
   - src/lib/my-widget.service.ts
   - src/index.ts
4. Update tsconfig.base.json
5. Register module in registry

// Reference: docs/english/GoGrab-Space/modules/modules-architecture.md

Document Version: 1.0
Session: 9
Date: December 9, 2025
Status: ✅ Production Ready (Core System)