Volver a la wiki

Componente TaskZohoLinks — sección vínculos Zoho del TaskModal

Componente TaskZohoLinks

Ruta: src/components/tasks/TaskZohoLinks.tsx App: tasks (frontend React/TypeScript) Introducido: s68 / commit 18f32fb (2026-05-17) ADR referenciado: decision--20260517--integracion-zoho-calendar-mail-pivot (ver comentario de cabecera del fichero)

Propósito

Encapsula la sección “Vínculos Zoho” del TaskModal. Gestiona dos subsecciones:

  1. Eventos Calendar — crear un evento en Zoho Calendar y vincularlo a la tarea.
  2. Emails Mail — buscar y vincular mensajes de Zoho Mail a la tarea.

Soporta dos modos de operación:

Prop taskIdModoComportamiento
numbereditPOST/DELETE inmediato al backend al añadir o quitar vínculos
nullcreateEstado local (pending*); el padre ejecuta los POSTs tras crear la task

Interface de props

interface Props {
  taskId: number | null;           // null = create mode
  taskTitle: string;
  taskDescription: string;
  selectedAssignees: string[];
  isLocal: boolean;
  onCountChange?: (taskId: number, kind: 'calendar' | 'email', newCount: number) => void;

  // Solo relevantes en create mode (ignoradas en edit):
  pendingEvent?: PendingCalendarEvent | null;
  onPendingEventChange?: (event: PendingCalendarEvent | null) => void;
  pendingEmailLinks?: PendingEmailLink[];
  onPendingEmailLinksChange?: (links: PendingEmailLink[]) => void;
}

Tipos exportados

// Datos de evento pre-creación. Enviados al padre via onPendingEventChange.
export interface PendingCalendarEvent {
  title: string;
  description?: string;
  start: string;       // ISO UTC
  end: string;         // ISO UTC
  location?: string;
  attendees: string[];
}

// Email seleccionado pre-creación. Enviado al padre via onPendingEmailLinksChange.
export interface PendingEmailLink {
  zoho_message_id: string;
  thread_id?: string;
  subject: string;
  from_address: string;
  email_date: string;
  url: string;
}

Estado interno relevante

StateTipoDescripción
calendarLinksCalendarLink[]Eventos vinculados (cargados del backend en edit mode)
emailLinksEmailLink[]Emails vinculados (cargados del backend en edit mode)
statusMembersZohoStatusMember[]Miembros con zoho_email para resolver attendees
showCreateEventbooleanControla visibilidad del mini-form de evento
showLinkEmailbooleanControla visibilidad del picker de emails
loadingbooleanInicializado a false si isCreate, true en edit

lastFetchedTaskIdRef (useRef) previene refetch del backend cuando taskId no cambia entre re-renders.

Acciones del usuario

+ Crear evento (ambos modos)

  1. Usuario abre mini-form (showCreateEvent = true), rellena título, inicio, fin, ubicación.
  2. handleCreateEvent():
    • create: llama onPendingEventChange(payload) y cierra el form. Constraint: solo 1 pending a la vez.
    • edit: POST /api/zoho/calendar → POST /api/tasks/{id}/links/calendar → actualiza calendarLinks.

+ Vincular email (ambos modos)

  1. Usuario abre picker, busca por q / from / subject → GET /api/zoho/mail/search.
  2. handlePickEmail(msg):
    • create: añade a pendingEmailLinks (deduplicado por messageId).
    • edit: POST /api/tasks/{id}/links/email → actualiza emailLinks.

+ Nuevo email (solo edit)

Deep-link a Zoho Mail compose con subject y body pre-rellenados. Deshabilitado en create mode (necesita taskId para contexto útil en la URL de compose).

Quitar pending (solo create mode)

Desvincular (solo edit mode)

Comportamiento visual create mode

Carga de datos por modo

edit mode:
  useEffect #1 → Promise.all([
    GET /api/tasks/{id}/links/calendar,
    GET /api/tasks/{id}/links/email,
    GET /api/zoho/status
  ])

create mode:
  useEffect #1 → skip (isCreate)
  useEffect #2 → GET /api/zoho/status  (solo para resolver attendees)

Funciones utilitarias internas

FunciónDescripción
nextHourLocal()Devuelve string para <input type="datetime-local"> con la próxima hora redondeada
plusOneHour(localIso)Suma 1h a un datetime-local string
localToISO(local)Convierte datetime-local a ISO UTC (new Date(local).toISOString())
formatDateShort(iso)Formatea ISO → DD/MM HH:MM
resolveAttendees(assignees, members)Mapea assignees a emails Zoho filtrando pending/unknown

Endpoints consumidos

MétodoRutaModo
GET/api/tasks/{id}/links/calendaredit
GET/api/tasks/{id}/links/emailedit
GET/api/zoho/statusambos
GET/api/zoho/mail/searchambos
POST/api/zoho/calendaredit (en create lo hace el padre)
POST/api/tasks/{id}/links/calendaredit (en create lo hace el padre)
POST/api/tasks/{id}/links/emailedit (en create lo hace el padre)
DELETE/api/tasks/{id}/links/calendar?uid=...edit
DELETE/api/tasks/{id}/links/email?message_id=...edit

Historial de versiones relevante

FechaCambio
2026-05-17Soporte taskId: null (create mode), tipos PendingCalendarEvent + PendingEmailLink exportados, patrón pending, resolveAttendees extraído, lastFetchedTaskIdRef, carga separada de statusMembers en create mode

Véase también

Subir