import * as _libxai_core from '@libxai/core'; import { Dependency, BaseViewAdapter, ViewBoardData, ExportFormat as ExportFormat$1, ViewOptions, BoardData, ColumnData, CardData, BoardState, BoardStore, Board as Board$1, Column as Column$2, Card as Card$2, Priority as Priority$1, CardStatus as CardStatus$1, DragState, SelectionState } from '@libxai/core'; export { AutoScheduleOptions, BaseEntity, Baseline, BaselineCardSnapshot, BoardData, Board as BoardModel, BoardState, BoardStore, CardData, Card as CardModel, ColumnData, Column as ColumnModel, CriticalPath, Dependency, DependencyEngine, DependencyType, DependencyValidation, GanttConfig as GanttCoreConfig, GanttState, Milestone, ResourceAllocation, ResourceUtilization, ScheduledTask, Store, StoreEvent, TaskConstraint, TaskConstraintType, UserData } from '@libxai/core'; import * as React$1 from 'react'; import React__default, { ReactNode, Component, ErrorInfo } from 'react'; import * as react_jsx_runtime from 'react/jsx-runtime'; import { ClassValue } from 'clsx'; import * as _tanstack_virtual_core from '@tanstack/virtual-core'; interface TaskSegment { startDate: Date; endDate: Date; } /** * v0.17.158: Tag/Label for tasks (ClickUp-style) * Tags are workspace-scoped and can be applied to multiple tasks */ interface TaskTag { id: string; name: string; color: string; } interface Task { id: string; name: string; startDate?: Date; endDate?: Date; progress: number; assignees?: Array<{ name: string; avatar?: string; initials: string; color: string; }>; status?: string; dependencies?: string[]; subtasks?: Task[]; isExpanded?: boolean; isMilestone?: boolean; isCriticalPath?: boolean; cpmData?: { earlyStart: number; earlyFinish: number; lateStart: number; lateFinish: number; totalFloat: number; freeFloat: number; isCritical: boolean; }; color?: string; priority?: 'low' | 'medium' | 'high' | 'urgent'; tags?: TaskTag[]; segments?: TaskSegment[]; parentId?: string; level?: number; position?: number; wbsCode?: string; taskCode?: string; scheduleVariance?: number; blockers?: Array<{ type: string; id: string; severity: 'critical' | 'warning' | 'info'; }>; teamLoad?: { percentage: number; label: string; }; effortMinutes?: number; timeLoggedMinutes?: number; soldEffortMinutes?: number; baselineStartDate?: Date; baselineEndDate?: Date; baselineProgress?: number; isHighlighted?: boolean; lastActivity?: { userName: string; summary: string; relativeTime: string; }; } type TimeScale = 'day' | 'week' | 'month'; type Theme$1 = 'dark' | 'light' | 'neutral'; type RowDensity = 'compact' | 'comfortable' | 'spacious'; type DependencyLineStyle = 'curved' | 'squared'; type TaskFilterType = 'all' | 'incomplete' | 'in_progress' | 'completed'; type ColumnType$1 = 'name' | 'startDate' | 'endDate' | 'duration' | 'assignees' | 'status' | 'progress' | 'priority'; interface GanttColumn { id: ColumnType$1; label: string; width: number; minWidth?: number; maxWidth?: number; visible: boolean; sortable?: boolean; resizable?: boolean; } interface Assignee { /** User ID — optional to preserve backward compatibility with older consumers */ id?: string; name: string; initials: string; color: string; /** Per-user estimated effort for the parent task, in minutes. * Set by the SaaS App when a task has multi-user effort distribution. * When present, cost calculations decompose as Σ(userMinutes × userRate). */ estimatedMinutes?: number; } interface GanttTheme { bgPrimary: string; bgSecondary: string; bgGrid: string; bgWeekend: string; border: string; borderLight: string; textPrimary: string; textSecondary: string; textTertiary: string; accent: string; accentHover: string; accentLight: string; taskBarPrimary: string; taskBarProgress: string; taskBarHandle: string; dependency: string; dependencyHover: string; criticalPath: string; criticalPathLight: string; today: string; todayLight: string; milestone: string; milestoneLight: string; statusTodo: string; statusInProgress: string; statusCompleted: string; hoverBg: string; focusRing: string; dotGrid?: string; glassHeader?: string; glassToolbar?: string; forecastHud?: string; neonRedGlow?: string; executionBarBg?: string; } /** * Templates for customizing Gantt rendering * Similar to DHTMLX gantt.templates.* */ interface GanttTemplates { /** * Customize task tooltip content * @param task - The task to render tooltip for * @returns Tooltip content (string or JSX) */ taskTooltip?: (task: Task) => string | React.ReactNode; /** * Customize task label in timeline * @param task - The task to render label for * @returns Label content (string or JSX) */ taskLabel?: (task: Task) => string | React.ReactNode; /** * Customize grid cell content * @param task - The task for this row * @param column - The column type * @param value - Default cell value * @returns Cell content (string or JSX) */ gridCell?: (task: Task, column: ColumnType$1, value: any) => string | React.ReactNode; /** * Add custom CSS classes to task bar * @param task - The task to style * @returns Space-separated CSS class names */ taskClass?: (task: Task) => string; /** * Customize milestone rendering * @param task - The milestone task * @returns Milestone content (string or JSX) */ milestoneContent?: (task: Task) => string | React.ReactNode; /** * Format date display * @param date - Date to format * @returns Formatted date string */ dateFormat?: (date: Date) => string; /** * Format duration display * @param days - Duration in days * @returns Formatted duration string */ durationFormat?: (days: number) => string; /** * Format progress display * @param progress - Progress percentage (0-100) * @returns Formatted progress string */ progressFormat?: (progress: number) => string; } /** * Permissions interface for controlling Gantt operations * Useful for integrating with authorization libraries like CASL * @example * * // With CASL integration * const ability = useAbility(); * * * */ interface GanttPermissions { canCreateTask?: boolean; /** v1.4.10: When true, user can only create subtasks (not root-level tasks) */ canCreateSubtaskOnly?: boolean; canUpdateTask?: boolean; canDeleteTask?: boolean; canCreateDependency?: boolean; canDeleteDependency?: boolean; canUpdateProgress?: boolean; canAssignUsers?: boolean; canModifyHierarchy?: boolean; canDuplicateTask?: boolean; canReorderTasks?: boolean; canExport?: boolean; canToggleExpansion?: boolean; canPerformAction?: (task: Task, action: 'create' | 'update' | 'delete' | 'assign' | 'progress') => boolean; /** v4.1.0: Per-task edit check — when provided, each task bar uses this to determine read-only state */ canEditTask?: (task: Task) => boolean; } /** * Scroll behavior configuration for timeline interactions * Controls how the Gantt chart viewport behaves during user interactions * * @example * // Disable all automatic scrolling during drag operations * * * @example * // Allow vertical auto-scroll but prevent horizontal * { * console.log(`Prevented ${axis} scroll by ${scrollDelta}px`); * } * } * }} * /> */ interface GanttScrollBehavior { /** * Prevent automatic viewport scrolling during drag operations * When true, the viewport will not automatically center on dragged tasks * Users can still manually scroll using scrollbars or mouse wheel * @default false */ preventAutoScroll?: boolean; /** * Which axis to prevent auto-scroll on * - 'horizontal': Only prevent horizontal auto-scroll (recommended for Gantt charts) * - 'vertical': Only prevent vertical auto-scroll * - 'both': Prevent both horizontal and vertical auto-scroll * @default 'horizontal' */ axis?: 'horizontal' | 'vertical' | 'both'; /** * Callback fired when auto-scroll is prevented * Useful for debugging or showing user feedback * @param axis - Which axis was prevented ('x' or 'y') * @param scrollDelta - How many pixels of scroll were prevented */ onScrollPrevented?: (axis: 'x' | 'y', scrollDelta: number) => void; /** * Allow auto-scroll if task would go out of viewport bounds * When true, auto-scroll is only prevented if task remains visible * @default false */ allowScrollWhenOutOfBounds?: boolean; } /** * AI chat message interface * @version 0.17.42 */ interface AIMessage { id: string; role: 'user' | 'assistant'; content: string; timestamp: Date; command?: AICommandResult; isLoading?: boolean; } /** * Configuration for persisting AI chat history in localStorage * @version 0.17.42 */ interface PersistHistoryConfig { /** Enable history persistence in localStorage */ enabled: boolean; /** Maximum messages to persist (default: 5) */ maxMessages?: number; /** Custom storage key (default: 'gantt-ai-history') */ storageKey?: string; } /** * AI Assistant configuration for natural language task editing * @version 0.14.0 * @updated 0.17.42 - Added persistHistory option */ interface GanttAIAssistantConfig { /** Enable AI assistant (default: false) */ enabled?: boolean; /** Custom placeholder text */ placeholder?: string; /** Position of the chat button */ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'; /** Handler for AI commands - should return task updates. * `history` is the recent conversation (oldest→newest, excluding the current * command) so the assistant can resolve follow-ups like "ahora movelas un * día más" / "deshacé eso". */ onCommand?: (command: string, tasks: Task[], history?: Array<{ role: 'user' | 'assistant'; content: string; }>) => Promise; /** Custom suggestions for the command palette */ suggestions?: string[]; /** Maximum messages to keep in memory history */ maxHistory?: number; /** Persist chat history in localStorage @version 0.17.42 */ persistHistory?: PersistHistoryConfig; /** Mentionable users for @mention autocomplete in the chat input */ mentionableUsers?: Array<{ id: string; name: string; email?: string; avatar?: string; }>; } /** * AI Command result interface * @version 0.14.0 */ interface AICommandResult { type: 'move_task' | 'resize_task' | 'rename_task' | 'delete_task' | 'create_task' | 'link_tasks' | 'unlink_tasks' | 'assign_task' | 'set_progress' | 'set_status' | 'split_task' | 'group_tasks' | 'unknown'; taskId?: string; taskName?: string; updates?: Partial; newTask?: Task; dependencyFrom?: string; dependencyTo?: string; message: string; success: boolean; error?: string; } /** * v3.1.0: Project forecast metrics for the Forecast HUD panel * Computed by the consumer app and passed through GanttConfig */ interface ProjectForecast { expectedFinish?: Date | null; /** * REQ-02 §5.3.C · el fin SEGUN LA LINEA BASE, para la franja «Plan contra * realidad»: «fin segun la linea base y fin vigente; desvio en dias». * * `null` cuando el proyecto no tiene linea base. No es cero: sin base no hay * con que comparar. */ finSegunPlan?: Date | null; delayDays?: number | null; confidencePercent?: number | null; costAtCompletion?: number | null; budgetVariancePercent?: number | null; currency?: string; /** * REQ-05 §8.4 · la frase que explica el desvio, ya redactada. * * «Un desvio sin explicacion es un numero que genera una pregunta y obliga a * abrir el cronograma». La libreria NO la calcula: la recibe hecha, porque * la regla —ruta critica primero, luego mayor desvio— depende de datos del * consumidor y §8.3 pide la misma frase en dos pantallas. */ causaDelDesvio?: string | null; } /** * v4.3.0 — Workspace working-day configuration consumed by the tooltip * Duration field (and any other piece that needs to count business days). * Lets the consumer mirror its weekend toggles + holiday calendar. */ interface GanttWorkingDaysConfig { /** Which weekdays count as working days. 0=Sun, 1=Mon, ..., 6=Sat. Length 7. */ enabledWeekdays?: boolean[]; /** Holiday dates in 'YYYY-MM-DD' (workspace-local) to exclude. */ holidayDates?: Set | string[]; } interface GanttConfig { theme?: Theme$1; timeScale?: TimeScale; rowDensity?: RowDensity; /** v4.3.0: Defines which days count as working days for duration calculations. */ workingDaysConfig?: GanttWorkingDaysConfig; showThemeSelector?: boolean; showExportButton?: boolean; /** * Override the default Excel export with a consumer-supplied handler. * When set, clicking "Export to Excel" in the share/export dropdown * runs this function instead of the library's built-in ganttUtils * exporter. The handler is responsible for the entire export (including * triggering the file download). Useful for plugging in a custom * template or branded format. `onExportSuccess` still fires after a * successful run. */ onExportExcel?: () => Promise; /** * Fires whenever the TODAY marker enters or leaves the visible * timeline viewport (after horizontal scroll, zoom, timeScale change, * or initial mount). Lets consumer apps render a floating "go to * today" affordance that only shows up when relevant. */ onTodayVisibilityChange?: (visible: boolean) => void; /** * v2.8.0: Fired AFTER a successful export so the consuming app can record * the event in its audit log / analytics. Receives the report type that * was just produced. */ onExportSuccess?: (reportType: 'pdf' | 'excel' | 'png' | 'csv' | 'json' | 'msproject') => void; projectName?: string; availableUsers?: Array<{ id: string; name: string; initials: string; color: string; }>; /** * v0.15.0: Internationalization (i18n) support * Set the locale for all UI text in the Gantt chart * Built-in support for 'en' (English) and 'es' (Spanish) * @default 'en' */ locale?: 'en' | 'es' | string; /** * v0.15.0: Custom translations to override default locale strings * Allows partial overrides while keeping defaults for missing keys * @see GanttTranslations in i18n.ts */ customTranslations?: Record; aiAssistant?: GanttAIAssistantConfig; showCreateTaskButton?: boolean; createTaskLabel?: string; onCreateTask?: () => void; taskFilter?: TaskFilterType; onTaskFilterChange?: (filter: TaskFilterType) => void; /** Render custom content on the right side of toolbar (e.g. lens toggle) */ toolbarRightContent?: ReactNode; /** * 1.9.34 · Pinta la barra de herramientas DENTRO de este elemento (por * portal) y en versión compacta: escala, filtro, contenido propio, vista y * compartir; el modo de vista y el nivel WBS van a «⋯». Para cabeceras de * una sola fila. Sin él, la barra de siempre. */ toolbarContainer?: HTMLElement | null; /** 1.9.35 · oculta el selector de nivel WBS (All / L1 / L2…) de la barra. */ hideWbsLevel?: boolean; /** 1.9.36 · cabecera de la escala W: 'number' («Week 36», por defecto) o 'range' («Sep 1–7»). */ weekHeaderFormat?: 'number' | 'range'; /** * 1.9.36 · columnas visibles por defecto (además de «name»). Solo cambia el * punto de partida: lo que el usuario guardó con persistColumns manda. */ defaultVisibleColumns?: ColumnType$1[]; /** 1.9.43 · texto del buscador de la app: oculta (sin tocar datos) las tareas que no coinciden por nombre. */ searchQuery?: string; /** 1.9.45 · pinta una fila «+ Add task» al final de la rejilla; la app decide qué hace al pulsarla. */ addTaskRow?: { label: string; onClick: () => void; }; templates?: GanttTemplates; permissions?: GanttPermissions; disableScrollSync?: boolean; /** * v0.9.2: Advanced scroll behavior configuration * Controls how the timeline viewport behaves during drag operations * Provides fine-grained control over auto-scroll prevention with events * @see GanttScrollBehavior */ scrollBehavior?: GanttScrollBehavior; /** * v0.11.1: Enable automatic Critical Path Method (CPM) calculation * When true (default), tasks with zero slack are automatically marked as critical (red) * When false, preserves custom task colors and disables automatic CPM marking * @default true */ enableAutoCriticalPath?: boolean; /** * v0.17.181: Persist task expanded/collapsed state in localStorage * When true, uses default key 'gantt-expanded-tasks' * When string, uses that string as the localStorage key (useful for per-project persistence) * When false/undefined, expanded state only persists during the current session * @default false */ persistExpandedState?: boolean | string; /** * v0.18.0: Persist filter state to localStorage * When true, uses default key 'gantt-filter-state' * When string, uses the provided string as the localStorage key * When false/undefined, filter state only persists during the current session * @default false */ persistFilter?: boolean | string; /** * Persist the visible-columns config (which data columns are shown + their * widths) to localStorage, so it survives navigating away from the Gantt. * When true, uses default key 'gantt-columns-state'. * When string, uses the provided string as the localStorage key (use a * per-project key like `gantt-columns:${projectId}`). * When false/undefined, columns only persist during the current session. * @default false */ persistColumns?: boolean | string; /** * v1.4.10: Clear filters key - when this value changes, internal filters are reset * Useful for navigation scenarios where filters should be cleared (e.g., from notifications) * Pass a timestamp or counter that changes when you want to reset filters */ clearFiltersKey?: string | number; /** * v0.17.310: Dependency line style * Controls how dependency arrows are rendered between tasks * - 'curved': Smooth bezier curves (default) * - 'squared': Right-angle orthogonal lines * @default 'curved' */ dependencyLineStyle?: DependencyLineStyle; /** * v0.18.0: Show weekends in timeline * When true, Saturday and Sunday are displayed in the timeline * When false, weekends are hidden from the timeline view * @default true */ showWeekends?: boolean; /** * v0.18.0: Auto-expand subtasks on load * When true, all tasks with subtasks are expanded by default * When false, tasks start collapsed (default behavior) * @default false */ autoExpandSubtasks?: boolean; /** * Show task name labels inside task bars * @default true */ showTaskBarLabels?: boolean; /** * Show/hide critical path highlighting (red border + glow on critical tasks) * @default true */ showCriticalPath?: boolean; onShowCriticalPathChange?: (show: boolean) => void; /** * Show/hide dependency connector arrows between tasks * @default true */ showDependencies?: boolean; onShowDependenciesChange?: (show: boolean) => void; /** * Highlight weekend columns with shading/hatch pattern * @default true */ highlightWeekends?: boolean; onHighlightWeekendsChange?: (show: boolean) => void; /** * v3.0.0: Show baseline ghost bars behind actual bars (Oracle view) * When true, tasks with baselineStartDate/baselineEndDate show a dashed outline behind the actual bar * @default false */ showBaseline?: boolean; /** * v3.0.0: Gantt view mode — Execution (actual) vs Oracle (baseline comparison) * Controls the Execution/Oracle toggle in the Chronos toolbar * @default 'execution' */ viewMode?: 'execution' | 'oracle'; onViewModeChange?: (mode: 'execution' | 'oracle') => void; /** * v3.1.0: Project forecast data for the Forecast HUD panel in Chronos toolbar * When provided, replaces hardcoded placeholder values with real metrics */ projectForecast?: ProjectForecast; /** * Oculta la barra interna del pronóstico (Forecast HUD) aunque se pase * projectForecast. Útil cuando el consumidor muestra el pronóstico en su propia * barra (p. ej. una barra de áreas del proyecto) y no quiere duplicarlo. */ hideForecastHud?: boolean; /** * Callback for "Copy Snapshot Link" in the Share dropdown * When provided, shows the option in the export/share menu */ onCopySnapshotLink?: () => void; onThemeChange?: (theme: Theme$1) => void; onTimeScaleChange?: (timeScale: TimeScale) => void; onZoomChange?: (zoom: number) => void; onDateRangeChange?: (startDate: Date, endDate: Date) => void; onTaskClick?: (task: Task) => void; /** * ═══ LA SELECCION SALE DEL GANTT ══════════════════════════════════════════ * * Divar, 27-ago, con dos capturas: el resaltado del Gantt marcaba una tarea y * el panel lateral del SaaS enseñaba otra, dos filas mas abajo. * * La causa eran DOS NAVEGACIONES corriendo a la vez. El Gantt ya movia su * resaltado con las flechas —`useGanttKeyboard`— pero esa seleccion se * quedaba dentro: `useGanttSelection` no recibe ningun callback, asi que * nadie fuera de la libreria podia enterarse. El SaaS, sin forma de seguirla, * habia montado su propio recorrido en paralelo; cada uno con su lista, y de * ahi el desfase. * * Con esto la seleccion tiene UNA sola fuente —la del Gantt, que es la que el * usuario ve— y quien la consuma se limita a seguirla. * * Se emite tanto al pulsar como al navegar con el teclado: son la misma * accion desde el punto de vista de quien mira la pantalla. */ onTaskSelectionChange?: (taskId: string | null) => void; /** * ═══ MOVER EL RESALTADO DESDE FUERA ═══════════════════════════════════════ * * Divar, 27-ago: «al seleccionar el nombre de la subtarea, el selector en * gantt tambien se reubique». * * El companero de `onTaskSelectionChange`: aquel SACA la seleccion, este la * METE. Sin los dos, abrir una tarea desde fuera —una subtarea, el * breadcrumb, una notificacion— dejaba el resaltado en una fila y el panel * en otra. * * NO es una prop controlada del todo: el Gantt conserva su estado y sigue * seleccionando solo con clic y flechas. Esto solo lo empuja a una fila * cuando cambia. */ selectedTaskId?: string | null; onTaskDblClick?: (task: Task) => void; onTaskContextMenu?: (task: Task, event: React.MouseEvent) => void; onTaskUpdate?: (task: Task) => void; /** v2.2.0: Called after drag with all dependent tasks that were rescheduled by cascade */ onDependentTasksScheduled?: (tasks: Task[]) => void; onTaskDateChange?: (task: Task, startDate: Date, endDate: Date) => void; onProgressChange?: (taskId: string, oldProgress: number, newProgress: number) => void; /** * Called when user clicks "Edit Task" in context menu * If not provided, the built-in TaskFormModal will be used */ onTaskEdit?: (task: Task) => void; /** * Called when user clicks "Add Subtask" in context menu * If not provided, the built-in subtask creation will be used */ onTaskAddSubtask?: (parentTask: Task) => void; /** * Called when user clicks "Mark Incomplete" in context menu * Sets task status to 'todo' and progress to 0 */ onTaskMarkIncomplete?: (task: Task) => void; /** * Called when user clicks "Set In Progress" in context menu * Sets task status to 'in-progress' */ onTaskSetInProgress?: (task: Task) => void; onDependencyCreate?: (fromTaskId: string, toTaskId: string) => void; onDependencyDelete?: (taskId: string, dependencyId: string) => void; onBeforeTaskAdd?: (task: Task) => boolean | void | Promise; onAfterTaskAdd?: (task: Task) => void; onBeforeTaskUpdate?: (taskId: string, newData: Partial) => boolean | void | Promise; onAfterTaskUpdate?: (task: Task) => void; onBeforeTaskDelete?: (taskId: string) => boolean | void | Promise; onAfterTaskDelete?: (taskId: string) => void; onTaskCreate?: (parentId: string | undefined, position: number) => void; onTaskDelete?: (taskId: string) => void; onMultiTaskDelete?: (taskIds: string[]) => void; onTaskDuplicate?: (task: Task) => void; onTaskMove?: (taskId: string, direction: 'up' | 'down') => void; onTaskIndent?: (taskId: string) => void; onTaskOutdent?: (taskId: string) => void; onTaskRename?: (taskId: string, newName: string) => void; onTaskToggleExpand?: (taskId: string) => void; onTaskReparent?: (taskId: string, newParentId: string | null, position?: number) => void; /** Drag-fill: a value (assignees / startDate / endDate) was applied to many * tasks at once. `updatedTasks` is the full task tree after the change, so * the consumer can persist the affected tasks directly. */ onBulkFill?: (taskIds: string[], column: 'assignees' | 'startDate' | 'endDate', value: any, updatedTasks: Task[]) => void; /** v2.5.0: Per-user hourly rate map for Excel export cost columns (userId → rate) */ rateMap?: Record; /** v2.5.0: Default hourly rate fallback when rateMap has no match for a user */ defaultRate?: number; } /** * Card Stack Types * Smart grouping of related cards within columns * @module types/card-stack */ type StackingStrategy = 'manual' | 'ai-similarity' | 'labels' | 'assignee' | 'priority' | 'epic'; interface CardStack$1 { /** Unique stack identifier */ id: string; /** Display title for the stack */ title: string; /** Cards contained in this stack */ cardIds: string[]; /** Column this stack belongs to */ columnId: string; /** How this stack was created */ strategy: StackingStrategy; /** Visual color for the stack */ color?: string; /** Whether stack is expanded or collapsed */ isExpanded: boolean; /** Position within the column */ position: number; /** Timestamp when stack was created */ createdAt: Date; /** AI confidence score (0-1) for auto-stacked groups */ confidence?: number; } interface StackingConfig { /** Enable automatic AI-powered stacking */ enableAutoStacking: boolean; /** Minimum confidence threshold for auto-stacking (0-1) */ autoStackConfidenceThreshold: number; /** Minimum cards required to form a stack */ minCardsPerStack: number; /** Enable manual drag-to-stack */ enableManualStacking: boolean; /** Show stack summaries (card count, assignees, etc.) */ showStackSummaries: boolean; /** Animation duration in ms */ animationDuration: number; } interface StackSuggestion { /** Suggested stack configuration */ stack: Omit; /** Reason for suggestion */ reason: string; /** Confidence score (0-1) */ confidence: number; } /** * Core types for ASAKAA Kanban Board * @module types */ /** * Priority levels for cards */ type Priority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT'; /** * Subtask entity * Represents a checklist item within a card */ interface Subtask { /** Unique identifier */ id: string; /** Subtask title */ title: string; /** Completion status */ completed: boolean; /** Position within the subtask list */ position?: number; /** Assigned user ID (optional) */ assigneeId?: string; /** Due date (optional) */ dueDate?: Date | string; /** Created timestamp */ createdAt?: Date | string; /** Updated timestamp */ updatedAt?: Date | string; } /** * Card status types */ type CardStatus = 'TODO' | 'IN_PROGRESS' | 'REVIEW' | 'DONE' | 'BLOCKED'; /** * File attachment on a card * v0.17.182: Moved before Card interface to allow usage in Card.attachments */ interface Attachment { /** Unique identifier */ id: string; /** Card ID */ cardId: string; /** File name */ name: string; /** File size in bytes */ size: number; /** MIME type */ type: string; /** File URL or data URI */ url: string; /** Upload timestamp */ uploadedAt: Date | string; /** User who uploaded */ uploadedBy: string; /** Thumbnail URL (for images) */ thumbnailUrl?: string; } /** * Card entity * Represents a single task/item in the Kanban board */ interface Card$1 { /** Unique identifier */ id: string; /** Card title (required) */ title: string; /** Card description (optional) */ description?: string; /** Lexicographic position within column (for ordering) */ position: number; /** Parent column ID */ columnId: string; /** Priority level */ priority?: Priority; /** Assigned user ID (legacy - use assignedUserIds) */ assigneeId?: string; /** Assigned user IDs (multiple users) */ assignedUserIds?: string[]; /** Tags/labels */ labels?: string[]; /** Due date (legacy - use startDate/endDate) */ dueDate?: Date | string; /** Date range - start date */ startDate?: Date | string; /** Date range - end date */ endDate?: Date | string; /** Task dependencies - supports both legacy format (string[]) and new format (Dependency[]) */ dependencies?: string[] | Dependency[]; /** Estimated time (in hours) - legacy field */ estimatedTime?: number; /** v1.1.0: Estimated effort in minutes (for time tracking) */ effortMinutes?: number | null; /** v1.1.0: Total logged time in minutes (aggregated) */ timeLoggedMinutes?: number; /** v1.2.0: Sold/quoted effort in minutes (client facing - "Tiempo ofertado") */ soldEffortMinutes?: number | null; /** Manual progress override (0-100%) */ progress?: number; /** Cover image URL */ coverImage?: string; /** Subtasks/checklist items */ subtasks?: Subtask[]; /** v0.17.29: Custom color for visual identification (hex color) */ color?: string; /** v0.17.158: Tags with colors (ClickUp-style) */ tags?: TaskTag[]; /** v0.17.182: Attachments for displaying thumbnails in card */ attachments?: Attachment[]; /** Custom metadata */ metadata?: Record; createdAt?: Date | string; updatedAt?: Date | string; } /** * Column entity * Represents a stage/status in the workflow */ interface Column$1 { /** Unique identifier */ id: string; /** Column title */ title: string; /** Lexicographic position (for ordering columns) */ position: number; /** Array of card IDs in this column */ cardIds: string[]; /** Work-in-progress limit */ wipLimit?: number; /** WIP limit enforcement type: 'soft' = warning, 'hard' = block */ wipLimitType?: 'soft' | 'hard'; /** Color for visual distinction */ color?: string; /** Custom metadata */ metadata?: Record; createdAt?: Date | string; updatedAt?: Date | string; } /** * Board entity * Top-level container for the Kanban board */ interface Board { /** Unique identifier */ id: string; /** Board title */ title?: string; /** Array of columns */ columns: Column$1[]; /** Array of all cards */ cards: Card$1[]; metadata?: Record; } /** * Callbacks for board operations * These allow the library consumer to persist changes */ interface BoardCallbacks { /** Called when a card is moved to a different position/column */ onCardMove?: (cardId: string, targetColumnId: string, position: number) => void | Promise; /** Called when card properties are updated */ onCardUpdate?: (cardId: string, updates: Partial) => void | Promise; /** Called when a new card is created */ onCardCreate?: (card: Omit) => void | Promise; /** Called when a card is deleted */ onCardDelete?: (cardId: string) => void | Promise; /** Called when a new column is created */ onColumnCreate?: (column: Omit) => void | Promise; /** Called when column properties are updated */ onColumnUpdate?: (columnId: string, updates: Partial) => void | Promise; /** Called when a column is deleted */ onColumnDelete?: (columnId: string) => void | Promise; /** Called when columns are reordered */ onColumnReorder?: (columnId: string, newPosition: number) => void | Promise; /** Called when WIP limit is exceeded (hard limit only) */ onWipLimitExceeded?: (column: Column$1, card: Card$1) => void; } /** * Insight types generated by AI */ type InsightType = 'RISK_DELAY' | 'RISK_OVERLOAD' | 'RISK_BLOCKER' | 'OPPORTUNITY' | 'SUGGESTION'; /** * Severity levels for insights */ type InsightSeverity = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'; /** * AI-generated insight about the board state */ interface Insight { /** Unique identifier */ id?: string; /** Type of insight */ type: InsightType; /** Severity level */ severity: InsightSeverity; /** Human-readable title */ title: string; /** Detailed description */ description: string; /** AI confidence score (0-1) */ confidence: number; /** Suggested action to take */ suggestedAction?: string; /** Related card IDs */ relatedCardIds?: string[]; /** Related column IDs */ relatedColumnIds?: string[]; /** Timestamp */ timestamp?: Date | string; } /** * Result of AI assignee suggestion */ interface AssigneeSuggestion { /** Suggested user ID */ userId: string; /** Confidence score (0-1) */ confidence: number; /** Reasoning for suggestion */ reasoning: string; } /** * Result of AI plan generation */ interface GeneratedPlan { /** Generated columns */ columns: Omit[]; /** Generated cards */ cards: Omit[]; /** Explanation of the plan */ explanation?: string; } /** * AI callbacks (optional) * Consumer provides these if they want AI features */ interface AICallbacks { /** Generate a complete board plan from a text prompt */ onGeneratePlan?: (prompt: string) => Promise; /** Suggest best assignee for a card */ onSuggestAssignee?: (card: Card$1) => Promise; /** Predict risks and opportunities based on board state */ onPredictRisks?: (boardState: Board) => Promise; /** Generate subtasks for a card */ onGenerateSubtasks?: (card: Card$1) => Promise[]>; /** Estimate effort for a card */ onEstimateEffort?: (card: Card$1) => Promise<{ hours: number; confidence: number; }>; } /** * Configuration options for the Kanban board */ interface BoardConfig { /** Theme: 'dark' | 'light' | 'neutral' */ theme?: 'dark' | 'light' | 'neutral'; /** Locale for i18n */ locale?: 'en' | 'es' | string; /** Enable virtualization (auto-enabled if >100 cards) */ enableVirtualization?: boolean; /** Enable AI features */ enableAI?: boolean; /** Animation duration in milliseconds */ animationDuration?: number; /** Fixed column width in pixels */ columnWidth?: number; /** Estimated card height for virtualization */ cardHeight?: number; /** * 1.9.37 · columnas plegadas: no pintan sus tarjetas pero siguen aceptando * arrastres. La app decide cuáles y pinta su propio aviso (p. ej. en * renderColumnFooter, «27 completed · Show»). */ collapsedColumnIds?: string[]; /** Enable keyboard shortcuts */ enableKeyboardShortcuts?: boolean; /** Show card count in column headers */ showCardCount?: boolean; /** Show WIP limits */ showWipLimits?: boolean; /** Enable column collapsing */ enableCollapsible?: boolean; /** Maximum cards to display per column before showing "show more" */ maxCardsPerColumn?: number; } /** * Render props for customization */ interface RenderProps { /** Custom card renderer */ renderCard?: (card: Card$1) => React.ReactNode; /** Custom column renderer */ renderColumn?: (column: Column$1, cards: Card$1[]) => React.ReactNode; /** Custom card overlay during drag */ renderCardOverlay?: (card: Card$1) => React.ReactNode; /** Custom column header */ renderColumnHeader?: (column: Column$1, cardCount: number) => React.ReactNode; /** Custom empty state */ renderEmptyState?: (column: Column$1) => React.ReactNode; /** v2.2.0: Custom column footer (e.g. AddCardButton) */ renderColumnFooter?: (column: Column$1) => React.ReactNode; } /** * User entity for assignment */ interface User$1 { id: string; name: string; initials: string; color: string; avatar?: string; } /** * Main KanbanBoard component props */ interface KanbanBoardProps { /** Board data (controlled) */ board: Board; /** Callbacks for mutations */ callbacks: BoardCallbacks; /** AI callbacks (optional) */ aiCallbacks?: AICallbacks; /** Card click handler */ onCardClick?: (card: Card$1) => void; /** Render customization */ renderProps?: RenderProps; /** Configuration */ config?: BoardConfig; /** Available users for assignment */ availableUsers?: User$1[]; /** Custom CSS class */ className?: string; /** Custom inline styles */ style?: React.CSSProperties; /** Loading state */ isLoading?: boolean; /** Error state */ error?: Error | string; /** Available tags in workspace for selection */ availableTags?: TaskTag[]; /** Callback to create a new tag */ onCreateTag?: (name: string, color: string) => Promise; /** v0.17.241: Attachments map by card ID (for modal display) */ attachmentsByCard?: Map; /** v0.17.241: Callback when files are dropped/selected for upload */ onUploadAttachments?: (cardId: string, files: File[]) => Promise; /** v0.17.241: Callback to delete an attachment */ onDeleteAttachment?: (attachmentId: string) => Promise; /** v0.17.254: Comments for TaskDetailModal */ comments?: Array<{ id: string; taskId: string; userId: string; content: string; createdAt: Date; updatedAt?: Date; user?: { id: string; name: string; email: string; avatarUrl?: string; }; }>; /** v0.17.254: Callback to add a comment */ onAddComment?: (taskId: string, content: string, mentionedUserIds?: string[]) => Promise; /** v0.17.254: Current user info for comment input */ currentUser?: { id: string; name: string; avatarUrl?: string; color?: string; }; /** v0.17.254: Callback when task is opened in modal (to load comments) */ /** v0.17.401: Users available for @mentions in comments */ mentionableUsers?: Array<{ id: string; name: string; email?: string; avatar?: string; color?: string; }>; onTaskOpen?: (taskId: string) => void; /** v0.18.13: Callback to upload attachments to comments (enables attachment icon in comment input) */ onUploadCommentAttachments?: (files: File[]) => Promise>; /** Enable time tracking features in TaskDetailModal */ enableTimeTracking?: boolean; /** Time tracking summary for the currently open task */ timeTrackingSummary?: TimeTrackingSummary; /** Time entries for the currently open task */ timeEntries?: TimeEntry[]; /** Current timer state */ timerState?: TimerState; /** Callback to log time manually */ onLogTime?: (taskId: string, input: TimeLogInput) => Promise; /** Callback to update task estimate */ onUpdateEstimate?: (taskId: string, minutes: number | null) => Promise; /** Callback to update sold effort (quoted time) */ onUpdateSoldEffort?: (taskId: string, minutes: number | null) => Promise; /** Callback to start timer */ onStartTimer?: (taskId: string) => void; /** Callback to stop timer and save time */ onStopTimer?: (taskId: string) => void; /** Callback to discard timer without saving */ onDiscardTimer?: (taskId: string) => void; /** Blur financial data (tiempo ofertado) for unauthorized users */ blurFinancials?: boolean; /** Side panel rendered alongside the board columns */ sidePanel?: React.ReactNode; /** Custom renderer for column header metrics (below title) */ renderColumnMetrics?: (column: Column$1, cards: Card$1[]) => React.ReactNode; /** v2.1.0: Suppress internal TaskDetailModal (consumer provides own drawer) */ suppressDetailModal?: boolean; } /** * Drag event data */ interface DragData { /** Card being dragged */ card: Card$1; /** Source column ID */ sourceColumnId: string; /** Source position */ sourcePosition: number; } /** * Drop event data */ interface DropData { /** Card being dropped */ card: Card$1; /** Target column ID */ targetColumnId: string; /** Target position */ targetPosition: number; /** Source column ID */ sourceColumnId: string; } /** * Filter criteria for cards */ interface CardFilter { /** Filter by assignee */ assigneeIds?: string[]; /** Filter by priority */ priorities?: Priority[]; /** Filter by labels */ labels?: string[]; /** Search in title/description */ search?: string; /** Filter by date range */ dateRange?: { start: Date | string; end: Date | string; }; } /** * Sort options for cards */ type CardSortKey = 'position' | 'priority' | 'dueDate' | 'createdAt' | 'title'; interface CardSort { key: CardSortKey; direction: 'asc' | 'desc'; } /** * Comment on a card */ interface Comment { /** Unique identifier */ id: string; /** Card ID */ cardId: string; /** Author user ID */ authorId: string; /** Comment content */ content: string; /** Timestamp */ createdAt: Date | string; /** Last update timestamp */ updatedAt?: Date | string; /** Mentions (user IDs) */ mentions?: string[]; } /** * Activity log entry types */ type ActivityType = 'CARD_CREATED' | 'CARD_UPDATED' | 'CARD_MOVED' | 'CARD_DELETED' | 'COMMENT_ADDED' | 'USER_ASSIGNED' | 'USER_UNASSIGNED' | 'PRIORITY_CHANGED' | 'DUE_DATE_CHANGED' | 'LABEL_ADDED' | 'LABEL_REMOVED' | 'DEPENDENCY_ADDED' | 'DEPENDENCY_REMOVED' | 'ATTACHMENT_ADDED' | 'ATTACHMENT_REMOVED' | 'TIME_LOGGED' | 'TIME_UPDATED' | 'TIME_DELETED' | 'ESTIMATE_SET' | 'ESTIMATE_UPDATED'; /** * Activity log entry */ interface Activity { /** Unique identifier */ id: string; /** Activity type */ type: ActivityType; /** Card ID */ cardId: string; /** User who performed the action */ userId: string; /** Timestamp */ timestamp: Date | string; /** Previous value (for updates) */ previousValue?: any; /** New value (for updates) */ newValue?: any; /** Additional metadata */ metadata?: Record; } /** * Bulk operations callbacks */ interface BulkOperationsCallbacks { /** Called when bulk update is performed */ onBulkUpdate?: (cardIds: string[], updates: Partial) => void | Promise; /** Called when bulk delete is performed */ onBulkDelete?: (cardIds: string[]) => void | Promise; /** Called when bulk move is performed */ onBulkMove?: (cardIds: string[], targetColumnId: string) => void | Promise; } /** * Grouping options for swimlanes */ type GroupByOption = 'none' | 'assignee' | 'priority' | 'label' | 'custom'; /** * Swimlane configuration */ interface SwimlaneConfig { /** Grouping option */ groupBy: GroupByOption; /** Custom field ID (when groupBy is 'custom') */ customFieldId?: string; /** Show empty swimlanes */ showEmptyLanes?: boolean; /** Collapsible swimlanes */ collapsible?: boolean; /** Default collapsed state */ defaultCollapsed?: boolean; } /** * Swimlane (horizontal row grouping cards) */ interface Swimlane { /** Unique identifier */ id: string; /** Swimlane title */ title: string; /** Group value (user ID, priority, label, etc.) */ groupValue: any; /** Card IDs in this swimlane */ cardIds: string[]; /** Is collapsed */ isCollapsed?: boolean; /** Color for visual distinction */ color?: string; /** Icon */ icon?: string; } /** * Keyboard shortcut action types * v0.5.0: Added single-key shortcuts for speed */ type KeyboardAction = 'navigate_up' | 'navigate_down' | 'navigate_left' | 'navigate_right' | 'open_card' | 'close_modal' | 'select_all' | 'deselect_all' | 'new_card' | 'edit_card' | 'delete_card' | 'focus_search' | 'show_shortcuts' | 'new_card_modal' | 'search' | 'open_filters' | 'save' | 'undo' | 'redo' | 'quick_add' | 'delete_card_confirm'; /** * Keyboard shortcut definition */ interface KeyboardShortcut { /** Shortcut key(s) */ keys: string | string[]; /** Action to perform */ action: KeyboardAction; /** Description */ description: string; /** Modifier keys required */ modifiers?: { ctrl?: boolean; shift?: boolean; alt?: boolean; meta?: boolean; }; } /** * Card template for quick creation */ interface CardTemplate { /** Unique identifier */ id: string; /** Template name */ name: string; /** Template description */ description?: string; /** Icon or emoji */ icon?: string; /** Pre-filled card data */ template: Partial>; /** Category for organization */ category?: string; } /** * Export format options */ type ExportFormat = 'json' | 'csv' | 'pdf'; /** * Export options */ interface ExportOptions { /** Format to export */ format: ExportFormat; /** Include card details */ includeCardDetails?: boolean; /** Include comments */ includeComments?: boolean; /** Include activity log */ includeActivity?: boolean; /** Include attachments */ includeAttachments?: boolean; /** Date range filter */ dateRange?: { start: Date | string; end: Date | string; }; } /** * Import result */ interface ImportResult { /** Was import successful */ success: boolean; /** Number of cards imported */ cardsImported?: number; /** Number of columns imported */ columnsImported?: number; /** Errors encountered */ errors?: string[]; /** Warnings */ warnings?: string[]; } /** * Source of time entry - how the time was logged */ type TimeLogSource = 'manual' | 'timer' | 'import'; /** * Time entry for a task * Represents a single time log (e.g., "2 hours worked on Jan 10") */ interface TimeEntry { /** Unique identifier */ id: string; /** Task/Card ID */ taskId: string; /** User who logged the time */ userId: string; /** Duration in minutes */ durationMinutes: number; /** When the work was done (date of the work, not when it was logged) */ loggedAt: Date | string; /** Optional note/description */ note?: string; /** Source of the entry */ source: TimeLogSource; /** Created timestamp */ createdAt: Date | string; /** Updated timestamp */ updatedAt?: Date | string; } /** * Input for creating a new time log * Used by UI components to send data to callbacks */ interface TimeLogInput { /** Duration in minutes */ durationMinutes: number; /** When the work was done */ loggedAt?: Date | string; /** Optional note */ note?: string; /** Source (defaults to 'manual') */ source?: TimeLogSource; } /** * Time tracking summary for a task * Aggregated view of time data */ interface TimeTrackingSummary { /** Estimated effort in minutes (null if not set) */ estimateMinutes: number | null; /** Total logged time in minutes */ loggedMinutes: number; /** Remaining time in minutes (estimate - logged, can be negative) */ remainingMinutes: number | null; /** Progress percentage (0-100+, can exceed 100 if over estimate) */ progressPercent: number | null; /** Health status based on progress */ health: 'on-track' | 'at-risk' | 'over-budget' | 'no-estimate'; } /** * Timer state for real-time tracking */ interface TimerState { /** Is timer currently running */ isRunning: boolean; /** Task ID being tracked (null if no timer active) */ taskId: string | null; /** When timer was started */ startedAt: Date | string | null; /** Elapsed seconds since start */ elapsedSeconds: number; } /** * Callbacks for time tracking operations * These allow the library consumer to persist time data */ interface TimeTrackingCallbacks { /** Called when user logs time manually */ onTimeLog?: (taskId: string, input: TimeLogInput) => Promise; /** Called when user updates a time entry */ onTimeUpdate?: (entryId: string, updates: Partial) => Promise; /** Called when user deletes a time entry */ onTimeDelete?: (entryId: string) => Promise; /** Called when user sets/updates time estimate */ onEstimateUpdate?: (taskId: string, estimateMinutes: number | null) => Promise; /** Called when timer is started */ onTimerStart?: (taskId: string) => void; /** Called when timer is stopped (returns logged entry) */ onTimerStop?: (taskId: string, durationMinutes: number) => Promise; /** Called when timer is discarded without saving */ onTimerDiscard?: (taskId: string) => void; } /** * Props extension for time tracking in Card * Add these to Card interface for time-enabled cards */ interface CardTimeProps { /** Estimated effort in minutes */ effortMinutes?: number | null; /** Total logged time in minutes (aggregated from entries) */ timeLoggedMinutes?: number; /** Time entries for this card */ timeEntries?: TimeEntry[]; } /** * Props extension for KanbanBoard with time tracking */ interface TimeTrackingBoardProps { /** Enable time tracking features */ enableTimeTracking?: boolean; /** Time tracking callbacks */ timeTrackingCallbacks?: TimeTrackingCallbacks; /** Current timer state (for global timer indicator) */ timerState?: TimerState; /** Time entries by task ID (for modal display) */ timeEntriesByTask?: Map; } /** * Profitability metrics for a single task * Compares sold effort vs actual time logged */ interface TaskProfitability { /** Task ID */ taskId: string; /** Task name */ taskName: string; /** Project ID (optional) */ projectId?: string | null; /** Project name (optional) */ projectName?: string | null; /** Sold effort in minutes (tiempo ofertado al cliente) */ soldEffortMinutes: number | null; /** Actual time logged in minutes */ loggedMinutes: number; /** Variance in minutes (sold - logged, positive = profit, negative = loss) */ varianceMinutes: number | null; /** Variance percentage (variance / sold * 100) */ variancePercent: number | null; /** Profitability status */ status: 'profitable' | 'at-cost' | 'loss' | 'no-estimate'; } /** * Aggregated profitability metrics for a project or workspace */ interface ProfitabilitySummary { /** Total sold effort in minutes */ totalSoldMinutes: number; /** Total logged time in minutes */ totalLoggedMinutes: number; /** Total variance in minutes */ totalVarianceMinutes: number; /** Average variance percentage */ avgVariancePercent: number; /** Number of profitable tasks */ profitableTasksCount: number; /** Number of loss-making tasks */ lossTasksCount: number; /** Number of tasks at cost (±5% margin) */ atCostTasksCount: number; /** Total number of tasks with sold effort set */ totalTasksWithEstimate: number; } /** * Profitability report data */ interface ProfitabilityReport$1 { /** Summary metrics */ summary: ProfitabilitySummary; /** Task-level profitability data */ tasks: TaskProfitability[]; /** Report generation timestamp */ generatedAt: Date | string; } /** * KanbanViewAdapter - ViewAdapter implementation for Kanban board * @module views/KanbanViewAdapter * * Implements the ViewAdapter interface from @libxai/core to enable * the Kanban board to work with AsakaaRuntime and ViewRegistry. */ /** * Kanban view configuration */ interface KanbanViewConfig { /** * Board callbacks */ callbacks?: KanbanBoardProps['callbacks']; /** * Card click handler */ onCardClick?: KanbanBoardProps['onCardClick']; /** * Custom render props */ renderProps?: KanbanBoardProps['renderProps']; /** * Board configuration */ config?: KanbanBoardProps['config']; /** * Available users for assignment */ availableUsers?: KanbanBoardProps['availableUsers']; /** * Custom class name */ className?: string; /** * Custom inline styles (React.CSSProperties) */ style?: React.CSSProperties; /** * View options */ viewOptions?: ViewOptions; } /** * KanbanViewAdapter * * React-based ViewAdapter implementation that wraps the KanbanBoard component. * This allows the Kanban board to be used as a view in the ViewRegistry and * work seamlessly with AsakaaRuntime. * * @example * ```typescript * import { KanbanViewAdapter } from '@libxai/board' * import { ViewRegistry } from '@libxai/core' * * const registry = new ViewRegistry() * const kanbanView = new KanbanViewAdapter({ * callbacks: { * onCardMove: (cardId, columnId) => { ... }, * onCardUpdate: (cardId, updates) => { ... } * } * }) * * registry.register(kanbanView) * await registry.activate('kanban', container, data) * ``` */ declare class KanbanViewAdapter extends BaseViewAdapter { readonly id = "kanban"; readonly name = "Kanban Board"; readonly version = "1.0.0"; readonly description = ""; readonly icon = ""; readonly supportedExports: ExportFormat$1[]; private root; private kanbanConfig; constructor(config?: KanbanViewConfig); /** * Mount the Kanban view * * @param container - DOM element to mount into * @param data - Initial board data */ mount(container: HTMLElement, data: ViewBoardData): void; /** * Unmount the Kanban view */ unmount(): void; /** * Update the view with new data * * @param data - New board data */ update(data: ViewBoardData): void; /** * Configure the view * * @param options - View options */ configure(options: ViewOptions): void; /** * Export the view to a specific format * * @param format - Export format * @returns Promise resolving to exported data */ export(format: 'json' | 'csv' | 'pdf' | 'png'): Promise; /** * Render the Kanban board */ private render; /** * Export board data to CSV format */ private exportToCSV; /** * Export board to PDF * Uses the PDF export functionality from the Board component */ private exportToPDF; /** * Export board to PNG image * Uses html2canvas to capture the board */ private exportToPNG; } /** * Create a new Kanban view adapter * * @param config - View configuration * @returns KanbanViewAdapter instance * * @example * ```typescript * const kanbanView = createKanbanView({ * callbacks: { * onCardMove: (cardId, columnId) => console.log('Card moved'), * }, * theme: 'dark', * }) * ``` */ declare function createKanbanView(config?: KanbanViewConfig): KanbanViewAdapter; declare function KanbanBoard({ board, callbacks, onCardClick, renderProps, config, availableUsers, className, style, isLoading, error, children, availableTags, onCreateTag, attachmentsByCard, onUploadAttachments, onDeleteAttachment, comments, onAddComment, currentUser, mentionableUsers, onTaskOpen, onUploadCommentAttachments, enableTimeTracking, timeTrackingSummary, timeEntries, timerState, onLogTime, onUpdateEstimate, onUpdateSoldEffort, onStartTimer, onStopTimer, onDiscardTimer, blurFinancials, sidePanel, renderColumnMetrics, suppressDetailModal, }: KanbanBoardProps & { children?: React.ReactNode; }): react_jsx_runtime.JSX.Element; interface KanbanToolbarI18n { newTask: string; selectColumn: string; export: string; exportCSV: string; exportJSON: string; exportExcel: string; } interface KanbanToolbarProps { columns: Column$1[]; /** * Handler for creating a new task. * - If useColumnSelector is true: receives columnId as parameter * - If useColumnSelector is false: called with no parameters (opens modal) */ onCreateTask?: (columnId?: string) => void; createTaskLabel?: string; theme?: 'dark' | 'light'; locale?: 'es' | 'en'; /** * v0.17.27: If true, shows dropdown to select column before creating task. * If false, shows a simple button that triggers onCreateTask() without columnId. * @default false */ useColumnSelector?: boolean; onExportCSV?: () => void; onExportJSON?: () => void; onExportExcel?: () => Promise; translations?: Partial; /** Render custom content on the right side of toolbar (e.g. lens toggle) */ toolbarRightContent?: React.ReactNode; /** v2.5.0: Render content just before the Create Task button (e.g., share/export dropdown) */ toolbarEndContent?: React.ReactNode; } declare function KanbanToolbar({ columns, onCreateTask, createTaskLabel, theme, locale, useColumnSelector, onExportCSV, onExportJSON, onExportExcel, translations, toolbarRightContent, toolbarEndContent, }: KanbanToolbarProps): react_jsx_runtime.JSX.Element; /** * AddColumnButton Component * Button to add new columns to the Kanban board * @module components/Board/AddColumnButton */ interface AddColumnButtonProps { /** Callback when a new column should be created */ onAddColumn: (title: string) => void; /** Custom class name */ className?: string; /** Placeholder text for input */ placeholder?: string; /** Button label */ buttonLabel?: string; /** Whether the button is disabled */ disabled?: boolean; } /** * AddColumnButton - A button that allows users to add new columns to the Kanban board * * Can be used in two modes: * 1. Simple mode: Just a button that calls onAddColumn with a default name * 2. Input mode: Shows an input field for the user to type the column name * * @example * ```tsx * // Simple usage - inside KanbanBoard as children * * callbacks.onColumnCreate?.({ title, position: 1000 })} /> * * * // With useKanbanState hook * const { helpers } = useKanbanState({ initialBoard }) * helpers.addColumn({ title, position: Date.now() })} /> * ``` */ declare function AddColumnButton({ onAddColumn, className, placeholder, buttonLabel, disabled, }: AddColumnButtonProps): react_jsx_runtime.JSX.Element; /** * User Assignment Selector Component * Multi-select user assignment with avatar display */ interface User { id: string; name: string; avatar?: string; initials: string; color: string; } interface UserAssignmentSelectorProps { assignedUsers?: User[]; availableUsers: User[]; onChange: (users: User[]) => void; className?: string; maxVisibleAvatars?: number; } declare function UserAssignmentSelector({ assignedUsers, availableUsers, onChange, className, maxVisibleAvatars, }: UserAssignmentSelectorProps): react_jsx_runtime.JSX.Element; interface AddCardData { /** Task name (required) */ name: string; /** Column ID where the card will be created */ columnId: string; /** Assigned user IDs */ assigneeIds?: string[]; /** Start date */ startDate?: Date; /** End date / due date */ endDate?: Date; /** Priority */ priority?: 'low' | 'medium' | 'high' | 'urgent'; } interface AddCardButtonProps { /** Column ID where cards will be created */ columnId: string; /** Callback when a new card should be created */ onAddCard: (data: AddCardData) => void | Promise; /** Available users for assignment */ availableUsers?: User[]; /** Custom class name */ className?: string; /** Placeholder text for input */ placeholder?: string; /** Button label */ buttonLabel?: string; /** Whether the button is disabled */ disabled?: boolean; /** Theme: 'light' or 'dark' */ theme?: 'light' | 'dark'; /** Locale for translations */ locale?: 'en' | 'es'; } declare function AddCardButton({ columnId, onAddCard, availableUsers, className, buttonLabel, disabled, theme, locale, }: AddCardButtonProps): react_jsx_runtime.JSX.Element; interface QuickTaskCreateData { name: string; priority?: 'low' | 'medium' | 'high' | 'urgent'; assignee?: User; assigneeId?: string | null; startDate?: Date; endDate?: Date; } interface QuickTaskCreateProps { /** Called when user submits the form */ onSubmit: (data: QuickTaskCreateData) => void; /** Called when user cancels / clicks outside */ onCancel: () => void; /** Available users for assignee picker */ availableUsers?: User[]; /** Dark or light theme */ isDark?: boolean; /** Locale for i18n */ locale?: 'en' | 'es'; /** Default date (e.g. the calendar cell's date) */ defaultDate?: Date; /** Extra CSS class */ className?: string; /** Whether dropdowns open upward (bottom-full) or downward (top-full). Default: 'up' */ dropdownDirection?: 'up' | 'down'; } declare function QuickTaskCreate({ onSubmit, onCancel, availableUsers, isDark, locale, defaultDate, className, dropdownDirection, }: QuickTaskCreateProps): react_jsx_runtime.JSX.Element; interface ColumnProps { /** Column data */ column: Column$1; /** Cards in this column */ cards: Card$1[]; /** Custom column renderer */ renderColumn?: (column: Column$1, cards: Card$1[]) => React.ReactNode; /** Custom card renderer */ renderCard?: (card: Card$1) => React.ReactNode; /** Custom header renderer */ renderHeader?: (column: Column$1, cardCount: number) => React.ReactNode; /** Custom empty state */ renderEmptyState?: (column: Column$1) => React.ReactNode; /** Card click handler */ onCardClick?: (card: Card$1) => void; /** Card update handler */ onCardUpdate?: (cardId: string, updates: Partial) => void; /** Available users for assignment */ availableUsers?: User[]; /** All cards (for dependencies) */ allCards?: Card$1[]; /** Enable virtualization */ enableVirtualization?: boolean; /** Estimated card height for virtualization */ cardHeight?: number; /** Is column collapsed */ isCollapsed?: boolean; /** Toggle collapse */ onToggleCollapse?: () => void; /** Column rename handler */ onColumnRename?: (columnId: string, newTitle: string) => void; /** v0.17.55: Column delete handler */ onColumnDelete?: (columnId: string) => void; /** v0.17.55: Whether column can be deleted (false for default columns) */ isDeletable?: boolean; /** Custom className */ className?: string; /** v2.0.0: Custom metrics renderer below column header */ renderMetrics?: (column: Column$1, cards: Card$1[]) => React.ReactNode; /** Locale for i18n */ locale?: 'en' | 'es'; } /** * Column Component * Uses virtualization for large lists automatically */ declare const Column: React$1.NamedExoticComponent; /** * Editable Column Title Component * Allows inline editing of column names */ interface EditableColumnTitleProps { title: string; onSave: (newTitle: string) => void; className?: string; } declare function EditableColumnTitle({ title, onSave, className, }: EditableColumnTitleProps): react_jsx_runtime.JSX.Element; interface CardProps { /** Card data */ card: Card$1; /** Custom render function */ render?: (card: Card$1) => React.ReactNode; /** Click handler */ onClick?: (card: Card$1) => void; /** Is card selected */ isSelected?: boolean; /** Disable drag */ disableDrag?: boolean; /** Custom className */ className?: string; /** Card update handler */ onUpdate?: (cardId: string, updates: Partial) => void; /** Available users for assignment */ availableUsers?: User[]; /** All cards (for dependencies) */ allCards?: Card$1[]; } /** * Default Card Component * Optimized with memo to prevent unnecessary re-renders */ declare const Card: React$1.NamedExoticComponent; interface PrioritySelectorProps { priority?: Priority; onChange: (priority?: Priority) => void; className?: string; } declare function PrioritySelector({ priority, onChange, className, }: PrioritySelectorProps): react_jsx_runtime.JSX.Element; /** * Date Range Picker Component * Quick selection buttons + interactive calendar */ interface DateRangePickerProps { startDate?: string; endDate?: string; onChange: (startDate?: string, endDate?: string) => void; className?: string; } declare function DateRangePicker({ startDate, endDate, onChange, className, }: DateRangePickerProps): react_jsx_runtime.JSX.Element; /** * Validate if adding a dependency would create a circular reference * Uses Depth-First Search (DFS) algorithm * @param allCards - All cards in the board * @param fromCardId - The card that would become a dependency (the task being depended on) * @param toCardId - The card that would depend on fromCardId * @returns True if adding this dependency would create a circular reference */ declare function wouldCreateCircularDependency(allCards: Card$1[], fromCardId: string, toCardId: string): boolean; interface DependenciesSelectorProps { /** Current card (to exclude from dependencies) */ currentCardId: string; /** Currently selected dependencies */ dependencies?: string[]; /** All available tasks */ availableTasks: Card$1[]; /** Change handler */ onChange: (dependencies: string[]) => void; /** Custom className */ className?: string; /** Enable circular dependency validation (default: true) */ validateCircular?: boolean; /** Callback when circular dependency is detected */ onCircularDependencyError?: (targetCardId: string, targetCardTitle: string) => void; } declare function DependenciesSelector({ currentCardId, dependencies, availableTasks, onChange, className, validateCircular, onCircularDependencyError, }: DependenciesSelectorProps): react_jsx_runtime.JSX.Element; interface ErrorBoundaryProps { /** Child components to wrap */ children: ReactNode; /** Custom fallback UI (receives error and reset callback) */ fallback?: (error: Error, reset: () => void) => ReactNode; /** Callback when error is caught */ onError?: (error: Error, errorInfo: ErrorInfo) => void; /** Component identifier for error tracking */ componentName?: string; } interface ErrorBoundaryState { hasError: boolean; error: Error | null; errorInfo: ErrorInfo | null; } /** * Error Boundary for catching React errors * * @example * ```tsx * console.error(error)} * componentName="KanbanBoard" * > * * * ``` */ declare class ErrorBoundary extends Component { constructor(props: ErrorBoundaryProps); static getDerivedStateFromError(error: Error): Partial; componentDidCatch(error: Error, errorInfo: ErrorInfo): void; resetError: () => void; render(): ReactNode; } /** * Hook-based error boundary wrapper * Use this for functional components */ declare function withErrorBoundary

(Component: React__default.ComponentType

, errorBoundaryProps?: Omit): { (props: P): react_jsx_runtime.JSX.Element; displayName: string; }; interface CommandPaletteProps { /** Current board state */ board: Board; /** Available users for assignment */ availableUsers?: User$1[]; /** Callback to create a new card */ onCreateCard?: (columnId: string, title: string) => void; /** Callback to navigate to a card */ onNavigateToCard?: (cardId: string) => void; /** Callback to search and filter cards */ onSearch?: (query: string) => void; /** Callback to change card priority */ onChangePriority?: (cardId: string, priority: Priority) => void; /** Callback to assign user to card */ onAssignUser?: (cardId: string, userId: string) => void; /** AI Callbacks */ onGeneratePlan?: () => void; onPredictRisks?: () => void; onOpenAIUsage?: () => void; /** Custom keyboard shortcut (default: Cmd+K / Ctrl+K) */ shortcut?: string; /** Custom CSS class */ className?: string; } declare function CommandPalette({ board, onCreateCard, onNavigateToCard, onSearch, onChangePriority, onAssignUser, onGeneratePlan, onPredictRisks, onOpenAIUsage, shortcut, className, }: CommandPaletteProps): react_jsx_runtime.JSX.Element | null; interface AttachmentUploaderProps { /** Card ID for attachments */ cardId: string; /** Existing attachments */ attachments?: Attachment[]; /** Callback when files are uploaded */ onUpload?: (files: File[]) => Promise | void; /** Callback when attachment is deleted */ onDelete?: (attachmentId: string) => void; /** Current user ID */ currentUserId?: string; /** Max file size in MB */ maxSizeMB?: number; /** Allowed file types (MIME types) */ allowedTypes?: string[]; /** Max number of files */ maxFiles?: number; } declare function AttachmentUploader({ attachments, onUpload, onDelete, maxSizeMB, allowedTypes, maxFiles, }: AttachmentUploaderProps): react_jsx_runtime.JSX.Element; interface VelocityDataPoint { /** Period name (e.g., "Week 1", "Sprint 3") */ period: string; /** Number of cards completed */ completed: number; /** Number of cards planned */ planned?: number; /** Average velocity (optional) */ average?: number; } interface VelocityChartProps { /** Velocity data points */ data: VelocityDataPoint[]; /** Chart title */ title?: string; /** Chart height in pixels */ height?: number; /** Show average line */ showAverage?: boolean; /** Show planned line */ showPlanned?: boolean; } declare function VelocityChart({ data, title, height, showAverage, showPlanned, }: VelocityChartProps): react_jsx_runtime.JSX.Element; interface BurnDownDataPoint { /** Day/Date label */ day: string; /** Remaining tasks */ remaining: number; /** Ideal burndown line */ ideal: number; } interface BurnDownChartProps { /** Burndown data points */ data: BurnDownDataPoint[]; /** Chart title */ title?: string; /** Chart height in pixels */ height?: number; /** Total tasks at start */ totalTasks?: number; /** Use area chart instead of line */ useArea?: boolean; } declare function BurnDownChart({ data, title, height, totalTasks, useArea, }: BurnDownChartProps): react_jsx_runtime.JSX.Element; interface DistributionDataPoint { /** Category name */ name: string; /** Value/count */ value: number; /** Optional color */ color?: string; } interface DistributionChartsProps { /** Distribution data */ data: DistributionDataPoint[]; /** Chart title */ title?: string; /** Chart type */ type?: 'pie' | 'bar'; /** Chart height in pixels */ height?: number; /** Show percentages */ showPercentages?: boolean; } declare function DistributionCharts({ data, title, type, height, showPercentages, }: DistributionChartsProps): react_jsx_runtime.JSX.Element; interface BulkOperationsToolbarProps { /** Selected cards */ selectedCards: Card$1[]; /** Available users for assignment */ availableUsers?: User[]; /** Callback when selection is cleared */ onClearSelection: () => void; /** Bulk operations callbacks */ callbacks: BulkOperationsCallbacks; /** Available columns for move operation */ columns?: Array<{ id: string; title: string; }>; /** Available labels */ availableLabels?: string[]; } /** * Bulk Operations Toolbar Component */ declare const BulkOperationsToolbar: React$1.NamedExoticComponent; interface SwimlaneBoardViewProps { /** Board data */ board: Board; /** Swimlane configuration */ swimlaneConfig: SwimlaneConfig; /** All available users */ availableUsers?: User[]; /** Board callbacks */ callbacks: { onCardMove?: (cardId: string, targetColumnId: string, position: number) => void; onCardUpdate?: (cardId: string, updates: Partial) => void; onColumnUpdate?: (columnId: string, updates: Partial) => void; onWipLimitExceeded?: (column: Column$1, card: Card$1) => void; }; /** Custom className */ className?: string; /** * Swimlanes PRE-CONSTRUIDOS por el consumidor. Si se proveen, se usan tal * cual y se ignora `swimlaneConfig.groupBy` / generateSwimlanes. Permite * agrupar por cualquier criterio externo (p.ej. jerarquía WBS padre→hojas) * que la librería no modela internamente. */ swimlanes?: Swimlane[]; /** * Render custom de la cabecera de cada lane. Si se omite, se usa el header * por defecto (icono + título + conteo). Recibe la lane y si está colapsada; * el click de colapso lo gestiona el contenedor — envolver el contenido en * el área clickeable es responsabilidad del header default, así que cuando * se provee este render, el toggle se expone vía `onToggleCollapse`. */ renderSwimlaneHeader?: (args: { lane: Swimlane; isCollapsed: boolean; cardCount: number; onToggleCollapse: () => void; }) => ReactNode; /** * renderProps/config/onCardClick que se reenvían al KanbanBoard de CADA * lane (antes se perdían: las tarjetas dentro de swimlanes no podían usar * renderers custom). Opcionales y retrocompatibles. */ renderProps?: KanbanBoardProps['renderProps']; config?: KanbanBoardProps['config']; onCardClick?: KanbanBoardProps['onCardClick']; suppressDetailModal?: boolean; availableTags?: KanbanBoardProps['availableTags']; attachmentsByCard?: KanbanBoardProps['attachmentsByCard']; renderColumnMetrics?: KanbanBoardProps['renderColumnMetrics']; } /** * SwimlaneBoardView Component */ declare function SwimlaneBoardView({ board, swimlaneConfig, availableUsers, callbacks, className, swimlanes: providedSwimlanes, renderSwimlaneHeader, renderProps, config, onCardClick, suppressDetailModal, availableTags, attachmentsByCard, renderColumnMetrics, }: SwimlaneBoardViewProps): react_jsx_runtime.JSX.Element; interface GroupBySelectorProps { /** Current groupBy value */ value: GroupByOption; /** Change handler */ onChange: (groupBy: GroupByOption) => void; /** Custom className */ className?: string; } /** * GroupBySelector Component */ declare function GroupBySelector({ value, onChange, className, }: GroupBySelectorProps): react_jsx_runtime.JSX.Element; interface KeyboardShortcutsHelpProps { /** Custom shortcuts to display */ shortcuts?: KeyboardShortcut[]; /** Is modal open */ isOpen: boolean; /** Close handler */ onClose: () => void; /** Custom className */ className?: string; } /** * KeyboardShortcutsHelp Component */ declare function KeyboardShortcutsHelp({ shortcuts, isOpen, onClose, className, }: KeyboardShortcutsHelpProps): react_jsx_runtime.JSX.Element | null; interface CardTemplateSelectorProps { /** Available templates */ templates: CardTemplate[]; /** Template selection handler */ onSelectTemplate: (template: CardTemplate) => void; /** Custom className */ className?: string; } /** * Default card templates */ declare const DEFAULT_TEMPLATES: CardTemplate[]; /** * CardTemplateSelector Component */ declare function CardTemplateSelector({ templates, onSelectTemplate, className, }: CardTemplateSelectorProps): react_jsx_runtime.JSX.Element; interface ExportImportModalProps { /** Board data to export */ board: Board; /** Is modal open */ isOpen: boolean; /** Close handler */ onClose: () => void; /** Import handler */ onImport?: (result: ImportResult, content: string) => void; /** Board element ref for PDF export */ boardElementRef?: React.RefObject; /** Custom className */ className?: string; } /** * ExportImportModal Component */ declare function ExportImportModal({ board, isOpen, onClose, onImport, boardElementRef, className, }: ExportImportModalProps): react_jsx_runtime.JSX.Element | null; type DateFilter = 'all' | 'overdue' | 'today' | 'this-week' | 'custom'; type SortBy = 'created' | 'priority' | 'dueDate' | 'title' | 'estimate' | 'none'; type SortOrder = 'asc' | 'desc'; interface FilterState { dateFilter: DateFilter; dateRange?: { start: Date; end: Date; }; priorities: Priority[]; assignees: string[]; labels: string[]; columns: string[]; search: string; } interface SortState { by: SortBy; order: SortOrder; } interface UseFiltersOptions { initialFilters?: Partial; initialSort?: Partial; currentUserId?: string; } interface UseFiltersReturn { filters: FilterState; sort: SortState; setFilters: (filters: Partial) => void; setSort: (sort: Partial) => void; resetFilters: () => void; filterMyTasks: () => void; filterOverdue: () => void; filterHighPriority: () => void; applyFilters: (cards: Card$1[]) => Card$1[]; hasActiveFilters: boolean; } /** * Hook for filtering and sorting board cards * * @example * ```tsx * const { filters, setFilters, applyFilters, filterMyTasks } = useFilters({ * currentUserId: 'user-1' * }) * * const filteredCards = applyFilters(board.cards) * ``` */ declare function useFilters({ initialFilters, initialSort, currentUserId, }?: UseFiltersOptions): UseFiltersReturn; interface FilterBarProps { filters: FilterState; sort: SortState; onFiltersChange: (filters: Partial) => void; onSortChange: (sort: Partial) => void; onReset: () => void; onFilterMyTasks?: () => void; onFilterOverdue?: () => void; onFilterHighPriority?: () => void; availableUsers?: User$1[]; availableLabels?: string[]; availableColumns?: Array<{ id: string; title: string; }>; showQuickFilters?: boolean; compact?: boolean; groupBy?: GroupByOption; onGroupByChange?: (value: GroupByOption) => void; } declare function FilterBar({ filters, sort, onFiltersChange, onSortChange, onReset, onFilterMyTasks, onFilterOverdue, onFilterHighPriority, availableUsers, availableLabels, availableColumns: _availableColumns, showQuickFilters, compact, groupBy, onGroupByChange, }: FilterBarProps): react_jsx_runtime.JSX.Element; interface ConfigMenuProps { onOpenExport: () => void; onOpenThemes: () => void; onOpenShortcuts: () => void; className?: string; viewMode?: 'kanban' | 'gantt'; onExportGanttPDF?: () => Promise; onExportGanttExcel?: () => Promise; onExportGanttPNG?: () => Promise; onExportGanttCSV?: () => void; } declare function ConfigMenu({ onOpenExport, onOpenThemes, onOpenShortcuts, className, viewMode, onExportGanttPDF, onExportGanttExcel, onExportGanttPNG, onExportGanttCSV, }: ConfigMenuProps): react_jsx_runtime.JSX.Element; interface ThemeModalProps { isOpen: boolean; onClose: () => void; className?: string; } declare function ThemeModal({ isOpen, onClose, className }: ThemeModalProps): react_jsx_runtime.JSX.Element | null; /** * MentionInput Component * A textarea with @mention autocomplete functionality * @version 0.17.422 - Added emoji picker and file attachments */ interface MentionUser { id: string; name: string; email?: string; avatar?: string; avatarUrl?: string; color?: string; } /** Attachment for comments */ interface CommentAttachment { id: string; name: string; url: string; type: string; size: number; } /** Pending file before upload */ interface PendingFile { id: string; file: File; preview?: string; } type TaskOrCard = Task | Card$1; /** Comment type for activity panel */ interface TaskComment { id: string; taskId: string; userId: string; content: string; /** v0.17.422: Attachments for comments */ attachments?: CommentAttachment[]; createdAt: Date | string; updatedAt?: Date | string; user?: { id: string; name: string; email?: string; avatarUrl?: string; color?: string; }; } interface TaskDetailModalProps { /** Task or Card to display */ task: TaskOrCard | null; /** Whether modal is open */ isOpen: boolean; /** Close callback */ onClose: () => void; /** Update task callback (receives Task type) */ onTaskUpdate?: (task: Task) => void; /** Update card callback (receives Card type) - use this for Kanban */ onCardUpdate?: (card: Card$1) => void; /** Theme */ theme?: 'dark' | 'light'; /** Locale */ locale?: 'en' | 'es'; /** Available users for assignment */ availableUsers?: Assignee[]; /** Available tags in workspace for selection */ availableTags?: TaskTag[]; /** Callback to create a new tag */ onCreateTag?: (name: string, color: string) => Promise; /** v0.17.241: Attachments for the task */ attachments?: Attachment[]; /** v0.17.241: Callback when files are dropped/selected for upload */ onUploadAttachments?: (taskId: string, files: File[]) => Promise; /** v0.17.241: Callback to delete an attachment */ onDeleteAttachment?: (attachmentId: string) => Promise; /** v0.17.243: Available tasks for dependencies selection */ availableTasks?: Task[]; /** v0.17.252: Comments for activity panel */ comments?: TaskComment[]; /** v0.17.422: Callback to add a new comment (with optional mentionedUserIds and attachments) */ onAddComment?: (taskId: string, content: string, mentionedUserIds?: string[], attachments?: CommentAttachment[]) => Promise; /** v0.17.252: Current user info for displaying comments */ currentUser?: { id: string; name: string; avatarUrl?: string; color?: string; }; /** v0.17.401: Users available for @mentions in comments */ mentionableUsers?: MentionUser[]; /** v0.17.422: Upload comment attachments callback */ onUploadCommentAttachments?: (files: File[]) => Promise; /** Enable time tracking section */ enableTimeTracking?: boolean; /** Time tracking summary for current task */ timeTrackingSummary?: TimeTrackingSummary; /** Time entries for current task */ timeEntries?: TimeEntry[]; /** Whether timer is running for this task */ isTimerRunning?: boolean; /** Timer elapsed seconds */ timerElapsedSeconds?: number; /** Log time callback */ onTimeLog?: (taskId: string, input: TimeLogInput) => Promise; /** Update estimate callback */ onEstimateUpdate?: (taskId: string, minutes: number | null) => Promise; /** Update sold effort callback (v1.2.0: Commercial time tracking) */ onSoldEffortUpdate?: (taskId: string, minutes: number | null) => Promise; /** Start timer callback */ onTimerStart?: (taskId: string) => void; /** Stop timer callback */ onTimerStop?: (taskId: string) => void; /** Discard timer callback */ onTimerDiscard?: (taskId: string) => void; /** * v1.4.11: Governance v2.0 - Blur financial data for unauthorized users * When true, "Tiempo ofertado" (Quoted time) field will be blurred */ blurFinancials?: boolean; } /** * TaskDetailModal - ClickUp style full-screen task detail */ declare function TaskDetailModal({ task, isOpen, onClose, onTaskUpdate, onCardUpdate, theme, locale, availableUsers, availableTags, onCreateTag, attachments, onUploadAttachments, onDeleteAttachment, availableTasks, comments, onAddComment, currentUser, mentionableUsers, onUploadCommentAttachments, enableTimeTracking, timeTrackingSummary, timeEntries: _timeEntries, isTimerRunning, timerElapsedSeconds, onTimeLog, onEstimateUpdate, onSoldEffortUpdate, onTimerStart, onTimerStop, onTimerDiscard: _onTimerDiscard, blurFinancials, }: TaskDetailModalProps): react_jsx_runtime.JSX.Element | null; interface TimePillProps { /** Time tracking summary data */ summary: TimeTrackingSummary; /** Size variant */ size?: 'sm' | 'md' | 'lg'; /** Show estimate in pill */ showEstimate?: boolean; /** Click handler (e.g., to open time popover) */ onClick?: () => void; /** Additional class names */ className?: string; } declare function TimePill({ summary, size, showEstimate, onClick, className, }: TimePillProps): react_jsx_runtime.JSX.Element | null; interface TimePopoverProps { /** Task ID */ taskId: string; /** Time tracking summary */ summary: TimeTrackingSummary; /** Recent time entries */ entries?: TimeEntry[]; /** Whether timer is running for this task */ isTimerRunning?: boolean; /** Timer elapsed seconds (when running) */ timerElapsedSeconds?: number; /** Callback to log time */ onLogTime?: (input: TimeLogInput) => Promise; /** Callback to update estimate */ onUpdateEstimate?: (minutes: number | null) => Promise; /** Callback to start timer */ onStartTimer?: () => void; /** Callback to stop timer */ onStopTimer?: () => void; /** Callback to discard timer */ onDiscardTimer?: () => void; /** Close popover callback */ onClose?: () => void; /** Position anchor element */ anchorEl?: HTMLElement | null; /** Additional class names */ className?: string; } declare function TimePopover({ taskId: _taskId, summary, entries, isTimerRunning, timerElapsedSeconds, onLogTime, onUpdateEstimate, onStartTimer, onStopTimer, onDiscardTimer, onClose, className, }: TimePopoverProps): react_jsx_runtime.JSX.Element; /** * TimeInputPopover - Chronos V2 micro-popover for time entry * Glass morphism design matching ListView Chronos style */ interface TimeInputPopoverProps { mode: 'estimate' | 'quoted' | 'log'; locale: 'en' | 'es'; isDark: boolean; currentValue?: number | null; onSave: (minutes: number | null, note?: string) => Promise; onClose: () => void; className?: string; } declare function TimeInputPopover({ mode, locale, isDark, currentValue, onSave, onClose, className, }: TimeInputPopoverProps): react_jsx_runtime.JSX.Element; interface HealthBarProps { /** Time tracking summary data */ summary: TimeTrackingSummary; /** Show percentage label */ showLabel?: boolean; /** Size variant */ size?: 'sm' | 'md' | 'lg'; /** Additional class names */ className?: string; } declare function HealthBar({ summary, showLabel, size, className, }: HealthBarProps): react_jsx_runtime.JSX.Element; interface ProfitabilityReportProps { /** Report data */ report: ProfitabilityReport$1 | null; /** Loading state */ isLoading?: boolean; /** Locale for i18n */ locale?: 'en' | 'es'; /** Theme: 'dark' | 'light' */ theme?: 'dark' | 'light'; /** Additional class names */ className?: string; /** Callback when task is clicked */ onTaskClick?: (taskId: string) => void; } declare function ProfitabilityReport({ report, isLoading, locale, theme, className, onTaskClick, }: ProfitabilityReportProps): react_jsx_runtime.JSX.Element; /** * GanttBoardRef - Imperative API for GanttBoard component * Similar to DHTMLX gantt.* methods for programmatic control */ interface GanttBoardRef { /** * Get a task by ID * Similar to: gantt.getTask(id) */ getTask: (id: string) => Task | undefined; /** * Add a new task * Similar to: gantt.addTask(task) */ addTask: (task: Task, parentId?: string) => void; /** * Update a task by ID * Similar to: gantt.updateTask(id, updates) */ updateTask: (id: string, updates: Partial) => void; /** * Delete a task by ID * Similar to: gantt.deleteTask(id) */ deleteTask: (id: string) => void; /** * Delete multiple tasks by IDs */ deleteTasks: (ids: string[]) => void; /** * Duplicate a task */ duplicateTask: (id: string) => void; /** * Split a task (create GAP in the middle, like Bryntum/DHTMLX) (v0.8.1) * Same task, but work is paused for some days then continues * Example: Jan 1-10 → Split at Jan 5 with 3 day gap → Jan 1-4 [GAP] Jan 8-13 * @param id - Task ID to split * @param splitDate - Date where gap starts * @param gapDays - Number of days to pause (default: 3) */ splitTask: (id: string, splitDate: Date, gapDays?: number) => void; /** * Calculate end date based on start date and duration * Similar to: gantt.calculateEndDate(start, duration) */ calculateEndDate: (start: Date, durationDays: number) => Date; /** * Calculate duration in days between two dates * Similar to: gantt.calculateDuration(start, end) */ calculateDuration: (start: Date, end: Date) => number; /** * Validate if creating a dependency would create a circular reference */ validateDependency: (fromTaskId: string, toTaskId: string) => boolean; /** * Get all tasks (including subtasks) as a flat array * Similar to: gantt.getTaskByTime() */ getAllTasks: () => Task[]; /** * Get tasks filtered by status */ getTasksByStatus: (status: 'todo' | 'in-progress' | 'completed') => Task[]; /** * Get tasks by parent ID */ getTasksByParent: (parentId?: string) => Task[]; /** * Get the critical path tasks */ getCriticalPath: () => Task[]; /** * Indent task(s) - make them children of previous sibling */ indentTask: (taskId: string) => void; /** * Outdent task(s) - move them to parent's level */ outdentTask: (taskId: string) => void; /** * Move task up or down in the list */ moveTask: (taskId: string, direction: 'up' | 'down') => void; /** * Create a subtask under a parent task */ createSubtask: (parentId: string) => void; /** * Scroll to a specific task */ scrollToTask: (id: string) => void; /** * Highlight a task temporarily */ highlightTask: (id: string, duration?: number) => void; /** * Expand a task to show its subtasks */ expandTask: (id: string) => void; /** * Collapse a task to hide its subtasks */ collapseTask: (id: string) => void; /** * Expand all tasks */ expandAll: () => void; /** * Collapse all tasks */ collapseAll: () => void; /** * v3.0.0: Collapse tasks to a specific WBS level * Level 1 = only root tasks visible * Level 2 = root + first-level children * 'all' = expand everything */ collapseToLevel: (level: number | 'all') => void; /** * Undo last change * Similar to: gantt.undo() */ undo: () => void; /** * Redo last undone change * Similar to: gantt.redo() */ redo: () => void; /** * Check if undo is available */ canUndo: () => boolean; /** * Check if redo is available */ canRedo: () => boolean; /** * Clear undo/redo history */ clearHistory: () => void; /** * Export Gantt chart to PNG image * Similar to: gantt.exportToPNG() */ exportToPNG: () => Promise; /** * Export tasks to PDF format * Similar to: gantt.exportToPDF() */ exportToPDF: (filename?: string) => Promise; /** * Export tasks to Excel format * Similar to: gantt.exportToExcel() */ exportToExcel: (filename?: string) => Promise; /** * Export tasks to JSON string * Similar to: gantt.serialize() */ exportToJSON: () => string; /** * Export tasks to CSV format */ exportToCSV: () => string; /** * Import tasks from JSON string * Similar to: gantt.parse(data) */ importFromJSON: (json: string) => void; /** * Get current tasks state */ getTasks: () => Task[]; /** * Refresh/re-render the Gantt chart * Similar to: gantt.render() */ refresh: () => void; /** * Clear all tasks * Similar to: gantt.clearAll() */ clearAll: () => void; /** * Smoothly scroll the timeline so that today's date sits in the * center of the visible viewport. No-op when today falls outside * the project's date range. */ scrollToToday: () => void; /** * 1.9.35 · Desplaza la línea de tiempo a una fecha. `align` 'start' la deja * cerca del borde izquierdo (con un pequeño margen); 'center', centrada. * Para abrir el Timeline encuadrado en las fechas del proyecto. */ scrollToDate: (date: Date, align?: 'start' | 'center') => void; /** * 1.9.35 · Encuadra un rango: elige la escala (≤3 semanas día, ≤4 meses semana, * si no mes) y desplaza al inicio del rango. */ fitToDates: (start: Date, end: Date) => void; } interface GanttBoardProps { tasks: Task[]; config?: GanttConfig; onTasksChange?: (tasks: Task[]) => void; } declare const GanttBoard: React$1.ForwardRefExoticComponent>; interface GanttToolbarProps { /** 1.9.34 · versión compacta para una cabecera de una fila (ver `toolbarContainer`). */ enCabecera?: boolean; theme: any; timeScale: TimeScale; onTimeScaleChange: (scale: TimeScale) => void; zoom: number; onZoomChange: (zoom: number) => void; currentTheme: Theme$1; onThemeChange: (theme: Theme$1) => void; rowDensity: RowDensity; onRowDensityChange: (density: RowDensity) => void; showThemeSelector?: boolean; showCreateTaskButton?: boolean; createTaskLabel?: string; onCreateTask?: () => void; taskFilter?: TaskFilterType; onTaskFilterChange?: (filter: TaskFilterType) => void; hideCompleted?: boolean; onHideCompletedChange?: (hide: boolean) => void; toolbarRightContent?: React.ReactNode; wbsLevel?: number | 'all'; onWbsLevelChange?: (level: number | 'all') => void; maxWbsDepth?: number; viewMode?: 'execution' | 'oracle'; onViewModeChange?: (mode: 'execution' | 'oracle') => void; projectForecast?: ProjectForecast; hideForecastHud?: boolean; onExportPNG?: () => Promise; onExportPDF?: () => Promise; onExportExcel?: () => Promise; onExportCSV?: () => void; onExportJSON?: () => void; onExportMSProject?: () => void; showCriticalPath?: boolean; onShowCriticalPathChange?: (show: boolean) => void; showDependencies?: boolean; onShowDependenciesChange?: (show: boolean) => void; highlightWeekends?: boolean; onHighlightWeekendsChange?: (show: boolean) => void; showBaseline?: boolean; onShowBaselineChange?: (show: boolean) => void; onCopySnapshotLink?: () => void; hasDependencies?: boolean; } interface ExportDropdownProps { theme: any; onExportPNG?: () => Promise; onExportPDF?: () => Promise; onExportExcel?: () => Promise; onExportCSV?: () => void; onExportJSON?: () => void; onExportMSProject?: () => void; } declare function ExportDropdown({ theme, onExportPNG, onExportPDF, onExportExcel, onExportCSV, onExportJSON, onExportMSProject }: ExportDropdownProps): react_jsx_runtime.JSX.Element | null; declare function GanttToolbar({ enCabecera, theme, timeScale, onTimeScaleChange, zoom, onZoomChange, currentTheme, onThemeChange, rowDensity, onRowDensityChange, showThemeSelector, // v0.17.29: Default to false - themes should be in app settings showCreateTaskButton, createTaskLabel, // v0.15.0: Will use translations if not provided onCreateTask, taskFilter, // v0.17.300: Task filter onTaskFilterChange, hideCompleted, // v0.18.0: Hide completed toggle onHideCompletedChange, toolbarRightContent, wbsLevel, onWbsLevelChange, maxWbsDepth, viewMode, onViewModeChange, projectForecast, hideForecastHud, onExportPNG, onExportPDF, onExportExcel, onExportCSV, onExportJSON, onExportMSProject, showCriticalPath, onShowCriticalPathChange, showDependencies, onShowDependenciesChange, highlightWeekends, onHighlightWeekendsChange, showBaseline, onShowBaselineChange, onCopySnapshotLink, hasDependencies, }: GanttToolbarProps): react_jsx_runtime.JSX.Element; interface TaskGridProps { tasks: Task[]; theme: any; rowHeight: number; availableUsers?: Array<{ id: string; name: string; initials: string; color: string; }>; templates: Required; onTaskClick?: (task: Task) => void; /** v1.9.16: la seleccion sale del Gantt — ver `onTaskSelectionChange` en types.ts */ onTaskSelectionChange?: (taskId: string | null) => void; /** v1.9.17: ...y tambien entra — ver `selectedTaskId` en types.ts */ selectedTaskId?: string | null; onTaskDblClick?: (task: Task) => void; onTaskContextMenu?: (task: Task, event: React.MouseEvent) => void; onTaskToggle?: (taskId: string) => void; scrollTop: number; columns: GanttColumn[]; onToggleColumn: (columnType: ColumnType$1) => void; onColumnResize?: (columnId: ColumnType$1, newWidth: number) => void; onTaskUpdate?: (taskId: string, updates: Partial) => void; onBulkFill?: (taskIds: string[], column: 'assignees' | 'startDate' | 'endDate', value: any) => void; onTaskIndent?: (taskIds: string[]) => void; onTaskOutdent?: (taskIds: string[]) => void; onTaskMove?: (taskIds: string[], direction: 'up' | 'down') => void; onMultiTaskDelete?: (taskIds: string[]) => void; onTaskDuplicate?: (taskIds: string[]) => void; onTaskCreate?: (afterTaskId: string, direction: 'above' | 'below') => void; onTaskRename?: (taskId: string, newName: string) => void; /** 1.9.45 · fila «+ Add task» al final de la rejilla (la app decide qué hace). */ addTaskRow?: { label: string; onClick: () => void; }; onCreateSubtask?: (parentTaskId: string) => void; onOpenTaskModal?: (task: Task) => void; /** v1.9.6: ahora recibe TODOS los ids a borrar (bulk desde el menú contextual * con multi-selección) + una etiqueta para el modal de confirmación. */ onDeleteRequest?: (taskIds: string[], label: string) => void; onTaskReparent?: (taskId: string, newParentId: string | null, position?: number) => void; /** v1.9.10: árbol COMPLETO sin filtrar. Cuando hay un filtro activo, `tasks` * es un subconjunto; para reordenar correctamente la posición de destino debe * traducirse al índice real entre TODOS los hermanos (no solo los visibles). */ allTasks?: Task[]; scrollContainerRef?: React.RefObject; showCriticalPath?: boolean; } declare function TaskGrid({ tasks, theme, rowHeight: ROW_HEIGHT, availableUsers, templates: _templates, // TODO: Use templates for custom rendering onTaskClick, onTaskSelectionChange, selectedTaskId, onTaskDblClick, // v0.8.0 onTaskContextMenu, // v0.8.0 onTaskToggle, scrollTop: _scrollTop, columns, onToggleColumn, onColumnResize, onTaskUpdate, onBulkFill, onTaskIndent, onTaskOutdent, onTaskMove, onMultiTaskDelete, onTaskDuplicate, onTaskCreate, onTaskRename, addTaskRow, onCreateSubtask, onOpenTaskModal, onDeleteRequest, // v0.17.34 onTaskReparent, // v0.17.68 allTasks, // v1.9.10: árbol completo para traducir posición con filtros activos scrollContainerRef, // v0.18.15 showCriticalPath, }: TaskGridProps): react_jsx_runtime.JSX.Element; /** * Optional working-days configuration so the tooltip Duration reflects the * workspace's actual working schedule (weekend toggles + holidays) instead * of raw calendar days. When omitted, falls back to calendar days. */ interface WorkingDaysConfig { /** Which weekdays count as working days. 0=Sun, 1=Mon, ..., 6=Sat. */ enabledWeekdays?: boolean[]; /** Holiday dates in 'YYYY-MM-DD' (workspace-local) to exclude. */ holidayDates?: Set | string[]; } interface TimelineProps { tasks: Task[]; theme: any; rowHeight: number; timeScale: TimeScale; startDate: Date; endDate: Date; zoom: number; locale?: string; templates: Required; dependencyLineStyle?: DependencyLineStyle; showTaskBarLabels?: boolean; onTaskClick?: (task: Task) => void; onTaskDblClick?: (task: Task) => void; onTaskContextMenu?: (task: Task, event: React__default.MouseEvent) => void; onTaskDateChange?: (task: Task, newStart: Date, newEnd: Date) => void; onDependencyCreate?: (fromTask: Task, toTaskId: string) => void; onDependencyDelete?: (taskId: string, dependencyId: string) => void; /** v3.0.0: Show baseline ghost bars behind actual bars (Oracle view) */ showBaseline?: boolean; showCriticalPath?: boolean; showDependencies?: boolean; highlightWeekends?: boolean; /** 1.9.36 · 'range' pinta «Sep 1–7» en la escala W. */ weekHeaderFormat?: 'number' | 'range'; /** v4.1.0: Per-task edit check — returns false for read-only bars */ canEditTask?: (task: Task) => boolean; /** v4.2.0: Committed on pointerup after dragging the progress edge of a task bar. */ onTaskProgressDrag?: (task: Task, newProgress: number) => void; /** v4.3.0: Workspace working-day config for the tooltip Duration field. */ workingDaysConfig?: WorkingDaysConfig; } interface TaskPosition { id: string; x: number; y: number; width: number; height: number; } declare function Timeline({ tasks, theme, rowHeight: ROW_HEIGHT, timeScale, startDate, endDate, zoom, locale, // v0.17.400: Default to English templates, dependencyLineStyle, // v0.17.310 showTaskBarLabels, onTaskClick, onTaskDblClick, // v0.8.0 onTaskContextMenu, // v0.8.0 onTaskDateChange, onDependencyCreate, onDependencyDelete, showBaseline, showCriticalPath, showDependencies, highlightWeekends, weekHeaderFormat, canEditTask, onTaskProgressDrag, workingDaysConfig, }: TimelineProps): react_jsx_runtime.JSX.Element; interface TaskTooltipData { task: Task; x: number; y: number; width: number; height: number; showBelow: boolean; /** Viewport mouse position — tooltip follows cursor for fluid UX */ mouseX: number; mouseY: number; } interface TaskBarProps { task: Task; x: number; y: number; width: number; theme: any; dayWidth: number; startDate: Date; templates: Required; onClick?: (task: Task) => void; onDoubleClick?: (task: Task) => void; onContextMenu?: (task: Task, event: React.MouseEvent) => void; onDateChange?: (task: Task, newStart: Date, newEnd: Date) => void; onDependencyCreate?: (fromTask: Task, toTaskId: string) => void; allTaskPositions?: TaskPosition[]; onDragMove?: (taskId: string, daysDelta: number, isDragging: boolean) => void; onHoverChange?: (tooltipData: TaskTooltipData | null) => void; showBaseline?: boolean; showTaskBarLabels?: boolean; showCriticalPath?: boolean; readOnly?: boolean; onProgressChange?: (task: Task, newProgress: number) => void; } declare function TaskBar({ task, x, y, width, theme, dayWidth, startDate, templates, onClick, onDoubleClick, // v0.8.0 onContextMenu, // v0.8.0 onDateChange, onDependencyCreate, allTaskPositions, onDragMove, // v0.13.0 onHoverChange, // v0.17.76 showBaseline, // v3.0.0 showTaskBarLabels, showCriticalPath, readOnly, onProgressChange, }: TaskBarProps): react_jsx_runtime.JSX.Element; interface DependencyLineProps { x1: number; y1: number; x2: number; y2: number; theme: any; onDelete?: () => void; lineStyle?: DependencyLineStyle; isHoverLayer?: boolean; onHoverChange?: (isHovered: boolean) => void; hoverOverlayOnly?: boolean; colorOverride?: string; strokeWidthOverride?: number; glowFilter?: string; } /** * v0.17.364: TRUE ClickUp-style dependency line routing * * RULES: * 1. Lines ALWAYS exit from the RIGHT side of the source bar * 2. Lines ALWAYS enter from the LEFT side of the destination bar * 3. The vertical segment is ALWAYS placed to the LEFT of the destination bar * * Pattern: source(right) → horizontal → vertical → horizontal → destination(left) * * For FORWARD dependencies (x2 > x1, destination RIGHT of source): * The vertical segment is just before destination: turnX = x2 - OFFSET * Path: right → horizontal → down/up → right into destination * * For BACKWARD dependencies (x2 <= x1, destination LEFT of or at same X as source): * The vertical segment must still be LEFT of destination: turnX = x2 - OFFSET * Path: right → horizontal past source → down/up → LEFT back to destination */ declare function DependencyLine({ x1, y1, x2, y2, theme, onDelete, lineStyle, isHoverLayer, onHoverChange, hoverOverlayOnly, colorOverride, strokeWidthOverride, glowFilter, }: DependencyLineProps): react_jsx_runtime.JSX.Element; interface MilestoneProps { task: Task; x: number; y: number; theme: any; onClick?: (task: Task) => void; } declare function Milestone({ task, x, y, theme, onClick }: MilestoneProps): react_jsx_runtime.JSX.Element; interface ColumnManagerProps { columns: GanttColumn[]; onToggleColumn: (columnId: ColumnType$1) => void; theme: any; } declare function ColumnManager({ columns, onToggleColumn, theme }: ColumnManagerProps): react_jsx_runtime.JSX.Element; interface ContextMenuItem { id: string; label: string; icon?: React.ReactNode; onClick: () => void; separator?: boolean; disabled?: boolean; submenu?: ContextMenuItem[]; } interface ContextMenuProps { isOpen: boolean; x: number; y: number; items: ContextMenuItem[]; onClose: () => void; theme: any; } declare function ContextMenu({ isOpen, x, y, items, onClose, theme }: ContextMenuProps): react_jsx_runtime.JSX.Element | null; declare const MenuIcons: { Edit: react_jsx_runtime.JSX.Element; Pencil: react_jsx_runtime.JSX.Element; Delete: react_jsx_runtime.JSX.Element; Add: react_jsx_runtime.JSX.Element; AddSubtask: react_jsx_runtime.JSX.Element; Remove: react_jsx_runtime.JSX.Element; Link: react_jsx_runtime.JSX.Element; Progress: react_jsx_runtime.JSX.Element; Sort: react_jsx_runtime.JSX.Element; SortAsc: react_jsx_runtime.JSX.Element; SortDesc: react_jsx_runtime.JSX.Element; Hide: react_jsx_runtime.JSX.Element; Show: react_jsx_runtime.JSX.Element; Settings: react_jsx_runtime.JSX.Element; Split: react_jsx_runtime.JSX.Element; Duplicate: react_jsx_runtime.JSX.Element; MarkIncomplete: react_jsx_runtime.JSX.Element; SetInProgress: react_jsx_runtime.JSX.Element; MarkComplete: react_jsx_runtime.JSX.Element; }; type TaskPriority = 'low' | 'medium' | 'high' | 'urgent'; interface CustomStatus { id: string; title: string; color?: string; } interface TaskFormData { name: string; description?: string; startDate?: Date; endDate?: Date; progress: number; status: string; priority?: TaskPriority; isMilestone: boolean; color?: string; assignees?: Array<{ name: string; avatar?: string; initials: string; color: string; }>; dependencies?: string[]; tags?: TaskTag[]; pendingFiles?: File[]; effortMinutes?: number | null; parentId?: string | null; location?: string; equipment?: string; } interface TaskFormModalProps { isOpen: boolean; onClose: () => void; task?: Task; availableTasks?: Task[]; availableUsers?: Array<{ id: string; name: string; avatar?: string; }>; onSubmit: (data: TaskFormData) => void | Promise; isLoading?: boolean; mode?: 'create' | 'edit'; theme?: Theme$1; customStatuses?: CustomStatus[]; availableTags?: TaskTag[]; onCreateTag?: (name: string, color: string) => Promise; attachments?: Attachment[]; onUploadAttachments?: (taskId: string, files: File[]) => Promise | void; onDeleteAttachment?: (attachmentId: string) => void; /** v2.2.0: Pre-select status when creating from a specific column */ defaultStatus?: string; } declare function TaskFormModal({ isOpen, onClose, task, availableTasks, availableUsers, onSubmit, isLoading, mode, theme, customStatuses, availableTags, onCreateTag, attachments, onUploadAttachments, onDeleteAttachment, defaultStatus, }: TaskFormModalProps): react_jsx_runtime.JSX.Element; interface GanttAIAssistantProps { /** All current tasks in the Gantt */ tasks: Task[]; /** Theme configuration */ theme: GanttTheme; /** AI assistant configuration */ config: GanttAIAssistantConfig; /** Callback when tasks should be updated */ onTasksUpdate: (updatedTasks: Task[]) => void; /** Callback for single task update */ onTaskUpdate?: (taskId: string, updates: Partial) => void; /** Callback for task creation */ onTaskCreate?: (task: Task) => void; /** Callback for task deletion */ onTaskDelete?: (taskId: string) => void; /** Callback for dependency creation */ onDependencyCreate?: (fromTaskId: string, toTaskId: string) => void; /** Callback for dependency deletion */ onDependencyDelete?: (taskId: string, dependencyId: string) => void; } declare function GanttAIAssistant({ tasks, theme, config, onTasksUpdate: _onTasksUpdate, // Reserved for batch updates onTaskUpdate, onTaskCreate, onTaskDelete, onDependencyCreate, onDependencyDelete, }: GanttAIAssistantProps): react_jsx_runtime.JSX.Element | null; interface TagPickerProps { /** Currently selected tags on the task */ selectedTags: TaskTag[]; /** All available tags in the workspace */ availableTags: TaskTag[]; /** Callback when tags change */ onChange: (tags: TaskTag[]) => void; /** Callback to create a new tag */ onCreateTag?: (name: string, color: string) => Promise; /** Theme colors */ theme: any; /** Disabled state */ disabled?: boolean; /** Compact mode (pill style) */ compact?: boolean; } declare function TagPicker({ selectedTags, availableTags, onChange, onCreateTag, theme, disabled, compact: _compact, }: TagPickerProps): react_jsx_runtime.JSX.Element; /** * TagBadge - Small tag badge for displaying in cards/lists */ declare function TagBadge({ tag, onRemove, size }: { tag: TaskTag; onRemove?: () => void; size?: 'xs' | 'sm'; }): react_jsx_runtime.JSX.Element; /** * TagList - Display list of tags (for cards) */ declare function TagList({ tags, maxVisible, size, }: { tags: TaskTag[]; maxVisible?: number; size?: 'xs' | 'sm'; }): react_jsx_runtime.JSX.Element | null; /** * AI Command Parser for Gantt Chart * Parses natural language commands and converts them to task operations * * This module provides utilities for parsing AI responses and generating * prompts for natural language task editing. * * @version 0.14.0 */ /** * System prompt for the AI model to understand Gantt task commands */ declare const GANTT_AI_SYSTEM_PROMPT = "You are a Gantt chart AI assistant. You help users edit project tasks using natural language commands.\n\nAVAILABLE COMMANDS:\n1. move_task - Move a task to a different date\n2. resize_task - Change task duration (extend/shorten)\n3. rename_task - Rename a task\n4. delete_task - Delete a task\n5. create_task - Create a new task\n6. link_tasks - Create dependency between tasks\n7. unlink_tasks - Remove dependency\n8. assign_task - Assign users to task\n9. set_progress - Update task progress (0-100%)\n10. set_status - Change task status (todo, in-progress, completed)\n\nRESPONSE FORMAT (JSON):\n{\n \"type\": \"command_type\",\n \"taskId\": \"id of the task to modify (if found)\",\n \"taskName\": \"name of the task mentioned\",\n \"updates\": { /* partial task updates */ },\n \"newTask\": { /* for create_task only */ },\n \"dependencyFrom\": \"source task id (for link/unlink)\",\n \"dependencyTo\": \"target task id (for link/unlink)\",\n \"message\": \"Human-readable response explaining what was done\",\n \"success\": true/false,\n \"error\": \"error message if failed\"\n}\n\nEXAMPLES:\n- \"Move Design to next Monday\" -> move_task with startDate update\n- \"Extend Testing by 3 days\" -> resize_task with endDate update\n- \"Rename 'Old Task' to 'New Task'\" -> rename_task with name update\n- \"Set Development progress to 50%\" -> set_progress with progress: 50\n- \"Link Design to Development\" -> link_tasks\n- \"Create a new task called 'Review'\" -> create_task\n\nTASK DATA FORMAT:\nTasks have: id, name, startDate, endDate, progress, status, dependencies[], assignees[]\n\nAlways try to match task names case-insensitively and handle partial matches.\nIf you can't find a task by name, search through the provided task list.\nIf ambiguous, ask for clarification in the message field."; /** * Generate the user prompt with current tasks context */ declare function generateTasksContext(tasks: Task[]): string; /** * Find a task by name (case-insensitive, partial match) */ declare function findTaskByName(tasks: Task[], name: string): Task | undefined; /** * Parse date from natural language */ declare function parseNaturalDate(text: string, referenceDate?: Date): Date | null; /** * Parse duration from natural language */ declare function parseNaturalDuration(text: string): number | null; /** * Parse progress percentage from natural language */ declare function parseProgress(text: string): number | null; /** * Parse task status from natural language */ declare function parseStatus(text: string): 'todo' | 'in-progress' | 'completed' | null; /** * Local command parser (for offline/simple commands without AI) * This can handle basic commands without needing an AI API call */ declare function parseLocalCommand(command: string, tasks: Task[]): AICommandResult | null; /** * Validate and sanitize AI response */ declare function validateAIResponse(response: unknown): AICommandResult; /** * Public utility functions for Gantt operations * Similar to DHTMLX gantt.* utility methods */ declare const ganttUtils: { /** * Calculate end date based on start date and duration in days * @param start - Start date * @param durationDays - Duration in days * @returns End date */ calculateEndDate: (start: Date, durationDays: number) => Date; /** * Calculate duration in days between two dates * @param start - Start date * @param end - End date * @returns Duration in days (rounded up) */ calculateDuration: (start: Date, end: Date) => number; /** * Calculate working days between two dates (excluding weekends) * @param start - Start date * @param end - End date * @returns Number of working days */ calculateWorkingDays: (start: Date, end: Date) => number; /** * Add working days to a date (excluding weekends) * @param start - Start date * @param workingDays - Number of working days to add * @returns End date */ addWorkingDays: (start: Date, workingDays: number) => Date; /** * Check if a date is a weekend * @param date - Date to check * @returns True if weekend */ isWeekend: (date: Date) => boolean; /** * Validate if creating a dependency would create a circular reference * Uses Depth-First Search (DFS) algorithm * @param tasks - All tasks * @param fromTaskId - Source task ID * @param toTaskId - Target task ID * @returns True if would create circular dependency */ validateDependencies: (tasks: Task[], fromTaskId: string, toTaskId: string) => boolean; /** * Flatten nested tasks into a single array * @param tasks - Tasks with potential subtasks * @returns Flat array of all tasks */ flattenTasks: (tasks: Task[]) => Task[]; /** * Find a task by ID in nested structure * @param tasks - Tasks to search * @param taskId - ID to find * @returns Task if found, undefined otherwise */ findTaskById: (tasks: Task[], taskId: string) => Task | undefined; /** * Get all parent tasks recursively * @param tasks - All tasks * @param taskId - Child task ID * @returns Array of parent tasks */ getParentTasks: (tasks: Task[], taskId: string) => Task[]; /** * Export tasks to JSON string * @param tasks - Tasks to export * @returns JSON string */ exportToJSON: (tasks: Task[]) => string; /** * Import tasks from JSON string * @param json - JSON string * @returns Parsed tasks */ importFromJSON: (json: string) => Task[]; /** * Export tasks to CSV format * @param tasks - Tasks to export * @returns CSV string */ exportToCSV: (tasks: Task[]) => string; /** * Format date to string (YYYY-MM-DD) * @param date - Date to format * @returns Formatted string */ formatDate: (date: Date) => string; /** * Parse date from string (YYYY-MM-DD) * @param dateString - Date string * @returns Parsed Date */ parseDate: (dateString: string) => Date; /** * Get date range for a task * @param task - Task to get range for * @returns Object with start and end dates, or null if no dates */ getTaskDateRange: (task: Task) => { start: Date; end: Date; } | null; /** * Get the earliest start date from tasks * @param tasks - Tasks to search * @returns Earliest date or null */ getEarliestStartDate: (tasks: Task[]) => Date | null; /** * Get the latest end date from tasks * @param tasks - Tasks to search * @returns Latest date or null */ getLatestEndDate: (tasks: Task[]) => Date | null; /** * Check if two tasks overlap in time * @param task1 - First task * @param task2 - Second task * @returns True if tasks overlap */ tasksOverlap: (task1: Task, task2: Task) => boolean; /** * Get all tasks that depend on a given task (children in dependency tree) * @param tasks - All tasks * @param taskId - Task ID to find dependents for * @returns Array of tasks that depend on this task */ getDependentTasks: (tasks: Task[], taskId: string) => Task[]; /** * Get all tasks that a given task depends on (parents in dependency tree) * @param tasks - All tasks * @param taskId - Task ID to find dependencies for * @returns Array of tasks this task depends on */ getDependencyTasks: (tasks: Task[], taskId: string) => Task[]; /** * Filter tasks by status * @param tasks - Tasks to filter * @param status - Status to filter by * @returns Filtered tasks */ filterByStatus: (tasks: Task[], status: "todo" | "in-progress" | "completed") => Task[]; /** * Filter tasks by date range * @param tasks - Tasks to filter * @param startDate - Range start * @param endDate - Range end * @returns Tasks that fall within the date range */ filterByDateRange: (tasks: Task[], startDate: Date, endDate: Date) => Task[]; /** * Sort tasks by start date * @param tasks - Tasks to sort * @param ascending - Sort ascending (default) or descending * @returns Sorted tasks */ sortByStartDate: (tasks: Task[], ascending?: boolean) => Task[]; /** * Sort tasks by end date * @param tasks - Tasks to sort * @param ascending - Sort ascending (default) or descending * @returns Sorted tasks */ sortByEndDate: (tasks: Task[], ascending?: boolean) => Task[]; /** * Sort tasks by progress * @param tasks - Tasks to sort * @param ascending - Sort ascending (default) or descending * @returns Sorted tasks */ sortByProgress: (tasks: Task[], ascending?: boolean) => Task[]; /** * Calculate total progress across all tasks * @param tasks - Tasks to calculate * @returns Average progress percentage */ calculateTotalProgress: (tasks: Task[]) => number; /** * Get task by path (array of indices in nested structure) * @param tasks - Root tasks * @param path - Array of indices [0, 2, 1] means tasks[0].subtasks[2].subtasks[1] * @returns Task at path or undefined */ getTaskByPath: (tasks: Task[], path: number[]) => Task | undefined; /** * Clone a task deeply (including subtasks) * @param task - Task to clone * @param newId - Optional new ID for the clone * @returns Cloned task */ cloneTask: (task: Task, newId?: string) => Task; /** * Export tasks to PDF format * @param tasks - Tasks to export * @param filename - Optional filename (default: 'gantt-chart.pdf') * @returns Promise */ exportToPDF: (tasks: Task[], filename?: string) => Promise; /** * Export tasks to Excel format * @param tasks - Tasks to export * @param filename - Optional filename (default: 'gantt-chart.xlsx') * @returns Promise */ exportToExcel: (tasks: Task[], filename?: string, options?: { rateMap?: Record; defaultRate?: number; projectName?: string; }) => Promise; /** * Export tasks to Microsoft Project XML format * Compatible with MS Project 2010+ and other project management tools * @param tasks - Tasks to export * @param projectName - Project name (default: 'Gantt Project') * @param filename - Optional filename (default: 'project.xml') * @returns void - Downloads the XML file */ exportToMSProject: (tasks: Task[], projectName?: string, filename?: string) => void; /** * Calculate Critical Path Method (CPM) - identifies tasks with zero slack * @param tasks - All tasks * @returns Array of task IDs on the critical path */ calculateCriticalPath: (tasks: Task[]) => string[]; /** * v5.1.0: Full CPM calculation — returns ES/EF/LS/LF/TF/FF per task * Used by GanttBoard to enrich tasks with cpmData for visual rendering */ calculateCriticalPathFull: (tasks: Task[]) => Map; /** * Calculate slack (float) time for a task * @param tasks - All tasks * @param taskId - Task ID to calculate slack for * @returns Slack in days, or null if cannot be calculated */ calculateSlack: (tasks: Task[], taskId: string) => number | null; /** * Check if a task is on the critical path * @param tasks - All tasks * @param taskId - Task ID to check * @returns True if task is on critical path */ isOnCriticalPath: (tasks: Task[], taskId: string) => boolean; /** * Auto-schedule dependent tasks when a task changes * v0.13.3: Now takes optional daysDelta to shift dependents by same amount (preserves gap) * @param tasks - All tasks * @param changedTaskId - Task that was changed * @param daysDelta - Optional: days the parent moved (for preserving relative gaps) * @returns Updated tasks with rescheduled dependencies */ autoScheduleDependents: (tasks: Task[], changedTaskId: string, daysDelta?: number, _visited?: Set) => Task[]; /** * v0.13.0: Calculate cascade preview positions for dependent tasks during drag * v0.13.3: FIXED - Preview shows ONLY actual movement needed (keeps same relative gap) * Dependents shift by the same daysDelta as their parent, preserving the original gap * @param tasks - All tasks (nested structure) * @param draggedTaskId - Task being dragged * @param daysDelta - How many days the dragged task is being moved * @param flatTasks - Flattened task list with row indices * @param timelineStartDate - Start date of the timeline * @param scaledDayWidth - Width of one day in pixels (already includes zoom: dayWidth * zoom) * @param rowHeight - Height of each row * @param headerHeight - Height of the header * @returns Array of DependentTaskPreview objects */ calculateCascadePreview: (tasks: Task[], draggedTaskId: string, daysDelta: number, flatTasks: Task[], timelineStartDate: Date, scaledDayWidth: number, rowHeight: number, headerHeight: number) => Array<{ taskId: string; taskName: string; originalX: number; previewX: number; width: number; y: number; rowIndex: number; daysDelta: number; color?: string; }>; /** * 🚀 KILLER FEATURE #3: Split a task (create GAP in the middle, like Bryntum/DHTMLX) * Same task, but work is paused for some days then continues * Example: Jan 1-10 → Split at Jan 5 with 3 day gap → Jan 1-4 [GAP] Jan 8-13 * @param tasks - All tasks * @param taskId - Task to split * @param splitDate - Date where gap starts * @param gapDays - Number of days to pause (default: 3) * @returns Updated tasks with split segments */ splitTask: (tasks: Task[], taskId: string, splitDate: Date, gapDays?: number) => Task[]; }; declare const themes$1: Record; /** * Type adapters for converting between ASAKAA Card types and Gantt Task types * @module Gantt/adapters */ /** * Converts an ASAKAA Card to a Gantt Task * * @param card - ASAKAA Card object * @param allCards - All cards in the board (for resolving subtasks) * @param users - Available users for assignee mapping * @returns Gantt Task object */ declare function cardToGanttTask(card: Card$1, allCards?: Card$1[], users?: Array<{ id: string; name: string; initials: string; color: string; }>): Task; /** * Converts a Gantt Task back to an ASAKAA Card (partial update) * Note: This only returns the fields that Gantt can modify * * @param task - Gantt Task object * @param users - Available users for reverse mapping assignees to userIds * @returns Partial Card update object */ declare function ganttTaskToCardUpdate(task: Task, users?: Array<{ id: string; name: string; initials: string; color: string; }>): Partial; /** * Converts an array of Cards to an array of Gantt Tasks * * @param cards - Array of ASAKAA Card objects * @param users - Available users for assignee mapping * @returns Array of Gantt Task objects */ declare function cardsToGanttTasks(cards: Card$1[], users?: Array<{ id: string; name: string; initials: string; color: string; }>): Task[]; /** * Internationalization (i18n) system for GanttBoard * @version 0.15.0 * * Supports English (en) and Spanish (es) out of the box. * Users can provide custom translations via the `locale` config prop. */ type SupportedLocale = 'en' | 'es'; interface GanttTranslations { columns: { taskName: string; startDate: string; endDate: string; duration: string; assignees: string; status: string; progress: string; priority: string; }; toolbar: { today: string; day: string; week: string; month: string; export: string; exportPdf: string; exportPng: string; exportCsv: string; exportExcel: string; exportMsProject: string; undo: string; redo: string; createTask: string; density: string; compact: string; normal: string; spacious: string; filterAll: string; filterIncomplete: string; filterInProgress: string; filterCompleted: string; filter: string; filterBy: string; filterAllDesc: string; filterIncompleteDesc: string; filterInProgressDesc: string; filterCompletedDesc: string; clearFilter: string; hideCompleted: string; toDo: string; wbsLevel: string; wbsAllLevels: string; viewExecution: string; viewOracle: string; simulateScenario: string; projectForecast: string; expectedFinish: string; confidence: string; costAtCompletion: string; delayLabel: string; earlyLabel: string; onTimeLabel: string; budgetOver: string; budgetUnder: string; baselines: string; visibility: string; share: string; copySnapshotLink: string; copied: string; /** 1.9.44 · tooltip del gestor de columnas de la rejilla. */ columns: string; }; contextMenu: { editTask: string; addSubtask: string; markIncomplete: string; setInProgress: string; markComplete: string; duplicateTask: string; splitTask: string; deleteTask: string; }; actions: { edit: string; delete: string; duplicate: string; addSubtask: string; indent: string; outdent: string; moveUp: string; moveDown: string; splitTask: string; linkTasks: string; unlinkTasks: string; }; status: { todo: string; inProgress: string; completed: string; }; labels: { progress: string; duration: string; days: string; day: string; assigned: string; milestone: string; criticalPath: string; subtask: string; task: string; noTasks: string; addTask: string; newTask: string; loading: string; error: string; today: string; week: string; clickToSetDates: string; }; ai: { placeholder: string; thinking: string; suggestions: { moveTask: string; extendTask: string; renameTask: string; setProgress: string; linkTasks: string; createTask: string; deleteTask: string; assignTask: string; }; errors: { taskNotFound: string; invalidDate: string; invalidDuration: string; invalidProgress: string; unknownCommand: string; processingError: string; }; }; export: { projectName: string; ganttTasks: string; taskId: string; taskName: string; startDate: string; endDate: string; isMilestone: string; parentId: string; yes: string; no: string; noTasksToExport: string; }; dateFormat: { short: string; medium: string; long: string; }; } /** * English translations (default) */ declare const en$1: GanttTranslations; /** * Spanish translations */ declare const es$1: GanttTranslations; /** * All available translations */ declare const translations: Record; /** * Get translations for a specific locale * Falls back to English if locale is not found */ declare function getTranslations(locale: SupportedLocale | string): GanttTranslations; /** * Merge custom translations with default translations * Allows partial overrides while keeping defaults for missing keys */ declare function mergeTranslations(locale: SupportedLocale | string, customTranslations?: Partial): GanttTranslations; /** * Context for Gantt internationalization * Default value is English translations */ declare const GanttI18nContext: React$1.Context; /** * Hook to access translations in Gantt components * @returns The current translations object * * @example * ```tsx * function MyGanttComponent() { * const t = useGanttI18n(); * return ; * } * ``` */ declare function useGanttI18n(): GanttTranslations; /** * ListView Component Types * @version 0.18.0 * * v0.18.0: Added dynamic columns, custom fields, context menu support */ /** * Sort direction for list columns */ type SortDirection = 'asc' | 'desc'; /** * Column types supported in ListView * - Standard: name, status, priority, assignees, startDate, endDate, progress, tags, estimatedTime, quotedTime, elapsedTime * - v1.2.0: effortMinutes, timeLoggedMinutes, soldEffortMinutes * - Custom: text, number, date, dropdown, checkbox */ type ColumnType = 'name' | 'status' | 'priority' | 'assignees' | 'startDate' | 'endDate' | 'progress' | 'tags' | 'estimatedTime' | 'quotedTime' | 'elapsedTime' | 'effortMinutes' | 'timeLoggedMinutes' | 'soldEffortMinutes' | 'scheduleVariance' | 'hoursBar' | 'teamLoad' | 'blockers' | 'weight' | 'text' | 'number' | 'date' | 'dropdown' | 'checkbox' | 'multiselect' | 'person' | 'file'; /** * Table column configuration for dynamic columns */ interface TableColumn { /** Unique column identifier */ id: string; /** Column type */ type: ColumnType; /** Display label */ label: string; /** Column width in pixels */ width: number; /** Minimum width */ minWidth?: number; /** Maximum width */ maxWidth?: number; /** Is column visible */ visible: boolean; /** Can be sorted */ sortable?: boolean; /** Can be resized */ resizable?: boolean; /** For custom fields - reference to field definition */ customFieldId?: string; /** v1.9.24: for multiselect - cap on how many options can be picked */ maxSelectable?: number; /** For dropdown type - available options */ options?: string[]; } /** * Custom field definition for user-created fields */ interface CustomFieldDefinition { /** Unique field ID */ id: string; /** Field display name */ name: string; /** Field type */ type: 'text' | 'number' | 'date' | 'dropdown' | 'checkbox'; /** Options for dropdown type */ options?: string[]; /** Default value */ defaultValue?: string | number | boolean | Date; /** Is field required */ required?: boolean; /** Project this field belongs to */ projectId?: string; } /** * Custom field value stored on task */ interface CustomFieldValue { fieldId: string; value: string | number | boolean | Date | null; } /** * Context menu action types */ type ContextMenuAction = 'edit' | 'changeStatus' | 'changePriority' | 'assignUser' | 'duplicate' | 'delete' | 'sortAsc' | 'sortDesc' | 'hideColumn' | 'moveLeft' | 'moveRight'; /** * Context menu state */ interface ContextMenuState { isOpen: boolean; x: number; y: number; type: 'task' | 'header'; task?: Task; columnId?: string; } /** * Sortable columns in the list view * @deprecated Use ColumnType instead */ type ListSortColumn = 'name' | 'startDate' | 'endDate' | 'progress' | 'status' | 'assignees' | 'priority'; /** * Sort configuration */ interface ListSort { column: ListSortColumn; direction: SortDirection; } /** * Filter configuration for list view */ interface ListFilter { search?: string; status?: Array<'todo' | 'in-progress' | 'completed'>; assignees?: string[]; dateRange?: { start: Date; end: Date; }; showCompleted?: boolean; } /** * Column configuration for list view */ interface ListColumn { id: ListSortColumn | 'actions'; label: string; width: number; minWidth?: number; maxWidth?: number; visible: boolean; sortable: boolean; resizable?: boolean; } /** * Theme configuration for list view */ interface ListViewTheme { bgPrimary: string; bgSecondary: string; bgHover: string; bgSelected: string; bgAlternate: string; border: string; borderLight: string; textPrimary: string; textSecondary: string; textMuted: string; accent: string; accentHover: string; accentLight: string; statusTodo: string; statusInProgress: string; statusCompleted: string; focusRing: string; checkboxBg: string; checkboxChecked: string; bgGroupHeader: string; headerBg: string; neonRed: string; neonGreen: string; neonAmber: string; neonBlue: string; } /** * Permissions for list view operations */ interface ListViewPermissions { canCreateTask?: boolean; /** v1.4.10: When true, user can only create subtasks (not root-level tasks) */ canCreateSubtaskOnly?: boolean; canUpdateTask?: boolean; canDeleteTask?: boolean; canBulkSelect?: boolean; canExport?: boolean; canSort?: boolean; canFilter?: boolean; canReorder?: boolean; } /** * v2.0.0: Project Health data for sidebar panel */ interface ProjectHealthData { openRFIs?: number; submittalsApprovalPercent?: number; scheduleVarianceDays?: number; scheduleVarianceLabel?: string; teams?: Array<{ name: string; color: string; utilizationPercent: number; }>; /** Total hours for the whole project (spent / allocated in minutes) */ totalHoursSpentMinutes?: number; totalHoursAllocatedMinutes?: number; /** Count of tasks with no assignees and progress < 100% */ unassignedCount?: number; /** Unassigned tasks (id + name for detail display + click-to-scroll in sidebar) */ unassignedTasks?: Array<{ id: string; name: string; }>; /** Financial data — shown when lens='financial' */ totalOffered?: number; totalEstimated?: number; /** v2.6.0 — Labor-only portion of the estimated cost (for breakdown tooltip) */ totalEstimatedLabor?: number; /** v2.6.0 — Equipment portion of the estimated cost (for breakdown tooltip) */ totalEstimatedEquipment?: number; /** v2.6.0 — Travel/per-diem portion of the estimated cost (for breakdown tooltip) */ totalEstimatedTravel?: number; totalExecuted?: number; /** v2.6.0 — Labor-only portion of the executed cost (for breakdown tooltip) */ totalExecutedLabor?: number; /** v2.6.0 — Equipment portion of the executed cost (for breakdown tooltip) */ totalExecutedEquipment?: number; /** v2.6.0 — Travel/per-diem portion of the executed cost (for breakdown tooltip) */ totalExecutedTravel?: number; offeredRate?: number; } /** * ListView configuration */ interface ListViewConfig { /** * v1.9.25 — Hide financial indicators entirely, not just blur them. * * Mesh (the simplified product) must not show ANY financial term: not a * budget, not a margin, and not an SPI badge either. Blurring is not enough * — the label «Avg SPI» IS the problem, whatever the number reads. * * Defaults to true so existing consumers keep the badge they have. */ mostrarIndicadoresFinancieros?: boolean; /** * v1.9.27 — ¿se OFRECEN las columnas densas en el selector? * * Estimado, ejecutado, ofertado y peso. Va aparte de * `mostrarIndicadoresFinancieros` A PROPOSITO: son DOS MOTIVOS DISTINTOS. * Lo financiero se esconde por CONFIDENCIALIDAD; estas por SIMPLICIDAD —una * lista con cuatro columnas de minutos deja de leerse—. Un cliente podria * querer una cosa sin la otra. * * Por defecto `true`: no cambia a quien ya lo usaba. */ mostrarColumnasDensas?: boolean; /** Theme: 'dark' | 'light' | 'neutral' */ theme?: 'dark' | 'light' | 'neutral'; /** Locale for i18n */ locale?: 'en' | 'es' | string; /** Custom translations */ customTranslations?: Partial; /** Enable row selection */ enableSelection?: boolean; /** Enable multi-select with checkboxes */ enableMultiSelect?: boolean; /** Show search bar */ showSearch?: boolean; /** Show filters */ showFilters?: boolean; /** Show hierarchy indentation */ showHierarchy?: boolean; /** Columns to display (legacy) */ columns?: ListColumn[]; /** Row height in pixels */ rowHeight?: number; /** Available users for filtering */ availableUsers?: User$1[]; /** Permissions */ permissions?: ListViewPermissions; /** Enable virtual scrolling for large lists */ enableVirtualization?: boolean; /** Items per page (0 = no pagination) */ pageSize?: number; /** Dynamic table columns configuration */ tableColumns?: TableColumn[]; /** Allow user to add/remove/reorder columns via "+" button */ allowColumnCustomization?: boolean; /** Allow user to resize columns by dragging */ allowColumnResize?: boolean; /** Enable context menu on right-click */ enableContextMenu?: boolean; /** Show create task button in toolbar */ showCreateTaskButton?: boolean; /** Callback when create task button is clicked */ onCreateTask?: () => void; /** LocalStorage key for persisting filter state, or false to disable */ persistFilter?: string | false; /** Configuration for project health sidebar panel */ healthSidebar?: { enabled: boolean; data: ProjectHealthData; }; /** Aggregate child hours into parent row hoursBar cell (default: false) */ aggregateParentHours?: boolean; /** * Configuration for blurring financial data based on user permissions * When enabled, financial columns (soldEffortMinutes, quotedTime) will be blurred */ financialBlur?: { /** Whether to blur financial time columns */ enabled: boolean; /** Specific columns to blur (defaults to ['soldEffortMinutes', 'quotedTime'] if not specified) */ columns?: Array<'soldEffortMinutes' | 'quotedTime' | 'quotedTimeMinutes'>; }; /** When true, shows the sold effort line in HoursBarCell even without onSoldEffortUpdate callback */ showSoldEffort?: boolean; /** Display mode: 'hours' shows time values, 'financial' converts to dollars (hours × hourlyRate) */ lens?: 'hours' | 'financial'; /** Hourly rate for converting hours → dollars when lens='financial' (fallback when rateMap has no match) */ hourlyRate?: number; /** Per-user hourly rate map (userId → rate). When provided, uses the task assignee's rate instead of the global hourlyRate */ rateMap?: Record; /** Show a sticky "TOTAL PROJECT" row at the bottom of the list */ showProjectTotals?: boolean; /** * v2.5.2: Canonical dollar totals override for the TOTAL PROJECT footer. * When provided, replaces the internally-computed dollar totals (which * multiply task.timeLoggedMinutes by current assignee rates) with the * consumer's authoritative figures — typically sourced from time_logs × * rate_at_time. Lets the footer stay in sync with the Portfolio view * and the financial health sidebar, which use frozen per-log rates. * Hours totals (spent/allocated/quoted in minutes) remain computed * internally from the rendered task tree. */ totalsDollarOverride?: { spent?: number; allocated?: number; quoted?: number; /** * Optional breakdown of the override totals into their components so the * footer can surface a tooltip explaining why the TOTAL differs from the * sum of the visible phase rows (which only count labor). * - labor: Σ(task minutes × rate) — the portion the phase rows show * - equipment / travel: committed project-level costs not tied to tasks */ breakdown?: { laborSpent?: number; laborAllocated?: number; equipment?: number; travel?: number; }; }; /** v2.5.0: Render content just before the Create Task button (e.g., share/export dropdown) */ toolbarEndContent?: ReactNode; /** * 1.9.34 · Pinta la barra de herramientas DENTRO de este elemento (por * portal) y en versión compacta: sin buscador (lo hace el de la app) ni * botón de crear. Para cabeceras de una sola fila. */ toolbarContainer?: HTMLElement | null; /** * 1.9.38 · la app decide qué es «vencida» (su zona, su regla de terminada). * Con ella, la fecha de fin vencida sale en rojo con icono y la celda lleva * `data-vencida`. Sin ella, nada cambia. */ isTaskOverdue?: (task: Task) => boolean; /** 1.9.38 · cómo se ve una completada: 'strike' (tachada, por defecto) o 'dim' (atenuada, sin tachar). */ completedStyle?: 'strike' | 'dim'; /** 1.9.38 · 'compact': filas de una línea y 40 px; 'comfortable' (por defecto) las de dos líneas y 56 px. */ rowDensity?: 'comfortable' | 'compact'; /** * 1.9.39 · `false` quita el botón «Filters» (estado / ocultar completadas) de * la barra, para la app que tiene su propio sistema de filtros. Por defecto se pinta. */ showStatusFilter?: boolean; /** * 1.9.40 · 'status' agrupa las tareas raíz en To do · In progress · Completed * (las subtareas van con su padre); dentro, por fin ascendente. Por defecto, sin agrupar. */ groupBy?: 'none' | 'status' | 'assignee' | 'due'; /** * 1.9.44 · con groupBy 'due', a qué grupo va cada tarea. La regla la pone la app * (la de vencida del Overview). Sin ella, todas caen en 'none' (Sin fecha). */ dueBucket?: (task: Task) => 'overdue' | 'today' | 'week' | 'later' | 'past' | 'none'; /** 1.9.40 · grupos plegados al empezar (por defecto ['completed']). */ defaultCollapsedGroups?: string[]; /** 1.9.40 · si se da, qué grupos están plegados se recuerda en localStorage con esta clave. */ groupStateKey?: string; /** 1.9.41 · una casilla por fila y Shift+clic para un rango; avisa con callbacks.onSelectionChange. */ selectable?: boolean; /** 1.9.41 · selección controlada por la app (p. ej. para vaciarla tras una acción en masa). */ selectedIds?: string[]; } /** * ListView translations */ interface ListViewTranslations { columns: { name: string; startDate: string; endDate: string; progress: string; status: string; assignees: string; priority: string; actions: string; estimatedTime?: string; quotedTime?: string; elapsedTime?: string; tags?: string; scheduleVariance?: string; hoursBar?: string; teamLoad?: string; blockers?: string; weight?: string; }; toolbar: { search: string; searchPlaceholder: string; filter: string; clearFilters: string; export: string; columns: string; newTask: string; }; filters: { status: string; assignees: string; dateRange: string; showCompleted: string; all: string; none: string; }; status: { todo: string; inProgress: string; completed: string; }; actions: { edit: string; delete: string; duplicate: string; viewDetails: string; }; empty: { noTasks: string; noResults: string; addFirstTask: string; }; pagination: { showing: string; of: string; tasks: string; previous: string; next: string; }; bulk: { selected: string; delete: string; move: string; assignTo: string; }; } /** * Callback functions for ListView */ interface ListViewCallbacks { /** Task click handler */ onTaskClick?: (task: Task) => void; /** Task double-click handler */ onTaskDoubleClick?: (task: Task) => void; /** Task update handler */ onTaskUpdate?: (task: Task) => void; /** Task delete handler */ onTaskDelete?: (taskId: string) => void; /** Task create handler */ onTaskCreate?: (parentId?: string) => void; /** Bulk delete handler */ onBulkDelete?: (taskIds: string[]) => void; /** Sort change handler */ onSortChange?: (sort: ListSort) => void; /** Filter change handler */ onFilterChange?: (filter: ListFilter) => void; /** Selection change handler */ onSelectionChange?: (selectedIds: string[]) => void; /** Row expand/collapse handler */ onTaskToggleExpand?: (taskId: string) => void; /** Export handler */ onExport?: (format: 'csv' | 'json' | 'excel') => void; /** Columns configuration changed (visibility, order, width) */ onColumnsChange?: (columns: TableColumn[]) => void; /** Task edit requested (from context menu) */ onTaskEdit?: (task: Task) => void; /** Task duplicate requested (from context menu) */ onTaskDuplicate?: (task: Task) => void; /** v2.5.0: Move task up in hierarchy */ onTaskMove?: (taskId: string, direction: 'up' | 'down') => void; /** v2.5.0: Indent task (make it a subtask of the task above) */ onTaskIndent?: (taskId: string) => void; /** v2.5.0: Outdent task (move it up one hierarchy level) */ onTaskOutdent?: (taskId: string) => void; /** v2.5.0: Reparent task (drag & drop to make subtask or reorder) */ onTaskReparent?: (taskId: string, newParentId: string | null, position?: number) => void; /** Create custom field */ onCreateCustomField?: (field: CustomFieldDefinition) => Promise; /** Handler for inline time logging - receives task, minutes, and optional note */ onLogTime?: (task: Task, minutes: number | null, note?: string) => void; /** Handler for opening time log modal from HoursBar cell */ onOpenTimeLog?: (task: Task) => void; /** Handler for updating task effort estimate (minutes) */ onEstimateUpdate?: (task: Task, minutes: number | null) => void; /** Handler for updating task sold/quoted effort (minutes) */ onSoldEffortUpdate?: (task: Task, minutes: number | null) => void; /** Handler for reporting a blocker on a task */ onReportBlocker?: (task: Task) => void; /** Handler for copying task link to clipboard */ onCopyTaskLink?: (task: Task) => void; /** Drag-fill (Excel-style): a value dragged from one cell was applied to * many tasks at once. * * `column` is either a built-in task property name or, since v1.9.28, a * `{ kind: 'customField', fieldId }` descriptor. The two are NOT * interchangeable: a built-in one names a property of the task, while a * custom field's value lives outside the task (in the host's own store), so * the host must persist it by its own route. Handlers written before 1.9.28 * only knew the string form — check `typeof column === 'string'` before * treating it as a property name. */ onBulkFill?: (taskIds: string[], column: FillColumn, value: any) => void; } /** * Qué columna se está rellenando en un arrastre (v1.9.28). * * Las de la izquierda son propiedades de la tarea; la de la derecha NO lo es * — el valor de un campo personalizado vive fuera del objeto `Task`, así que * el anfitrión tiene que guardarlo por su propia ruta. */ type FillColumn = 'assignees' | 'startDate' | 'endDate' | { kind: 'customField'; fieldId: string; }; /** * Available user for assignment */ interface AvailableUser { id: string; name: string; email?: string; avatarUrl?: string; color?: string; /** v1.4.0: Workload indicator for Smart Dropdown */ workload?: UserWorkload; } /** * v1.4.0: User workload indicator for Smart Dropdown * Shows user capacity in the assignment dropdown */ interface UserWorkload { /** Total hours assigned this week */ assignedHoursThisWeek: number; /** Total hours capacity per week (typically 40) */ weeklyCapacity: number; /** Number of active tasks assigned */ activeTasks: number; /** Workload level for visual indicator */ level: 'light' | 'moderate' | 'heavy' | 'overloaded'; } /** * Main ListView props */ interface ListViewProps { /** Tasks to display */ tasks: Task[]; /** Configuration */ config?: ListViewConfig; /** Callbacks */ callbacks?: ListViewCallbacks; /** Loading state */ isLoading?: boolean; /** Error state */ error?: Error | string; /** Custom CSS class */ className?: string; /** Inline styles */ style?: React.CSSProperties; /** Available users for assignment in context menu */ availableUsers?: AvailableUser[]; /** Custom fields defined for this project */ customFields?: CustomFieldDefinition[]; /** Render custom content on the right side of toolbar (before create button) */ toolbarRightContent?: ReactNode; /** v2.5.0: Render content just before the Create Task button (e.g., share/export dropdown) */ toolbarEndContent?: ReactNode; /** * 1.9.34 · Pinta la barra de herramientas DENTRO de este elemento (por * portal) y en versión compacta: sin buscador (lo hace el de la app) ni * botón de crear. Para cabeceras de una sola fila. */ toolbarContainer?: HTMLElement | null; /** * Fires when the user clicks anywhere on a column header. The consumer * renders its own dropdown (Sort + Filter + Hide) anchored to `anchorRect`. * If unset, the header keeps the legacy behavior (click on the sort icon * cycles asc/desc/clear). */ onColumnHeaderClick?: (columnId: string, anchorRect: DOMRect) => void; /** * IDs of columns that currently have an active filter applied. Each one * gets a small accent dot rendered next to its label. */ columnsWithFilter?: string[]; /** * Color (hex / CSS) of the dot rendered for filtered columns. Defaults * to the brand cyan #00E5CC so consumers don't have to think about it. */ filterDotColor?: string; } /** * Flattened task with hierarchy info */ interface FlattenedTask extends Task { level: number; hasChildren: boolean; parentPath: string[]; } /** * Default columns configuration * Used when no tableColumns are provided */ declare const DEFAULT_TABLE_COLUMNS: TableColumn[]; /** * Standard field definitions (non-custom) * Used in column selector to show available fields */ declare const STANDARD_FIELDS: Array<{ type: ColumnType; labelKey: string; icon: string; }>; /** * Custom field type definitions * Used in "Create Field" modal */ declare const CUSTOM_FIELD_TYPES: Array<{ type: CustomFieldDefinition['type']; labelKey: string; icon: string; }>; /** * Main ListView Component */ declare function ListView({ tasks, config, callbacks, isLoading, error, className, style, availableUsers, customFields, toolbarRightContent, onColumnHeaderClick, columnsWithFilter, filterDotColor, }: ListViewProps): react_jsx_runtime.JSX.Element; /** * ListView Themes * @version 2.0.0 — Chronos V2.0 visual language */ /** * Dark theme for ListView — Chronos V2.0 */ declare const darkTheme$2: ListViewTheme; /** * Light theme for ListView */ declare const lightTheme$2: ListViewTheme; /** * Neutral theme for ListView */ declare const neutralTheme$2: ListViewTheme; /** * All available themes */ declare const listViewThemes: { readonly dark: ListViewTheme; readonly light: ListViewTheme; readonly neutral: ListViewTheme; }; type ListViewThemeName = keyof typeof listViewThemes; /** * Get theme by name */ declare function getListViewTheme(themeName: ListViewThemeName): ListViewTheme; /** * Internationalization (i18n) for ListView * @version 0.17.0 */ type ListViewSupportedLocale = 'en' | 'es'; /** * English translations */ declare const en: ListViewTranslations; /** * Spanish translations */ declare const es: ListViewTranslations; /** * All available translations */ declare const listViewTranslations: Record; /** * Get translations for a specific locale */ declare function getListViewTranslations(locale: ListViewSupportedLocale | string): ListViewTranslations; /** * Merge custom translations with default translations */ declare function mergeListViewTranslations(locale: ListViewSupportedLocale | string, customTranslations?: Partial): ListViewTranslations; /** * Motor de layout del Calendario (Asakaa Pulse) — Sprint 1. * * Convierte tareas reales (del Gantt) en barras posicionadas por semana, y los * elementos de día (hitos/desembolsos/vencimientos/externos/ausencias) en chips, * empaquetándolos en "lanes" sin solaparse — fiel a layoutWeek del diseño de * referencia (cal-data.js). Solo lectura. * * El calendario usa un "serial" de día: índice continuo dentro del mes visible * (1..N), con lunes = columna 0. Esto permite posicionar barras que cruzan * semanas con muescas de continuación. */ type DayItemType = 'hito' | 'desembolso' | 'deadline' | 'ext' | 'aus'; interface CalTask { uid: string; id: string; name: string; projectId: string; /** * v1.9.25 — color propio del evento, que gana sobre el del proyecto. * * P1 §6.4: «un campo de selección puede elegirse para colorear los * eventos». Hasta ahora el calendario solo coloreaba por proyecto, así que * esa regla no se podía cumplir sin tocar la librería. */ color?: string; startSerial: number; endSerial: number; hrs: number; cost: string; critical: boolean; who?: string; realStart: Date; realEnd: Date; /** fase = tarea-padre RAÍZ del WBS (para el filtro "Fase"). uid de la raíz; * si la tarea es de primer nivel, su propia fase es ella misma. */ phaseId?: string; phaseName?: string; /** 1.9.42 · estado para los chips del modo vencimiento. */ done?: boolean; overdue?: boolean; milestone?: boolean; /** 1.9.42 · tarea padre (contenedor): el modo vencimiento no la pinta. */ container?: boolean; } interface DayItem { serial: number; type: DayItemType; label: string; } interface MonthGrid { /** Fecha del primer día visible (puede ser de mes anterior, siempre lunes). */ gridStart: Date; /** Semanas como rangos de serial [ws, we], 6 semanas máximo. */ weeks: Array<{ ws: number; we: number; }>; /** serial → Date */ serialToDate: (serial: number) => Date; /** Date → serial dentro de la grid (o null si fuera). */ dateToSerial: (d: Date) => number; /** serial del primer día del mes objetivo (para detectar "out"). */ monthStartSerial: number; monthEndSerial: number; } /** * Calendario (Asakaa Pulse) — componentes de presentación puros (Sprint 1, solo lectura). * * Traducción a TSX de cal-components.jsx, fiel al diseño aprobado. Sin estado, * sin drag/resize: solo pintan barras de tarea, chips de día, "+N más" y la * leyenda usando las clases .cal-* de calendar.css y el motor de calendarLayout.ts. * * El color de cada proyecto NO se inventa: se recibe vía la prop `projects` * (mapa projectId → color CSS) y se inyecta en la barra como variable `--proj`. */ /** Modo del valor mostrado en el extremo de la barra. */ type MoneyMode = '$' | 'Hrs'; type CalView = 'mes' | 'semana' | 'lookahead' | 'agenda'; type CalMoney = 'hrs' | '$'; type CalLayerId = 'tareas' | 'cpm' | 'hitos' | 'ext' | 'festivos' | 'aus'; interface DailyLog { date: string; hours: number; } interface TeamMember { userId: string; name: string; weeklyCapacity?: number; dailyEstimated: DailyLog[]; } interface Props { /** 1.9.34 · las vistas (Month/Week/Agenda) se pintan dentro de este elemento: cabeceras de una fila. */ toolbarContainer?: HTMLElement | null; /** 1.9.34 · vistas que no se ofrecen en el selector (p. ej. ['lookahead']). */ hiddenViews?: CalView[]; tasks: Task[]; projectName: string; projectId: string; projectColor?: string; workspaceId?: string; locale: 'es' | 'en'; /** 'light' aplica la paleta clara; cualquier otro = oscuro. */ themeMode?: 'dark' | 'light'; hourlyRate: number; /** * ═══ EL FILTRO DE FASES ═════════════════════════════════════════════════ * * Divar, 27-ago (punto 17 de la lista de Juan): en el producto simplificado * no va. * * Las «fases» son las tareas-padre raíz, y filtrar por ellas tiene sentido * en un proyecto de obra con estructura WBS. En uno de tareas simples es un * desplegable que casi siempre está vacío. * * Por defecto SÍ se muestra: quien no pase nada se comporta como siempre. */ mostrarFiltroDeFases?: boolean; /** REQ-07 §2.7 · el par «Hrs / $» del calendario. Ver `CalendarChrome`. */ mostrarConmutadorDeDinero?: boolean; /** * REQ-07 §2.5: crear la primera tarea desde el estado vacio del mes. * Sin esto el mensaje describe pero no ofrece salida. */ onCreateTask?: () => void; /** money compartido con Gantt/Lista (lens global). */ money: MoneyMode; onMoneyChange: (m: MoneyMode) => void; /** abrir el drawer global de tarea. */ onTaskOpen?: (taskId: string) => void; /** contenido extra a la derecha de la topbar (historial, etc.). */ rightContent?: React.ReactNode; /** S3 (C5): ¿el usuario puede reprogramar? Si no, el calendario es solo lectura. */ canReschedule?: boolean; /** S3 (C5): commit del movimiento (la tarea + sus sucesoras). Devuelve éxito. */ onReschedule?: (changes: Array<{ id: string; startDate: Date; endDate: Date; }>) => Promise; /** miembros con su carga diaria (de useTeamCapacity en el SaaS). */ members?: TeamMember[]; /** festivos del workspace como 'YYYY-MM-DD' (de useHolidays en el SaaS). */ holidayDates?: string[]; /** jornada del workspace (de timesheetSettings) — capacidad diaria por persona. */ timesheetSettings?: { hoursPerDay?: Record; }; /** se llama cuando cambia el rango visible (mes) para que el consumidor * recargue la capacidad de ese rango. */ onVisibleRangeChange?: (range: { start: string; end: string; }) => void; /** * 1.9.42 · 'due': el Mes responde «qué vence cada día» — un chip por tarea en * su fecha de fin, tantos como quepan y «+N more»; la rejilla llena el alto sin * scroll. 'span' (por defecto): las barras de siempre. */ monthMode?: 'span' | 'due'; /** * 1.9.44 · abrir SIEMPRE en el mes de hoy (Yesid, 2-oct). Sin esto se mantiene * REQ-07 §2.5: si el mes actual no tiene tareas, abrir en el de la primera. */ openOnToday?: boolean; /** 1.9.42 · `false`: ni horas ni coste en las barras. */ showValues?: boolean; } declare function CalendarView({ tasks, projectName, projectId, projectColor, locale, themeMode, hourlyRate, money, onMoneyChange, onTaskOpen, toolbarContainer, hiddenViews, mostrarFiltroDeFases, mostrarConmutadorDeDinero, onCreateTask, canReschedule, onReschedule, members, holidayDates, timesheetSettings, onVisibleRangeChange, monthMode, showValues, openOnToday, }: Props): react_jsx_runtime.JSX.Element; /** * Simulación de reprogramación con CPM (Calendario, Sprint 3, regla C5). * * Dado un movimiento de fechas de UNA tarea, calcula —sobre una copia en * memoria, SIN persistir— la consecuencia: qué sucesoras se desplazan, cuánto * cambia el fin de proyecto, y si la tarea es/sigue en ruta crítica. * * Reutiliza el modelo de dependencias del Gantt (task.dependencies). NO duplica * el commit: confirmar usa el endpoint real (updateTask) — esto es solo el * "forward pass" en simulación para mostrar el popover de impacto. */ interface RescheduleSimulation { taskId: string; oldStart: Date; oldEnd: Date; newStart: Date; newEnd: Date; /** sucesoras que se mueven por respetar dependencias (id + nombre + nuevas fechas). */ movedSuccessors: Array<{ id: string; name: string; newStart: Date; newEnd: Date; }>; /** delta del fin de proyecto en días (>0 lo retrasa, 0 = absorbido por holgura). */ projectEndDeltaDays: number; oldProjectEnd: Date; newProjectEnd: Date; /** ¿la tarea movida estaba en ruta crítica antes del movimiento? */ wasCritical: boolean; /** ¿sigue en ruta crítica tras el movimiento? */ stillCritical: boolean; /** holgura (días) de la tarea antes del movimiento (informativo). */ slackDays: number; } /** * Simula mover una tarea a [newStart, newEnd]. Devuelve el impacto SIN persistir. */ declare function simulateReschedule(tasks: Task[], taskId: string, newStart: Date, newEnd: Date): RescheduleSimulation | null; /** * Mapeo de datos reales del Gantt → estructuras del Calendario (Sprint 1). * * Toma las tareas reales (LibXAITask) que ya carga ProjectCalendar y las * proyecta sobre la grilla del mes visible como barras (CalTask). NO inventa * datos: hitos/desembolsos/externos/ausencias solo aparecen si hay fuente real * (en S1 derivamos "vencimientos" de tareas que terminan en el mes; el resto * llega cuando existan sus entidades — S2/S3). */ interface BuildOpts { tasks: Task[]; grid: MonthGrid; /** projectId → color (CSS). En vista de un proyecto, un solo color. */ projectColor: (projectId: string) => string; /** tarifa media para estimar costo cuando no hay costo explícito. */ hourlyRate: number; /** id de proyecto de las tareas (el calendario es por proyecto en S1). */ projectId: string; } interface BuiltCalendar { calTasks: CalTask[]; dayItems: DayItem[]; /** ¿el mes visible tiene algo que mostrar? (para estado vacío C13) */ isEmpty: boolean; } /** * Construye las barras (y items derivados) para el mes visible de la grilla. * Recorta tareas a la ventana de la grilla; las que no intersectan se omiten. */ declare function buildCalendar(opts: BuildOpts): BuiltCalendar; interface CardStackProps { /** Stack configuration */ stack: CardStack$1; /** All cards in the board */ cards: Card$1[]; /** Card render function */ renderCard?: (card: Card$1) => React.ReactNode; /** Click handler for individual cards */ onCardClick?: (card: Card$1) => void; /** Expand/collapse handler */ onToggleExpand?: (stackId: string) => void; /** Unstack handler (remove card from stack) */ onUnstack?: (stackId: string, cardId: string) => void; /** Delete entire stack handler */ onDeleteStack?: (stackId: string) => void; /** Custom className */ className?: string; } /** * CardStack - Collapsible group of related cards */ declare function CardStack({ stack, cards, renderCard, onCardClick, onToggleExpand, onUnstack, onDeleteStack, className, }: CardStackProps): react_jsx_runtime.JSX.Element; /** * Card History & Time Travel Types * Tracks all changes to cards with full reproducibility * @module types/card-history */ /** * Types of events that can occur in a card's history */ type CardHistoryEventType = 'created' | 'status_changed' | 'assignee_changed' | 'priority_changed' | 'moved' | 'title_updated' | 'description_updated' | 'dates_changed' | 'labels_changed' | 'dependency_added' | 'dependency_removed' | 'comment_added' | 'archived' | 'restored'; /** * Represents a single change in a card's history */ interface CardHistoryEvent { /** Unique event ID */ id: string; /** Card this event belongs to */ cardId: string; /** When the event occurred */ timestamp: Date; /** Type of change */ type: CardHistoryEventType; /** User who made the change */ userId: string; /** User display name (for UI) */ userName?: string; /** User avatar URL (for UI) */ userAvatar?: string; /** Detailed changes (before/after) */ changes: Record; /** Additional context */ metadata?: { /** Column names for moves */ fromColumn?: string; toColumn?: string; /** Comment text for comment events */ commentText?: string; /** Reason for change */ reason?: string; /** Related card IDs */ relatedCards?: string[]; }; } /** * Filter configuration for history events */ interface HistoryFilter { /** Filter by event types */ types?: CardHistoryEventType[]; /** Filter by users */ users?: string[]; /** Filter by date range */ dateRange?: { start: Date; end: Date; }; /** Search in change descriptions */ searchTerm?: string; } /** * State for the replay/time-travel feature */ interface ReplayState { /** Current position in history (0 = oldest, length-1 = newest) */ currentIndex: number; /** Is replay actively playing */ isPlaying: boolean; /** Playback speed (1 = normal, 2 = 2x, etc.) */ speed: number; /** Card state at current index */ cardState: Card$1; /** Total number of events */ totalEvents: number; /** Can go back */ canGoBack: boolean; /** Can go forward */ canGoForward: boolean; } /** * Timeline visualization configuration */ interface TimelineConfig { /** Show event icons */ showIcons: boolean; /** Show user avatars */ showAvatars: boolean; /** Group events by day */ groupByDay: boolean; /** Show relative times (e.g. "2 hours ago") */ useRelativeTime: boolean; /** Compact mode (less spacing) */ compact: boolean; } interface CardHistoryTimelineProps { /** History events to display */ events: CardHistoryEvent[]; /** Current filter */ filter: HistoryFilter; /** Update filter */ onFilterChange: (filter: HistoryFilter) => void; /** Clear filter */ onClearFilter: () => void; /** Click on event */ onEventClick?: (event: CardHistoryEvent) => void; /** Selected event ID */ selectedEventId?: string; /** Timeline configuration */ config?: Partial; /** Custom className */ className?: string; } /** * Timeline component showing card history */ declare function CardHistoryTimeline({ events, filter, onFilterChange, onClearFilter, onEventClick, selectedEventId, config: customConfig, className, }: CardHistoryTimelineProps): react_jsx_runtime.JSX.Element; interface CardHistoryReplayProps { /** Current replay state */ replayState: ReplayState | null; /** All history events */ events: CardHistoryEvent[]; /** Start replay */ onStartReplay: () => void; /** Stop replay */ onStopReplay: () => void; /** Toggle play/pause */ onTogglePlayback: () => void; /** Go to previous event */ onPrevious: () => void; /** Go to next event */ onNext: () => void; /** Go to specific event */ onGoToEvent: (index: number) => void; /** Change playback speed */ onSpeedChange: (speed: number) => void; /** Custom className */ className?: string; } /** * Replay controls for time-travel functionality */ declare function CardHistoryReplay({ replayState, events, onStartReplay, onStopReplay, onTogglePlayback, onPrevious, onNext, onGoToEvent, onSpeedChange, className, }: CardHistoryReplayProps): react_jsx_runtime.JSX.Element; /** * Card Relationships & Graph Types * Force-directed graph visualization for card dependencies and relationships * @module types/card-relationships */ /** * Types of relationships between cards */ type RelationshipType = 'blocks' | 'blocked_by' | 'depends_on' | 'required_by' | 'relates_to' | 'duplicates' | 'parent_of' | 'child_of' | 'similar_to'; /** * Node in the relationship graph */ interface GraphNode { /** Card ID */ id: string; /** Card reference */ card: Card$1; /** X position (calculated by force simulation) */ x?: number; /** Y position (calculated by force simulation) */ y?: number; /** X velocity (for force simulation) */ vx?: number; /** Y velocity (for force simulation) */ vy?: number; /** Fixed position (prevent movement) */ fx?: number | null; /** Fixed position (prevent movement) */ fy?: number | null; /** Node degree (number of connections) */ degree?: number; /** Is this node on the critical path */ onCriticalPath?: boolean; /** Cluster ID (for grouping) */ clusterId?: string; } /** * Edge in the relationship graph */ interface GraphEdge { /** Relationship ID */ id: string; /** Source node ID */ source: string | GraphNode; /** Target node ID */ target: string | GraphNode; /** Relationship type */ type: RelationshipType; /** Edge strength (for styling) */ strength?: number; /** Is this edge on the critical path */ onCriticalPath?: boolean; } /** * Graph layout algorithms */ type GraphLayout = 'force' | 'hierarchical' | 'circular' | 'radial' | 'grid'; /** * Graph visualization configuration */ interface GraphConfig { /** Layout algorithm */ layout: GraphLayout; /** Width of the graph container */ width: number; /** Height of the graph container */ height: number; /** Enable node dragging */ enableDragging: boolean; /** Enable zoom and pan */ enableZoom: boolean; /** Show node labels */ showLabels: boolean; /** Show edge labels */ showEdgeLabels: boolean; /** Highlight critical path */ highlightCriticalPath: boolean; /** Node size */ nodeSize: number; /** Edge width */ edgeWidth: number; /** Animation duration */ animationDuration: number; /** Force simulation strength */ forceStrength: number; /** Link distance */ linkDistance: number; /** Charge strength (repulsion) */ chargeStrength: number; /** Center force strength */ centerForce: number; /** Color scheme */ colorScheme: 'status' | 'priority' | 'assignee' | 'cluster'; } /** * Graph filters */ interface GraphFilter { /** Filter by relationship types */ types?: RelationshipType[]; /** Filter by card IDs */ cardIds?: string[]; /** Filter by columns */ columnIds?: string[]; /** Minimum relationship strength */ minStrength?: number; /** Show only critical path */ criticalPathOnly?: boolean; /** Maximum depth from selected node */ maxDepth?: number; } /** * Critical path analysis result */ interface CriticalPath { /** Cards on the critical path */ cardIds: string[]; /** Relationships on the critical path */ relationshipIds: string[]; /** Total estimated time */ totalDuration: number; /** Bottleneck cards */ bottlenecks: string[]; } /** * Graph statistics */ interface GraphStats { /** Total nodes */ totalNodes: number; /** Total edges */ totalEdges: number; /** Average degree */ averageDegree: number; /** Density (0-1) */ density: number; /** Number of clusters */ clusters: number; /** Isolated nodes (no connections) */ isolatedNodes: string[]; /** Hub nodes (most connections) */ hubNodes: Array<{ cardId: string; degree: number; }>; /** Most common relationship type */ mostCommonRelationType: RelationshipType; } /** * Graph interaction event */ interface GraphInteraction { /** Event type */ type: 'node-click' | 'node-hover' | 'edge-click' | 'edge-hover' | 'canvas-click'; /** Selected node */ node?: GraphNode; /** Selected edge */ edge?: GraphEdge; /** Mouse position */ position?: { x: number; y: number; }; } interface CardRelationshipsGraphProps { /** Graph nodes */ nodes: GraphNode[]; /** Graph edges */ edges: GraphEdge[]; /** Graph configuration */ config: GraphConfig; /** Current filter */ filter: GraphFilter; /** Update filter */ onFilterChange: (filter: GraphFilter) => void; /** Critical path */ criticalPath: CriticalPath | null; /** Graph statistics */ stats: GraphStats; /** Interaction callback */ onInteraction?: (interaction: GraphInteraction) => void; /** Custom className */ className?: string; } /** * Graph visualization component */ declare function CardRelationshipsGraph({ nodes, edges, config, filter: _filter, onFilterChange: _onFilterChange, criticalPath, stats, onInteraction, className, }: CardRelationshipsGraphProps): react_jsx_runtime.JSX.Element; interface GeneratePlanModalProps { /** Is modal open */ isOpen: boolean; /** Close handler */ onClose: () => void; /** Plan generated callback */ onPlanGenerated: (plan: GeneratedPlan) => void; /** Generate plan function (from useAI hook) */ onGeneratePlan: (prompt: string) => Promise; /** Is AI loading */ isLoading?: boolean; } declare function GeneratePlanModal({ isOpen, onClose, onPlanGenerated, onGeneratePlan, isLoading: externalLoading, }: GeneratePlanModalProps): react_jsx_runtime.JSX.Element | null; /** * AI Usage Dashboard * Display AI usage statistics and costs */ interface AIUsageDashboardProps { /** Is dashboard open */ isOpen: boolean; /** Close handler */ onClose: () => void; /** Current plan tier */ planTier?: 'hobby' | 'pro' | 'enterprise'; } declare function AIUsageDashboard({ isOpen, onClose, planTier, }: AIUsageDashboardProps): react_jsx_runtime.JSX.Element | null; /** * Generate Gantt Tasks Dialog * AI-powered Gantt task generation with cost control */ interface GanttTask { id: string; name: string; start: string; end: string; duration: number; progress: number; dependencies: string[]; type: string; priority: 'high' | 'medium' | 'low'; } interface GeneratedTasksResponse { tasks: { tasks: GanttTask[]; }; from_cache: boolean; tokens_used: number; mock_mode?: boolean; similarity?: number; tokens_saved?: number; } interface GenerateGanttTasksDialogProps { /** Is dialog open */ isOpen: boolean; /** Close handler */ onClose: () => void; /** Tasks generated callback */ onTasksGenerated: (tasks: GanttTask[]) => void; /** Generate tasks function (calls Supabase Edge Function) */ onGenerateTasks: (params: { prompt: string; projectName?: string; startDate?: string; endDate?: string; }) => Promise; /** Is AI loading */ isLoading?: boolean; /** Project ID (optional) */ projectId?: string; /** Project name (optional) */ projectName?: string; } declare function GenerateGanttTasksDialog({ isOpen, onClose, onTasksGenerated, onGenerateTasks, isLoading: externalLoading, projectName, }: GenerateGanttTasksDialogProps): react_jsx_runtime.JSX.Element | null; /** * useKanbanState Hook * Optional hook for managing board state locally * Consumers can use this or manage state themselves * @module hooks/useKanbanState */ interface UseKanbanStateOptions { /** Initial board state */ initialBoard: Board; /** Persist changes (e.g., to localStorage, API) */ onPersist?: (board: Board) => void | Promise; /** Enable optimistic updates (default: true) */ optimistic?: boolean; } interface UseKanbanStateReturn { /** Current board state */ board: Board; /** Callbacks for the KanbanBoard component */ callbacks: BoardCallbacks; /** Direct state setters (advanced usage) */ setBoard: React.Dispatch>; /** Helper functions */ helpers: { addCard: (card: Omit) => string; addColumn: (column: Omit) => string; deleteCard: (cardId: string) => void; deleteColumn: (columnId: string) => void; clearBoard: () => void; }; } /** * Hook for managing Kanban board state * * @example * ```tsx * const { board, callbacks } = useKanbanState({ * initialBoard: myBoard, * onPersist: async (board) => { * await api.updateBoard(board) * } * }) * * return * ``` */ declare function useKanbanState({ initialBoard, onPersist, }: UseKanbanStateOptions): UseKanbanStateReturn; interface UseBoardOptions { initialData: Board; availableUsers?: User$1[]; onSave?: (board: Board) => void | Promise; saveDelay?: number; } interface UseBoardReturn$1 { props: Pick; board: Board; callbacks: BoardCallbacks; utils: { addCard: (columnId: string, title: string, data?: Partial) => void; addColumn: (title: string, position?: number) => void; reset: () => void; }; } /** * Simplified hook for Kanban board state management * * @example * ```tsx * import { KanbanBoard, useBoard } from '@libxai/board' * * function App() { * const board = useBoard({ * initialData: myData, * onSave: (board) => localStorage.setItem('board', JSON.stringify(board)) * }) * * return * } * ``` */ declare function useBoard$1({ initialData, availableUsers, onSave, }: UseBoardOptions): UseBoardReturn$1; /** * useAI Hook * Optional AI features using Vercel AI SDK * Requires 'ai' package to be installed * @module hooks/useAI */ interface UseAIOptions { /** API key for AI provider */ apiKey?: string; /** Model to use */ model?: 'gpt-4' | 'gpt-4-turbo' | 'claude-3-5-sonnet' | string; /** Custom API endpoint */ endpoint?: string; /** Base URL */ baseURL?: string; } interface UseAIReturn extends AICallbacks { /** Is AI available (SDK installed + API key provided) */ isAvailable: boolean; /** Is AI currently processing */ isLoading: boolean; /** Last error */ error: Error | null; } /** * Hook for AI features * * @example * ```tsx * const ai = useAI({ * apiKey: process.env.OPENAI_API_KEY, * model: 'gpt-4-turbo' * }) * * if (ai.isAvailable) { * const plan = await ai.onGeneratePlan('Build a todo app') * } * ``` */ declare function useAI(options?: UseAIOptions): UseAIReturn; /** * Multi-select hook for bulk operations * Supports keyboard modifiers (Cmd/Ctrl, Shift) for selection * @module hooks/useMultiSelect */ interface UseMultiSelectReturn { /** Selected card IDs */ selectedCardIds: string[]; /** Last selected card ID */ lastSelectedCardId: string | null; /** Check if a card is selected */ isCardSelected: (cardId: string) => boolean; /** Select a card */ selectCard: (cardId: string, event?: React.MouseEvent) => void; /** Deselect a card */ deselectCard: (cardId: string) => void; /** Clear all selections */ clearSelection: () => void; /** Select all cards */ selectAll: () => void; /** Toggle card selection */ toggleCard: (cardId: string) => void; /** Get selected cards */ getSelectedCards: () => Card$1[]; } interface UseMultiSelectOptions { /** Board cards (required for range selection and selectAll) */ cards: Card$1[]; } /** * Hook for multi-select functionality * * @param options - Configuration options */ declare function useMultiSelect(options: UseMultiSelectOptions): UseMultiSelectReturn; /** * useKeyboardShortcuts Hook * Global keyboard shortcuts system for board navigation and actions * @module hooks/keyboard */ interface UseKeyboardShortcutsOptions { /** Shortcuts configuration */ shortcuts?: KeyboardShortcut[]; /** Enable/disable shortcuts */ enabled?: boolean; /** Prevent default browser behavior */ preventDefault?: boolean; } interface UseKeyboardShortcutsReturn { /** Register a keyboard shortcut dynamically */ registerShortcut: (shortcut: KeyboardShortcut) => void; /** Unregister a keyboard shortcut */ unregisterShortcut: (action: KeyboardAction) => void; /** Check if shortcuts are enabled */ isEnabled: boolean; } /** * Default keyboard shortcuts for Kanban board */ declare const DEFAULT_SHORTCUTS: KeyboardShortcut[]; /** * useKeyboardShortcuts Hook * * @example * ```tsx * const { registerShortcut } = useKeyboardShortcuts({ * shortcuts: DEFAULT_SHORTCUTS, * enabled: true, * preventDefault: true, * }) * * // Listen for keyboard actions * useEffect(() => { * const handleKeyboardAction = (event: CustomEvent) => { * console.log('Action triggered:', event.detail) * } * * window.addEventListener('keyboard-action', handleKeyboardAction) * return () => window.removeEventListener('keyboard-action', handleKeyboardAction) * }, []) * ``` */ declare function useKeyboardShortcuts(options?: UseKeyboardShortcutsOptions): UseKeyboardShortcutsReturn; /** * useCardStacking Hook * Manages card stack state and AI-powered grouping suggestions * @module hooks/useCardStacking */ interface UseCardStackingOptions { /** Board cards */ cards: Card$1[]; /** Configuration */ config?: Partial; /** AI service for similarity detection (optional) */ aiService?: { findSimilar: (card: Card$1, candidates: Card$1[]) => Promise<{ card: Card$1; similarity: number; }[]>; }; } interface UseCardStackingResult { /** All card stacks */ stacks: CardStack$1[]; /** Create a new stack */ createStack: (title: string, cardIds: string[], columnId: string, strategy: StackingStrategy, color?: string) => void; /** Delete a stack */ deleteStack: (stackId: string) => void; /** Toggle stack expand/collapse */ toggleStack: (stackId: string) => void; /** Add card to stack */ addToStack: (stackId: string, cardId: string) => void; /** Remove card from stack */ removeFromStack: (stackId: string, cardId: string) => void; /** Get stacks for a specific column */ getStacksForColumn: (columnId: string) => CardStack$1[]; /** Get AI-powered stack suggestions */ getSuggestions: (columnId: string) => Promise; /** Apply a suggestion */ applySuggestion: (suggestion: StackSuggestion) => void; /** Configuration */ config: StackingConfig; } /** * Hook for managing card stacking */ declare function useCardStacking(options: UseCardStackingOptions): UseCardStackingResult; /** * Board Provider Props */ interface BoardProviderProps { children: React__default.ReactNode; initialData?: { board?: BoardData; columns?: ColumnData[]; cards?: CardData[]; }; onStateChange?: (state: BoardState) => void; } /** * BoardProvider component * * Wraps your app with BoardStore context * * @example * ```tsx * * * * ``` */ declare function BoardProvider({ children, initialData, onStateChange }: BoardProviderProps): react_jsx_runtime.JSX.Element; /** * Hook to access BoardStore from context * * @throws Error if used outside BoardProvider */ declare function useBoardStore(): BoardStore; /** * Return type for useBoard hook */ interface UseBoardReturn { board: Board$1 | null; columns: Column$2[]; cards: Card$2[]; updateBoard: (changes: Partial>) => void; addColumn: (columnData: Omit) => void; updateColumn: (columnId: string, changes: Partial>) => void; deleteColumn: (columnId: string) => void; getColumn: (columnId: string) => Column$2 | undefined; addCard: (cardData: Omit) => void; updateCard: (cardId: string, changes: Partial>) => void; deleteCard: (cardId: string) => void; moveCard: (cardId: string, toColumnId: string, newPosition: number) => void; getCard: (cardId: string) => Card$2 | undefined; getCardsByColumn: (columnId: string) => Card$2[]; } /** * Main hook for board operations * * Provides reactive state and methods for managing board, columns, and cards * * @example * ```tsx * function MyBoard() { * const { board, columns, cards, addCard, moveCard } = useBoard() * * return ( *

* {columns.map(column => ( *
*

{column.title}

* {cards * .filter(card => card.columnId === column.id) * .map(card => ( *
{card.title}
* ))} *
* ))} *
* ) * } * ``` */ declare function useBoard(): UseBoardReturn; /** * useFilteredCards - Hook for filtering cards with memoization * @module adapters/react */ /** * Filter options for cards */ interface CardFilters { searchQuery?: string; priorities?: Priority$1[]; statuses?: CardStatus$1[]; assignedUserIds?: string[]; labels?: string[]; columnIds?: string[]; isOverdue?: boolean; } /** * Hook for filtered and sorted cards * * Automatically memoizes results for performance * * @param filters - Filter criteria * @returns Filtered cards array * * @example * ```tsx * function CardList() { * const filteredCards = useFilteredCards({ * priorities: ['HIGH', 'URGENT'], * isOverdue: true * }) * * return
{filteredCards.length} urgent overdue tasks
* } * ``` */ declare function useFilteredCards(filters?: CardFilters): Card$2[]; /** * Hook for sorted cards * * @param sortBy - Sort field * @param sortOrder - Sort order ('asc' | 'desc') * @returns Sorted cards array */ declare function useSortedCards(sortBy?: 'title' | 'priority' | 'createdAt' | 'updatedAt' | 'position', sortOrder?: 'asc' | 'desc'): Card$2[]; /** * Class name utility (cn) * Combines clsx and tailwind-merge for optimal Tailwind class handling */ /** * Merge class names intelligently * Handles Tailwind class conflicts properly * * @example * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' * cn('text-red-500', condition && 'text-[#00E5CC]') // => 'text-[#00E5CC]' if condition is true */ declare function cn(...inputs: ClassValue[]): string; /** * Lexicographic positioning utilities * Uses fractional indexing for efficient reordering without touching all items * @module utils/positioning */ /** * Calculate position between two items * Uses lexicographic ordering (fractional indexing) * * @param before - Position of item before (or null if first) * @param after - Position of item after (or null if last) * @returns New position value * * @example * calculatePosition(null, 1000) // => 500 (before first item) * calculatePosition(1000, 2000) // => 1500 (between two items) * calculatePosition(1000, null) // => 2000 (after last item) */ declare function calculatePosition(before: number | null, after: number | null): number; /** * Generate initial positions for an array of items * Spaces them 1000 apart for room to insert * * @param count - Number of items * @returns Array of position values */ declare function generateInitialPositions(count: number): number[]; /** * Retry utilities with exponential backoff * For resilient API calls and persistence operations * @module utils/retry */ interface RetryOptions { /** Maximum number of retry attempts (default: 3) */ maxAttempts?: number; /** Initial delay in ms (default: 1000) */ initialDelay?: number; /** Multiplier for exponential backoff (default: 2) */ backoffMultiplier?: number; /** Maximum delay in ms (default: 10000) */ maxDelay?: number; /** Function to determine if error should be retried */ shouldRetry?: (error: Error, attempt: number) => boolean; /** Callback when retry is attempted */ onRetry?: (error: Error, attempt: number, delay: number) => void; } interface RetryResult { data?: T; error?: Error; attempts: number; success: boolean; } /** * Retry a function with exponential backoff * * @example * ```ts * const result = await retryWithBackoff( * () => api.updateBoard(board), * { * maxAttempts: 3, * onRetry: (error, attempt) => { * console.log(`Retry attempt ${attempt}: ${error.message}`) * } * } * ) * ``` */ declare function retryWithBackoff(fn: () => Promise, options?: RetryOptions): Promise>; /** * Retry a function synchronously (for non-async operations) * No backoff, just immediate retries */ declare function retrySyncOperation(fn: () => T, maxAttempts?: number): { data?: T; error?: Error; success: boolean; }; /** * Create a retry wrapper function * Returns a function that automatically retries on failure * * @example * ```ts * const saveBoard = createRetryWrapper( * api.saveBoard, * { maxAttempts: 3 } * ) * * const result = await saveBoard(boardData) * ``` */ declare function createRetryWrapper(fn: (...args: TArgs) => Promise, options?: RetryOptions): (...args: TArgs) => Promise>; /** * Retry with circuit breaker pattern * Stops retrying if too many failures occur */ declare class CircuitBreaker { private threshold; private resetTimeout; private failures; private lastFailureTime; private isOpen; constructor(threshold?: number, resetTimeout?: number); execute(fn: () => Promise): Promise; private onSuccess; private onFailure; private reset; getStatus(): { failures: number; isOpen: boolean; }; } /** * Supported AI Models */ declare const AI_MODELS: { readonly 'gpt-4-turbo': { readonly provider: "openai"; readonly name: "GPT-4 Turbo"; readonly contextWindow: 128000; readonly costPer1kInput: 0.01; readonly costPer1kOutput: 0.03; readonly supportsVision: true; readonly supportsJSON: true; }; readonly 'gpt-4': { readonly provider: "openai"; readonly name: "GPT-4"; readonly contextWindow: 8192; readonly costPer1kInput: 0.03; readonly costPer1kOutput: 0.06; readonly supportsVision: false; readonly supportsJSON: true; }; readonly 'gpt-3.5-turbo': { readonly provider: "openai"; readonly name: "GPT-3.5 Turbo"; readonly contextWindow: 16385; readonly costPer1kInput: 0.0005; readonly costPer1kOutput: 0.0015; readonly supportsVision: false; readonly supportsJSON: true; }; readonly 'claude-3-5-sonnet-20241022': { readonly provider: "anthropic"; readonly name: "Claude 3.5 Sonnet"; readonly contextWindow: 200000; readonly costPer1kInput: 0.003; readonly costPer1kOutput: 0.015; readonly supportsVision: true; readonly supportsJSON: true; }; readonly 'claude-3-opus-20240229': { readonly provider: "anthropic"; readonly name: "Claude 3 Opus"; readonly contextWindow: 200000; readonly costPer1kInput: 0.015; readonly costPer1kOutput: 0.075; readonly supportsVision: true; readonly supportsJSON: true; }; readonly 'claude-3-haiku-20240307': { readonly provider: "anthropic"; readonly name: "Claude 3 Haiku"; readonly contextWindow: 200000; readonly costPer1kInput: 0.00025; readonly costPer1kOutput: 0.00125; readonly supportsVision: true; readonly supportsJSON: true; }; }; type AIModelKey = keyof typeof AI_MODELS; /** * Rate Limits by Plan */ declare const RATE_LIMITS: { readonly hobby: { readonly requestsPerMonth: 50; readonly maxConcurrent: 1; readonly maxTokensPerRequest: 4096; }; readonly pro: { readonly requestsPerMonth: 500; readonly maxConcurrent: 3; readonly maxTokensPerRequest: 8192; }; readonly enterprise: { readonly requestsPerMonth: 2000; readonly maxConcurrent: 10; readonly maxTokensPerRequest: 16384; }; }; /** * Feature Flags for AI */ declare const AI_FEATURES: { readonly generatePlan: { readonly enabled: true; readonly minPlanTier: "hobby"; readonly estimatedTokens: 2000; }; readonly predictRisks: { readonly enabled: true; readonly minPlanTier: "pro"; readonly estimatedTokens: 1500; }; readonly suggestAssignee: { readonly enabled: true; readonly minPlanTier: "hobby"; readonly estimatedTokens: 800; }; readonly generateReport: { readonly enabled: true; readonly minPlanTier: "enterprise"; readonly estimatedTokens: 3000; }; readonly generateSubtasks: { readonly enabled: true; readonly minPlanTier: "hobby"; readonly estimatedTokens: 1000; }; }; /** * AI Cost Tracking * Calculate and track AI API usage costs */ interface AIOperation { id: string; feature: 'generatePlan' | 'predictRisks' | 'suggestAssignee' | 'generateSubtasks' | 'estimateEffort'; model: AIModelKey; inputTokens: number; outputTokens: number; cost: number; duration: number; timestamp: Date; success: boolean; error?: string; } interface UsageStats { totalOperations: number; totalCost: number; totalInputTokens: number; totalOutputTokens: number; operationsByFeature: Record; costsByFeature: Record; averageDuration: number; successRate: number; } /** * Format cost as USD string */ declare function formatCost(cost: number): string; /** * AI Usage Tracker * In-memory tracking of AI operations * In production, this would persist to a database */ declare class AIUsageTracker { private operations; private listeners; /** * Record a new AI operation */ record(operation: Omit): AIOperation; /** * Get usage statistics */ getStats(timeRange?: { start: Date; end: Date; }): UsageStats; /** * Get recent operations */ getRecentOperations(limit?: number): AIOperation[]; /** * Check if usage is within limits */ checkLimit(planTier: 'hobby' | 'pro' | 'enterprise', period?: 'month' | 'day'): { used: number; limit: number; remaining: number; percentUsed: number; isExceeded: boolean; }; /** * Subscribe to operation events */ subscribe(listener: (operation: AIOperation) => void): () => void; /** * Clear all tracked operations */ clear(): void; /** * Export operations as JSON */ export(): string; } /** * Global usage tracker instance */ declare const aiUsageTracker: AIUsageTracker; /** * useDragState - React hook for drag state management * @module hooks/useDragState * * Replacement for Jotai's useAtom(dragStateAtom) */ /** * Hook return type */ type UseDragStateReturn = [ state: DragState, setState: (state: DragState) => void ]; /** * React hook for drag state * * Drop-in replacement for `useAtom(dragStateAtom)` * * @example * ```tsx * function MyComponent() { * const [dragState, setDragState] = useDragState() * * const handleDragStart = () => { * setDragState({ * isDragging: true, * draggedCardId: 'card-1', * sourceColumnId: 'col-1', * targetColumnId: 'col-1', * }) * } * * return
{dragState.isDragging ? 'Dragging...' : 'Idle'}
* } * ``` */ declare function useDragState(): UseDragStateReturn; /** * useSelectionState - React hook for selection state management * @module hooks/useSelectionState * * Replacement for Jotai's useAtom(selectionStateAtom) */ /** * Hook return type */ type UseSelectionStateReturn = [ state: SelectionState, setState: (state: SelectionState) => void ]; /** * React hook for selection state * * Drop-in replacement for `useAtom(selectionStateAtom)` * * @example * ```tsx * function MyComponent() { * const [selectionState, setSelectionState] = useSelectionState() * * const handleSelect = (cardId: string) => { * setSelectionState({ * selectedCardIds: [cardId], * lastSelectedCardId: cardId, * }) * } * * return ( *
* {selectionState.selectedCardIds.length} cards selected *
* ) * } * ``` */ declare function useSelectionState(): UseSelectionStateReturn; /** * Plugin System Types * Extensible plugin architecture for ASAKAA * @module plugins/types */ interface PluginContext { /** Current board state */ board: Board; /** Board callbacks */ callbacks: BoardCallbacks; /** Set board state */ setBoard: (board: Board) => void; /** Get plugin config */ getConfig: (key: string) => T | undefined; /** Set plugin config */ setConfig: (key: string, value: any) => void; } interface PluginHooks { /** Called when plugin is registered */ onInit?: (context: PluginContext) => void | Promise; /** Called when plugin is unregistered */ onDestroy?: () => void | Promise; /** Called before board is loaded */ onBeforeBoardLoad?: (board: Board, context: PluginContext) => Board | Promise; /** Called after board is loaded */ onAfterBoardLoad?: (board: Board, context: PluginContext) => void | Promise; /** Called before card is created */ onBeforeCardCreate?: (card: Partial, context: PluginContext) => Partial | Promise>; /** Called after card is created */ onAfterCardCreate?: (card: Card$1, context: PluginContext) => void | Promise; /** Called before card is updated */ onBeforeCardUpdate?: (cardId: string, updates: Partial, context: PluginContext) => Partial | Promise>; /** Called after card is updated */ onAfterCardUpdate?: (card: Card$1, context: PluginContext) => void | Promise; /** Called before card is moved */ onBeforeCardMove?: (cardId: string, fromColumn: string, toColumn: string, position: number, context: PluginContext) => { toColumn: string; position: number; } | Promise<{ toColumn: string; position: number; }>; /** Called after card is moved */ onAfterCardMove?: (cardId: string, fromColumn: string, toColumn: string, context: PluginContext) => void | Promise; /** Called before card is deleted */ onBeforeCardDelete?: (cardId: string, context: PluginContext) => boolean | Promise; /** Called after card is deleted */ onAfterCardDelete?: (cardId: string, context: PluginContext) => void | Promise; /** Called before column is created */ onBeforeColumnCreate?: (column: Partial, context: PluginContext) => Partial | Promise>; /** Called after column is created */ onAfterColumnCreate?: (column: Column$1, context: PluginContext) => void | Promise; /** Called before column is deleted */ onBeforeColumnDelete?: (columnId: string, context: PluginContext) => boolean | Promise; /** Called after column is deleted */ onAfterColumnDelete?: (columnId: string, context: PluginContext) => void | Promise; /** Called on board state change */ onBoardChange?: (board: Board, prevBoard: Board, context: PluginContext) => void | Promise; } interface Plugin extends PluginHooks { /** Unique plugin identifier */ id: string; /** Plugin name */ name: string; /** Plugin version */ version: string; /** Plugin description */ description?: string; /** Plugin author */ author?: string; /** Plugin dependencies (other plugin IDs) */ dependencies?: string[]; /** Plugin configuration schema */ configSchema?: Record; /** Default configuration */ defaultConfig?: Record; } interface IPluginManager { /** Register a plugin */ register(plugin: Plugin): void; /** Unregister a plugin */ unregister(pluginId: string): void; /** Get registered plugin */ getPlugin(pluginId: string): Plugin | undefined; /** Get all registered plugins */ getPlugins(): Plugin[]; /** Check if plugin is registered */ hasPlugin(pluginId: string): boolean; /** Enable/disable plugin */ setEnabled(pluginId: string, enabled: boolean): void; /** Check if plugin is enabled */ isEnabled(pluginId: string): boolean; } /** * Plugin Manager Implementation * Manages plugin lifecycle and execution * @module plugins/PluginManager */ declare class PluginManager implements IPluginManager { private plugins; private enabled; private config; private context; private pluginLogger; /** * Set plugin context (board state, callbacks, etc.) */ setContext(context: PluginContext): void; /** * Register a plugin */ register(plugin: Plugin): void; /** * Unregister a plugin */ unregister(pluginId: string): void; /** * Get registered plugin */ getPlugin(pluginId: string): Plugin | undefined; /** * Get all registered plugins */ getPlugins(): Plugin[]; /** * Check if plugin is registered */ hasPlugin(pluginId: string): boolean; /** * Enable/disable plugin */ setEnabled(pluginId: string, enabled: boolean): void; /** * Check if plugin is enabled */ isEnabled(pluginId: string): boolean; /** * Get plugin config */ getConfig(pluginId: string, key: string): T | undefined; /** * Set plugin config */ setConfig(pluginId: string, key: string, value: any): void; /** * Execute plugin hooks */ executeHook(hookName: keyof Plugin, args: any[], defaultValue?: T): Promise; /** * Execute plugin hooks in parallel */ executeHookParallel(hookName: keyof Plugin, args: any[]): Promise; } /** * Global plugin manager instance */ declare const pluginManager: PluginManager; interface VirtualListProps { /** Array of items to render */ items: T[]; /** Height of the scrollable container in pixels */ height: number | string; /** Estimated size of each item in pixels */ estimateSize: number; /** Render function for each item */ renderItem: (item: T, index: number) => React__default.ReactNode; /** Optional className for the container */ className?: string; /** Overscan count (number of items to render outside viewport) */ overscan?: number; /** Enable horizontal scrolling instead of vertical */ horizontal?: boolean; /** Optional gap between items in pixels */ gap?: number; /** Optional key extractor function */ getItemKey?: (item: T, index: number) => string | number; } /** * VirtualList component for efficient rendering of large lists * * Uses @tanstack/react-virtual for windowing/virtualization * * @example * ```tsx * } * getItemKey={(card) => card.id} * /> * ``` */ declare function VirtualList({ items, height, estimateSize, renderItem, className, overscan, horizontal, gap, getItemKey, }: VirtualListProps): react_jsx_runtime.JSX.Element; /** * Hook to access virtualizer instance for advanced use cases */ declare function useVirtualList(options: { items: T[]; scrollElement: HTMLElement | null; estimateSize: number; overscan?: number; horizontal?: boolean; gap?: number; }): _tanstack_virtual_core.Virtualizer; interface VirtualGridProps { /** Array of items to render */ items: T[]; /** Height of the scrollable container in pixels */ height: number | string; /** Width of the scrollable container in pixels */ width?: number | string; /** Estimated width of each column in pixels */ estimateColumnWidth: number; /** Render function for each column */ renderColumn: (item: T, index: number) => React__default.ReactNode; /** Optional className for the container */ className?: string; /** Overscan count (number of columns to render outside viewport) */ overscan?: number; /** Optional gap between columns in pixels */ gap?: number; /** Optional key extractor function */ getItemKey?: (item: T, index: number) => string | number; /** Enable horizontal scrolling only */ horizontal?: boolean; } /** * VirtualGrid component for efficient rendering of large horizontal lists/grids * * Optimized for Kanban boards with many columns * * @example * ```tsx * } * getItemKey={(column) => column.id} * /> * ``` */ declare function VirtualGrid({ items, height, width, estimateColumnWidth, renderColumn, className, overscan, gap, getItemKey, horizontal, }: VirtualGridProps): react_jsx_runtime.JSX.Element; /** * Hook for advanced 2D virtualization with both rows and columns */ declare function useVirtualGrid(options: { items: T[]; scrollElement: HTMLElement | null; estimateColumnWidth: number; estimateRowHeight?: number; overscan?: number; gap?: number; }): { columnVirtualizer: _tanstack_virtual_core.Virtualizer; virtualColumns: _tanstack_virtual_core.VirtualItem[]; totalWidth: number; }; /** * Utility to determine if grid should use virtualization */ declare function shouldVirtualizeGrid(columnCount: number, threshold?: number): boolean; /** * Design Tokens - Centralized design system tokens * @module tokens/design-tokens */ /** * Spacing tokens (in pixels) */ declare const spacing: { readonly none: 0; readonly xs: 4; readonly sm: 8; readonly md: 12; readonly lg: 16; readonly xl: 20; readonly '2xl': 24; readonly '3xl': 32; readonly '4xl': 40; readonly '5xl': 48; readonly '6xl': 64; }; /** * Border radius tokens (in pixels) */ declare const borderRadius: { readonly none: 0; readonly sm: 4; readonly md: 8; readonly lg: 12; readonly xl: 16; readonly '2xl': 20; readonly full: 9999; }; /** * Font size tokens (in pixels) */ declare const fontSize: { readonly xs: 12; readonly sm: 14; readonly base: 16; readonly lg: 18; readonly xl: 20; readonly '2xl': 24; readonly '3xl': 30; readonly '4xl': 36; readonly '5xl': 48; }; /** * Font weight tokens */ declare const fontWeight: { readonly light: 300; readonly normal: 400; readonly medium: 500; readonly semibold: 600; readonly bold: 700; readonly extrabold: 800; }; /** * Line height tokens */ declare const lineHeight: { readonly none: 1; readonly tight: 1.25; readonly snug: 1.375; readonly normal: 1.5; readonly relaxed: 1.625; readonly loose: 2; }; /** * Z-index layers */ declare const zIndex: { readonly base: 0; readonly dropdown: 1000; readonly sticky: 1020; readonly fixed: 1030; readonly modalBackdrop: 1040; readonly modal: 1050; readonly popover: 1060; readonly tooltip: 1070; }; /** * Transition durations (in milliseconds) */ declare const duration: { readonly instant: 0; readonly fastest: 75; readonly faster: 100; readonly fast: 150; readonly normal: 200; readonly slow: 300; readonly slower: 400; readonly slowest: 500; }; /** * Transition timing functions */ declare const easing: { readonly linear: "linear"; readonly ease: "ease"; readonly easeIn: "ease-in"; readonly easeOut: "ease-out"; readonly easeInOut: "ease-in-out"; readonly smooth: "cubic-bezier(0.4, 0.0, 0.2, 1)"; readonly sharp: "cubic-bezier(0.4, 0.0, 0.6, 1)"; readonly bounce: "cubic-bezier(0.68, -0.55, 0.265, 1.55)"; }; /** * Shadow tokens */ declare const shadows: { readonly none: "none"; readonly sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"; readonly base: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"; readonly md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"; readonly lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"; readonly xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"; readonly '2xl': "0 25px 50px -12px rgba(0, 0, 0, 0.25)"; readonly inner: "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)"; }; /** * Opacity tokens */ declare const opacity: { readonly 0: 0; readonly 5: 0.05; readonly 10: 0.1; readonly 20: 0.2; readonly 30: 0.3; readonly 40: 0.4; readonly 50: 0.5; readonly 60: 0.6; readonly 70: 0.7; readonly 80: 0.8; readonly 90: 0.9; readonly 100: 1; }; /** * Kanban-specific tokens */ declare const kanban: { readonly column: { readonly width: 320; readonly minWidth: 280; readonly maxWidth: 400; readonly gap: 16; readonly padding: 12; readonly headerHeight: 48; }; readonly card: { readonly minHeight: 80; readonly maxHeight: 400; readonly padding: 12; readonly gap: 8; }; readonly board: { readonly padding: 16; readonly gap: 16; }; }; /** * Gantt-specific tokens */ declare const gantt: { readonly timeline: { readonly headerHeight: 60; readonly rowHeight: 44; readonly minRowHeight: 32; readonly maxRowHeight: 80; readonly taskPadding: 4; readonly gridLineWidth: 1; }; readonly task: { readonly height: 28; readonly minHeight: 20; readonly maxHeight: 40; readonly borderRadius: 4; readonly padding: 6; }; readonly dependency: { readonly lineWidth: 2; readonly arrowSize: 8; }; readonly scale: { readonly day: { readonly columnWidth: 40; readonly minColumnWidth: 30; readonly maxColumnWidth: 60; }; readonly week: { readonly columnWidth: 80; readonly minColumnWidth: 60; readonly maxColumnWidth: 120; }; readonly month: { readonly columnWidth: 120; readonly minColumnWidth: 80; readonly maxColumnWidth: 200; }; readonly quarter: { readonly columnWidth: 200; readonly minColumnWidth: 150; readonly maxColumnWidth: 300; }; }; readonly milestone: { readonly size: 16; readonly rotation: 45; }; }; /** * Combined design tokens */ declare const designTokens: { readonly spacing: { readonly none: 0; readonly xs: 4; readonly sm: 8; readonly md: 12; readonly lg: 16; readonly xl: 20; readonly '2xl': 24; readonly '3xl': 32; readonly '4xl': 40; readonly '5xl': 48; readonly '6xl': 64; }; readonly borderRadius: { readonly none: 0; readonly sm: 4; readonly md: 8; readonly lg: 12; readonly xl: 16; readonly '2xl': 20; readonly full: 9999; }; readonly fontSize: { readonly xs: 12; readonly sm: 14; readonly base: 16; readonly lg: 18; readonly xl: 20; readonly '2xl': 24; readonly '3xl': 30; readonly '4xl': 36; readonly '5xl': 48; }; readonly fontWeight: { readonly light: 300; readonly normal: 400; readonly medium: 500; readonly semibold: 600; readonly bold: 700; readonly extrabold: 800; }; readonly lineHeight: { readonly none: 1; readonly tight: 1.25; readonly snug: 1.375; readonly normal: 1.5; readonly relaxed: 1.625; readonly loose: 2; }; readonly zIndex: { readonly base: 0; readonly dropdown: 1000; readonly sticky: 1020; readonly fixed: 1030; readonly modalBackdrop: 1040; readonly modal: 1050; readonly popover: 1060; readonly tooltip: 1070; }; readonly duration: { readonly instant: 0; readonly fastest: 75; readonly faster: 100; readonly fast: 150; readonly normal: 200; readonly slow: 300; readonly slower: 400; readonly slowest: 500; }; readonly easing: { readonly linear: "linear"; readonly ease: "ease"; readonly easeIn: "ease-in"; readonly easeOut: "ease-out"; readonly easeInOut: "ease-in-out"; readonly smooth: "cubic-bezier(0.4, 0.0, 0.2, 1)"; readonly sharp: "cubic-bezier(0.4, 0.0, 0.6, 1)"; readonly bounce: "cubic-bezier(0.68, -0.55, 0.265, 1.55)"; }; readonly shadows: { readonly none: "none"; readonly sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"; readonly base: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"; readonly md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"; readonly lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"; readonly xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"; readonly '2xl': "0 25px 50px -12px rgba(0, 0, 0, 0.25)"; readonly inner: "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)"; }; readonly opacity: { readonly 0: 0; readonly 5: 0.05; readonly 10: 0.1; readonly 20: 0.2; readonly 30: 0.3; readonly 40: 0.4; readonly 50: 0.5; readonly 60: 0.6; readonly 70: 0.7; readonly 80: 0.8; readonly 90: 0.9; readonly 100: 1; }; readonly kanban: { readonly column: { readonly width: 320; readonly minWidth: 280; readonly maxWidth: 400; readonly gap: 16; readonly padding: 12; readonly headerHeight: 48; }; readonly card: { readonly minHeight: 80; readonly maxHeight: 400; readonly padding: 12; readonly gap: 8; }; readonly board: { readonly padding: 16; readonly gap: 16; }; }; readonly gantt: { readonly timeline: { readonly headerHeight: 60; readonly rowHeight: 44; readonly minRowHeight: 32; readonly maxRowHeight: 80; readonly taskPadding: 4; readonly gridLineWidth: 1; }; readonly task: { readonly height: 28; readonly minHeight: 20; readonly maxHeight: 40; readonly borderRadius: 4; readonly padding: 6; }; readonly dependency: { readonly lineWidth: 2; readonly arrowSize: 8; }; readonly scale: { readonly day: { readonly columnWidth: 40; readonly minColumnWidth: 30; readonly maxColumnWidth: 60; }; readonly week: { readonly columnWidth: 80; readonly minColumnWidth: 60; readonly maxColumnWidth: 120; }; readonly month: { readonly columnWidth: 120; readonly minColumnWidth: 80; readonly maxColumnWidth: 200; }; readonly quarter: { readonly columnWidth: 200; readonly minColumnWidth: 150; readonly maxColumnWidth: 300; }; }; readonly milestone: { readonly size: 16; readonly rotation: 45; }; }; }; /** * Type helpers */ type SpacingToken = keyof typeof spacing; type BorderRadiusToken = keyof typeof borderRadius; type FontSizeToken = keyof typeof fontSize; type FontWeightToken = keyof typeof fontWeight; type LineHeightToken = keyof typeof lineHeight; type ZIndexToken = keyof typeof zIndex; type DurationToken = keyof typeof duration; type EasingToken = keyof typeof easing; type ShadowToken = keyof typeof shadows; type OpacityToken = keyof typeof opacity; /** * Design token value types */ type DesignTokens = typeof designTokens; type TokenValue = string | number; /** * Utility to get token value with fallback */ declare function getToken(tokens: Record, key: string, fallback: T): T; /** * CSS Custom Properties Generator * Generates CSS variables from design tokens * @module tokens/css-generator */ /** * Generate CSS custom properties from design tokens */ declare function generateCSSVariables(prefix?: string): string; /** * Generate CSS custom properties for a specific theme */ interface ThemeColors$1 { background: { primary: string; secondary: string; tertiary: string; card: string; hover: string; active: string; }; text: { primary: string; secondary: string; tertiary: string; disabled: string; inverse: string; }; border: { default: string; hover: string; focus: string; active: string; }; status: { success: string; warning: string; error: string; info: string; }; priority: { low: string; medium: string; high: string; urgent: string; }; interactive: { primary: string; primaryHover: string; primaryActive: string; secondary: string; secondaryHover: string; secondaryActive: string; }; gantt: { gridLine: string; todayLine: string; taskBackground: string; taskBorder: string; criticalPath: string; milestone: string; dependency: string; weekend: string; }; } /** * Generate theme CSS variables */ declare function generateThemeVariables(theme: ThemeColors$1, prefix?: string): string; /** * Dark theme colors */ declare const darkTheme$1: ThemeColors$1; /** * Light theme colors */ declare const lightTheme$1: ThemeColors$1; /** * Neutral theme colors */ declare const neutralTheme$1: ThemeColors$1; /** * Generate complete CSS with all tokens and theme */ declare function generateCompleteCSS(theme?: ThemeColors$1, prefix?: string): string; /** * Export CSS to file content */ declare function exportTokensToCSS(): string; /** * Theme System Types * ASAKAA v0.5.0 */ type ThemeName = 'dark' | 'light' | 'neutral'; interface ThemeColors { bgPrimary: string; bgSecondary: string; bgTertiary: string; bgCard: string; bgHover: string; bgActive: string; bgInput: string; textPrimary: string; textSecondary: string; textTertiary: string; textDisabled: string; textInverse: string; accentPrimary: string; accentHover: string; borderPrimary: string; borderSecondary: string; borderDefault: string; borderHover: string; borderSubtle: string; interactivePrimary: string; interactivePrimaryHover: string; interactivePrimaryBorder: string; interactivePrimaryBackground: string; interactivePrimaryBackgroundHover: string; success?: string; warning?: string; error?: string; info?: string; danger: string; dangerBorder: string; dangerBackground: string; dangerBackgroundHover: string; } interface Theme { name: ThemeName; displayName: string; emoji: string; colors: ThemeColors; shadows: { sm: string; md: string; lg: string; }; radii: { sm: string; md: string; lg: string; full: string; }; spacing: { xs: string; sm: string; md: string; lg: string; xl: string; }; } interface ThemeContextValue { theme: ThemeName; setTheme: (theme: ThemeName) => void; themes: Record; } interface ThemeProviderProps { children: ReactNode; defaultTheme?: ThemeName; storageKey?: string; } declare function ThemeProvider({ children, defaultTheme: initialTheme, storageKey, }: ThemeProviderProps): react_jsx_runtime.JSX.Element; /** * Hook to access theme context */ declare function useTheme(): ThemeContextValue; interface ThemeSwitcherProps { /** Show labels for each theme */ showLabels?: boolean; /** Compact mode (icon-only) */ compact?: boolean; /** Custom class name */ className?: string; } declare function ThemeSwitcher({ showLabels, compact, className }: ThemeSwitcherProps): react_jsx_runtime.JSX.Element; /** * Theme Definitions * ASAKAA v0.5.0 - Elite Theming System */ /** * DARK THEME (Enhanced) - DEFAULT * Philosophy: Speed, efficiency, focus * Optimized for developer productivity */ declare const darkTheme: Theme; /** * LIGHT THEME (Accessible Standard) * Philosophy: Clarity, legibility, professionalism * WCAG AAA compliant (7:1 contrast) */ declare const lightTheme: Theme; /** * NEUTRAL THEME (Zen Mode) * Philosophy: Minimalism, calm technology, maximum concentration * Strictly monochromatic - states communicated via icons/typography */ declare const neutralTheme: Theme; /** * All themes registry */ declare const themes: Record; /** * Default theme */ declare const defaultTheme: ThemeName; export { type AICallbacks, type AICommandResult, type GanttTask as AIGanttTask, type AIMessage, type AIModelKey, type AIOperation, AIUsageDashboard, type AIUsageDashboardProps, AI_FEATURES, AI_MODELS, type Activity, type ActivityType, AddCardButton, type AddCardButtonProps, type AddCardData, AddColumnButton, type AddColumnButtonProps, type AssigneeSuggestion, type Attachment, AttachmentUploader, type AttachmentUploaderProps, type AvailableUser, type Board, type BoardCallbacks, type BoardConfig, BoardProvider, type BoardProviderProps, type BorderRadiusToken, BulkOperationsToolbar, type BulkOperationsToolbarProps, BurnDownChart, type BurnDownChartProps, type BurnDownDataPoint, CUSTOM_FIELD_TYPES, type CalLayerId, type CalMoney, type CalView, CalendarView as CalendarBoard, type DailyLog as CalendarDailyLog, type TeamMember as CalendarTeamMember, Card, type CardFilter, type CardFilters, CardHistoryReplay, type CardHistoryReplayProps, CardHistoryTimeline, type CardHistoryTimelineProps, type CardProps, CardRelationshipsGraph, type CardRelationshipsGraphProps, type CardSort, type CardSortKey, CardStack, type CardStackProps, type CardStack$1 as CardStackType, type CardStatus, type CardTemplate, CardTemplateSelector, type CardTemplateSelectorProps, type CardTimeProps, type Card$1 as CardType, CircuitBreaker, Column, ColumnManager, type ColumnProps, type Column$1 as ColumnType, CommandPalette, type CommandPaletteProps, type Comment, type CommentAttachment, ConfigMenu, type ConfigMenuProps, ContextMenu, type ContextMenuAction, type ContextMenuState, type CustomFieldDefinition, type CustomFieldValue, DEFAULT_SHORTCUTS, DEFAULT_TABLE_COLUMNS, DEFAULT_TEMPLATES, type DateFilter, DateRangePicker, type DateRangePickerProps, DependenciesSelector, type DependenciesSelectorProps, DependencyLine, type DesignTokens, DistributionCharts, type DistributionChartsProps, type DistributionDataPoint, type DragData, type DropData, type DurationToken, type EasingToken, EditableColumnTitle, type EditableColumnTitleProps, ErrorBoundary, type ErrorBoundaryProps, ExportDropdown, type ExportFormat, ExportImportModal, type ExportImportModalProps, type ExportOptions, type FillColumn, FilterBar, type FilterBarProps, type FilterState, type FlattenedTask, type FontSizeToken, type FontWeightToken, GANTT_AI_SYSTEM_PROMPT, GanttAIAssistant, type GanttAIAssistantConfig, type Assignee as GanttAssignee, GanttBoard, type GanttConfig as GanttBoardConfig, type GanttBoardRef, type GanttColumn, type ColumnType$1 as GanttColumnType, type GanttConfig, GanttI18nContext, Milestone as GanttMilestone, type GanttPermissions, type Task as GanttTask, type GanttTemplates, type Theme$1 as GanttTheme, type GanttTheme as GanttThemeConfig, GanttToolbar, type GanttTranslations, GenerateGanttTasksDialog, type GenerateGanttTasksDialogProps, GeneratePlanModal, type GeneratePlanModalProps, type GeneratedPlan, type GeneratedTasksResponse, type GroupByOption, GroupBySelector, type GroupBySelectorProps, HealthBar, type HealthBarProps, type IPluginManager, type ImportResult, type Insight, type InsightSeverity, type InsightType, KanbanBoard, type KanbanBoardProps, KanbanToolbar, type KanbanToolbarProps, KanbanViewAdapter, type KanbanViewConfig, type KeyboardAction, type KeyboardShortcut, KeyboardShortcutsHelp, type KeyboardShortcutsHelpProps, type LineHeightToken, type ListColumn, type ColumnType as ListColumnType, type ListFilter, type ListSort, type ListSortColumn, ListView, type ListViewCallbacks, type ListViewConfig, type ListViewPermissions, type ListViewProps, type ListViewSupportedLocale, type ListViewTheme, type ListViewThemeName, type ListViewTranslations, MenuIcons, type MoneyMode, type OpacityToken, type PendingFile, type PersistHistoryConfig, type Plugin, type PluginContext, type PluginHooks, PluginManager, type Priority, PrioritySelector, type PrioritySelectorProps, ProfitabilityReport, type ProfitabilityReportProps, type ProjectForecast, type ProjectHealthData, QuickTaskCreate, type QuickTaskCreateData, type QuickTaskCreateProps, RATE_LIMITS, type RenderProps, type RescheduleSimulation, type RetryOptions, type RetryResult, STANDARD_FIELDS, type ShadowToken, type SortBy, type SortDirection, type SortOrder, type SortState, type SpacingToken, type StackSuggestion, type StackingConfig, type StackingStrategy, type Subtask, type SupportedLocale, type Swimlane, SwimlaneBoardView, type SwimlaneBoardViewProps, type SwimlaneConfig, type TableColumn, TagBadge, TagList, TagPicker, TaskBar, type TaskComment, TaskDetailModal, type TaskDetailModalProps, type TaskFilterType, type TaskFormData, TaskFormModal, type TaskFormModalProps, TaskGrid, type TaskPriority, type TaskTag, type Theme, type ThemeColors, type ThemeContextValue, ThemeModal, type ThemeModalProps, type ThemeName, ThemeProvider, ThemeSwitcher, type TimeEntry, TimeInputPopover, type TimeInputPopoverProps, type TimeLogInput, type TimeLogSource, TimePill, type TimePillProps, TimePopover, type TimePopoverProps, type TimeScale, type TimeTrackingBoardProps, type TimeTrackingCallbacks, type TimeTrackingSummary, Timeline, type TimerState, type ThemeColors$1 as TokenThemeColors, type TokenValue, type UsageStats, type UseAIOptions, type UseAIReturn, type UseBoardReturn as UseBoardCoreReturn, type UseBoardOptions, type UseBoardReturn$1 as UseBoardReturn, type UseCardStackingOptions, type UseCardStackingResult, type UseDragStateReturn, type UseFiltersOptions, type UseFiltersReturn, type UseKanbanStateOptions, type UseKanbanStateReturn, type UseKeyboardShortcutsOptions, type UseKeyboardShortcutsReturn, type UseMultiSelectReturn, type UseSelectionStateReturn, type User$1 as User, UserAssignmentSelector, type UserAssignmentSelectorProps, VelocityChart, type VelocityChartProps, type VelocityDataPoint, VirtualGrid, type VirtualGridProps, VirtualList, type VirtualListProps, type ZIndexToken, aiUsageTracker, borderRadius, buildCalendar, calculatePosition, cardToGanttTask, cardsToGanttTasks, cn, createKanbanView, createRetryWrapper, darkTheme, darkTheme$1 as darkTokenTheme, defaultTheme, designTokens, duration, easing, exportTokensToCSS, findTaskByName, fontSize, fontWeight, formatCost, en$1 as ganttEnTranslations, es$1 as ganttEsTranslations, ganttTaskToCardUpdate, themes$1 as ganttThemes, gantt as ganttTokens, translations as ganttTranslations, ganttUtils, generateCSSVariables, generateCompleteCSS, generateInitialPositions, generateTasksContext, generateThemeVariables, getListViewTheme, getListViewTranslations, getToken, getTranslations, kanban as kanbanTokens, lightTheme, lightTheme$1 as lightTokenTheme, lineHeight, darkTheme$2 as listViewDarkTheme, en as listViewEnTranslations, es as listViewEsTranslations, lightTheme$2 as listViewLightTheme, neutralTheme$2 as listViewNeutralTheme, listViewThemes, listViewTranslations, mergeListViewTranslations, mergeTranslations, neutralTheme, neutralTheme$1 as neutralTokenTheme, opacity, parseLocalCommand, parseNaturalDate, parseNaturalDuration, parseProgress, parseStatus, pluginManager, retrySyncOperation, retryWithBackoff, shadows, shouldVirtualizeGrid, simulateReschedule, spacing, themes, useAI, useBoard$1 as useBoard, useBoard as useBoardCore, useBoardStore, useCardStacking, useDragState, useFilteredCards, useFilters, useGanttI18n, useKanbanState, useKeyboardShortcuts, useMultiSelect, useSelectionState, useSortedCards, useTheme, useVirtualGrid, useVirtualList, validateAIResponse, withErrorBoundary, wouldCreateCircularDependency, zIndex };