Drag-and-Drop & Module System Integration

Complete guide to how modules are created, stored, and used in the Modular Universe Builder

Drag-and-Drop & Module System Integration

Overview

The Modular Universe Builder (modular-universe) is now fully integrated with the module creation system (modularity-lib), enabling a complete workflow from module creation to platform building.

🎯 Complete Workflow

1. Creating Modules

Via Modularity Library (modularity-lib):

// User clicks "Create Module" button
// → Opens ModuleCreationWizardComponent
// → User selects pages, widgets, flows
// → Wizard calls ModulePackagerService.packageModule()

// Result: Module is:
// ✅ Saved to GgStorage (IndexedDB + MongoDB)
// ✅ Registered with ModuleRegistryService
// ✅ Available in ModulePaletteComponent
// ✅ Usable immediately (no page refresh needed)

Storage Locations:

GgStorage:
├── modularity/generated-modules/{moduleId}/manifest  (ModuleManifest)
├── modularity/generated-modules/{moduleId}/files     (GeneratedModuleFiles)
└── modularity/module-metadata/{moduleId}             (Metadata)

File System (via backend API):
└── modules/generated/{slug}/
    ├── src/lib/
    │   ├── components/
    │   ├── services/
    │   └── {module-name}.module.ts
    └── package.json

2. Displaying Modules in Palette

Module Merging Strategy (ModuleMergingService):

// Combines three sources:
1. Hardcoded BrowserModuleContract instances (from ModuleRegistry)
2. Simple manifests (from ModuleRegistry.getAllModules())
3. User-created modules (from GgStorage with prefix 'modularity/generated-modules')

// Filters out system modules:
- By ID: singularity, space-map, editor, modularity, widgets-manager, launch-station
- By category: 'core-tool', 'system'
- By tags: 'system', 'core-tool', 'internal'

Result: ModulePaletteComponent shows all available user-facing modules.

3. Drag-and-Drop System

Implementation:

<!-- Parent: cdkDropListGroup connects all nested drop lists -->
<div class="modular-universe-builder" cdkDropListGroup>
  
  <!-- Source: Module Palette -->
  <lib-module-palette>
    <div class="items-list" cdkDropList [cdkDropListConnectedTo]="[]">
      <div cdkDrag [cdkDragData]="{ type: 'module', data: manifest }">
        <!-- Module item -->
      </div>
    </div>
  </lib-module-palette>

  <!-- Target: Grid Canvas Sections -->
  <lib-grid-canvas>
    <lib-grid-section>
      <div class="section-content" 
           cdkDropList 
           [cdkDropListData]="section"
           (cdkDropListDropped)="onContentDrop($event, section)">
        <!-- Drop zone -->
      </div>
    </lib-grid-section>
  </lib-grid-canvas>

</div>

Drop Behavior (GridCanvasComponent.onContentDrop()):

// Case 1: Dropping into EMPTY section
// → Assign module/widget directly to section
// → Update section.contentType = 'module' | 'widget'
// → Update section.moduleId or section.widgetId

// Case 2: Dropping into section WITH CONTENT
// → Create nested child section
// → Add to section.children array
// → Supports recursive nesting (modules inside modules)

4. Recursive/Nested Module Support

Data Structure:

interface SectionConfig {
  id: string;
  name?: string;
  contentType: 'empty' | 'module' | 'widget' | 'page' | 'custom';
  moduleId?: string;
  widgetId?: string;
  
  // ✨ NEW: Nested sections for container modules
  children?: SectionConfig[];
  
  // Layout, positioning, behavior, etc.
}

Recursive Rendering (GridSectionComponent):

<lib-grid-section [section]="parent" [depth]="0">
  <!-- Section content -->
  
  <!-- Recursively render children -->
  @if (section.children && section.children.length > 0) {
    @for (child of section.children; track child.id) {
      <lib-grid-section [section]="child" [depth]="depth + 1">
        <!-- Nested section (can have its own children) -->
      </lib-grid-section>
    }
  }
</lib-grid-section>

Visual Feedback:

🔄 Real-Time Synchronization

Storage System (GgStorage)

Features:

  1. Flash Persistence: Instant write to IndexedDB
  2. MongoDB Sync: Automatic background sync when online
  3. Cross-Tab Sync: Changes reflect across all open tabs
  4. Offline-First: Works without internet connection

Module Lifecycle:

// 1. Create Module
await modulePackager.packageModule(config);
// → Saves to GgStorage
// → Registers with ModuleRegistry
// → Syncs to MongoDB (if online)

// 2. Load Module
const modules = await moduleMergingService.getMergedModules();
// → Loads from GgStorage (fast!)
// → Merges with hardcoded modules
// → Filters system modules

// 3. Use Module
// Module is dragged onto canvas
// → onContentDrop() updates section
// → saveLayoutConfiguration() persists to GgStorage
// → MongoDB sync happens automatically

🎨 Widget Integration

Widget Sources

1. Pre-built Widgets (widgets-manager):

// Loaded from: space_{spaceId}_widget_{widgetId}
// Examples: Hero Section, Product Card, Contact Form, etc.

2. Custom Widgets (created in Widget Builder):

// Created via: Widget Builder UI
// Stored in: GgStorage with space-specific keys
// Available in: ModulePaletteComponent > Widgets tab

3. Module Widgets (part of packaged modules):

// Defined in: ModuleManifest.embeddableComponents
// Generated during: Module packaging process
// Usable as: Standalone widgets or module components

Widget Rendering

Currently, widgets display as placeholders in the builder:

<div class="widget-content">
  <i class="fas fa-puzzle-piece"></i>
  <p>Widget: {{ section.widgetId }}</p>
</div>

Future Enhancement: Dynamic widget rendering using WidgetRendererService.

🚀 Module Usability

What Makes a Module "Usable"?

A module is considered usable when it:

✅ Has a valid manifest (ModuleManifest):

✅ Is properly stored:

✅ Can be instantiated:

✅ Is discoverable:

Current State

✅ Fully Working:

⚠️ Placeholder Rendering:

🔮 Future Enhancement:

🔗 Integration Points

1. Modularity Lib → Modular Universe

// ModuleCreationWizardComponent emits:
@Output() moduleCreated = new EventEmitter<string>();

// ModularUniverseBuilderComponent receives:
onModuleCreated(moduleId: string): void {
  this.closeEditor();
  this.loadAvailableModules(); // Refresh palette
}

2. Module Palette → Grid Canvas

// Palette provides drag data:
{
  type: 'module' | 'widget',
  data: ModuleManifest | SpaceWidget
}

// Canvas receives drop:
onContentDrop(event, section):
  - Extracts drag data
  - Updates section content
  - Persists to GgStorage

3. Grid Canvas → Section Config Panel

// Canvas emits:
@Output() sectionSelected = new EventEmitter<SectionConfig>();

// Panel receives:
// → Shows section properties
// → Allows editing contentType, moduleId, widgetId
// → Changes persist via GridCanvas.updateSection()

🎯 Best Practices

Creating Modules

  1. Use the Wizard: ModuleCreationWizardComponent ensures proper structure
  2. Select Assets: Choose pages, widgets, and flows that work together
  3. Name Descriptively: Use clear names for discoverability
  4. Tag Appropriately: Tags help with filtering and organization

Using Modules

  1. Drag from Palette: All modules are draggable
  2. Drop into Sections: Empty sections accept modules directly
  3. Nest for Complexity: Drop into filled sections to create nested structures
  4. Configure via Panel: Use Section Config Panel for fine-tuning

Storage Strategy

  1. Trust GgStorage: Automatic sync, offline-first
  2. Don't Manual Sync: Flash persistence handles it
  3. Use Prefixes: Follow the pattern (modularity/, space_, etc.)
  4. Check Sync Status: Use ModuleStorageService.getAllSyncStatuses()

📊 Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│                  Modular Universe Builder                    │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌──────────────────┐      ┌─────────────────────────────┐ │
│  │ Module Palette   │─────▶│    Grid Canvas              │ │
│  │ (Drag Source)    │      │    (Drop Target)            │ │
│  │                  │      │                             │ │
│  │  Modules Tab     │      │  ┌─────────────────────┐   │ │
│  │  Widgets Tab     │      │  │ Section (empty)     │   │ │
│  └──────────────────┘      │  │ [Drop here]         │   │ │
│           │                │  └─────────────────────┘   │ │
│           │                │                             │ │
│           ▼                │  ┌─────────────────────┐   │ │
│  ┌──────────────────┐      │  │ Section (module)    │   │ │
│  │ Module Merging   │      │  │  ├─ Child Section  │   │ │
│  │ Service          │      │  │  └─ Child Section  │   │ │
│  │                  │      │  └─────────────────────┘   │ │
│  │ • Hardcoded      │      └─────────────────────────────┘ │
│  │ • User-Created   │                   │                  │
│  │ • Filtered       │                   ▼                  │
│  └──────────────────┘      ┌─────────────────────────────┐ │
│           │                │  Section Config Panel        │ │
│           │                │  (Property Editor)           │ │
│           ▼                └─────────────────────────────┘ │
│  ┌──────────────────┐                                      │
│  │ GgStorage        │◀────────────────────────────────────┤
│  │ (Flash Persist)  │                                      │
│  └──────────────────┘                                      │
│           │                                                 │
│           ├──▶ IndexedDB (Offline)                        │
│           └──▶ MongoDB (Online Sync)                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                     Modularity Library                       │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ Module Creation Wizard                                │  │
│  │  Step 1: Type Selection                              │  │
│  │  Step 2: Basic Info                                  │  │
│  │  Step 3: Content (Pages, Widgets, Flows)            │  │
│  │  Step 4: Configuration                               │  │
│  │  Step 5: Preview & Generate                          │  │
│  └──────────────────────────────────────────────────────┘  │
│           │                                                  │
│           ▼                                                  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ Module Packager Service                              │  │
│  │  • Load Assets                                       │  │
│  │  • Generate Platform-Agnostic Types                  │  │
│  │  • Generate Module Manifest                          │  │
│  │  • Generate Module Files                             │  │
│  │  • Create Deployment Bundle                          │  │
│  └──────────────────────────────────────────────────────┘  │
│           │                                                  │
│           ▼                                                  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ Module Storage Service (Dual Storage)                │  │
│  │  • Save to GgStorage (Runtime)                       │  │
│  │  • Save to File System (Build-time)                  │  │
│  │  • Register with ModuleRegistry                      │  │
│  │  • Track Sync Status                                 │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                               │
└─────────────────────────────────────────────────────────────┘

🎉 Summary

The Modular Universe Builder now provides a complete, Ferrari-level module system:

✅ Create: Modules via visual wizard ✅ Store: Dual storage (runtime + build-time) ✅ Discover: Merged module palette with filtering ✅ Use: Drag-and-drop onto canvas ✅ Nest: Recursive sections for complex layouts ✅ Persist: Flash persistence with MongoDB sync ✅ Scale: Supports unlimited modules and nesting

This is the foundation for building "the most powerful platform builder in the universe." 🚀