Dynamic Elements
Complex Workflows

Complex Workflows

This guide demonstrates advanced patterns and real-world examples of complex dynamic design workflows in Canvelete (opens in a new tab). Learn how to combine multiple dynamic elements, data sources, and conditional logic to create sophisticated, data-driven designs.

Multi-Source Dashboard Workflow

Scenario: Executive Dashboard

Create a comprehensive dashboard that pulls data from multiple APIs and displays different visualizations based on user role and permissions.

Data Sources Configuration

{
  "dataSources": {
    "salesData": {
      "type": "api",
      "url": "https://api.company.com/sales/summary",
      "refreshInterval": 300000,
      "headers": {"Authorization": "Bearer {{userToken}}"}
    },
    "userMetrics": {
      "type": "api", 
      "url": "https://api.company.com/users/metrics",
      "refreshInterval": 600000
    },
    "realTimeEvents": {
      "type": "websocket",
      "url": "wss://api.company.com/events",
      "events": ["sale", "signup", "error"]
    }
  },
  "computed": {
    "totalRevenue": "{{salesData.monthly.reduce((sum, month) => sum + month.revenue, 0)}}",
    "growthRate": "{{((salesData.currentMonth.revenue - salesData.previousMonth.revenue) / salesData.previousMonth.revenue * 100).toFixed(1)}}",
    "conversionRate": "{{(salesData.conversions / userMetrics.visitors * 100).toFixed(2)}}",
    "isPerformingWell": "{{growthRate > 5 && conversionRate > 2.5}}"
  }
}

Dynamic Dashboard Template

"<div class='dashboard {{user.role}} {{isPerformingWell ? 'positive' : 'needs-attention'}}'>
  
  <!-- Header with role-based content -->
  <header class='dashboard-header'>
    <h1>{{user.role === 'executive' ? 'Executive' : 'Sales'}} Dashboard</h1>
    <div class='last-updated'>
      Last updated: {{salesData.lastUpdated | fromNow}}
    </div>
  </header>
 
  <!-- KPI Cards with conditional styling -->
  <div class='kpi-grid'>
    {{#each kpiCards}}
      <div class='kpi-card {{this.trend}}' style='--accent-color: {{this.color}}'>
        <div class='kpi-header'>
          <h3>{{this.title}}</h3>
          {{#if (hasPermission user.permissions this.requiredPermission)}}
            <button class='drill-down' data-metric='{{this.id}}'>Details</button>
          {{/if}}
        </div>
        <div class='kpi-value'>
          {{#if this.type === 'currency'}}
            {{this.value | currency}}
          {{else if this.type === 'percentage'}}
            {{this.value}}%
          {{else}}
            {{this.value | number}}
          {{/if}}
        </div>
        <div class='kpi-change {{this.change >= 0 ? 'positive' : 'negative'}}'>
          {{this.change >= 0 ? '↗' : '↘'}} {{Math.abs(this.change)}}%
        </div>
      </div>
    {{/each}}
  </div>
 
  <!-- Conditional chart sections based on role -->
  {{#if (includes ['executive', 'manager'] user.role)}}
    <div class='charts-section'>
      <div class='chart-container'>
        <h2>Revenue Trend</h2>
        {{#if salesData.monthly.length > 0}}
          <canvas id='revenue-chart' data-values='{{JSON.stringify(salesData.monthly)}}'></canvas>
        {{else}}
          <div class='no-data'>No revenue data available</div>
        {{/if}}
      </div>
      
      {{#if user.role === 'executive'}}
        <div class='chart-container'>
          <h2>Department Performance</h2>
          <div class='department-grid'>
            {{#each salesData.departments}}
              <div class='department-card {{this.performance}}'>
                <h4>{{this.name}}</h4>
                <div class='performance-indicator' style='width: {{this.score}}%'></div>
                <span>{{this.score}}% of target</span>
              </div>
            {{/each}}
          </div>
        </div>
      {{/if}}
    </div>
  {{/if}}
 
  <!-- Real-time events feed -->
  {{#if realTimeEvents.length > 0}}
    <div class='events-feed'>
      <h2>Live Activity</h2>
      <div class='events-list'>
        {{#each (slice realTimeEvents 0 10)}}
          <div class='event-item {{this.type}}'>
            <span class='event-time'>{{this.timestamp | time}}</span>
            <span class='event-description'>
              {{#if this.type === 'sale'}}
                💰 Sale: {{this.amount | currency}} - {{this.product}}
              {{else if this.type === 'signup'}}
                👤 New user: {{this.userEmail}}
              {{else if this.type === 'error'}}
                âš ī¸ Error: {{this.message}}
              {{/if}}
            </span>
          </div>
        {{/each}}
      </div>
    </div>
  {{/if}}
 
</div>"

E-commerce Product Catalog Workflow

Scenario: Dynamic Product Showcase

Create a product catalog that adapts to user preferences, inventory levels, and promotional campaigns.

Complex Data Structure

{
  "products": [
    {
      "id": "prod-001",
      "name": "Wireless Headphones Pro",
      "category": "electronics",
      "price": 299.99,
      "salePrice": 249.99,
      "inventory": 15,
      "rating": 4.7,
      "reviews": 1247,
      "images": [
        "https://example.com/headphones-1.jpg",
        "https://example.com/headphones-2.jpg"
      ],
      "features": ["noise-cancelling", "wireless", "long-battery"],
      "variants": [
        {"color": "black", "stock": 8},
        {"color": "white", "stock": 7}
      ],
      "promotion": {
        "type": "flash-sale",
        "endTime": "2024-01-20T23:59:59Z",
        "discount": 17
      }
    }
  ],
  "user": {
    "preferences": {
      "categories": ["electronics", "books"],
      "priceRange": {"min": 0, "max": 500},
      "brands": ["sony", "apple", "samsung"]
    },
    "browsingHistory": ["prod-001", "prod-045"],
    "cart": {"items": [], "total": 0},
    "wishlist": ["prod-001"]
  },
  "computed": {
    "filteredProducts": "{{products.filter(p => user.preferences.categories.includes(p.category) && p.price <= user.preferences.priceRange.max)}}",
    "recommendedProducts": "{{products.filter(p => user.browsingHistory.includes(p.id) || user.preferences.brands.includes(p.brand))}}",
    "flashSaleProducts": "{{products.filter(p => p.promotion && p.promotion.type === 'flash-sale' && new Date(p.promotion.endTime) > new Date())}}",
    "lowStockProducts": "{{products.filter(p => p.inventory > 0 && p.inventory <= 5)}}"
  }
}

Dynamic Product Grid Template

"<div class='product-catalog'>
  
  <!-- Flash sale banner -->
  {{#if flashSaleProducts.length > 0}}
    <div class='flash-sale-banner'>
      <h2>⚡ Flash Sale - Limited Time!</h2>
      <div class='countdown' data-end='{{flashSaleProducts[0].promotion.endTime}}'>
        Ends in: <span class='time-remaining'></span>
      </div>
    </div>
  {{/if}}
 
  <!-- Personalized recommendations -->
  {{#if recommendedProducts.length > 0}}
    <section class='recommendations'>
      <h2>Recommended for You</h2>
      <div class='product-grid recommended'>
        {{#each (slice recommendedProducts 0 4)}}
          {{> productCard this context='recommendation'}}
        {{/each}}
      </div>
    </section>
  {{/if}}
 
  <!-- Main product grid with filters -->
  <section class='main-catalog'>
    <div class='catalog-header'>
      <h2>All Products ({{filteredProducts.length}})</h2>
      <div class='filters'>
        <!-- Dynamic filter controls -->
      </div>
    </div>
    
    <div class='product-grid main'>
      {{#each filteredProducts}}
        {{> productCard this context='catalog'}}
      {{/each}}
    </div>
  </section>
 
</div>
 
<!-- Product Card Partial Template -->
{{#*inline 'productCard'}}
  <div class='product-card {{context}} {{#if this.promotion}}on-sale{{/if}} {{#if (lte this.inventory 5)}}low-stock{{/if}}'>
    
    <!-- Product image with conditional badges -->
    <div class='product-image'>
      <img src='{{this.images[0]}}' alt='{{this.name}}' loading='lazy'>
      
      <!-- Conditional badges -->
      {{#if this.promotion}}
        <div class='sale-badge'>
          {{this.promotion.discount}}% OFF
        </div>
      {{/if}}
      
      {{#if (includes user.wishlist this.id)}}
        <div class='wishlist-badge'>â¤ī¸</div>
      {{/if}}
      
      {{#if (lte this.inventory 5)}}
        <div class='stock-badge'>Only {{this.inventory}} left!</div>
      {{/if}}
    </div>
 
    <!-- Product info -->
    <div class='product-info'>
      <h3 class='product-name'>{{this.name}}</h3>
      
      <!-- Dynamic pricing -->
      <div class='pricing'>
        {{#if this.salePrice}}
          <span class='sale-price'>{{this.salePrice | currency}}</span>
          <span class='original-price'>{{this.price | currency}}</span>
          <span class='savings'>Save {{((this.price - this.salePrice) / this.price * 100).toFixed(0)}}%</span>
        {{else}}
          <span class='price'>{{this.price | currency}}</span>
        {{/if}}
      </div>
 
      <!-- Rating and reviews -->
      {{#if this.rating}}
        <div class='rating'>
          <div class='stars' style='--rating: {{this.rating}}'>★★★★★</div>
          <span class='review-count'>({{this.reviews}} reviews)</span>
        </div>
      {{/if}}
 
      <!-- Variant selection -->
      {{#if this.variants.length > 1}}
        <div class='variants'>
          {{#each this.variants}}
            <button class='variant-option {{#unless this.stock}}out-of-stock{{/unless}}' 
                    data-variant='{{this.color}}'
                    {{#unless this.stock}}disabled{{/unless}}>
              {{this.color | titlecase}}
              {{#unless this.stock}}(Out of Stock){{/unless}}
            </button>
          {{/each}}
        </div>
      {{/if}}
 
      <!-- Action buttons -->
      <div class='product-actions'>
        {{#if (gt this.inventory 0)}}
          <button class='add-to-cart' data-product='{{this.id}}'>
            Add to Cart
          </button>
        {{else}}
          <button class='notify-restock' data-product='{{this.id}}'>
            Notify When Available
          </button>
        {{/if}}
        
        <button class='wishlist-toggle {{#if (includes user.wishlist this.id)}}active{{/if}}' 
                data-product='{{this.id}}'>
          {{#if (includes user.wishlist this.id)}}â¤ī¸{{else}}🤍{{/if}}
        </button>
      </div>
    </div>
 
  </div>
{{/inline}}"

Social Media Content Generator Workflow

Scenario: Multi-Platform Post Creation

Generate social media posts optimized for different platforms with dynamic content adaptation.

Platform-Specific Configuration

{
  "platforms": {
    "twitter": {
      "maxLength": 280,
      "supportsImages": true,
      "supportsVideo": true,
      "hashtagLimit": 2,
      "mentionLimit": 10
    },
    "instagram": {
      "maxLength": 2200,
      "supportsImages": true,
      "supportsVideo": true,
      "hashtagLimit": 30,
      "aspectRatios": ["1:1", "4:5", "16:9"]
    },
    "linkedin": {
      "maxLength": 3000,
      "supportsImages": true,
      "supportsVideo": true,
      "professionalTone": true
    }
  },
  "content": {
    "type": "product-launch",
    "product": {
      "name": "EcoSmart Water Bottle",
      "features": ["BPA-free", "Temperature control", "Smart tracking"],
      "price": 49.99,
      "launchDate": "2024-02-01"
    },
    "campaign": {
      "hashtags": ["#EcoSmart", "#SustainableLiving", "#Innovation", "#WaterBottle", "#EcoFriendly"],
      "mentions": ["@EcoSmartTech", "@SustainabilityNow"],
      "callToAction": "Order now and get 20% off!"
    }
  },
  "computed": {
    "shortDescription": "{{content.product.name}} - {{content.product.features.slice(0, 2).join(' & ')}}",
    "platformHashtags": "{{platform => content.campaign.hashtags.slice(0, platforms[platform].hashtagLimit || content.campaign.hashtags.length)}}",
    "adaptedContent": "{{platform => adaptContentForPlatform(content, platforms[platform])}}"
  }
}

Multi-Platform Template Generator

"{{#each platforms as |config platform|}}
  <div class='platform-post {{platform}}'>
    <div class='platform-header'>
      <h3>{{platform | titlecase}} Post</h3>
      <div class='character-count'>
        <span class='current'>{{(adaptedContent platform).length}}</span>
        <span class='max'>/{{config.maxLength}}</span>
      </div>
    </div>
 
    <div class='post-content'>
      <!-- Platform-specific content adaptation -->
      {{#if platform === 'twitter'}}
        {{> twitterPost config}}
      {{else if platform === 'instagram'}}
        {{> instagramPost config}}
      {{else if platform === 'linkedin'}}
        {{> linkedinPost config}}
      {{/if}}
    </div>
 
    <!-- Media preview -->
    {{#if config.supportsImages}}
      <div class='media-preview'>
        <img src='{{content.product.image}}' alt='{{content.product.name}}'>
        {{#if platform === 'instagram'}}
          <div class='aspect-ratio-options'>
            {{#each config.aspectRatios}}
              <button class='aspect-option' data-ratio='{{this}}'>{{this}}</button>
            {{/each}}
          </div>
        {{/if}}
      </div>
    {{/if}}
 
    <!-- Engagement predictions -->
    <div class='engagement-prediction'>
      <div class='metric'>
        <span class='label'>Predicted Reach:</span>
        <span class='value'>{{predictEngagement platform 'reach'}}</span>
      </div>
      <div class='metric'>
        <span class='label'>Engagement Rate:</span>
        <span class='value'>{{predictEngagement platform 'engagement'}}%</span>
      </div>
    </div>
 
  </div>
{{/each}}
 
<!-- Platform-specific templates -->
{{#*inline 'twitterPost'}}
  <div class='twitter-content'>
    🚀 Introducing {{content.product.name}}! 
    
    {{#each (slice content.product.features 0 2)}}
      ✅ {{this}}
    {{/each}}
    
    {{#if (lt (calculateLength twitterContent) 200)}}
      Starting at ${{content.product.price}}
    {{/if}}
    
    {{content.campaign.callToAction}}
    
    {{#each (platformHashtags 'twitter')}}{{this}} {{/each}}
    
    {{#each (slice content.campaign.mentions 0 2)}}{{this}} {{/each}}
  </div>
{{/inline}}
 
{{#*inline 'instagramPost'}}
  <div class='instagram-content'>
    ✨ Meet the {{content.product.name}} ✨
    
    The future of hydration is here! Our latest innovation combines:
    
    {{#each content.product.features}}
    🌟 {{this}}
    {{/each}}
    
    Perfect for the eco-conscious lifestyle you've been building. 💚
    
    {{content.campaign.callToAction}}
    
    Link in bio! 👆
    
    ---
    
    {{#each (platformHashtags 'instagram')}}{{this}} {{/each}}
    
    {{#each content.campaign.mentions}}{{this}} {{/each}}
  </div>
{{/inline}}
 
{{#*inline 'linkedinPost'}}
  <div class='linkedin-content'>
    We're excited to announce the launch of {{content.product.name}}, a breakthrough in sustainable hydration technology.
    
    In today's environmentally conscious market, consumers are seeking products that align with their values. Our new {{content.product.name}} addresses this need by offering:
    
    {{#each content.product.features}}
    â€ĸ {{this}}
    {{/each}}
    
    This launch represents our continued commitment to innovation and sustainability in the consumer goods sector.
    
    {{content.campaign.callToAction}}
    
    What are your thoughts on sustainable product innovation? Share your perspective in the comments.
    
    {{#each (slice (platformHashtags 'linkedin') 0 5)}}{{this}} {{/each}}
  </div>
{{/inline}}"

Event-Driven Dynamic Layouts

Scenario: Real-Time Conference Dashboard

Create a conference dashboard that updates in real-time based on event data, attendee interactions, and schedule changes.

Event Data Structure

{
  "conference": {
    "name": "TechConf 2024",
    "startDate": "2024-03-15T09:00:00Z",
    "endDate": "2024-03-17T18:00:00Z",
    "timezone": "America/New_York"
  },
  "sessions": [
    {
      "id": "session-001",
      "title": "The Future of AI",
      "speaker": "Dr. Jane Smith",
      "startTime": "2024-03-15T10:00:00Z",
      "endTime": "2024-03-15T11:00:00Z",
      "room": "Main Hall",
      "capacity": 500,
      "registered": 487,
      "status": "live",
      "tags": ["AI", "Machine Learning", "Future Tech"]
    }
  ],
  "attendee": {
    "id": "att-123",
    "name": "John Doe",
    "registeredSessions": ["session-001", "session-003"],
    "preferences": ["AI", "Web Development"],
    "currentLocation": "Main Hall"
  },
  "realTimeData": {
    "currentAttendance": 450,
    "networkingMatches": 12,
    "livePolls": [
      {
        "sessionId": "session-001",
        "question": "What's the most exciting AI development?",
        "responses": {"GPT": 45, "Computer Vision": 32, "Robotics": 23}
      }
    ]
  },
  "computed": {
    "currentSession": "{{sessions.find(s => new Date(s.startTime) <= new Date() && new Date(s.endTime) > new Date())}}",
    "upcomingSession": "{{sessions.find(s => new Date(s.startTime) > new Date()).sort((a,b) => new Date(a.startTime) - new Date(b.startTime))[0]}}",
    "personalizedRecommendations": "{{sessions.filter(s => s.tags.some(tag => attendee.preferences.includes(tag)) && !attendee.registeredSessions.includes(s.id))}}",
    "isSessionFull": "{{session => session.registered >= session.capacity * 0.95}}"
  }
}

Dynamic Conference Dashboard

"<div class='conference-dashboard' data-attendee='{{attendee.id}}'>
  
  <!-- Real-time status header -->
  <header class='dashboard-header'>
    <div class='conference-info'>
      <h1>{{conference.name}}</h1>
      <div class='live-status'>
        {{#if currentSession}}
          <span class='live-indicator'>🔴 LIVE</span>
          <span class='current-session'>{{currentSession.title}}</span>
        {{else}}
          <span class='between-sessions'>Between Sessions</span>
        {{/if}}
      </div>
    </div>
    
    <div class='attendee-info'>
      <span class='welcome'>Welcome, {{attendee.name}}</span>
      <div class='quick-stats'>
        <span class='stat'>
          <span class='label'>Registered:</span>
          <span class='value'>{{attendee.registeredSessions.length}}</span>
        </span>
        <span class='stat'>
          <span class='label'>Networking:</span>
          <span class='value'>{{realTimeData.networkingMatches}}</span>
        </span>
      </div>
    </div>
  </header>
 
  <!-- Current session focus -->
  {{#if currentSession}}
    <section class='current-session-focus'>
      <div class='session-header'>
        <h2>{{currentSession.title}}</h2>
        <div class='session-meta'>
          <span class='speaker'>{{currentSession.speaker}}</span>
          <span class='room'>{{currentSession.room}}</span>
          <span class='time'>
            {{currentSession.startTime | time}} - {{currentSession.endTime | time}}
          </span>
        </div>
      </div>
      
      <!-- Live attendance and capacity -->
      <div class='attendance-info'>
        <div class='attendance-bar'>
          <div class='fill' style='width: {{(realTimeData.currentAttendance / currentSession.capacity * 100)}}%'></div>
        </div>
        <span class='attendance-text'>
          {{realTimeData.currentAttendance}} / {{currentSession.capacity}} attendees
          {{#if (isSessionFull currentSession)}}
            <span class='full-indicator'>Nearly Full!</span>
          {{/if}}
        </span>
      </div>
 
      <!-- Live polls if available -->
      {{#each realTimeData.livePolls}}
        {{#if (eq this.sessionId ../currentSession.id)}}
          <div class='live-poll'>
            <h3>Live Poll: {{this.question}}</h3>
            <div class='poll-results'>
              {{#each this.responses}}
                <div class='poll-option'>
                  <span class='option-name'>{{@key}}</span>
                  <div class='option-bar'>
                    <div class='fill' style='width: {{(this / (sum ../this.responses) * 100)}}%'></div>
                  </div>
                  <span class='option-count'>{{this}}</span>
                </div>
              {{/each}}
            </div>
          </div>
        {{/if}}
      {{/each}}
 
      <!-- Session actions -->
      <div class='session-actions'>
        {{#if (includes attendee.registeredSessions currentSession.id)}}
          {{#if (eq attendee.currentLocation currentSession.room)}}
            <button class='action-btn checked-in'>✓ Checked In</button>
          {{else}}
            <button class='action-btn check-in' data-session='{{currentSession.id}}'>
              Check In to {{currentSession.room}}
            </button>
          {{/if}}
        {{else}}
          {{#if (isSessionFull currentSession)}}
            <button class='action-btn full' disabled>Session Full</button>
          {{else}}
            <button class='action-btn register' data-session='{{currentSession.id}}'>
              Join Session
            </button>
          {{/if}}
        {{/if}}
        
        <button class='action-btn networking' data-session='{{currentSession.id}}'>
          Find Networking Opportunities
        </button>
      </div>
    </section>
  {{/if}}
 
  <!-- Upcoming sessions -->
  <section class='upcoming-sessions'>
    <h2>Your Schedule</h2>
    <div class='session-timeline'>
      {{#each (filter sessions s => includes attendee.registeredSessions s.id)}}
        <div class='timeline-item {{#if (eq this.id currentSession.id)}}current{{/if}}'>
          <div class='time-marker'>
            {{this.startTime | time}}
          </div>
          <div class='session-card'>
            <h3>{{this.title}}</h3>
            <p class='speaker'>{{this.speaker}}</p>
            <p class='room'>{{this.room}}</p>
            
            {{#if (eq this.status 'cancelled')}}
              <div class='status-badge cancelled'>Cancelled</div>
            {{else if (eq this.status 'moved')}}
              <div class='status-badge moved'>Room Changed</div>
            {{else if (isSessionFull this)}}
              <div class='status-badge full'>Nearly Full</div>
            {{/if}}
          </div>
        </div>
      {{/each}}
    </div>
  </section>
 
  <!-- Personalized recommendations -->
  {{#if personalizedRecommendations.length > 0}}
    <section class='recommendations'>
      <h2>Recommended for You</h2>
      <div class='recommendation-grid'>
        {{#each (slice personalizedRecommendations 0 3)}}
          <div class='recommendation-card'>
            <h3>{{this.title}}</h3>
            <p class='speaker'>{{this.speaker}}</p>
            <div class='match-tags'>
              {{#each this.tags}}
                {{#if (includes ../attendee.preferences this)}}
                  <span class='tag matched'>{{this}}</span>
                {{else}}
                  <span class='tag'>{{this}}</span>
                {{/if}}
              {{/each}}
            </div>
            <div class='recommendation-actions'>
              <button class='register-btn' data-session='{{this.id}}'>
                Add to Schedule
              </button>
              <span class='availability'>
                {{this.capacity - this.registered}} spots left
              </span>
            </div>
          </div>
        {{/each}}
      </div>
    </section>
  {{/if}}
 
  <!-- Real-time notifications -->
  <div class='notification-center'>
    {{#if notifications.length > 0}}
      {{#each notifications}}
        <div class='notification {{this.type}}'>
          <span class='notification-icon'>
            {{#if (eq this.type 'session-starting')}}⏰
            {{else if (eq this.type 'room-change')}}📍
            {{else if (eq this.type 'networking')}}🤝
            {{else}}â„šī¸{{/if}}
          </span>
          <span class='notification-text'>{{this.message}}</span>
          <button class='dismiss-btn' data-notification='{{this.id}}'>×</button>
        </div>
      {{/each}}
    {{/if}}
  </div>
 
</div>"

Best Practices for Complex Workflows

1. Data Architecture

  • Normalize data structures: Keep related data together
  • Use computed properties: For expensive calculations
  • Implement caching: For frequently accessed data
  • Plan for real-time updates: Design with live data in mind

2. Template Organization

  • Use partials: Break complex templates into reusable components
  • Implement template inheritance: Share common layouts
  • Organize by feature: Group related templates together
  • Document complex logic: Explain non-obvious template decisions

3. Performance Optimization

  • Lazy load sections: Only render visible content
  • Batch data updates: Group multiple changes together
  • Use efficient filters: Optimize data transformations
  • Monitor render times: Track template performance

4. Error Handling

  • Graceful degradation: Handle missing data elegantly
  • Provide fallbacks: Always have backup content
  • Log errors: Track template failures
  • Test edge cases: Verify behavior with unusual data

5. Maintainability

  • Use consistent patterns: Establish team conventions
  • Keep logic simple: Move complex operations to computed properties
  • Version templates: Track changes over time
  • Document workflows: Explain the overall system design

These complex workflows demonstrate how Canvelete's dynamic elements can be combined to create sophisticated, data-driven applications that adapt to user needs and real-time conditions.