LTB Method Actions

Componente de gestion de etapas y agentes

Demo
Simulador de Permisos
Activa o desactiva permisos para probar como se comporta el componente con diferentes roles. En tu aplicacion, estos permisos vendran de tu sistema de autenticacion.

Documentacion Tecnica

Referencia completa para integrar ltb-method en cualquier proyecto React o Next.js.

Arquitectura

Basada en Context API de React. Dos niveles independientes: organizacion y cuenta (proyecto).

API Adapter Pattern

Desacoplado del backend mediante un adaptador intercambiable. Implementa la interfaz LTBApiAdapter.

Permisos granulares

Cada vista acepta un objeto LTBPermissions que controla que agentes son visibles e interactivos.

1. Instalacion
Copia la carpeta del componente a tu proyecto. No requiere paquetes adicionales mas alla de las dependencias de shadcn/ui.
cp -r components/ltb-method/ your-project/components/
2. Interfaces principales
Tipos TypeScript exportados por el componente. Todos se importan desde ./components/ltb-method.

LTBPermissions— Controla la visibilidad e interaccion de cada vista

interface LTBPermissions {
  canManage: boolean;               // Crear / editar / eliminar etapas y agentes
  canToggleAccountActions: boolean; // Activar / desactivar agentes por proyecto
}

LTBApiAdapter— Interfaz que debe implementar tu capa de datos

interface LTBApiAdapter {
  // Etapas
  getStages(): Promise;
  createStage(data: StageFormData): Promise;
  updateStage(id: string, data: Partial): Promise;
  deleteStage(id: string): Promise;
  reorderStages(orderedIds: string[]): Promise;

  // Agentes
  getActions(): Promise;
  createAction(data: ActionFormData): Promise;
  updateAction(id: string, data: Partial): Promise;
  deleteAction(id: string): Promise;
  reorderActions(stageId: string, orderedIds: string[]): Promise;

  // Agentes por cuenta
  getAccountActions(accountId: string): Promise;
  toggleAccountAction(
    accountId: string,
    actionId: string,
    isActive: boolean
  ): Promise;

  // Ejecuciones
  executeAction(context: ExecutionContext): Promise;
  getExecutionHistory(accountId: string, actionId?: string): Promise;
  getAccountActionsWithExecutions(accountId: string): Promise;
}
3. Implementar el adaptador de API
Crea una instancia del adaptador apuntando a tus propios endpoints. El helper createApiAdapter valida que se implementen todos los metodos requeridos.
import { createApiAdapter } from '@/components/ltb-method';

export const myApiAdapter = createApiAdapter({
  getStages: () =>
    fetch('/api/stages').then((r) => r.json()),

  createStage: (data) =>
    fetch('/api/stages', {
      method: 'POST',
      body: JSON.stringify(data),
    }).then((r) => r.json()),

  reorderStages: (orderedIds) =>
    fetch('/api/stages/reorder', {
      method: 'PUT',
      body: JSON.stringify({ orderedIds }),
    }).then((r) => r.json()),

  getActions: () =>
    fetch('/api/actions').then((r) => r.json()),

  reorderActions: (stageId, orderedIds) =>
    fetch('/api/actions/reorder', {
      method: 'PUT',
      body: JSON.stringify({ stageId, orderedIds }),
    }).then((r) => r.json()),

  getAccountActions: (accountId) =>
    fetch('/api/accounts/' + accountId + '/actions').then((r) => r.json()),

  toggleAccountAction: (accountId, actionId, isActive) =>
    fetch('/api/accounts/' + accountId + '/actions/' + actionId, {
      method: 'PATCH',
      body: JSON.stringify({ isActive }),
    }).then((r) => r.json()),

  // ... resto de metodos
});
4. Providers y vistas
Cada vista requiere su propio provider. LTBMethodProvider gestiona el nivel de organizacion y LTBAccountProvider el nivel de proyecto.
import {
  LTBMethodProvider,
  LTBAccountProvider,
  OrganizationView,
  AccountView,
  type LTBPermissions,
} from '@/components/ltb-method';

// Vista de Organizacion / Agencia
const orgPermissions: LTBPermissions = {
  canManage: user.role === 'admin',
  canToggleAccountActions: false,
};


  


// Vista de Proyecto (Account)
const accountPermissions: LTBPermissions = {
  canManage: false,
  canToggleAccountActions: user.permissions.includes('account:write'),
};


  
5. Contrato de la API REST
Esquema de los endpoints que debe exponer tu backend para que el adaptador funcione correctamente.

GET /api/accounts/{accountId}/actions

// Response 200
{
  "stages": [
    {
      "id": "string",
      "name": "string",
      "order": 1,
      "actions": [
        {
          "id": "string",
          "stage_id": "string",
          "name": "string",
          "icon": "string",         // nombre de icono Lucide
          "description": "string",
          "rich_description": "string | null",  // HTML permitido
          "agent_source": "claude | n8n",       // fuente del agente
          "agent_id": "string | null",          // ID del agente
          "order": 1,                           // orden dentro de la etapa
          "is_active": true
        }
      ]
    }
  ]
}

PUT /api/actions/reorder

// Request body
{
  "stageId": "string",
  "orderedIds": ["agent-1", "agent-3", "agent-2"]
}

// Response 200 - array de agentes reordenados
[
  {
    "id": "string",
    "stage_id": "string",
    "order": 1,
    // ... resto de campos del agente
  }
]
6. Reordenar etapas y agentes
El componente soporta drag-and-drop para reordenar tanto etapas como agentes dentro de etapas. Utiliza @dnd-kit internamente.

Callbacks en StagesTimeline

 {
    // orderedIds: string[] - nuevos IDs en orden
    await reorderStages(orderedIds);
  }}
  // Llamado cuando se reordena agentes dentro una etapa
  onReorderActions={(stageId, orderedIds) => {
    // stageId: string - etapa que contiene los agentes
    // orderedIds: string[] - nuevos IDs de agentes en orden
    await reorderActions(stageId, orderedIds);
  }}
/>

Comportamiento de reordenamiento

  • Arrastra etapas verticalmente para cambiar su orden
  • Arrastra agentes dentro de una etapa para reordenarlos
  • Los cambios se persisten automaticamente en el backend
  • El campo order se actualiza en la base de datos
7. Historial de ejecuciones
Registra y muestra el historial de ejecuciones de agentes por cuenta. Incluye % de metodo completado.

Tipos de ejecucion

type ExecutionStatus = "pending" | "running" | "completed" | "failed";

interface ActionExecution {
  id: string;
  account_id: string;
  action_id: string;
  status: ExecutionStatus;
  output?: string;          // Resultado de la ejecucion
  error?: string;           // Mensaje de error si fallo
  execution_time_ms?: number;
  tokens_used?: number;
  metadata?: Record;
  started_at: string;
  completed_at?: string;
  created_at: string;
}

interface ActionWithExecutionStatus extends ActionWithStatus {
  last_execution?: ActionExecution;  // Ultima ejecucion
  execution_count: number;           // Total de ejecuciones
  has_completed: boolean;            // Si se completo al menos una vez
}

Contexto de cuenta con ejecuciones

// El contexto de cuenta ahora incluye:
const {
  stagesWithExecutions,    // Etapas con estado de ejecucion
  executionHistory,        // Historial completo
  completionPercentage,    // % de agentes activos completados
  executeAction,           // Funcion para ejecutar un agente
  refreshExecutions,       // Refrescar datos de ejecucion
} = useLTBAccount();

// Ejecutar un agente
const result = await executeAction(action, userInput);
if (result.success) {
  console.log('Resultado:', result.output);
}

Visualizacion del progreso

  • La vista de proyecto muestra barra de % Metodo Completado
  • Los agentes completados muestran un icono de check verde
  • El badge muestra numero de ejecuciones por agente
  • El modal de detalle tiene pestanas para ver informacion y resultados
8. Referencia de propiedades de componentes
Todas las propiedades e interfaces disponibles en los componentes exportados.

StagesTimelineProps

interface StagesTimelineProps {
  // Datos - usar stages+actions O stagesWithActions
  stages?: Stage[];
  actions?: Action[];
  stagesWithActions?: StageWithActions[];

  // Estados
  isLoading?: boolean;

  // Permisos
  canManageStages?: boolean;   // derived from canManage
  canManageActions?: boolean;  // derived from canManage
  canToggleActions?: boolean;
  showActionToggle?: boolean;
  showExecutionStatus?: boolean;  // Mostrar estado de ejecucion

  // Callbacks
  onAddStage?: () => void;
  onEditStage?: (stage: Stage) => void;
  onDeleteStage?: (stage: Stage) => void;
  onAddAction?: (stageId: string) => void;
  onEditAction?: (action: Action | ActionWithStatus) => void;
  onActionClick?: (action: Action | ActionWithStatus) => void;
  onToggleAction?: (actionId: string, isActive: boolean) => void;
  onReorderStages?: (orderedIds: string[]) => void;
  onReorderActions?: (stageId: string, orderedIds: string[]) => void;

  className?: string;
}

ActionItemProps

interface ActionItemProps {
  action: ActionWithStatus | Action | ActionWithExecutionStatus;
  isActive?: boolean;
  showToggle?: boolean;
  canToggle?: boolean;
  canClick?: boolean;
  showExecutionStatus?: boolean;  // Mostrar check y contador
  onToggle?: (actionId: string, isActive: boolean) => void;
  onClick?: (action: Action) => void;
  className?: string;
}

ActionDetailModalProps

interface ActionDetailModalProps {
  action: Action | ActionWithStatus | ActionWithExecutionStatus | null;
  isOpen: boolean;
  onClose: () => void;
  onExecute?: (userInput?: string) => void;
  canExecute?: boolean;
  isExecuting?: boolean;
  executionResult?: string;
}

Provider Props

interface LTBMethodProviderProps {
  children: React.ReactNode;
  permissions?: Partial;
  apiAdapter?: LTBApiAdapter;
}

interface LTBAccountProviderProps {
  children: React.ReactNode;
  accountId: string;
  permissions?: Partial;
  apiAdapter?: LTBApiAdapter;
}