Dashboard Framework Overview

Dashboard Framework Overview

Dashboards are apps that run inside Huitzo Hub. They launch from the Hub like apps in an operating system, providing users with focused, task-specific interfaces while the Hub handles navigation, authentication, and discovery.

Optional fullstack scaffolding. When a Dashboard ships alongside a Pack as one app, huitzo project init can scaffold both into a single directory. That is a CLI convenience for fullstack work — it does not change anything about how huitzo dashboard ... behaves. Standalone Dashboards created with huitzo dashboard new remain fully supported. See Intelligence Projects if fullstack scaffolding is useful for your work.

What is a Huitzo Dashboard?

A Huitzo Dashboard is a frontend application that: - Launches from Hub – Users click a tile to open the dashboard - Runs inside Hub – Renders at hub.huitzo.com/d/{slug}, not a separate URL - Consumes packs – Executes Intelligence Pack commands via API - Shares session – Uses the same JWT session as Hub

┌─────────────────────────────────────────────────────────────────────┐
│                    HUITZO HUB (The Container)                        │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  YOUR DASHBOARDS                                    [+ Explore More] │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐            │
│  │  Claims  │  │ Analytics│  │ Reports  │  │ WebCLI   │            │
│  │ Dashboard│  │ Dashboard│  │ Dashboard│  │ Terminal │            │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘            │
│                                                                      │
│  User clicks "Claims Dashboard" tile...                              │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
        │
        │ Route: hub.huitzo.com/d/claims-dashboard
        ▼
┌─────────────────────────────────────────────────────────────────────┐
│  [← Hub]  Claims Dashboard                      [Settings] [Help]   │
│  ─────────────────────────────────────────────────────────────────  │
│                                                                      │
│  ┌─────────────────────────────────────────────────────────────────┐│
│  │                                                                 ││
│  │     DASHBOARD RENDERS HERE (Full-width, app-like)               ││
│  │     • Consumes @acme/claims commands                            ││
│  │     • Uses shared HuitzoProvider                                ││
│  │     • Same JWT session as Hub                                   ││
│  │                                                                 ││
│  └─────────────────────────────────────────────────────────────────┘│
│                                                                      │
├─────────────────────────────────────────────────────────────────────┤
│                          Huitzo API (REST + WebSocket)               │
├─────────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                  │
│  │   Pack A    │  │   Pack B    │  │   Pack C    │                  │
│  │ (commands)  │  │ (commands)  │  │ (commands)  │                  │
│  └─────────────┘  └─────────────┘  └─────────────┘                  │
└─────────────────────────────────────────────────────────────────────┘

Key Concepts

Dashboards vs Packs

Aspect Intelligence Pack Dashboard
Purpose Business logic, data processing User interface, visualization
Language Python JavaScript/TypeScript (React)
Manifest huitzo.yaml huitzo-dashboard.yaml
Access API endpoints Hub tile → /d/{slug} route
Execution Server-side (Huitzo workers) Client-side (browser, inside Hub)
Relationship Can be consumed by dashboards Consumes one or more packs

Hub Integration

Dashboards are apps inside Hub, not separate applications:

  • Single URL – All dashboards at hub.huitzo.com/d/{slug}
  • Shared session – No re-authentication when switching dashboards
  • Hub navigation[← Hub] button returns to dashboard grid
  • Role-based visibility – Users only see assigned dashboards

Dashboard Independence

Dashboards are not bundled inside packs. A single dashboard can: - Consume commands from multiple packs - Work with different pack versions - Be distributed independently - Have its own pricing and licensing

First-Class Distribution

Dashboards have the same marketplace features as packs:

Feature Packs Dashboards
Visibility (public/unlisted/org/private)
Pricing (one-time/subscription/usage/free)
Marketplace listing ("Explore" tile in Hub)
Reviews and ratings
Version management
Access grants
Deletion (owner-only, cascade)

Dashboard Project Structure

my-dashboard/
├── huitzo-dashboard.yaml     # Dashboard manifest (required)
├── package.json
├── tsconfig.json
├── vite.config.ts
├── src/
│   ├── main.tsx              # Entry point
│   ├── App.tsx               # Root component
│   ├── components/           # UI components
│   ├── pages/                # Route pages
│   ├── hooks/                # Custom hooks (useHuitzo, useCommand)
│   ├── services/             # API layer
│   └── stores/               # State management
└── dist/                     # Build output

Quick Start

1. Create a New Dashboard

huitzo dashboard new claims-dashboard
cd claims-dashboard

2. Define Pack Dependencies

Edit huitzo-dashboard.yaml:

dashboard:
  name: "claims-dashboard"
  namespace: "claims"
  version: "1.0.0"
  description: "Claims management dashboard"

pack_dependencies:
  - scope: "@acme"
    name: "claims-processor"
    version: ">=2.0.0"
    required: true

3. Use the Dashboard SDK

import { useHuitzo, useCommand } from '@huitzo/dashboard-sdk-react';

function ClaimsList() {
  const { execute, data, loading, error } = useCommand('@acme/claims/list-claims');

  useEffect(() => {
    execute({ status: 'pending' });
  }, []);

  if (loading) return <Spinner />;
  if (error) return <Error message={error.message} />;

  return (
    <ul>
      {data?.claims.map(claim => (
        <li key={claim.id}>{claim.title}</li>
      ))}
    </ul>
  );
}

4. Run Development Server

huitzo dashboard dev

This starts: - Local dev server at http://localhost:3000 - API proxy to Huitzo backend - Hot reload for instant feedback

5. Publish to Marketplace

huitzo dashboard build
huitzo dashboard publish

Deployment Options

Dashboards are deployed to Hub—users access them via Hub routes:

Your dashboard is accessible through Huitzo's hosted Hub:

https://hub.huitzo.com/d/claims-dashboard

Benefits: - Zero configuration - Automatic HTTPS - Global CDN - Built-in authentication - Hub handles navigation and discovery

Option B: Self-Hosted Hub

Deploy Hub to your own infrastructure:

https://hub.company.com/d/claims-dashboard

Benefits: - Full control - Enterprise compliance - On-premises option - Data stays in your network

Note: Dashboards are always accessed through Hub routes. There are no separate dashboard URLs—Hub is the single entry point.

See Deployment Guide for complete setup instructions.

Dashboard SDK

The @huitzo/dashboard-sdk package provides Hub-aware components:

Core Client (Framework-Agnostic)

import { HuitzoClient } from '@huitzo/dashboard-sdk';

const huitzo = new HuitzoClient();
const result = await huitzo.commands.execute('@acme/claims/process-claim', {
  claimId: 'CLM-12345'
});

React Hooks with Hub Integration

import {
  HuitzoProvider,
  useCommand,
  useRealtime,
  useHubNavigation,
  useHubContext
} from '@huitzo/dashboard-sdk-react';

// HuitzoProvider receives the context object passed to mount()
// See loading.md for the full entry point contract
<HuitzoProvider context={context}>
  <App />
</HuitzoProvider>

// Execute commands
const { execute, data, loading } = useCommand('@acme/claims/process');

// Hub navigation
const { navigateToHub, currentDashboard } = useHubNavigation();

// Hub context
const { hubUrl, dashboardSlug } = useHubContext();

// Real-time updates
useRealtime('claims:updated', (event) => {
  console.log('Claim updated:', event.data);
});

See Dashboard SDK Reference for complete API documentation.

Discovery via "Explore"

Hub-Based Discovery

Dashboards are discovered through the "Explore" tile on Hub home:

Hub Home
├── Your Dashboards (assigned to you)
├── [+ Explore More] tile
│   └── Opens /explore with:
│       ├── Packs tab (Intelligence Packs)
│       └── Dashboards tab (Dashboard apps)
└── Search bar for quick access

Cross-Linking

Explore pages automatically show: - On pack pages: "Dashboards that use this pack" - On dashboard pages: "Required packs"

Role-Based Assignment

Admins assign dashboards to users/roles: - Users see only dashboards assigned to them - Users can pin/unpin dashboards within their allowed set - WebCLI tile shown to all users (last position)

Use Cases

1. Agency White-Label Dashboards

Consulting agencies build custom dashboards for clients:

dashboard:
  name: "client-analytics"
  visibility: "unlisted"  # Share via direct link

pack_dependencies:
  - scope: "@agency"
    name: "analytics-core"
    required: true

2. SaaS Product Frontend

Build your product's frontend as a Huitzo Dashboard:

dashboard:
  name: "saas-product"
  visibility: "organization"

pricing:
  model: "subscription"
  price: 99
  billing_period: "monthly"

3. Enterprise Internal Tools

Internal dashboards for enterprise customers:

dashboard:
  name: "internal-reporting"
  visibility: "private"

deployment:
  hosting: "self-hosted"  # On-premises deployment

Best Practices

1. Design for Pack Independence

// ✅ Good: Works with any pack that has list-claims
const { execute } = useCommand('@acme/claims/list-claims');

// ❌ Avoid: Tight coupling to specific pack internals
import { internalClaimsLogic } from '@acme/claims-processor';

2. Handle Loading and Errors

const { execute, data, loading, error } = useCommand('@acme/claims/get-claim');

if (loading) return <Skeleton />;
if (error) return <ErrorBoundary error={error} />;
return <ClaimDetails claim={data} />;

3. Use Real-Time Updates

// Subscribe to relevant events
useRealtime('claims:created', (event) => {
  // Refresh list or show notification
  refetch();
});

4. Optimize Pack Dependencies

pack_dependencies:
  - scope: "@acme"
    name: "claims-processor"
    version: ">=2.0.0 <3.0.0"  # Semver range
    required: true

  - scope: "@huitzo"
    name: "analytics"
    version: "*"
    required: false  # Optional enhancement