@burdenoff/microfe-vibecontrols 2026.623.1 → 2026.623.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/actions/ActionCard.js +2 -2
- package/dist/components/actions/ActionCard.js.map +1 -1
- package/dist/components/actions/ActionTypeBadge.js +1 -1
- package/dist/components/actions/ActionTypeBadge.js.map +1 -1
- package/dist/components/actions/ExecutionHistory.js +1 -1
- package/dist/components/actions/ExecutionHistory.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerAdminBar.js +1 -1
- package/dist/components/agent-manager/AgentManagerAdminBar.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerChatPane.js +2 -2
- package/dist/components/agent-manager/AgentManagerChatPane.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerInputArea.js +4 -4
- package/dist/components/agent-manager/AgentManagerInputArea.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerLayout.js +1 -1
- package/dist/components/agent-manager/AgentManagerLayout.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerMessageItem.js +1 -1
- package/dist/components/agent-manager/AgentManagerMessageItem.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerSidebar.js +5 -5
- package/dist/components/agent-manager/AgentManagerSidebar.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerTab.js +1 -1
- package/dist/components/agent-manager/AgentManagerTab.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerTabBar.js +1 -1
- package/dist/components/agent-manager/AgentManagerTabBar.js.map +1 -1
- package/dist/components/agent-manager/BridleConfigPanel.js +24 -24
- package/dist/components/agent-manager/BridleConfigPanel.js.map +1 -1
- package/dist/components/agent-manager/PluginInstallModal.js +1 -1
- package/dist/components/agent-manager/PluginInstallModal.js.map +1 -1
- package/dist/components/agent-manager/ProfilesPanel.js +5 -5
- package/dist/components/agent-manager/ProfilesPanel.js.map +1 -1
- package/dist/components/agent-manager/controls/AutonomySelector.js +1 -1
- package/dist/components/agent-manager/controls/AutonomySelector.js.map +1 -1
- package/dist/components/agent-manager/controls/SdkSelector.js +1 -1
- package/dist/components/agent-manager/controls/SdkSelector.js.map +1 -1
- package/dist/components/agent-manager/controls/VoiceToggle.js +1 -1
- package/dist/components/agent-manager/controls/VoiceToggle.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionConfigPanel.js +6 -6
- package/dist/components/agent-manager/detail/SessionConfigPanel.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionLogsPanel.js +5 -5
- package/dist/components/agent-manager/detail/SessionLogsPanel.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionToolsPanel.js +1 -1
- package/dist/components/agent-manager/detail/SessionToolsPanel.js.map +1 -1
- package/dist/components/agent-manager/dialogs/NewSessionDialog.js +2 -2
- package/dist/components/agent-manager/dialogs/NewSessionDialog.js.map +1 -1
- package/dist/components/agent-manager/dialogs/RenameSessionDialog.js +1 -1
- package/dist/components/agent-manager/dialogs/RenameSessionDialog.js.map +1 -1
- package/dist/components/agents/AgentCard.js +14 -11
- package/dist/components/agents/AgentCard.js.map +1 -1
- package/dist/components/ai/AIContextsTab.js +1 -1
- package/dist/components/ai/AIContextsTab.js.map +1 -1
- package/dist/components/ai/AIOverviewTab.js +4 -4
- package/dist/components/ai/AIOverviewTab.js.map +1 -1
- package/dist/components/ai/AIPlanPanel.js +4 -4
- package/dist/components/ai/AIPlanPanel.js.map +1 -1
- package/dist/components/ai/AIPlaygroundTab.js +1 -1
- package/dist/components/ai/AIPlaygroundTab.js.map +1 -1
- package/dist/components/ai/AIPromptsTab.js +2 -2
- package/dist/components/ai/AIPromptsTab.js.map +1 -1
- package/dist/components/ai/AIProviderCredentialsCard.js +4 -4
- package/dist/components/ai/AIProviderCredentialsCard.js.map +1 -1
- package/dist/components/ai/AIQueueTab.js +4 -4
- package/dist/components/ai/AIQueueTab.js.map +1 -1
- package/dist/components/ai/AISessionsTab.js +4 -4
- package/dist/components/ai/AISessionsTab.js.map +1 -1
- package/dist/components/ai/AITasksTab.js +1 -1
- package/dist/components/ai/AITasksTab.js.map +1 -1
- package/dist/components/ai/ClaudeCredentialsCard.js +3 -3
- package/dist/components/ai/ClaudeCredentialsCard.js.map +1 -1
- package/dist/components/ai/PluginHarnessPicker.js +3 -3
- package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
- package/dist/components/analytics/AnalyticsBreakdownChart.js +8 -8
- package/dist/components/analytics/AnalyticsBreakdownChart.js.map +1 -1
- package/dist/components/analytics/AnalyticsTimeSeriesChart.js +5 -5
- package/dist/components/analytics/AnalyticsTimeSeriesChart.js.map +1 -1
- package/dist/components/audit/AuditDeleteDialog.js +2 -2
- package/dist/components/audit/AuditDeleteDialog.js.map +1 -1
- package/dist/components/audit/AuditExportButton.js +5 -5
- package/dist/components/audit/AuditExportButton.js.map +1 -1
- package/dist/components/audit/AuditLogDetail.js +9 -9
- package/dist/components/audit/AuditLogDetail.js.map +1 -1
- package/dist/components/audit/AuditLogFilters.js +1 -1
- package/dist/components/audit/AuditLogFilters.js.map +1 -1
- package/dist/components/audit/AuditLogStats.js +1 -1
- package/dist/components/audit/AuditLogStats.js.map +1 -1
- package/dist/components/audit/AuditLogTable.js +28 -28
- package/dist/components/audit/AuditLogTable.js.map +1 -1
- package/dist/components/catalog/CatalogCard.js +3 -3
- package/dist/components/catalog/CatalogCard.js.map +1 -1
- package/dist/components/catalog/CatalogForm.js +1 -1
- package/dist/components/catalog/CatalogForm.js.map +1 -1
- package/dist/components/common/ActionAgentTargetNotice.js +6 -6
- package/dist/components/common/ActionAgentTargetNotice.js.map +1 -1
- package/dist/components/common/CommandEditor.js +1 -1
- package/dist/components/common/CommandEditor.js.map +1 -1
- package/dist/components/docs/DocsPageTree.js +1 -1
- package/dist/components/docs/DocsPageTree.js.map +1 -1
- package/dist/components/docs/DocsPreviewPanel.js +1 -1
- package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
- package/dist/components/docs/DocsRevisionHistory.js +4 -4
- package/dist/components/docs/DocsRevisionHistory.js.map +1 -1
- package/dist/components/docs/DocsSettingsPanel.js +7 -7
- package/dist/components/docs/DocsSettingsPanel.js.map +1 -1
- package/dist/components/docs/DocsTabPanel.js +1 -1
- package/dist/components/docs/DocsTabPanel.js.map +1 -1
- package/dist/components/graph/ConnectionPermissionsDialog.js +2 -2
- package/dist/components/graph/ConnectionPermissionsDialog.js.map +1 -1
- package/dist/components/graph/MeshDeployWizard.js +3 -3
- package/dist/components/graph/MeshDeployWizard.js.map +1 -1
- package/dist/components/graph/MeshRequestPanel.js +2 -2
- package/dist/components/graph/MeshRequestPanel.js.map +1 -1
- package/dist/components/idp-components/ComponentCard.js +5 -5
- package/dist/components/idp-components/ComponentCard.js.map +1 -1
- package/dist/components/idp-components/ComponentForm.js +1 -1
- package/dist/components/idp-components/ComponentForm.js.map +1 -1
- package/dist/components/idp-components/DependencyGraphTab.js +7 -7
- package/dist/components/idp-components/DependencyGraphTab.js.map +1 -1
- package/dist/components/logs/LogViewer.js +14 -14
- package/dist/components/logs/LogViewer.js.map +1 -1
- package/dist/components/notes/NoteCard.js +1 -1
- package/dist/components/notes/NoteCard.js.map +1 -1
- package/dist/components/notes/NoteEditor.js +2 -2
- package/dist/components/notes/NoteEditor.js.map +1 -1
- package/dist/components/notes/NoteList.js +1 -1
- package/dist/components/notes/NoteList.js.map +1 -1
- package/dist/components/notes/NotesTabPanel.js +1 -1
- package/dist/components/notes/NotesTabPanel.js.map +1 -1
- package/dist/components/scorecard/ScorecardEmptyState.js +1 -1
- package/dist/components/scorecard/ScorecardEmptyState.js.map +1 -1
- package/dist/components/scorecard/ScorecardPanel.js +3 -3
- package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
- package/dist/components/security/SecurityScanList.js +11 -11
- package/dist/components/security/SecurityScanList.js.map +1 -1
- package/dist/components/sessions/SessionCard.js +26 -19
- package/dist/components/sessions/SessionCard.js.map +1 -1
- package/dist/components/sessions/SessionStatusBadge.js +7 -7
- package/dist/components/sessions/SessionStatusBadge.js.map +1 -1
- package/dist/components/shared/AgentSelector.js +4 -4
- package/dist/components/shared/AgentSelector.js.map +1 -1
- package/dist/components/shared/AgentSetupBanner.js +4 -4
- package/dist/components/shared/AgentSetupBanner.js.map +1 -1
- package/dist/components/shared/Card.js +4 -4
- package/dist/components/shared/Card.js.map +1 -1
- package/dist/components/shared/ErrorState.js +15 -9
- package/dist/components/shared/ErrorState.js.map +1 -1
- package/dist/components/shared/FilterDropdown.js +2 -2
- package/dist/components/shared/FilterDropdown.js.map +1 -1
- package/dist/components/shared/PageSkeleton.js +6 -6
- package/dist/components/shared/PageSkeleton.js.map +1 -1
- package/dist/components/shared/SearchInput.js +1 -1
- package/dist/components/shared/SearchInput.js.map +1 -1
- package/dist/components/shared/StatCard.js +7 -7
- package/dist/components/shared/StatCard.js.map +1 -1
- package/dist/components/templates/PublishTemplateForm.js +2 -2
- package/dist/components/templates/PublishTemplateForm.js.map +1 -1
- package/dist/components/templates/TemplateCard.js +5 -5
- package/dist/components/templates/TemplateCard.js.map +1 -1
- package/dist/components/templates/TemplateWizard.js +2 -2
- package/dist/components/templates/TemplateWizard.js.map +1 -1
- package/dist/components/tunnels/DomainVerificationBadge.js +4 -4
- package/dist/components/tunnels/DomainVerificationBadge.js.map +1 -1
- package/dist/components/tunnels/ProviderBadge.js +1 -1
- package/dist/components/tunnels/ProviderBadge.js.map +1 -1
- package/dist/components/tunnels/TunnelCard.js +16 -16
- package/dist/components/tunnels/TunnelCard.js.map +1 -1
- package/dist/components/tunnels/TunnelCreateWizard.js +1 -1
- package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
- package/dist/components/tunnels/TunnelPublicAccessPanel.js +1 -1
- package/dist/components/tunnels/TunnelPublicAccessPanel.js.map +1 -1
- package/dist/components/tunnels/TunnelStatusBadge.js +4 -4
- package/dist/components/tunnels/TunnelStatusBadge.js.map +1 -1
- package/dist/components/vibecalendar/LogsDrawer.js +2 -2
- package/dist/components/vibecalendar/LogsDrawer.js.map +1 -1
- package/dist/components/vibecalendar/ScheduleTaskModal.js +5 -5
- package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalAgendaView.js +2 -2
- package/dist/components/vibecalendar/VibeCalAgendaView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalDayView.js +3 -3
- package/dist/components/vibecalendar/VibeCalDayView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalMonthView.js +1 -1
- package/dist/components/vibecalendar/VibeCalMonthView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalWeekView.js +4 -4
- package/dist/components/vibecalendar/VibeCalWeekView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalendarHeader.js +4 -4
- package/dist/components/vibecalendar/VibeCalendarHeader.js.map +1 -1
- package/dist/components/vibecalendar/VibeTaskBlock.js +2 -2
- package/dist/components/vibecalendar/VibeTaskBlock.js.map +1 -1
- package/dist/components/vibecalendar/types.js +7 -7
- package/dist/components/vibecalendar/types.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckButtonForm.js +9 -9
- package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckButtonTile.js +6 -6
- package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckExecutionLog.js +10 -10
- package/dist/components/vibedeck/VibeDeckExecutionLog.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckForm.js +8 -8
- package/dist/components/vibedeck/VibeDeckForm.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckGrid.js +2 -2
- package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js +2 -2
- package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckSwitcher.js +8 -8
- package/dist/components/vibedeck/VibeDeckSwitcher.js.map +1 -1
- package/dist/components/vibes/VibeCard.js +22 -18
- package/dist/components/vibes/VibeCard.js.map +1 -1
- package/dist/components/vibes/VibeList.js +16 -12
- package/dist/components/vibes/VibeList.js.map +1 -1
- package/dist/pages/ActionsPage.js +4 -3
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/AgentDetailsPage.js +9 -9
- package/dist/pages/AgentDetailsPage.js.map +1 -1
- package/dist/pages/AgentsLandingPage.js +4 -4
- package/dist/pages/AgentsLandingPage.js.map +1 -1
- package/dist/pages/AgentsPage.js +14 -14
- package/dist/pages/AgentsPage.js.map +1 -1
- package/dist/pages/AnalyticsPage.js +8 -8
- package/dist/pages/AnalyticsPage.js.map +1 -1
- package/dist/pages/CatalogDetailPage.js +11 -11
- package/dist/pages/CatalogDetailPage.js.map +1 -1
- package/dist/pages/CatalogPage.js +12 -9
- package/dist/pages/CatalogPage.js.map +1 -1
- package/dist/pages/ComponentDetailPage.js +7 -7
- package/dist/pages/ComponentDetailPage.js.map +1 -1
- package/dist/pages/ComponentsPage.js +12 -9
- package/dist/pages/ComponentsPage.js.map +1 -1
- package/dist/pages/EnvTopologyPage.js +2 -2
- package/dist/pages/EnvTopologyPage.js.map +1 -1
- package/dist/pages/GettingStartedPage.js +12 -12
- package/dist/pages/GettingStartedPage.js.map +1 -1
- package/dist/pages/HealthPage.js +12 -12
- package/dist/pages/HealthPage.js.map +1 -1
- package/dist/pages/LogsPage.js +4 -4
- package/dist/pages/LogsPage.js.map +1 -1
- package/dist/pages/NoteDetailsPage.js +5 -5
- package/dist/pages/NoteDetailsPage.js.map +1 -1
- package/dist/pages/OverviewPage.js +76 -43
- package/dist/pages/OverviewPage.js.map +1 -1
- package/dist/pages/PluginsCatalogPage.js +7 -4
- package/dist/pages/PluginsCatalogPage.js.map +1 -1
- package/dist/pages/ScheduledJobDetailPage.js +7 -7
- package/dist/pages/ScheduledJobDetailPage.js.map +1 -1
- package/dist/pages/SessionDetailsPage.js +21 -21
- package/dist/pages/SessionDetailsPage.js.map +1 -1
- package/dist/pages/SessionsPage.js +20 -20
- package/dist/pages/SessionsPage.js.map +1 -1
- package/dist/pages/SettingsPage.js +64 -52
- package/dist/pages/SettingsPage.js.map +1 -1
- package/dist/pages/SharedSessionPage.js +21 -21
- package/dist/pages/SharedSessionPage.js.map +1 -1
- package/dist/pages/SharedVibeDeckPage.js +5 -5
- package/dist/pages/SharedVibeDeckPage.js.map +1 -1
- package/dist/pages/TargetDetailsPage.js +56 -65
- package/dist/pages/TargetDetailsPage.js.map +1 -1
- package/dist/pages/TargetsPage.js +4 -4
- package/dist/pages/TargetsPage.js.map +1 -1
- package/dist/pages/TemplateDetailPage.js +10 -10
- package/dist/pages/TemplateDetailPage.js.map +1 -1
- package/dist/pages/TemplatesPage.js +6 -5
- package/dist/pages/TemplatesPage.js.map +1 -1
- package/dist/pages/VibeAuditPage.js +3 -3
- package/dist/pages/VibeAuditPage.js.map +1 -1
- package/dist/pages/VibeCalendarPage.js +3 -3
- package/dist/pages/VibeCalendarPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +3 -3
- package/dist/pages/VibeDeckPage.js.map +1 -1
- package/dist/pages/VibeDetailsPage.js +15 -15
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/VibeTaskDetailPage.js +5 -5
- package/dist/pages/VibeTaskDetailPage.js.map +1 -1
- package/dist/pages/VibesPage.js +18 -18
- package/dist/pages/VibesPage.js.map +1 -1
- package/dist/pages/WebhooksPage.js +11 -11
- package/dist/pages/WebhooksPage.js.map +1 -1
- package/dist/pages/ai/AIBookmarksPage.js +1 -1
- package/dist/pages/ai/AIBookmarksPage.js.map +1 -1
- package/dist/pages/ai/AISessionDetailPage.js +6 -6
- package/dist/pages/ai/AISessionDetailPage.js.map +1 -1
- package/dist/pages/tunnels/AuditTab.js +1 -1
- package/dist/pages/tunnels/AuditTab.js.map +1 -1
- package/dist/pages/tunnels/DomainsTab.js +1 -1
- package/dist/pages/tunnels/DomainsTab.js.map +1 -1
- package/dist/pages/tunnels/ProvidersTab.js +1 -1
- package/dist/pages/tunnels/ProvidersTab.js.map +1 -1
- package/dist/pages/tunnels/SessionsTab.js +1 -1
- package/dist/pages/tunnels/SessionsTab.js.map +1 -1
- package/dist/pages/tunnels/TunnelDetailsPage.js +3 -3
- package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
- package/dist/pages/tunnels/UsageTab.js +1 -1
- package/dist/pages/tunnels/UsageTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelDomainsTab.js +16 -16
- package/dist/pages/tunnels/tabs/TunnelDomainsTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelOverviewTab.js +1 -1
- package/dist/pages/tunnels/tabs/TunnelOverviewTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelSessionsTab.js +52 -49
- package/dist/pages/tunnels/tabs/TunnelSessionsTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelSettingsTab.js +9 -9
- package/dist/pages/tunnels/tabs/TunnelSettingsTab.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScheduleTaskModal.js","names":[],"sources":["../../../src/components/vibecalendar/ScheduleTaskModal.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { X, Zap, Search } from 'lucide-react';\nimport { useListActionsQuery } from '@/generated/wspace-operations';\nimport type { Action } from '@/generated/wspace-types';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { ActionAgentTargetNotice } from '../common/ActionAgentTargetNotice';\n\ntype ActionPickItem = Pick<\n Action,\n | 'id'\n | 'name'\n | 'displayName'\n | 'description'\n | 'actionType'\n | 'triggerType'\n | 'targetAgentId'\n | 'targetPlatformFilter'\n>;\n\ninterface ScheduleTaskModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (input: ScheduleTaskInput) => void;\n // Legacy prop kept for compatibility; unused in Action-only mode.\n agents?: Array<{ id: string; name: string }>;\n loading?: boolean;\n // When provided, the picker is locked to this action (user navigated\n // in from \"Add to calendar\" on the Actions page). Otherwise the user\n // picks from a searchable dropdown of their actions.\n prefillActionId?: string;\n}\n\n/**\n * Calendar entries always delegate execution to a VibeControls Action.\n * Agent, command, script, and webhook fields come from the Action\n * definition at execution time — this modal only collects the calendar\n * metadata and the schedule.\n */\nexport interface ScheduleTaskInput {\n calendarId: string;\n title: string;\n description?: string;\n scheduleType: 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL';\n scheduledAt?: string;\n cronExpression?: string;\n rrule?: string;\n interval?: number;\n intervalUnit?: string;\n timezone: string;\n actionId: string;\n}\n\nconst INPUT_CLASS =\n 'w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-lg text-sm text-text-primary placeholder-text-placeholder focus:outline-none focus:border-border-primary';\nconst MONO_INPUT_CLASS = `${INPUT_CLASS} font-mono`;\nconst LABEL_CLASS = 'block text-sm font-medium text-text-secondary mb-1';\n\nexport function ScheduleTaskModal({\n isOpen,\n onClose,\n onSubmit,\n loading,\n prefillActionId,\n}: ScheduleTaskModalProps) {\n const tr = useTr();\n const [selectedActionId, setSelectedActionId] = useState<string>(prefillActionId ?? '');\n const [actionSearch, setActionSearch] = useState('');\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [scheduleType, setScheduleType] = useState<\n 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL'\n >('ONE_TIME');\n const [scheduledAt, setScheduledAt] = useState('');\n const [cronExpression, setCronExpression] = useState('');\n const [interval, setInterval] = useState(60);\n const [intervalUnit, setIntervalUnit] = useState('minutes');\n const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone);\n\n const { data: actionsData, loading: actionsLoading } = useListActionsQuery({\n variables: { pagination: { limit: 100 } },\n skip: !isOpen,\n fetchPolicy: 'cache-and-network',\n });\n\n const allActions = useMemo<ActionPickItem[]>(\n () => (actionsData?.actions?.items ?? []) as ActionPickItem[],\n [actionsData?.actions?.items]\n );\n\n const filteredActions = useMemo(() => {\n if (!actionSearch.trim()) return allActions;\n const q = actionSearch.trim().toLowerCase();\n return allActions.filter(\n (a: ActionPickItem) =>\n a.name?.toLowerCase().includes(q) ||\n a.displayName?.toLowerCase().includes(q) ||\n a.description?.toLowerCase().includes(q)\n );\n }, [allActions, actionSearch]);\n\n const selectedAction = useMemo(\n () => allActions.find((a: ActionPickItem) => a.id === selectedActionId),\n [allActions, selectedActionId]\n );\n\n if (!isOpen) return null;\n\n const isActionLocked = Boolean(prefillActionId);\n const canSubmit = Boolean(selectedActionId) && !loading;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!selectedActionId) return;\n onSubmit({\n calendarId: '',\n title,\n description: description || undefined,\n scheduleType,\n scheduledAt: scheduleType === 'ONE_TIME' ? new Date(scheduledAt).toISOString() : undefined,\n cronExpression: scheduleType === 'CRON' ? cronExpression : undefined,\n interval: scheduleType === 'FIXED_INTERVAL' ? interval : undefined,\n intervalUnit: scheduleType === 'FIXED_INTERVAL' ? intervalUnit : undefined,\n timezone,\n actionId: selectedActionId,\n });\n };\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (onClose as (...a: unknown[]) => unknown)();\n }\n }}\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={onClose}\n />\n <div className=\"relative bg-bg-surface border border-border-default rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {isActionLocked\n ? tr('vibecontrols.calendar.schedule.addActionToCalendar', 'Add Action to Calendar')\n : tr(\n 'vibecontrols.calendar.schedule.scheduleActionOnCalendar',\n 'Schedule Action on Calendar'\n )}\n </h2>\n <button type=\"button\" onClick={onClose} className=\"p-1 rounded hover:bg-bg-secondary\">\n <X size={18} />\n </button>\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"px-6 py-4 space-y-4\">\n {/* Action Picker — always required */}\n <div className=\"space-y-2\">\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.actionToSchedule', 'Action to Schedule')} *\n </label>\n <p className=\"text-xs text-text-tertiary -mt-1\">\n Calendar entries trigger VibeControls Actions. Agent, command, and webhook details\n come from the Action definition.\n </p>\n\n {isActionLocked && selectedAction && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg border border-border-default bg-bg-secondary\">\n <div className=\"p-1.5 rounded-md bg-primary/10 text-primary flex-shrink-0\">\n <Zap size={16} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">\n {selectedAction.displayName || selectedAction.name}\n </p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {selectedAction.actionType} · {selectedAction.triggerType}\n </p>\n {selectedAction.description && (\n <p className=\"text-xs text-text-tertiary mt-1 line-clamp-2\">\n {selectedAction.description}\n </p>\n )}\n </div>\n </div>\n )}\n\n {isActionLocked && !selectedAction && actionsLoading && (\n <div className=\"p-3 rounded-lg border border-border-default bg-bg-secondary text-xs text-text-secondary\">\n Loading action…\n </div>\n )}\n\n {isActionLocked && !selectedAction && !actionsLoading && (\n <div className=\"p-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle text-xs text-status-error-text\">\n Action not found. It may have been deleted.\n </div>\n )}\n\n {!isActionLocked && (\n <>\n <div className=\"relative\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary\"\n />\n <input\n aria-label=\"Search actions by name…\"\n type=\"text\"\n value={actionSearch}\n onChange={(e) => setActionSearch(e.target.value)}\n placeholder=\"Search actions by name…\"\n className={`${INPUT_CLASS} pl-9`}\n />\n </div>\n\n <div className=\"max-h-40 overflow-y-auto border border-border-default rounded-lg divide-y divide-border-default\">\n {actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n Loading actions…\n </div>\n )}\n {!actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions yet. Create an Action in VibeControls first, then come back to\n schedule it.\n </div>\n )}\n {!actionsLoading && allActions.length > 0 && filteredActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions match \"{actionSearch}\".\n </div>\n )}\n {filteredActions.map((action: ActionPickItem) => {\n const isSelected = action.id === selectedActionId;\n return (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => setSelectedActionId(action.id)}\n className={`w-full text-left px-3 py-2.5 hover:bg-bg-secondary transition-colors ${\n isSelected ? 'bg-primary/5' : ''\n }`}\n >\n <div className=\"flex items-start gap-2.5\">\n <div\n className={`p-1 rounded-md flex-shrink-0 ${\n isSelected\n ? 'bg-primary/10 text-primary'\n : 'bg-bg-sunken text-text-tertiary'\n }`}\n >\n <Zap size={14} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {action.displayName || action.name}\n </p>\n <p className=\"text-xs text-text-tertiary mt-0.5\">\n {action.actionType} · {action.triggerType}\n </p>\n </div>\n {isSelected && (\n <span className=\"text-xs font-medium text-primary flex-shrink-0\">\n Selected\n </span>\n )}\n </div>\n </button>\n );\n })}\n </div>\n </>\n )}\n\n {/* Tell the user which agent this action runs on, and warn if that\n agent is unhealthy or gone — before the schedule is created. */}\n {selectedAction && <ActionAgentTargetNotice action={selectedAction} />}\n </div>\n\n {/* Title */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.title', 'Title')}\n </label>\n <input\n aria-label=\"e.g. Run test suite\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"e.g. Run test suite\"\n className={INPUT_CLASS}\n required\n />\n </div>\n\n {/* Description */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.description', 'Description')}\n </label>\n <input\n aria-label=\"Optional description\"\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional description\"\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Schedule Type */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.schedule', 'Schedule')}\n </label>\n <select\n value={scheduleType}\n onChange={(e) => setScheduleType(e.target.value as typeof scheduleType)}\n className={INPUT_CLASS}\n >\n <option value=\"ONE_TIME\">One Time</option>\n <option value=\"CRON\">Cron Expression</option>\n <option value=\"FIXED_INTERVAL\">Fixed Interval</option>\n </select>\n </div>\n\n {/* Schedule-specific fields */}\n {scheduleType === 'ONE_TIME' && (\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.runAt', 'Run At')}\n </label>\n <input\n aria-label=\"control\"\n type=\"datetime-local\"\n value={scheduledAt}\n onChange={(e) => setScheduledAt(e.target.value)}\n className={INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'CRON' && (\n <div>\n <label htmlFor=\"scheduletaskmodal-40\" className={LABEL_CLASS}>\n Cron Expression\n </label>\n <input\n id=\"scheduletaskmodal-40\"\n aria-label=\"*/5 * * * * (every 5 minutes)\"\n type=\"text\"\n value={cronExpression}\n onChange={(e) => setCronExpression(e.target.value)}\n placeholder=\"*/5 * * * * (every 5 minutes)\"\n className={MONO_INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'FIXED_INTERVAL' && (\n <div className=\"flex gap-2\">\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-39\" className={LABEL_CLASS}>\n Every\n </label>\n <input\n id=\"scheduletaskmodal-39\"\n aria-label=\"control\"\n type=\"number\"\n value={interval}\n onChange={(e) => setInterval(Number(e.target.value))}\n min={1}\n className={INPUT_CLASS}\n required\n />\n </div>\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-38\" className={LABEL_CLASS}>\n Unit\n </label>\n <select\n id=\"scheduletaskmodal-38\"\n value={intervalUnit}\n onChange={(e) => setIntervalUnit(e.target.value)}\n className={INPUT_CLASS}\n >\n <option value=\"seconds\">Seconds</option>\n <option value=\"minutes\">Minutes</option>\n <option value=\"hours\">Hours</option>\n <option value=\"days\">Days</option>\n </select>\n </div>\n </div>\n )}\n\n {/* Timezone */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.timezone', 'Timezone')}\n </label>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={timezone}\n onChange={(e) => setTimezone(e.target.value)}\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center justify-end gap-3 pt-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.calendar.schedule.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={!canSubmit}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed\"\n title={\n !selectedActionId\n ? tr('vibecontrols.calendar.schedule.selectActionFirst', 'Select an Action first')\n : undefined\n }\n >\n {loading\n ? tr('vibecontrols.calendar.schedule.creating', 'Creating...')\n : tr('vibecontrols.calendar.schedule.scheduleBtn', 'Schedule')}\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ScheduleTaskModal.js","names":[],"sources":["../../../src/components/vibecalendar/ScheduleTaskModal.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { X, Zap, Search } from 'lucide-react';\nimport { useListActionsQuery } from '@/generated/wspace-operations';\nimport type { Action } from '@/generated/wspace-types';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { ActionAgentTargetNotice } from '../common/ActionAgentTargetNotice';\n\ntype ActionPickItem = Pick<\n Action,\n | 'id'\n | 'name'\n | 'displayName'\n | 'description'\n | 'actionType'\n | 'triggerType'\n | 'targetAgentId'\n | 'targetPlatformFilter'\n>;\n\ninterface ScheduleTaskModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (input: ScheduleTaskInput) => void;\n // Legacy prop kept for compatibility; unused in Action-only mode.\n agents?: Array<{ id: string; name: string }>;\n loading?: boolean;\n // When provided, the picker is locked to this action (user navigated\n // in from \"Add to calendar\" on the Actions page). Otherwise the user\n // picks from a searchable dropdown of their actions.\n prefillActionId?: string;\n}\n\n/**\n * Calendar entries always delegate execution to a VibeControls Action.\n * Agent, command, script, and webhook fields come from the Action\n * definition at execution time — this modal only collects the calendar\n * metadata and the schedule.\n */\nexport interface ScheduleTaskInput {\n calendarId: string;\n title: string;\n description?: string;\n scheduleType: 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL';\n scheduledAt?: string;\n cronExpression?: string;\n rrule?: string;\n interval?: number;\n intervalUnit?: string;\n timezone: string;\n actionId: string;\n}\n\nconst INPUT_CLASS =\n 'w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-lg text-sm text-text-primary placeholder-text-placeholder focus:outline-none focus:border-border-default';\nconst MONO_INPUT_CLASS = `${INPUT_CLASS} font-mono`;\nconst LABEL_CLASS = 'block text-sm font-medium text-text-secondary mb-1';\n\nexport function ScheduleTaskModal({\n isOpen,\n onClose,\n onSubmit,\n loading,\n prefillActionId,\n}: ScheduleTaskModalProps) {\n const tr = useTr();\n const [selectedActionId, setSelectedActionId] = useState<string>(prefillActionId ?? '');\n const [actionSearch, setActionSearch] = useState('');\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [scheduleType, setScheduleType] = useState<\n 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL'\n >('ONE_TIME');\n const [scheduledAt, setScheduledAt] = useState('');\n const [cronExpression, setCronExpression] = useState('');\n const [interval, setInterval] = useState(60);\n const [intervalUnit, setIntervalUnit] = useState('minutes');\n const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone);\n\n const { data: actionsData, loading: actionsLoading } = useListActionsQuery({\n variables: { pagination: { limit: 100 } },\n skip: !isOpen,\n fetchPolicy: 'cache-and-network',\n });\n\n const allActions = useMemo<ActionPickItem[]>(\n () => (actionsData?.actions?.items ?? []) as ActionPickItem[],\n [actionsData?.actions?.items]\n );\n\n const filteredActions = useMemo(() => {\n if (!actionSearch.trim()) return allActions;\n const q = actionSearch.trim().toLowerCase();\n return allActions.filter(\n (a: ActionPickItem) =>\n a.name?.toLowerCase().includes(q) ||\n a.displayName?.toLowerCase().includes(q) ||\n a.description?.toLowerCase().includes(q)\n );\n }, [allActions, actionSearch]);\n\n const selectedAction = useMemo(\n () => allActions.find((a: ActionPickItem) => a.id === selectedActionId),\n [allActions, selectedActionId]\n );\n\n if (!isOpen) return null;\n\n const isActionLocked = Boolean(prefillActionId);\n const canSubmit = Boolean(selectedActionId) && !loading;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!selectedActionId) return;\n onSubmit({\n calendarId: '',\n title,\n description: description || undefined,\n scheduleType,\n scheduledAt: scheduleType === 'ONE_TIME' ? new Date(scheduledAt).toISOString() : undefined,\n cronExpression: scheduleType === 'CRON' ? cronExpression : undefined,\n interval: scheduleType === 'FIXED_INTERVAL' ? interval : undefined,\n intervalUnit: scheduleType === 'FIXED_INTERVAL' ? intervalUnit : undefined,\n timezone,\n actionId: selectedActionId,\n });\n };\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (onClose as (...a: unknown[]) => unknown)();\n }\n }}\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={onClose}\n />\n <div className=\"relative bg-bg-surface border border-border-default rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {isActionLocked\n ? tr('vibecontrols.calendar.schedule.addActionToCalendar', 'Add Action to Calendar')\n : tr(\n 'vibecontrols.calendar.schedule.scheduleActionOnCalendar',\n 'Schedule Action on Calendar'\n )}\n </h2>\n <button type=\"button\" onClick={onClose} className=\"p-1 rounded hover:bg-bg-surface\">\n <X size={18} />\n </button>\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"px-6 py-4 space-y-4\">\n {/* Action Picker — always required */}\n <div className=\"space-y-2\">\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.actionToSchedule', 'Action to Schedule')} *\n </label>\n <p className=\"text-xs text-text-tertiary -mt-1\">\n Calendar entries trigger VibeControls Actions. Agent, command, and webhook details\n come from the Action definition.\n </p>\n\n {isActionLocked && selectedAction && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg border border-border-default bg-bg-surface\">\n <div className=\"p-1.5 rounded-md bg-primary/10 text-primary flex-shrink-0\">\n <Zap size={16} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">\n {selectedAction.displayName || selectedAction.name}\n </p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {selectedAction.actionType} · {selectedAction.triggerType}\n </p>\n {selectedAction.description && (\n <p className=\"text-xs text-text-tertiary mt-1 line-clamp-2\">\n {selectedAction.description}\n </p>\n )}\n </div>\n </div>\n )}\n\n {isActionLocked && !selectedAction && actionsLoading && (\n <div className=\"p-3 rounded-lg border border-border-default bg-bg-surface text-xs text-text-secondary\">\n Loading action…\n </div>\n )}\n\n {isActionLocked && !selectedAction && !actionsLoading && (\n <div className=\"p-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle text-xs text-status-error-text\">\n Action not found. It may have been deleted.\n </div>\n )}\n\n {!isActionLocked && (\n <>\n <div className=\"relative\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary\"\n />\n <input\n aria-label=\"Search actions by name…\"\n type=\"text\"\n value={actionSearch}\n onChange={(e) => setActionSearch(e.target.value)}\n placeholder=\"Search actions by name…\"\n className={`${INPUT_CLASS} pl-9`}\n />\n </div>\n\n <div className=\"max-h-40 overflow-y-auto border border-border-default rounded-lg divide-y divide-border-default\">\n {actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n Loading actions…\n </div>\n )}\n {!actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions yet. Create an Action in VibeControls first, then come back to\n schedule it.\n </div>\n )}\n {!actionsLoading && allActions.length > 0 && filteredActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions match \"{actionSearch}\".\n </div>\n )}\n {filteredActions.map((action: ActionPickItem) => {\n const isSelected = action.id === selectedActionId;\n return (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => setSelectedActionId(action.id)}\n className={`w-full text-left px-3 py-2.5 hover:bg-bg-surface transition-colors ${\n isSelected ? 'bg-primary/5' : ''\n }`}\n >\n <div className=\"flex items-start gap-2.5\">\n <div\n className={`p-1 rounded-md flex-shrink-0 ${\n isSelected\n ? 'bg-primary/10 text-primary'\n : 'bg-bg-sunken text-text-tertiary'\n }`}\n >\n <Zap size={14} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {action.displayName || action.name}\n </p>\n <p className=\"text-xs text-text-tertiary mt-0.5\">\n {action.actionType} · {action.triggerType}\n </p>\n </div>\n {isSelected && (\n <span className=\"text-xs font-medium text-primary flex-shrink-0\">\n Selected\n </span>\n )}\n </div>\n </button>\n );\n })}\n </div>\n </>\n )}\n\n {/* Tell the user which agent this action runs on, and warn if that\n agent is unhealthy or gone — before the schedule is created. */}\n {selectedAction && <ActionAgentTargetNotice action={selectedAction} />}\n </div>\n\n {/* Title */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.title', 'Title')}\n </label>\n <input\n aria-label=\"e.g. Run test suite\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"e.g. Run test suite\"\n className={INPUT_CLASS}\n required\n />\n </div>\n\n {/* Description */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.description', 'Description')}\n </label>\n <input\n aria-label=\"Optional description\"\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional description\"\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Schedule Type */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.schedule', 'Schedule')}\n </label>\n <select\n value={scheduleType}\n onChange={(e) => setScheduleType(e.target.value as typeof scheduleType)}\n className={INPUT_CLASS}\n >\n <option value=\"ONE_TIME\">One Time</option>\n <option value=\"CRON\">Cron Expression</option>\n <option value=\"FIXED_INTERVAL\">Fixed Interval</option>\n </select>\n </div>\n\n {/* Schedule-specific fields */}\n {scheduleType === 'ONE_TIME' && (\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.runAt', 'Run At')}\n </label>\n <input\n aria-label=\"control\"\n type=\"datetime-local\"\n value={scheduledAt}\n onChange={(e) => setScheduledAt(e.target.value)}\n className={INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'CRON' && (\n <div>\n <label htmlFor=\"scheduletaskmodal-40\" className={LABEL_CLASS}>\n Cron Expression\n </label>\n <input\n id=\"scheduletaskmodal-40\"\n aria-label=\"*/5 * * * * (every 5 minutes)\"\n type=\"text\"\n value={cronExpression}\n onChange={(e) => setCronExpression(e.target.value)}\n placeholder=\"*/5 * * * * (every 5 minutes)\"\n className={MONO_INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'FIXED_INTERVAL' && (\n <div className=\"flex gap-2\">\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-39\" className={LABEL_CLASS}>\n Every\n </label>\n <input\n id=\"scheduletaskmodal-39\"\n aria-label=\"control\"\n type=\"number\"\n value={interval}\n onChange={(e) => setInterval(Number(e.target.value))}\n min={1}\n className={INPUT_CLASS}\n required\n />\n </div>\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-38\" className={LABEL_CLASS}>\n Unit\n </label>\n <select\n id=\"scheduletaskmodal-38\"\n value={intervalUnit}\n onChange={(e) => setIntervalUnit(e.target.value)}\n className={INPUT_CLASS}\n >\n <option value=\"seconds\">Seconds</option>\n <option value=\"minutes\">Minutes</option>\n <option value=\"hours\">Hours</option>\n <option value=\"days\">Days</option>\n </select>\n </div>\n </div>\n )}\n\n {/* Timezone */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.timezone', 'Timezone')}\n </label>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={timezone}\n onChange={(e) => setTimezone(e.target.value)}\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center justify-end gap-3 pt-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.calendar.schedule.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={!canSubmit}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed\"\n title={\n !selectedActionId\n ? tr('vibecontrols.calendar.schedule.selectActionFirst', 'Select an Action first')\n : undefined\n }\n >\n {loading\n ? tr('vibecontrols.calendar.schedule.creating', 'Creating...')\n : tr('vibecontrols.calendar.schedule.scheduleBtn', 'Schedule')}\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -74,14 +74,14 @@ function s({ occurrences: s, onTriggerNow: c, onViewLogs: l, onViewDetail: u })
|
|
|
74
74
|
c && /* @__PURE__ */ a("button", {
|
|
75
75
|
type: "button",
|
|
76
76
|
onClick: () => c(d.id),
|
|
77
|
-
className: "p-1.5 rounded hover:bg-bg-
|
|
77
|
+
className: "p-1.5 rounded hover:bg-bg-surface transition-colors",
|
|
78
78
|
title: "Trigger Now",
|
|
79
79
|
children: /* @__PURE__ */ a(i, { size: 14 })
|
|
80
80
|
}),
|
|
81
81
|
/* @__PURE__ */ a("button", {
|
|
82
82
|
type: "button",
|
|
83
83
|
onClick: () => l(d),
|
|
84
|
-
className: "p-1.5 rounded hover:bg-bg-
|
|
84
|
+
className: "p-1.5 rounded hover:bg-bg-surface transition-colors",
|
|
85
85
|
title: "View Logs",
|
|
86
86
|
children: /* @__PURE__ */ a(r, { size: 14 })
|
|
87
87
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeCalAgendaView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalAgendaView.tsx"],"sourcesContent":["import { Play, Eye, ChevronRight } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalAgendaViewProps {\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nexport function VibeCalAgendaView({\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalAgendaViewProps) {\n const tr = useTr();\n // Group by date\n const grouped = occurrences.reduce(\n (acc, occ) => {\n const dateKey = new Date(occ.occurrenceAt).toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n });\n if (!acc[dateKey]) acc[dateKey] = [];\n acc[dateKey].push(occ);\n return acc;\n },\n {} as Record<string, CalendarOccurrence[]>\n );\n\n if (occurrences.length === 0) {\n return (\n <div className=\"flex-1 flex items-center justify-center\">\n <div className=\"text-center\">\n <p className=\"text-text-secondary text-sm\">\n {tr('vibecontrols.calendar.agenda.noTasks', 'No scheduled tasks in this range')}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 overflow-auto space-y-6\">\n {Object.entries(grouped).map(([dateLabel, dayOccurrences]) => (\n <div key={dateLabel}>\n <h3 className=\"text-sm font-semibold text-text-secondary mb-2 sticky top-0 bg-bg-surface py-1\">\n {dateLabel}\n </h3>\n <div className=\"space-y-2\">\n {dayOccurrences.map((occ, i) => {\n const task = occ.task;\n const statusColor =\n STATUS_COLORS[occ.execution?.status || task.status] || STATUS_COLORS.PENDING;\n const time = new Date(occ.occurrenceAt).toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n });\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (() => onViewDetail(task.id))();\n }\n }}\n key={`${task.id}-${i}`}\n className={`flex items-center gap-4 p-3 rounded-lg border ${statusColor} hover:opacity-90 transition-opacity cursor-pointer`}\n onClick={() => onViewDetail(task.id)}\n >\n {/* Time */}\n <div className=\"w-16 text-sm font-mono text-text-secondary\">{time}</div>\n\n {/* Task Info */}\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-sm text-text-primary truncate\">{task.title}</h4>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <span className=\"text-xs text-text-tertiary font-mono truncate\">\n {task.taskConfig.command || 'Script'}\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {task.cronExpression ? 'Cron' : task.rrule ? 'Recurrence' : 'One Time'}\n </span>\n </div>\n </div>\n\n {/* Status */}\n <span className=\"text-xs px-2 py-0.5 rounded-full border\">\n {occ.execution?.status || task.status}\n </span>\n\n {/* Actions */}\n <div className=\"flex items-center gap-1\" onClick={(e) => e.stopPropagation()}>\n {onTriggerNow && (\n <button\n type=\"button\"\n onClick={() => onTriggerNow(task.id)}\n className=\"p-1.5 rounded hover:bg-bg-
|
|
1
|
+
{"version":3,"file":"VibeCalAgendaView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalAgendaView.tsx"],"sourcesContent":["import { Play, Eye, ChevronRight } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalAgendaViewProps {\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nexport function VibeCalAgendaView({\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalAgendaViewProps) {\n const tr = useTr();\n // Group by date\n const grouped = occurrences.reduce(\n (acc, occ) => {\n const dateKey = new Date(occ.occurrenceAt).toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n });\n if (!acc[dateKey]) acc[dateKey] = [];\n acc[dateKey].push(occ);\n return acc;\n },\n {} as Record<string, CalendarOccurrence[]>\n );\n\n if (occurrences.length === 0) {\n return (\n <div className=\"flex-1 flex items-center justify-center\">\n <div className=\"text-center\">\n <p className=\"text-text-secondary text-sm\">\n {tr('vibecontrols.calendar.agenda.noTasks', 'No scheduled tasks in this range')}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 overflow-auto space-y-6\">\n {Object.entries(grouped).map(([dateLabel, dayOccurrences]) => (\n <div key={dateLabel}>\n <h3 className=\"text-sm font-semibold text-text-secondary mb-2 sticky top-0 bg-bg-surface py-1\">\n {dateLabel}\n </h3>\n <div className=\"space-y-2\">\n {dayOccurrences.map((occ, i) => {\n const task = occ.task;\n const statusColor =\n STATUS_COLORS[occ.execution?.status || task.status] || STATUS_COLORS.PENDING;\n const time = new Date(occ.occurrenceAt).toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n });\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (() => onViewDetail(task.id))();\n }\n }}\n key={`${task.id}-${i}`}\n className={`flex items-center gap-4 p-3 rounded-lg border ${statusColor} hover:opacity-90 transition-opacity cursor-pointer`}\n onClick={() => onViewDetail(task.id)}\n >\n {/* Time */}\n <div className=\"w-16 text-sm font-mono text-text-secondary\">{time}</div>\n\n {/* Task Info */}\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-sm text-text-primary truncate\">{task.title}</h4>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <span className=\"text-xs text-text-tertiary font-mono truncate\">\n {task.taskConfig.command || 'Script'}\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {task.cronExpression ? 'Cron' : task.rrule ? 'Recurrence' : 'One Time'}\n </span>\n </div>\n </div>\n\n {/* Status */}\n <span className=\"text-xs px-2 py-0.5 rounded-full border\">\n {occ.execution?.status || task.status}\n </span>\n\n {/* Actions */}\n <div className=\"flex items-center gap-1\" onClick={(e) => e.stopPropagation()}>\n {onTriggerNow && (\n <button\n type=\"button\"\n onClick={() => onTriggerNow(task.id)}\n className=\"p-1.5 rounded hover:bg-bg-surface transition-colors\"\n title=\"Trigger Now\"\n >\n <Play size={14} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onViewLogs(task)}\n className=\"p-1.5 rounded hover:bg-bg-surface transition-colors\"\n title=\"View Logs\"\n >\n <Eye size={14} />\n </button>\n <ChevronRight size={14} className=\"text-text-tertiary\" />\n </div>\n </div>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":";;;;;AAYA,SAAgB,EAAkB,EAChC,gBACA,iBACA,eACA,mBACyB;CACzB,IAAM,IAAK,GAAO,EAEZ,IAAU,EAAY,QACzB,GAAK,MAAQ;EACZ,IAAM,IAAU,IAAI,KAAK,EAAI,aAAa,CAAC,mBAAmB,SAAS;GACrE,SAAS;GACT,OAAO;GACP,KAAK;GACL,MAAM;GACP,CAAC;AAGF,SAFK,EAAI,OAAU,EAAI,KAAW,EAAE,GACpC,EAAI,GAAS,KAAK,EAAI,EACf;IAET,EAAE,CACH;AAcD,QAZI,EAAY,WAAW,IAEvB,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,KAAD;IAAG,WAAU;cACV,EAAG,wCAAwC,mCAAmC;IAC7E,CAAA;GACA,CAAA;EACF,CAAA,GAKR,kBAAC,OAAD;EAAK,WAAU;YACZ,OAAO,QAAQ,EAAQ,CAAC,KAAK,CAAC,GAAW,OACxC,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aACX;GACE,CAAA,EACL,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAe,KAAK,GAAK,MAAM;IAC9B,IAAM,IAAO,EAAI,MACX,IACJ,EAAc,EAAI,WAAW,UAAU,EAAK,WAAW,EAAc,SACjE,IAAO,IAAI,KAAK,EAAI,aAAa,CAAC,mBAAmB,SAAS;KAClE,MAAM;KACN,QAAQ;KACT,CAAC;AAEF,WACE,kBAAC,OAAD;KACE,MAAK;KACL,UAAU;KACV,YAAY,MAAM;AAChB,OAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EACX,EAAa,EAAK,GAAG;;KAIhC,WAAW,iDAAiD,EAAY;KACxE,eAAe,EAAa,EAAK,GAAG;eAXtC;MAcE,kBAAC,OAAD;OAAK,WAAU;iBAA8C;OAAW,CAAA;MAGxE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBAAkD,EAAK;QAAW,CAAA,EAChF,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAK,WAAW,WAAW;SACvB,CAAA,EACP,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAK,iBAAiB,SAAS,EAAK,QAAQ,eAAe;SACvD,CAAA,CACH;UACF;;MAGN,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAI,WAAW,UAAU,EAAK;OAC1B,CAAA;MAGP,kBAAC,OAAD;OAAK,WAAU;OAA0B,UAAU,MAAM,EAAE,iBAAiB;iBAA5E;QACG,KACC,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAa,EAAK,GAAG;SACpC,WAAU;SACV,OAAM;mBAEN,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;SACX,CAAA;QAEX,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAW,EAAK;SAC/B,WAAU;SACV,OAAM;mBAEN,kBAAC,GAAD,EAAK,MAAM,IAAM,CAAA;SACV,CAAA;QACT,kBAAC,GAAD;SAAc,MAAM;SAAI,WAAU;SAAuB,CAAA;QACrD;;MACF;OA/CC,GAAG,EAAK,GAAG,GAAG,IA+Cf;KAER;GACE,CAAA,CACF,EAAA,EA3EI,EA2EJ,CACN;EACE,CAAA"}
|
|
@@ -47,7 +47,7 @@ function u({ currentDate: u, occurrences: d, onTriggerNow: f, onViewLogs: p, onV
|
|
|
47
47
|
children: c.map((e) => {
|
|
48
48
|
let n = y(e), c = _ && e === v;
|
|
49
49
|
return /* @__PURE__ */ s("div", {
|
|
50
|
-
className: `flex border-b border-border-default ${c ? "bg-
|
|
50
|
+
className: `flex border-b border-border-default ${c ? "bg-[var(--color-accent-soft)]" : ""}`,
|
|
51
51
|
style: { minHeight: n.length > 0 ? "auto" : "48px" },
|
|
52
52
|
children: [/* @__PURE__ */ s("div", {
|
|
53
53
|
className: "w-20 flex-shrink-0 text-right pr-3 pt-1.5 border-r border-border-default",
|
|
@@ -105,14 +105,14 @@ function u({ currentDate: u, occurrences: d, onTriggerNow: f, onViewLogs: p, onV
|
|
|
105
105
|
f && /* @__PURE__ */ o("button", {
|
|
106
106
|
type: "button",
|
|
107
107
|
onClick: () => f(c.id),
|
|
108
|
-
className: "p-1.5 rounded hover:bg-bg-
|
|
108
|
+
className: "p-1.5 rounded hover:bg-bg-surface transition-colors",
|
|
109
109
|
title: "Trigger Now",
|
|
110
110
|
children: /* @__PURE__ */ o(a, { size: 14 })
|
|
111
111
|
}),
|
|
112
112
|
/* @__PURE__ */ o("button", {
|
|
113
113
|
type: "button",
|
|
114
114
|
onClick: () => p(c),
|
|
115
|
-
className: "p-1.5 rounded hover:bg-bg-
|
|
115
|
+
className: "p-1.5 rounded hover:bg-bg-surface transition-colors",
|
|
116
116
|
title: "View Logs",
|
|
117
117
|
children: /* @__PURE__ */ o(i, { size: 14 })
|
|
118
118
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeCalDayView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalDayView.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Play, Eye, ChevronRight } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalDayViewProps {\n currentDate: Date;\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i);\n\nfunction formatHour(hour: number): string {\n if (hour === 0) return '12 AM';\n if (hour < 12) return `${hour} AM`;\n if (hour === 12) return '12 PM';\n return `${hour - 12} PM`;\n}\n\nexport function VibeCalDayView({\n currentDate,\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalDayViewProps) {\n const tr = useTr();\n const today = new Date();\n\n const isToday =\n currentDate.getFullYear() === today.getFullYear() &&\n currentDate.getMonth() === today.getMonth() &&\n currentDate.getDate() === today.getDate();\n\n const nowHour = today.getHours();\n\n const getOccurrencesForHour = (hour: number): CalendarOccurrence[] =>\n occurrences.filter((occ) => {\n const d = new Date(occ.occurrenceAt);\n return (\n d.getFullYear() === currentDate.getFullYear() &&\n d.getMonth() === currentDate.getMonth() &&\n d.getDate() === currentDate.getDate() &&\n d.getHours() === hour\n );\n });\n\n // Count total tasks for the day\n const dayOccurrences = useMemo(\n () =>\n occurrences.filter((occ) => {\n const d = new Date(occ.occurrenceAt);\n return (\n d.getFullYear() === currentDate.getFullYear() &&\n d.getMonth() === currentDate.getMonth() &&\n d.getDate() === currentDate.getDate()\n );\n }),\n [occurrences, currentDate]\n );\n\n return (\n <div className=\"flex-1 flex flex-col overflow-hidden\">\n {/* Day summary header */}\n <div className=\"flex items-center justify-between px-4 py-2 border-b border-border-default flex-shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div\n className={`flex flex-col items-center px-3 py-1.5 rounded-lg ${\n isToday ? 'bg-action-primary-bg text-action-primary-text' : 'bg-bg-sunken'\n }`}\n >\n <span className=\"text-xs font-medium\">\n {currentDate.toLocaleDateString('en-US', { weekday: 'short' })}\n </span>\n <span className=\"text-lg font-bold\">{currentDate.getDate()}</span>\n </div>\n <div>\n <span className=\"text-sm text-text-secondary\">\n {dayOccurrences.length}{' '}\n {dayOccurrences.length !== 1\n ? tr('vibecontrols.calendar.day.tasksScheduled', 'tasks scheduled')\n : tr('vibecontrols.calendar.day.taskScheduled', 'task scheduled')}\n </span>\n </div>\n </div>\n </div>\n\n {/* Time grid - scrollable */}\n <div className=\"flex-1 overflow-auto\">\n <div className=\"relative\">\n {HOURS.map((hour) => {\n const hourOccurrences = getOccurrencesForHour(hour);\n const isCurrent = isToday && hour === nowHour;\n\n return (\n <div\n key={hour}\n className={`flex border-b border-border-default ${\n isCurrent ? 'bg-action-primary-bg/5' : ''\n }`}\n style={{ minHeight: hourOccurrences.length > 0 ? 'auto' : '48px' }}\n >\n {/* Time label */}\n <div className=\"w-20 flex-shrink-0 text-right pr-3 pt-1.5 border-r border-border-default\">\n <span\n className={`text-xs ${isCurrent ? 'text-action-primary-text font-semibold' : 'text-text-tertiary'}`}\n >\n {formatHour(hour)}\n </span>\n {isCurrent && (\n <div className=\"mt-0.5 text-[10px] text-action-primary-text\">NOW</div>\n )}\n </div>\n\n {/* Tasks */}\n <div className=\"flex-1 p-1 space-y-1\">\n {hourOccurrences.map((occ, j) => {\n const task = occ.task;\n const statusColor =\n STATUS_COLORS[occ.execution?.status || task.status] || STATUS_COLORS.PENDING;\n const time = new Date(occ.occurrenceAt).toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n });\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (() => onViewDetail(task.id))();\n }\n }}\n key={`${task.id}-${j}`}\n onClick={() => onViewDetail(task.id)}\n className={`flex items-center gap-3 px-3 py-2.5 rounded-lg border cursor-pointer ${statusColor} hover:opacity-90 transition-opacity`}\n >\n {/* Time */}\n <div className=\"w-14 text-xs font-mono text-text-secondary flex-shrink-0\">\n {time}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-sm text-text-primary truncate\">\n {task.title}\n </h4>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <span className=\"text-xs text-text-tertiary font-mono truncate\">\n {task.taskConfig.taskType === 'WEBHOOK'\n ? `${task.taskConfig.webhookMethod || 'POST'} ${task.taskConfig.webhookUrl}`\n : task.taskConfig.command || 'Script'}\n </span>\n <span className=\"text-xs text-text-tertiary flex-shrink-0\">\n {task.cronExpression\n ? 'Cron'\n : task.rrule\n ? 'Recurrence'\n : 'One Time'}\n </span>\n </div>\n </div>\n\n {/* Status badge */}\n <span className=\"text-xs px-2 py-0.5 rounded-full border flex-shrink-0\">\n {occ.execution?.status || task.status}\n </span>\n\n {/* Actions */}\n <div\n className=\"flex items-center gap-1 flex-shrink-0\"\n onClick={(e) => e.stopPropagation()}\n >\n {onTriggerNow && (\n <button\n type=\"button\"\n onClick={() => onTriggerNow(task.id)}\n className=\"p-1.5 rounded hover:bg-bg-secondary transition-colors\"\n title=\"Trigger Now\"\n >\n <Play size={14} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onViewLogs(task)}\n className=\"p-1.5 rounded hover:bg-bg-secondary transition-colors\"\n title=\"View Logs\"\n >\n <Eye size={14} />\n </button>\n <ChevronRight size={14} className=\"text-text-tertiary\" />\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VibeCalDayView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalDayView.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Play, Eye, ChevronRight } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalDayViewProps {\n currentDate: Date;\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i);\n\nfunction formatHour(hour: number): string {\n if (hour === 0) return '12 AM';\n if (hour < 12) return `${hour} AM`;\n if (hour === 12) return '12 PM';\n return `${hour - 12} PM`;\n}\n\nexport function VibeCalDayView({\n currentDate,\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalDayViewProps) {\n const tr = useTr();\n const today = new Date();\n\n const isToday =\n currentDate.getFullYear() === today.getFullYear() &&\n currentDate.getMonth() === today.getMonth() &&\n currentDate.getDate() === today.getDate();\n\n const nowHour = today.getHours();\n\n const getOccurrencesForHour = (hour: number): CalendarOccurrence[] =>\n occurrences.filter((occ) => {\n const d = new Date(occ.occurrenceAt);\n return (\n d.getFullYear() === currentDate.getFullYear() &&\n d.getMonth() === currentDate.getMonth() &&\n d.getDate() === currentDate.getDate() &&\n d.getHours() === hour\n );\n });\n\n // Count total tasks for the day\n const dayOccurrences = useMemo(\n () =>\n occurrences.filter((occ) => {\n const d = new Date(occ.occurrenceAt);\n return (\n d.getFullYear() === currentDate.getFullYear() &&\n d.getMonth() === currentDate.getMonth() &&\n d.getDate() === currentDate.getDate()\n );\n }),\n [occurrences, currentDate]\n );\n\n return (\n <div className=\"flex-1 flex flex-col overflow-hidden\">\n {/* Day summary header */}\n <div className=\"flex items-center justify-between px-4 py-2 border-b border-border-default flex-shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div\n className={`flex flex-col items-center px-3 py-1.5 rounded-lg ${\n isToday ? 'bg-action-primary-bg text-action-primary-text' : 'bg-bg-sunken'\n }`}\n >\n <span className=\"text-xs font-medium\">\n {currentDate.toLocaleDateString('en-US', { weekday: 'short' })}\n </span>\n <span className=\"text-lg font-bold\">{currentDate.getDate()}</span>\n </div>\n <div>\n <span className=\"text-sm text-text-secondary\">\n {dayOccurrences.length}{' '}\n {dayOccurrences.length !== 1\n ? tr('vibecontrols.calendar.day.tasksScheduled', 'tasks scheduled')\n : tr('vibecontrols.calendar.day.taskScheduled', 'task scheduled')}\n </span>\n </div>\n </div>\n </div>\n\n {/* Time grid - scrollable */}\n <div className=\"flex-1 overflow-auto\">\n <div className=\"relative\">\n {HOURS.map((hour) => {\n const hourOccurrences = getOccurrencesForHour(hour);\n const isCurrent = isToday && hour === nowHour;\n\n return (\n <div\n key={hour}\n className={`flex border-b border-border-default ${\n isCurrent ? 'bg-[var(--color-accent-soft)]' : ''\n }`}\n style={{ minHeight: hourOccurrences.length > 0 ? 'auto' : '48px' }}\n >\n {/* Time label */}\n <div className=\"w-20 flex-shrink-0 text-right pr-3 pt-1.5 border-r border-border-default\">\n <span\n className={`text-xs ${isCurrent ? 'text-action-primary-text font-semibold' : 'text-text-tertiary'}`}\n >\n {formatHour(hour)}\n </span>\n {isCurrent && (\n <div className=\"mt-0.5 text-[10px] text-action-primary-text\">NOW</div>\n )}\n </div>\n\n {/* Tasks */}\n <div className=\"flex-1 p-1 space-y-1\">\n {hourOccurrences.map((occ, j) => {\n const task = occ.task;\n const statusColor =\n STATUS_COLORS[occ.execution?.status || task.status] || STATUS_COLORS.PENDING;\n const time = new Date(occ.occurrenceAt).toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n });\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (() => onViewDetail(task.id))();\n }\n }}\n key={`${task.id}-${j}`}\n onClick={() => onViewDetail(task.id)}\n className={`flex items-center gap-3 px-3 py-2.5 rounded-lg border cursor-pointer ${statusColor} hover:opacity-90 transition-opacity`}\n >\n {/* Time */}\n <div className=\"w-14 text-xs font-mono text-text-secondary flex-shrink-0\">\n {time}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-sm text-text-primary truncate\">\n {task.title}\n </h4>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <span className=\"text-xs text-text-tertiary font-mono truncate\">\n {task.taskConfig.taskType === 'WEBHOOK'\n ? `${task.taskConfig.webhookMethod || 'POST'} ${task.taskConfig.webhookUrl}`\n : task.taskConfig.command || 'Script'}\n </span>\n <span className=\"text-xs text-text-tertiary flex-shrink-0\">\n {task.cronExpression\n ? 'Cron'\n : task.rrule\n ? 'Recurrence'\n : 'One Time'}\n </span>\n </div>\n </div>\n\n {/* Status badge */}\n <span className=\"text-xs px-2 py-0.5 rounded-full border flex-shrink-0\">\n {occ.execution?.status || task.status}\n </span>\n\n {/* Actions */}\n <div\n className=\"flex items-center gap-1 flex-shrink-0\"\n onClick={(e) => e.stopPropagation()}\n >\n {onTriggerNow && (\n <button\n type=\"button\"\n onClick={() => onTriggerNow(task.id)}\n className=\"p-1.5 rounded hover:bg-bg-surface transition-colors\"\n title=\"Trigger Now\"\n >\n <Play size={14} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onViewLogs(task)}\n className=\"p-1.5 rounded hover:bg-bg-surface transition-colors\"\n title=\"View Logs\"\n >\n <Eye size={14} />\n </button>\n <ChevronRight size={14} className=\"text-text-tertiary\" />\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -33,7 +33,7 @@ function o({ currentDate: o, occurrences: s, onTriggerNow: c, onViewLogs: l, onV
|
|
|
33
33
|
children: y.map((e, a) => {
|
|
34
34
|
let o = e ? b(e) : [], s = o.length - 3;
|
|
35
35
|
return /* @__PURE__ */ r("div", {
|
|
36
|
-
className: `border-b border-r border-border-default p-1 ${e === null ? "bg-bg-sunken" : "bg-bg-surface"} ${x(e) ? "bg-
|
|
36
|
+
className: `border-b border-r border-border-default p-1 ${e === null ? "bg-bg-sunken" : "bg-bg-surface"} ${x(e) ? "bg-[var(--color-accent-soft)]" : ""}`,
|
|
37
37
|
children: e !== null && /* @__PURE__ */ i(n, { children: [/* @__PURE__ */ r("span", {
|
|
38
38
|
className: `inline-flex items-center justify-center size-6 text-xs rounded-full ${x(e) ? "bg-action-primary-bg text-action-primary-text font-bold" : "text-text-secondary"}`,
|
|
39
39
|
children: e
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeCalMonthView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalMonthView.tsx"],"sourcesContent":["import { VibeTaskBlock } from './VibeTaskBlock';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalMonthViewProps {\n currentDate: Date;\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nconst DAYS_OF_WEEK = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nexport function VibeCalMonthView({\n currentDate,\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalMonthViewProps) {\n const tr = useTr();\n const year = currentDate.getFullYear();\n const month = currentDate.getMonth();\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n const startOffset = firstDay.getDay();\n const daysInMonth = lastDay.getDate();\n const today = new Date();\n\n // Build 6x7 grid\n const cells: (number | null)[] = [];\n for (let i = 0; i < startOffset; i++) cells.push(null);\n for (let d = 1; d <= daysInMonth; d++) cells.push(d);\n while (cells.length < 42) cells.push(null);\n\n const getOccurrencesForDay = (day: number): CalendarOccurrence[] => {\n return occurrences.filter((occ) => {\n const occDate = new Date(occ.occurrenceAt);\n return (\n occDate.getFullYear() === year && occDate.getMonth() === month && occDate.getDate() === day\n );\n });\n };\n\n const isToday = (day: number): boolean => {\n return today.getFullYear() === year && today.getMonth() === month && today.getDate() === day;\n };\n\n return (\n <div className=\"flex-1 overflow-auto\">\n {/* Day headers */}\n <div className=\"grid grid-cols-7 border-b border-border-default\">\n {DAYS_OF_WEEK.map((day) => (\n <div key={day} className=\"p-2 text-xs font-medium text-text-tertiary text-center\">\n {day}\n </div>\n ))}\n </div>\n\n {/* Calendar grid */}\n <div className=\"grid grid-cols-7 auto-rows-[minmax(100px,1fr)]\">\n {cells.map((day, i) => {\n const dayOccurrences = day ? getOccurrencesForDay(day) : [];\n const maxVisible = 3;\n const overflow = dayOccurrences.length - maxVisible;\n\n return (\n <div\n key={i}\n className={`border-b border-r border-border-default p-1 ${\n day === null ? 'bg-bg-sunken' : 'bg-bg-surface'\n } ${isToday(day!) ? 'bg-
|
|
1
|
+
{"version":3,"file":"VibeCalMonthView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalMonthView.tsx"],"sourcesContent":["import { VibeTaskBlock } from './VibeTaskBlock';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalMonthViewProps {\n currentDate: Date;\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nconst DAYS_OF_WEEK = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nexport function VibeCalMonthView({\n currentDate,\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalMonthViewProps) {\n const tr = useTr();\n const year = currentDate.getFullYear();\n const month = currentDate.getMonth();\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n const startOffset = firstDay.getDay();\n const daysInMonth = lastDay.getDate();\n const today = new Date();\n\n // Build 6x7 grid\n const cells: (number | null)[] = [];\n for (let i = 0; i < startOffset; i++) cells.push(null);\n for (let d = 1; d <= daysInMonth; d++) cells.push(d);\n while (cells.length < 42) cells.push(null);\n\n const getOccurrencesForDay = (day: number): CalendarOccurrence[] => {\n return occurrences.filter((occ) => {\n const occDate = new Date(occ.occurrenceAt);\n return (\n occDate.getFullYear() === year && occDate.getMonth() === month && occDate.getDate() === day\n );\n });\n };\n\n const isToday = (day: number): boolean => {\n return today.getFullYear() === year && today.getMonth() === month && today.getDate() === day;\n };\n\n return (\n <div className=\"flex-1 overflow-auto\">\n {/* Day headers */}\n <div className=\"grid grid-cols-7 border-b border-border-default\">\n {DAYS_OF_WEEK.map((day) => (\n <div key={day} className=\"p-2 text-xs font-medium text-text-tertiary text-center\">\n {day}\n </div>\n ))}\n </div>\n\n {/* Calendar grid */}\n <div className=\"grid grid-cols-7 auto-rows-[minmax(100px,1fr)]\">\n {cells.map((day, i) => {\n const dayOccurrences = day ? getOccurrencesForDay(day) : [];\n const maxVisible = 3;\n const overflow = dayOccurrences.length - maxVisible;\n\n return (\n <div\n key={i}\n className={`border-b border-r border-border-default p-1 ${\n day === null ? 'bg-bg-sunken' : 'bg-bg-surface'\n } ${isToday(day!) ? 'bg-[var(--color-accent-soft)]' : ''}`}\n >\n {day !== null && (\n <>\n <span\n className={`inline-flex items-center justify-center size-6 text-xs rounded-full ${\n isToday(day)\n ? 'bg-action-primary-bg text-action-primary-text font-bold'\n : 'text-text-secondary'\n }`}\n >\n {day}\n </span>\n <div className=\"mt-1 space-y-0.5\">\n {dayOccurrences.slice(0, maxVisible).map((occ, j) => (\n <VibeTaskBlock\n key={`${occ.task.id}-${j}`}\n task={occ.task}\n compact\n onTriggerNow={onTriggerNow}\n onViewLogs={onViewLogs}\n onViewDetail={onViewDetail}\n />\n ))}\n {overflow > 0 && (\n <span className=\"text-xs text-text-tertiary pl-1\">\n +{overflow} {tr('vibecontrols.calendar.month.more', 'more')}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;AAYA,IAAM,IAAe;CAAC;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAM;AAEtE,SAAgB,EAAiB,EAC/B,gBACA,gBACA,iBACA,eACA,mBACwB;CACxB,IAAM,IAAK,GAAO,EACZ,IAAO,EAAY,aAAa,EAChC,IAAQ,EAAY,UAAU,EAC9B,IAAW,IAAI,KAAK,GAAM,GAAO,EAAE,EACnC,IAAU,IAAI,KAAK,GAAM,IAAQ,GAAG,EAAE,EACtC,IAAc,EAAS,QAAQ,EAC/B,IAAc,EAAQ,SAAS,EAC/B,oBAAQ,IAAI,MAAM,EAGlB,IAA2B,EAAE;AACnC,MAAK,IAAI,IAAI,GAAG,IAAI,GAAa,IAAK,GAAM,KAAK,KAAK;AACtD,MAAK,IAAI,IAAI,GAAG,KAAK,GAAa,IAAK,GAAM,KAAK,EAAE;AACpD,QAAO,EAAM,SAAS,IAAI,GAAM,KAAK,KAAK;CAE1C,IAAM,KAAwB,MACrB,EAAY,QAAQ,MAAQ;EACjC,IAAM,IAAU,IAAI,KAAK,EAAI,aAAa;AAC1C,SACE,EAAQ,aAAa,KAAK,KAAQ,EAAQ,UAAU,KAAK,KAAS,EAAQ,SAAS,KAAK;GAE1F,EAGE,KAAW,MACR,EAAM,aAAa,KAAK,KAAQ,EAAM,UAAU,KAAK,KAAS,EAAM,SAAS,KAAK;AAG3F,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAa,KAAK,MACjB,kBAAC,OAAD;IAAe,WAAU;cACtB;IACG,EAFI,EAEJ,CACN;GACE,CAAA,EAGN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAM,KAAK,GAAK,MAAM;IACrB,IAAM,IAAiB,IAAM,EAAqB,EAAI,GAAG,EAAE,EAErD,IAAW,EAAe,SAAS;AAEzC,WACE,kBAAC,OAAD;KAEE,WAAW,+CACT,MAAQ,OAAO,iBAAiB,gBACjC,GAAG,EAAQ,EAAK,GAAG,kCAAkC;eAErD,MAAQ,QACP,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,QAAD;MACE,WAAW,uEACT,EAAQ,EAAI,GACR,4DACA;gBAGL;MACI,CAAA,EACP,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,EAAe,MAAM,GAAG,EAAW,CAAC,KAAK,GAAK,MAC7C,kBAAC,GAAD;OAEE,MAAM,EAAI;OACV,SAAA;OACc;OACF;OACE;OACd,EANK,GAAG,EAAI,KAAK,GAAG,GAAG,IAMvB,CACF,EACD,IAAW,KACV,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QAAkD;QAC9C;QAAS;QAAE,EAAG,oCAAoC,OAAO;QACtD;SAEL;QACL,EAAA,CAAA;KAED,EAnCC,EAmCD;KAER;GACE,CAAA,CACF"}
|
|
@@ -33,7 +33,7 @@ function u({ currentDate: u, occurrences: d, onTriggerNow: f, onViewLogs: p, onV
|
|
|
33
33
|
children: [/* @__PURE__ */ o("div", {
|
|
34
34
|
className: "flex border-b border-border-default flex-shrink-0",
|
|
35
35
|
children: [/* @__PURE__ */ a("div", { className: "w-16 flex-shrink-0" }), g.map((e, t) => /* @__PURE__ */ o("div", {
|
|
36
|
-
className: `flex-1 text-center py-2 border-l border-border-default ${_(e) ? "bg-
|
|
36
|
+
className: `flex-1 text-center py-2 border-l border-border-default ${_(e) ? "bg-[var(--color-accent-soft)]" : ""}`,
|
|
37
37
|
children: [/* @__PURE__ */ a("div", {
|
|
38
38
|
className: "text-xs text-text-tertiary",
|
|
39
39
|
children: c[t]
|
|
@@ -58,7 +58,7 @@ function u({ currentDate: u, occurrences: d, onTriggerNow: f, onViewLogs: p, onV
|
|
|
58
58
|
}), g.map((n, s) => {
|
|
59
59
|
let c = v(n, e);
|
|
60
60
|
return /* @__PURE__ */ a("div", {
|
|
61
|
-
className: `flex-1 border-l border-t border-border-default p-0.5 ${_(n) && e === y ? "bg-
|
|
61
|
+
className: `flex-1 border-l border-t border-border-default p-0.5 ${_(n) && e === y ? "bg-[var(--color-accent-soft)]" : ""}`,
|
|
62
62
|
children: c.map((e, n) => {
|
|
63
63
|
let s = e.task;
|
|
64
64
|
return /* @__PURE__ */ a("div", {
|
|
@@ -80,13 +80,13 @@ function u({ currentDate: u, occurrences: d, onTriggerNow: f, onViewLogs: p, onV
|
|
|
80
80
|
children: [f && /* @__PURE__ */ a("button", {
|
|
81
81
|
type: "button",
|
|
82
82
|
onClick: () => f(s.id),
|
|
83
|
-
className: "p-0.5 rounded hover:bg-bg-
|
|
83
|
+
className: "p-0.5 rounded hover:bg-bg-surface",
|
|
84
84
|
title: "Trigger Now",
|
|
85
85
|
children: /* @__PURE__ */ a(i, { size: 10 })
|
|
86
86
|
}), /* @__PURE__ */ a("button", {
|
|
87
87
|
type: "button",
|
|
88
88
|
onClick: () => p(s),
|
|
89
|
-
className: "p-0.5 rounded hover:bg-bg-
|
|
89
|
+
className: "p-0.5 rounded hover:bg-bg-surface",
|
|
90
90
|
title: "View Logs",
|
|
91
91
|
children: /* @__PURE__ */ a(r, { size: 10 })
|
|
92
92
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeCalWeekView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalWeekView.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Play, Eye } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalWeekViewProps {\n currentDate: Date;\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i);\nconst DAYS_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nfunction formatHour(hour: number): string {\n if (hour === 0) return '12 AM';\n if (hour < 12) return `${hour} AM`;\n if (hour === 12) return '12 PM';\n return `${hour - 12} PM`;\n}\n\nexport function VibeCalWeekView({\n currentDate,\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalWeekViewProps) {\n const tr = useTr();\n const today = new Date();\n\n // Calculate the week's dates (Sun-Sat)\n const weekDates = useMemo(() => {\n const start = new Date(currentDate);\n start.setDate(start.getDate() - start.getDay());\n return Array.from({ length: 7 }, (_, i) => {\n const d = new Date(start);\n d.setDate(d.getDate() + i);\n return d;\n });\n }, [currentDate]);\n\n const isToday = (date: Date): boolean =>\n date.getFullYear() === today.getFullYear() &&\n date.getMonth() === today.getMonth() &&\n date.getDate() === today.getDate();\n\n const getOccurrencesForSlot = (date: Date, hour: number): CalendarOccurrence[] =>\n occurrences.filter((occ) => {\n const d = new Date(occ.occurrenceAt);\n return (\n d.getFullYear() === date.getFullYear() &&\n d.getMonth() === date.getMonth() &&\n d.getDate() === date.getDate() &&\n d.getHours() === hour\n );\n });\n\n const nowHour = today.getHours();\n\n return (\n <div className=\"flex-1 flex flex-col overflow-hidden\">\n {/* Day column headers */}\n <div className=\"flex border-b border-border-default flex-shrink-0\">\n {/* Time gutter */}\n <div className=\"w-16 flex-shrink-0\" />\n {weekDates.map((date, i) => (\n <div\n key={i}\n className={`flex-1 text-center py-2 border-l border-border-default ${\n isToday(date) ? 'bg-
|
|
1
|
+
{"version":3,"file":"VibeCalWeekView.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalWeekView.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Play, Eye } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { CalendarOccurrence, VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalWeekViewProps {\n currentDate: Date;\n occurrences: CalendarOccurrence[];\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i);\nconst DAYS_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nfunction formatHour(hour: number): string {\n if (hour === 0) return '12 AM';\n if (hour < 12) return `${hour} AM`;\n if (hour === 12) return '12 PM';\n return `${hour - 12} PM`;\n}\n\nexport function VibeCalWeekView({\n currentDate,\n occurrences,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeCalWeekViewProps) {\n const tr = useTr();\n const today = new Date();\n\n // Calculate the week's dates (Sun-Sat)\n const weekDates = useMemo(() => {\n const start = new Date(currentDate);\n start.setDate(start.getDate() - start.getDay());\n return Array.from({ length: 7 }, (_, i) => {\n const d = new Date(start);\n d.setDate(d.getDate() + i);\n return d;\n });\n }, [currentDate]);\n\n const isToday = (date: Date): boolean =>\n date.getFullYear() === today.getFullYear() &&\n date.getMonth() === today.getMonth() &&\n date.getDate() === today.getDate();\n\n const getOccurrencesForSlot = (date: Date, hour: number): CalendarOccurrence[] =>\n occurrences.filter((occ) => {\n const d = new Date(occ.occurrenceAt);\n return (\n d.getFullYear() === date.getFullYear() &&\n d.getMonth() === date.getMonth() &&\n d.getDate() === date.getDate() &&\n d.getHours() === hour\n );\n });\n\n const nowHour = today.getHours();\n\n return (\n <div className=\"flex-1 flex flex-col overflow-hidden\">\n {/* Day column headers */}\n <div className=\"flex border-b border-border-default flex-shrink-0\">\n {/* Time gutter */}\n <div className=\"w-16 flex-shrink-0\" />\n {weekDates.map((date, i) => (\n <div\n key={i}\n className={`flex-1 text-center py-2 border-l border-border-default ${\n isToday(date) ? 'bg-[var(--color-accent-soft)]' : ''\n }`}\n >\n <div className=\"text-xs text-text-tertiary\">{DAYS_SHORT[i]}</div>\n <div\n className={`text-sm font-medium mt-0.5 ${\n isToday(date)\n ? 'inline-flex items-center justify-center size-7 rounded-full bg-action-primary-bg text-action-primary-text'\n : 'text-text-primary'\n }`}\n >\n {date.getDate()}\n </div>\n </div>\n ))}\n </div>\n\n {/* Time grid - scrollable */}\n <div className=\"flex-1 overflow-auto\">\n <div className=\"relative\">\n {HOURS.map((hour) => (\n <div key={hour} className=\"flex\" style={{ minHeight: '48px' }}>\n {/* Time label */}\n <div className=\"w-16 flex-shrink-0 text-right pr-2 pt-0.5\">\n <span className=\"text-xs text-text-tertiary\">{formatHour(hour)}</span>\n </div>\n\n {/* Day columns */}\n {weekDates.map((date, dayIdx) => {\n const slotOccurrences = getOccurrencesForSlot(date, hour);\n const isCurrent = isToday(date) && hour === nowHour;\n\n return (\n <div\n key={dayIdx}\n className={`flex-1 border-l border-t border-border-default p-0.5 ${\n isCurrent ? 'bg-[var(--color-accent-soft)]' : ''\n }`}\n >\n {slotOccurrences.map((occ, j) => {\n const task = occ.task;\n const statusColor =\n STATUS_COLORS[occ.execution?.status || task.status] ||\n STATUS_COLORS.PENDING;\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (() => onViewDetail(task.id))();\n }\n }}\n key={`${task.id}-${j}`}\n onClick={() => onViewDetail(task.id)}\n className={`mb-0.5 px-1.5 py-1 rounded text-xs border cursor-pointer ${statusColor} hover:opacity-80 transition-opacity`}\n >\n <div className=\"flex items-center justify-between gap-1\">\n <span className=\"truncate font-medium\">{task.title}</span>\n <div\n className=\"flex items-center gap-0.5 flex-shrink-0\"\n onClick={(e) => e.stopPropagation()}\n >\n {onTriggerNow && (\n <button\n type=\"button\"\n onClick={() => onTriggerNow(task.id)}\n className=\"p-0.5 rounded hover:bg-bg-surface\"\n title=\"Trigger Now\"\n >\n <Play size={10} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onViewLogs(task)}\n className=\"p-0.5 rounded hover:bg-bg-surface\"\n title=\"View Logs\"\n >\n <Eye size={10} />\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -55,7 +55,7 @@ function d({ currentDate: t, viewMode: i, onDateChange: a, onViewModeChange: o,
|
|
|
55
55
|
/* @__PURE__ */ c("button", {
|
|
56
56
|
type: "button",
|
|
57
57
|
onClick: () => p("today"),
|
|
58
|
-
className: "px-3 py-1.5 text-sm font-medium bg-bg-surface border border-border-default rounded-md hover:bg-bg-
|
|
58
|
+
className: "px-3 py-1.5 text-sm font-medium bg-bg-surface border border-border-default rounded-md hover:bg-bg-surface transition-colors",
|
|
59
59
|
children: f("vibecontrols.calendar.header.today", "Today")
|
|
60
60
|
}),
|
|
61
61
|
/* @__PURE__ */ l("div", {
|
|
@@ -63,12 +63,12 @@ function d({ currentDate: t, viewMode: i, onDateChange: a, onViewModeChange: o,
|
|
|
63
63
|
children: [/* @__PURE__ */ c("button", {
|
|
64
64
|
type: "button",
|
|
65
65
|
onClick: () => p("prev"),
|
|
66
|
-
className: "p-1.5 rounded-md hover:bg-bg-
|
|
66
|
+
className: "p-1.5 rounded-md hover:bg-bg-surface transition-colors",
|
|
67
67
|
children: /* @__PURE__ */ c(n, { size: 18 })
|
|
68
68
|
}), /* @__PURE__ */ c("button", {
|
|
69
69
|
type: "button",
|
|
70
70
|
onClick: () => p("next"),
|
|
71
|
-
className: "p-1.5 rounded-md hover:bg-bg-
|
|
71
|
+
className: "p-1.5 rounded-md hover:bg-bg-surface transition-colors",
|
|
72
72
|
children: /* @__PURE__ */ c(r, { size: 18 })
|
|
73
73
|
})]
|
|
74
74
|
}),
|
|
@@ -116,7 +116,7 @@ function d({ currentDate: t, viewMode: i, onDateChange: a, onViewModeChange: o,
|
|
|
116
116
|
children: u.map(({ mode: e, label: t, icon: n }) => /* @__PURE__ */ l("button", {
|
|
117
117
|
type: "button",
|
|
118
118
|
onClick: () => o(e),
|
|
119
|
-
className: `flex items-center justify-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs transition-colors sm:px-3 sm:text-sm ${i === e ? "bg-action-primary-bg text-action-primary-text" : "text-text-secondary hover:text-text-primary hover:bg-bg-
|
|
119
|
+
className: `flex items-center justify-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs transition-colors sm:px-3 sm:text-sm ${i === e ? "bg-action-primary-bg text-action-primary-text" : "text-text-secondary hover:text-text-primary hover:bg-bg-surface"}`,
|
|
120
120
|
children: [/* @__PURE__ */ c(n, { size: 14 }), t]
|
|
121
121
|
}, e))
|
|
122
122
|
}), d && /* @__PURE__ */ l("button", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeCalendarHeader.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalendarHeader.tsx"],"sourcesContent":["import { ChevronLeft, ChevronRight, Plus, Calendar, List, LayoutGrid, Clock } from 'lucide-react';\nimport type { CalendarViewMode } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalendarHeaderProps {\n currentDate: Date;\n viewMode: CalendarViewMode;\n onDateChange: (date: Date) => void;\n onViewModeChange: (mode: CalendarViewMode) => void;\n onCreateTask?: () => void;\n}\n\nconst VIEW_OPTIONS: { mode: CalendarViewMode; label: string; icon: typeof Calendar }[] = [\n { mode: 'month', label: 'Month', icon: LayoutGrid },\n { mode: 'week', label: 'Week', icon: Calendar },\n { mode: 'day', label: 'Day', icon: Clock },\n { mode: 'agenda', label: 'Agenda', icon: List },\n];\n\nexport function VibeCalendarHeader({\n currentDate,\n viewMode,\n onDateChange,\n onViewModeChange,\n onCreateTask,\n}: VibeCalendarHeaderProps) {\n const tr = useTr();\n const navigateDate = (direction: 'prev' | 'next' | 'today') => {\n if (direction === 'today') {\n onDateChange(new Date());\n return;\n }\n\n const newDate = new Date(currentDate);\n const delta = direction === 'prev' ? -1 : 1;\n\n switch (viewMode) {\n case 'month':\n newDate.setMonth(newDate.getMonth() + delta);\n break;\n case 'week':\n newDate.setDate(newDate.getDate() + delta * 7);\n break;\n case 'day':\n newDate.setDate(newDate.getDate() + delta);\n break;\n case 'agenda':\n newDate.setMonth(newDate.getMonth() + delta);\n break;\n }\n\n onDateChange(newDate);\n };\n\n const formatDateLabel = (): string => {\n const options: Intl.DateTimeFormatOptions = { year: 'numeric' };\n\n switch (viewMode) {\n case 'month':\n return currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });\n case 'week': {\n const weekStart = new Date(currentDate);\n weekStart.setDate(weekStart.getDate() - weekStart.getDay());\n const weekEnd = new Date(weekStart);\n weekEnd.setDate(weekEnd.getDate() + 6);\n return `${weekStart.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} - ${weekEnd.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}`;\n }\n case 'day':\n return currentDate.toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n });\n case 'agenda':\n return currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });\n default:\n return currentDate.toLocaleDateString('en-US', options);\n }\n };\n\n return (\n <div className=\"flex flex-col gap-3 border-b border-border-default pb-4 lg:flex-row lg:items-center lg:justify-between\">\n {/* Left: Navigation */}\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateDate('today')}\n className=\"px-3 py-1.5 text-sm font-medium bg-bg-surface border border-border-default rounded-md hover:bg-bg-
|
|
1
|
+
{"version":3,"file":"VibeCalendarHeader.js","names":[],"sources":["../../../src/components/vibecalendar/VibeCalendarHeader.tsx"],"sourcesContent":["import { ChevronLeft, ChevronRight, Plus, Calendar, List, LayoutGrid, Clock } from 'lucide-react';\nimport type { CalendarViewMode } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeCalendarHeaderProps {\n currentDate: Date;\n viewMode: CalendarViewMode;\n onDateChange: (date: Date) => void;\n onViewModeChange: (mode: CalendarViewMode) => void;\n onCreateTask?: () => void;\n}\n\nconst VIEW_OPTIONS: { mode: CalendarViewMode; label: string; icon: typeof Calendar }[] = [\n { mode: 'month', label: 'Month', icon: LayoutGrid },\n { mode: 'week', label: 'Week', icon: Calendar },\n { mode: 'day', label: 'Day', icon: Clock },\n { mode: 'agenda', label: 'Agenda', icon: List },\n];\n\nexport function VibeCalendarHeader({\n currentDate,\n viewMode,\n onDateChange,\n onViewModeChange,\n onCreateTask,\n}: VibeCalendarHeaderProps) {\n const tr = useTr();\n const navigateDate = (direction: 'prev' | 'next' | 'today') => {\n if (direction === 'today') {\n onDateChange(new Date());\n return;\n }\n\n const newDate = new Date(currentDate);\n const delta = direction === 'prev' ? -1 : 1;\n\n switch (viewMode) {\n case 'month':\n newDate.setMonth(newDate.getMonth() + delta);\n break;\n case 'week':\n newDate.setDate(newDate.getDate() + delta * 7);\n break;\n case 'day':\n newDate.setDate(newDate.getDate() + delta);\n break;\n case 'agenda':\n newDate.setMonth(newDate.getMonth() + delta);\n break;\n }\n\n onDateChange(newDate);\n };\n\n const formatDateLabel = (): string => {\n const options: Intl.DateTimeFormatOptions = { year: 'numeric' };\n\n switch (viewMode) {\n case 'month':\n return currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });\n case 'week': {\n const weekStart = new Date(currentDate);\n weekStart.setDate(weekStart.getDate() - weekStart.getDay());\n const weekEnd = new Date(weekStart);\n weekEnd.setDate(weekEnd.getDate() + 6);\n return `${weekStart.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} - ${weekEnd.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}`;\n }\n case 'day':\n return currentDate.toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n });\n case 'agenda':\n return currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });\n default:\n return currentDate.toLocaleDateString('en-US', options);\n }\n };\n\n return (\n <div className=\"flex flex-col gap-3 border-b border-border-default pb-4 lg:flex-row lg:items-center lg:justify-between\">\n {/* Left: Navigation */}\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateDate('today')}\n className=\"px-3 py-1.5 text-sm font-medium bg-bg-surface border border-border-default rounded-md hover:bg-bg-surface transition-colors\"\n >\n {tr('vibecontrols.calendar.header.today', 'Today')}\n </button>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => navigateDate('prev')}\n className=\"p-1.5 rounded-md hover:bg-bg-surface transition-colors\"\n >\n <ChevronLeft size={18} />\n </button>\n <button\n type=\"button\"\n onClick={() => navigateDate('next')}\n className=\"p-1.5 rounded-md hover:bg-bg-surface transition-colors\"\n >\n <ChevronRight size={18} />\n </button>\n </div>\n <h2 className=\"min-w-0 text-base font-semibold text-text-primary sm:ml-2 sm:text-lg\">\n {formatDateLabel()}\n </h2>\n </div>\n\n {/* Right: View Mode + Create */}\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between lg:justify-end\">\n {/* View Mode Switcher */}\n <div className=\"grid grid-cols-2 gap-1 rounded-lg border border-border-default bg-bg-surface p-1 sm:flex sm:items-center sm:gap-0.5 sm:p-0.5\">\n {VIEW_OPTIONS.map(({ mode, label, icon: Icon }) => (\n <button\n type=\"button\"\n key={mode}\n onClick={() => onViewModeChange(mode)}\n className={`flex items-center justify-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs transition-colors sm:px-3 sm:text-sm ${\n viewMode === mode\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-surface'\n }`}\n >\n <Icon size={14} />\n {label}\n </button>\n ))}\n </div>\n\n {/* Create Task Button */}\n {onCreateTask && (\n <button\n type=\"button\"\n onClick={onCreateTask}\n className=\"flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-opacity hover:opacity-90 sm:w-auto\"\n >\n <Plus size={16} />\n {tr('vibecontrols.calendar.header.scheduleTask', 'Schedule Task')}\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -47,13 +47,13 @@ function o({ task: o, compact: s = !1, onTriggerNow: c, onViewLogs: l, onViewDet
|
|
|
47
47
|
children: [c && /* @__PURE__ */ i("button", {
|
|
48
48
|
type: "button",
|
|
49
49
|
onClick: () => c(o.id),
|
|
50
|
-
className: "p-1 rounded hover:bg-bg-
|
|
50
|
+
className: "p-1 rounded hover:bg-bg-surface transition-colors",
|
|
51
51
|
title: "Trigger Now",
|
|
52
52
|
children: /* @__PURE__ */ i(r, { size: 14 })
|
|
53
53
|
}), /* @__PURE__ */ i("button", {
|
|
54
54
|
type: "button",
|
|
55
55
|
onClick: () => l(o),
|
|
56
|
-
className: "p-1 rounded hover:bg-bg-
|
|
56
|
+
className: "p-1 rounded hover:bg-bg-surface transition-colors",
|
|
57
57
|
title: "View Logs",
|
|
58
58
|
children: /* @__PURE__ */ i(n, { size: 14 })
|
|
59
59
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeTaskBlock.js","names":[],"sources":["../../../src/components/vibecalendar/VibeTaskBlock.tsx"],"sourcesContent":["import { Play, Eye } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeTaskBlockProps {\n task: VibeCalendarTask;\n compact?: boolean;\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nexport function VibeTaskBlock({\n task,\n compact = false,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeTaskBlockProps) {\n const tr = useTr();\n const statusColor = STATUS_COLORS[task.status] || STATUS_COLORS.PENDING;\n const commandPreview = task.taskConfig.command\n ? task.taskConfig.command.length > 40\n ? task.taskConfig.command.slice(0, 40) + '...'\n : task.taskConfig.command\n : task.taskConfig.script\n ? 'Script'\n : 'File Operation';\n\n if (compact) {\n return (\n <button\n type=\"button\"\n onClick={() => onViewDetail(task.id)}\n className={`w-full text-left px-2 py-1 rounded text-xs truncate border ${statusColor} hover:opacity-80 transition-opacity`}\n title={task.title}\n >\n {task.title}\n </button>\n );\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (() => onViewDetail(task.id))();\n }\n }}\n className={`relative p-3 rounded-lg border ${statusColor} hover:opacity-90 transition-opacity cursor-pointer`}\n onClick={() => onViewDetail(task.id)}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-sm text-text-primary truncate\">{task.title}</h4>\n <p className=\"text-xs text-text-secondary mt-0.5 font-mono truncate\">{commandPreview}</p>\n <div className=\"flex items-center gap-2 mt-1.5\">\n {task.nextExecutionAt && (\n <span className=\"text-xs text-text-tertiary\">\n Next: {new Date(task.nextExecutionAt).toLocaleString()}\n </span>\n )}\n </div>\n </div>\n\n {/* Quick Actions */}\n <div className=\"flex items-center gap-1\" onClick={(e) => e.stopPropagation()}>\n {onTriggerNow && (\n <button\n type=\"button\"\n onClick={() => onTriggerNow(task.id)}\n className=\"p-1 rounded hover:bg-bg-
|
|
1
|
+
{"version":3,"file":"VibeTaskBlock.js","names":[],"sources":["../../../src/components/vibecalendar/VibeTaskBlock.tsx"],"sourcesContent":["import { Play, Eye } from 'lucide-react';\nimport { STATUS_COLORS } from './types';\nimport type { VibeCalendarTask } from './types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface VibeTaskBlockProps {\n task: VibeCalendarTask;\n compact?: boolean;\n onTriggerNow?: (taskId: string) => void;\n onViewLogs: (task: VibeCalendarTask) => void;\n onViewDetail: (taskId: string) => void;\n}\n\nexport function VibeTaskBlock({\n task,\n compact = false,\n onTriggerNow,\n onViewLogs,\n onViewDetail,\n}: VibeTaskBlockProps) {\n const tr = useTr();\n const statusColor = STATUS_COLORS[task.status] || STATUS_COLORS.PENDING;\n const commandPreview = task.taskConfig.command\n ? task.taskConfig.command.length > 40\n ? task.taskConfig.command.slice(0, 40) + '...'\n : task.taskConfig.command\n : task.taskConfig.script\n ? 'Script'\n : 'File Operation';\n\n if (compact) {\n return (\n <button\n type=\"button\"\n onClick={() => onViewDetail(task.id)}\n className={`w-full text-left px-2 py-1 rounded text-xs truncate border ${statusColor} hover:opacity-80 transition-opacity`}\n title={task.title}\n >\n {task.title}\n </button>\n );\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (() => onViewDetail(task.id))();\n }\n }}\n className={`relative p-3 rounded-lg border ${statusColor} hover:opacity-90 transition-opacity cursor-pointer`}\n onClick={() => onViewDetail(task.id)}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-sm text-text-primary truncate\">{task.title}</h4>\n <p className=\"text-xs text-text-secondary mt-0.5 font-mono truncate\">{commandPreview}</p>\n <div className=\"flex items-center gap-2 mt-1.5\">\n {task.nextExecutionAt && (\n <span className=\"text-xs text-text-tertiary\">\n Next: {new Date(task.nextExecutionAt).toLocaleString()}\n </span>\n )}\n </div>\n </div>\n\n {/* Quick Actions */}\n <div className=\"flex items-center gap-1\" onClick={(e) => e.stopPropagation()}>\n {onTriggerNow && (\n <button\n type=\"button\"\n onClick={() => onTriggerNow(task.id)}\n className=\"p-1 rounded hover:bg-bg-surface transition-colors\"\n title=\"Trigger Now\"\n >\n <Play size={14} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onViewLogs(task)}\n className=\"p-1 rounded hover:bg-bg-surface transition-colors\"\n title=\"View Logs\"\n >\n <Eye size={14} />\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAaA,SAAgB,EAAc,EAC5B,SACA,aAAU,IACV,iBACA,eACA,mBACqB;AACV,IAAO;CAClB,IAAM,IAAc,EAAc,EAAK,WAAW,EAAc,SAC1D,IAAiB,EAAK,WAAW,UACnC,EAAK,WAAW,QAAQ,SAAS,KAC/B,EAAK,WAAW,QAAQ,MAAM,GAAG,GAAG,GAAG,QACvC,EAAK,WAAW,UAClB,EAAK,WAAW,SACd,WACA;AAeN,QAbI,IAEA,kBAAC,UAAD;EACE,MAAK;EACL,eAAe,EAAa,EAAK,GAAG;EACpC,WAAW,8DAA8D,EAAY;EACrF,OAAO,EAAK;YAEX,EAAK;EACC,CAAA,GAKX,kBAAC,OAAD;EACE,MAAK;EACL,UAAU;EACV,YAAY,MAAM;AAChB,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EACX,EAAa,EAAK,GAAG;;EAGhC,WAAW,kCAAkC,EAAY;EACzD,eAAe,EAAa,EAAK,GAAG;YAEpC,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,MAAD;MAAI,WAAU;gBAAkD,EAAK;MAAW,CAAA;KAChF,kBAAC,KAAD;MAAG,WAAU;gBAAyD;MAAmB,CAAA;KACzF,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAK,mBACJ,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CAA6C,UACpC,IAAI,KAAK,EAAK,gBAAgB,CAAC,gBAAgB,CACjD;;MAEL,CAAA;KACF;OAGN,kBAAC,OAAD;IAAK,WAAU;IAA0B,UAAU,MAAM,EAAE,iBAAiB;cAA5E,CACG,KACC,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAa,EAAK,GAAG;KACpC,WAAU;KACV,OAAM;eAEN,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;KACX,CAAA,EAEX,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAW,EAAK;KAC/B,WAAU;KACV,OAAM;eAEN,kBAAC,GAAD,EAAK,MAAM,IAAM,CAAA;KACV,CAAA,CACL;MACF;;EACF,CAAA"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
//#region src/components/vibecalendar/types.ts
|
|
2
2
|
var e = {
|
|
3
|
-
PENDING: "bg-status-info-bg
|
|
4
|
-
RUNNING: "bg-status-warning-bg
|
|
5
|
-
COMPLETED: "bg-status-success-bg
|
|
6
|
-
FAILED: "bg-status-error-bg
|
|
3
|
+
PENDING: "bg-status-info-bg-subtle text-status-info-text border-status-info-border/30",
|
|
4
|
+
RUNNING: "bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border/30",
|
|
5
|
+
COMPLETED: "bg-status-success-bg-subtle text-status-success-text border-status-success-border/30",
|
|
6
|
+
FAILED: "bg-status-error-bg-subtle text-status-error-text border-status-error-border/30",
|
|
7
7
|
PAUSED: "bg-bg-muted/10 text-text-tertiary border-border-subtle/30",
|
|
8
8
|
CANCELLED: "bg-bg-muted/10 text-text-tertiary border-border-subtle/30",
|
|
9
9
|
DRAFT: "bg-bg-muted/10 text-text-tertiary border-border-subtle/30",
|
|
10
|
-
TIMEOUT: "bg-status-warning-bg
|
|
11
|
-
MANUAL: "bg-accent-purple-subtle text-
|
|
12
|
-
SCHEDULE: "bg-status-info-bg
|
|
10
|
+
TIMEOUT: "bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border/30",
|
|
11
|
+
MANUAL: "bg-accent-purple-subtle text-text-primary border-accent-purple/30",
|
|
12
|
+
SCHEDULE: "bg-status-info-bg-subtle text-status-info-text border-status-info-border/30",
|
|
13
13
|
ARCHIVED: "bg-bg-muted/10 text-text-tertiary border-border-subtle/30",
|
|
14
14
|
DISABLED: "bg-bg-muted/10 text-text-tertiary border-border-subtle/30"
|
|
15
15
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/components/vibecalendar/types.ts"],"sourcesContent":["export type CalendarViewMode = 'month' | 'week' | 'day' | 'agenda';\n\n// Where a calendar tile's data originally came from. Set by\n// client-side mappers ONLY — never present on the GraphQL response.\n// Page handlers branch on this to pick the matching subgraph for\n// mutations and the matching detail route. Omitted = default\n// `vibeCalendarTask` (rows from wspace-calendar-svc).\nexport type VibeCalendarTaskSource = 'scheduledJob' | 'vibeCalendarTask';\n\nexport interface VibeCalendarTask {\n id: string;\n /**\n * Set by client-side mappers (e.g. `jobToVibeCalendarTask`). Reading\n * code branches on this to pick the correct mutation/route. Omitted\n * for real VibeCalendarTask rows fetched from wspace-calendar-svc —\n * treat `undefined` as `'vibeCalendarTask'`.\n */\n source?: VibeCalendarTaskSource;\n title: string;\n description: string | null;\n calendarId: string;\n calendarEventId: string;\n agentId: string;\n taskConfig: {\n taskType: string;\n command?: string | null;\n script?: string | null;\n interpreter?: string | null;\n cwd?: string | null;\n env?: Record<string, string> | null;\n timeout?: number | null;\n webhookUrl?: string | null;\n webhookMethod?: string | null;\n webhookHeaders?: Record<string, string> | null;\n webhookAuthType?: string | null;\n webhookPayload?: Record<string, unknown> | null;\n };\n cronExpression: string | null;\n rrule: string | null;\n scheduledAt: string | null;\n timezone: string;\n nextExecutionAt: string | null;\n lastExecutedAt: string | null;\n status: string;\n totalExecutions: number;\n consecutiveFailures: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface VibeCalendarExecution {\n id: string;\n taskId: string;\n status: string;\n output: string | null;\n exitCode: number | null;\n webhookStatusCode: number | null;\n startedAt: string | null;\n completedAt: string | null;\n error: string | null;\n}\n\nexport interface CalendarOccurrence {\n task: VibeCalendarTask;\n occurrenceAt: string;\n isPast: boolean;\n execution: VibeCalendarExecution | null;\n}\n\nexport const STATUS_COLORS: Record<string, string> = {\n PENDING: 'bg-status-info-bg
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/components/vibecalendar/types.ts"],"sourcesContent":["export type CalendarViewMode = 'month' | 'week' | 'day' | 'agenda';\n\n// Where a calendar tile's data originally came from. Set by\n// client-side mappers ONLY — never present on the GraphQL response.\n// Page handlers branch on this to pick the matching subgraph for\n// mutations and the matching detail route. Omitted = default\n// `vibeCalendarTask` (rows from wspace-calendar-svc).\nexport type VibeCalendarTaskSource = 'scheduledJob' | 'vibeCalendarTask';\n\nexport interface VibeCalendarTask {\n id: string;\n /**\n * Set by client-side mappers (e.g. `jobToVibeCalendarTask`). Reading\n * code branches on this to pick the correct mutation/route. Omitted\n * for real VibeCalendarTask rows fetched from wspace-calendar-svc —\n * treat `undefined` as `'vibeCalendarTask'`.\n */\n source?: VibeCalendarTaskSource;\n title: string;\n description: string | null;\n calendarId: string;\n calendarEventId: string;\n agentId: string;\n taskConfig: {\n taskType: string;\n command?: string | null;\n script?: string | null;\n interpreter?: string | null;\n cwd?: string | null;\n env?: Record<string, string> | null;\n timeout?: number | null;\n webhookUrl?: string | null;\n webhookMethod?: string | null;\n webhookHeaders?: Record<string, string> | null;\n webhookAuthType?: string | null;\n webhookPayload?: Record<string, unknown> | null;\n };\n cronExpression: string | null;\n rrule: string | null;\n scheduledAt: string | null;\n timezone: string;\n nextExecutionAt: string | null;\n lastExecutedAt: string | null;\n status: string;\n totalExecutions: number;\n consecutiveFailures: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface VibeCalendarExecution {\n id: string;\n taskId: string;\n status: string;\n output: string | null;\n exitCode: number | null;\n webhookStatusCode: number | null;\n startedAt: string | null;\n completedAt: string | null;\n error: string | null;\n}\n\nexport interface CalendarOccurrence {\n task: VibeCalendarTask;\n occurrenceAt: string;\n isPast: boolean;\n execution: VibeCalendarExecution | null;\n}\n\nexport const STATUS_COLORS: Record<string, string> = {\n PENDING: 'bg-status-info-bg-subtle text-status-info-text border-status-info-border/30',\n RUNNING: 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border/30',\n COMPLETED: 'bg-status-success-bg-subtle text-status-success-text border-status-success-border/30',\n FAILED: 'bg-status-error-bg-subtle text-status-error-text border-status-error-border/30',\n PAUSED: 'bg-bg-muted/10 text-text-tertiary border-border-subtle/30',\n CANCELLED: 'bg-bg-muted/10 text-text-tertiary border-border-subtle/30',\n DRAFT: 'bg-bg-muted/10 text-text-tertiary border-border-subtle/30',\n TIMEOUT: 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border/30',\n MANUAL: 'bg-accent-purple-subtle text-text-primary border-accent-purple/30',\n SCHEDULE: 'bg-status-info-bg-subtle text-status-info-text border-status-info-border/30',\n // Scheduler-svc JobStatus exclusives — without these the badge\n // silently falls back to PENDING styling on archived/disabled jobs.\n ARCHIVED: 'bg-bg-muted/10 text-text-tertiary border-border-subtle/30',\n DISABLED: 'bg-bg-muted/10 text-text-tertiary border-border-subtle/30',\n};\n"],"mappings":";AAqEA,IAAa,IAAwC;CACnD,SAAS;CACT,SAAS;CACT,WAAW;CACX,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,OAAO;CACP,SAAS;CACT,QAAQ;CACR,UAAU;CAGV,UAAU;CACV,UAAU;CACX"}
|