@agent-native/core 0.134.0 → 0.135.0
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/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +113 -0
- package/corpus/core/docs/content/template-content-developers.mdx +1 -1
- package/corpus/core/package.json +3 -2
- package/corpus/core/src/automations/service.ts +41 -4
- package/corpus/core/src/cli/mcp-config-writers.ts +27 -21
- package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +187 -85
- package/corpus/core/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
- package/corpus/core/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
- package/corpus/core/src/client/agent-page/TimezoneSelect.tsx +241 -0
- package/corpus/core/src/client/agent-page/use-jobs.ts +50 -10
- package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -0
- package/corpus/core/src/client/settings/AccountSettingsCard.tsx +35 -31
- package/corpus/core/src/client/settings/SchedulingTimezoneField.tsx +71 -0
- package/corpus/core/src/client/settings/SettingsRow.tsx +113 -0
- package/corpus/core/src/client/settings/agent-settings-search.ts +2 -1
- package/corpus/core/src/client/settings/index.ts +6 -0
- package/corpus/core/src/integrations/identity.ts +2 -12
- package/corpus/core/src/jobs/actions/list-automation-runs.ts +33 -0
- package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +27 -6
- package/corpus/core/src/jobs/actions/manage-recurring-job.ts +41 -9
- package/corpus/core/src/jobs/background-automation-runner.ts +88 -0
- package/corpus/core/src/jobs/cron.ts +52 -6
- package/corpus/core/src/jobs/frontmatter.ts +20 -0
- package/corpus/core/src/jobs/run-history.ts +242 -0
- package/corpus/core/src/jobs/scheduler.ts +73 -18
- package/corpus/core/src/jobs/tools.ts +54 -6
- package/corpus/core/src/localization/actions/get-localization-preference.ts +2 -2
- package/corpus/core/src/localization/actions/set-localization-preference.ts +49 -11
- package/corpus/core/src/localization/default-messages.ts +27 -0
- package/corpus/core/src/localization/shared.ts +39 -6
- package/corpus/core/src/localization/user-timezone.ts +36 -0
- package/corpus/core/src/org/app-roles-handlers.ts +1 -9
- package/corpus/core/src/org/index.ts +2 -0
- package/corpus/core/src/org/membership.ts +18 -0
- package/corpus/core/src/review/actions/create-review-comment.ts +4 -1
- package/corpus/core/src/review/actions/reply-review-comment.ts +4 -1
- package/corpus/core/src/review/index.ts +5 -0
- package/corpus/core/src/review/notifications.ts +163 -0
- package/corpus/core/src/review/types.ts +7 -0
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/activity-notifications.ts +174 -0
- package/corpus/core/src/server/app-name.ts +31 -0
- package/corpus/core/src/server/better-auth-instance.ts +4 -4
- package/corpus/core/src/server/email-templates.ts +70 -14
- package/corpus/core/src/server/email.ts +66 -3
- package/corpus/core/src/server/index.ts +10 -0
- package/corpus/core/src/sharing/index.ts +5 -0
- package/corpus/core/src/sharing/recipients.ts +67 -0
- package/corpus/core/src/triggers/actions/list-automations.ts +27 -8
- package/corpus/core/src/triggers/actions/manage-automation.ts +17 -6
- package/corpus/core/src/triggers/actions.ts +16 -4
- package/corpus/core/src/triggers/dispatcher.ts +44 -30
- package/corpus/core/src/triggers/routes.ts +19 -6
- package/corpus/core/src/vitest-config.ts +68 -0
- package/corpus/core/vitest.config.ts +5 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +37 -53
- package/corpus/templates/analytics/changelog/2026-08-01-new-error-alerts-now-reach-you-by-email-and-a-scheduled-dash.md +6 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +43 -0
- package/corpus/templates/analytics/server/lib/error-capture.ts +5 -1
- package/corpus/templates/analytics/vitest.config.ts +16 -12
- package/corpus/templates/assets/actions/refresh-generation-run.ts +3 -0
- package/corpus/templates/assets/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/assets/app/hooks/use-assets-prefs.ts +55 -0
- package/corpus/templates/assets/app/i18n-data.ts +30 -0
- package/corpus/templates/assets/app/routes/settings.tsx +58 -55
- package/corpus/templates/assets/changelog/2026-08-01-get-an-email-when-a-generation-you-started-finishes-or-fails.md +6 -0
- package/corpus/templates/assets/server/lib/generation-run-notifications.ts +89 -0
- package/corpus/templates/assets/server/lib/video-runs.ts +8 -1
- package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.get.ts +17 -0
- package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.put.ts +36 -0
- package/corpus/templates/assets/shared/assets-user-prefs.ts +10 -0
- package/corpus/templates/assets/vitest.config.ts +16 -12
- package/corpus/templates/brain/app/routes/settings.tsx +15 -15
- package/corpus/templates/brain/vitest.config.ts +16 -12
- package/corpus/templates/calendar/app/pages/Settings.tsx +32 -40
- package/corpus/templates/calendar/changelog/2026-08-01-language-and-appearance-now-sit-together-in-one-preferences-.md +6 -0
- package/corpus/templates/calendar/vitest.config.ts +16 -12
- package/corpus/templates/chat/app/routes/settings.tsx +14 -22
- package/corpus/templates/chat/vitest.config.ts +9 -0
- package/corpus/templates/clips/.agents/skills/video-editing/SKILL.md +31 -0
- package/corpus/templates/clips/AGENTS.md +1 -0
- package/corpus/templates/clips/actions/add-comment.ts +12 -1
- package/corpus/templates/clips/actions/create-meeting.ts +2 -2
- package/corpus/templates/clips/actions/create-recording.ts +2 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +42 -6
- package/corpus/templates/clips/actions/generate-filmstrip.ts +154 -0
- package/corpus/templates/clips/actions/get-recording-player-data.ts +6 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +2 -2
- package/corpus/templates/clips/actions/lib/ensure-recording-filmstrip.ts +258 -0
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +11 -3
- package/corpus/templates/clips/actions/react-to-comment.ts +13 -0
- package/corpus/templates/clips/actions/react-to-recording.ts +10 -1
- package/corpus/templates/clips/actions/reply-to-comment.ts +12 -1
- package/corpus/templates/clips/actions/stitch-recordings.ts +2 -2
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +152 -23
- package/corpus/templates/clips/app/components/editor/waveform.tsx +237 -75
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +23 -1
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +441 -0
- package/corpus/templates/clips/app/components/settings/slack-section.tsx +329 -0
- package/corpus/templates/clips/app/components/settings/types.ts +14 -0
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +443 -0
- package/corpus/templates/clips/app/hooks/use-secret-status.ts +69 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +9 -1
- package/corpus/templates/clips/app/lib/video-filmstrip.ts +262 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +165 -1351
- package/corpus/templates/clips/changelog/2026-07-27-saved-clips-now-resume-from-the-last-uploaded-byte-after-an-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-meeting-notes-no-longer-transcribe-the-other-side-twice-when.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-editor-timeline-now-shows-video-frames-behind-the-waveform-g.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-email-notifications-now-go-out-when-someone-comments-on-or-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-you-can-now-set-a-default-visibility-for-new-recordings-in-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-01-email-notifications-for-comments-and-reactions-now-actually-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-03-the-desktop-app-now-opens-directly-beneath-its-tray-icon-on-.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +1 -0
- package/corpus/templates/clips/chrome-extension/vitest.config.ts +9 -0
- package/corpus/templates/clips/desktop/package.json +1 -0
- package/corpus/templates/clips/desktop/src/app.tsx +17 -1
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +37 -48
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +331 -36
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +7 -5
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +182 -106
- package/corpus/templates/clips/desktop/src/lib/upload-recovery.ts +129 -0
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +43 -14
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +3 -3
- package/corpus/templates/clips/desktop/src-tauri/src/echo_guard.rs +443 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +815 -15
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +61 -11
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +125 -16
- package/corpus/templates/clips/desktop/vitest.config.ts +9 -0
- package/corpus/templates/clips/server/db/schema.ts +17 -0
- package/corpus/templates/clips/server/jobs/media-verification.ts +4 -0
- package/corpus/templates/clips/server/lib/activity-notifications.ts +185 -0
- package/corpus/templates/clips/server/lib/recording-media-cleanup.ts +2 -0
- package/corpus/templates/clips/server/lib/recording-upload-state.ts +46 -9
- package/corpus/templates/clips/server/lib/recordings.ts +24 -0
- package/corpus/templates/clips/server/lib/resumable-session.ts +10 -4
- package/corpus/templates/clips/server/lib/transactional-email-templates.ts +109 -0
- package/corpus/templates/clips/server/lib/upload-interruption.ts +8 -0
- package/corpus/templates/clips/server/lib/upload-lease.ts +50 -4
- package/corpus/templates/clips/server/lib/video-filmstrip-sprite.ts +207 -0
- package/corpus/templates/clips/server/lib/video-remux.ts +13 -4
- package/corpus/templates/clips/server/plugins/db.ts +16 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +4 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +123 -36
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +159 -29
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +197 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +193 -39
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/resume.get.ts +191 -12
- package/corpus/templates/clips/shared/clips-ai-prefs.ts +6 -0
- package/corpus/templates/clips/shared/feature-flags.ts +12 -0
- package/corpus/templates/clips/shared/recording-core.ts +4 -0
- package/corpus/templates/clips/vitest.config.ts +23 -19
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +6 -4
- package/corpus/templates/content/actions/_database-membership-lock.ts +25 -0
- package/corpus/templates/content/actions/_database-row-batch.ts +6 -2
- package/corpus/templates/content/actions/_database-source-utils.ts +289 -129
- package/corpus/templates/content/actions/_database-utils.ts +12 -3
- package/corpus/templates/content/actions/add-comment.ts +15 -1
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +39 -21
- package/corpus/templates/content/actions/attach-content-database-source.ts +4 -1
- package/corpus/templates/content/actions/change-content-database-source-role.ts +3 -5
- package/corpus/templates/content/actions/duplicate-document-property.ts +59 -46
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +77 -71
- package/corpus/templates/content/actions/list-documents.ts +1 -0
- package/corpus/templates/content/actions/materialize-builder-required-fields.ts +7 -0
- package/corpus/templates/content/actions/remove-database-items.ts +183 -0
- package/corpus/templates/content/actions/set-document-property.ts +57 -39
- package/corpus/templates/content/actions/sync-local-folder-source.ts +7 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +5 -2
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +50 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +471 -329
- package/corpus/templates/content/app/components/editor/database/row-access.ts +45 -0
- package/corpus/templates/content/app/components/editor/database/shared.tsx +141 -38
- package/corpus/templates/content/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +2 -2
- package/corpus/templates/content/app/hooks/use-content-prefs.ts +55 -0
- package/corpus/templates/content/app/i18n-data.ts +170 -0
- package/corpus/templates/content/app/routes/_app.settings.tsx +47 -18
- package/corpus/templates/content/changelog/2026-07-30-breadcrumb-menus-now-hide-internal-system-pages.md +6 -0
- package/corpus/templates/content/changelog/2026-07-30-database-rows-can-now-be-removed-without-deleting-their-page.md +6 -0
- package/corpus/templates/content/changelog/2026-08-01-get-an-email-when-someone-comments-on-replies-in-or-mentions.md +6 -0
- package/corpus/templates/content/parity/eval-scenarios.ts +2 -2
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +4 -5
- package/corpus/templates/content/server/lib/comment-notifications.ts +146 -0
- package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.get.ts +17 -0
- package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.put.ts +36 -0
- package/corpus/templates/content/shared/api.ts +4 -0
- package/corpus/templates/content/shared/content-user-prefs.ts +11 -0
- package/corpus/templates/content/vitest.config.ts +20 -16
- package/corpus/templates/crm/app/routes/settings.tsx +14 -22
- package/corpus/templates/crm/vitest.config.ts +8 -4
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +26 -11
- package/corpus/templates/design/actions/take-design-screenshot.ts +7 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +11 -3
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +4 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +54 -17
- package/corpus/templates/design/app/components/design/design-canvas/local-runtime.ts +126 -0
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +2 -0
- package/corpus/templates/design/app/pages/Index.tsx +3 -1
- package/corpus/templates/design/app/pages/Present.tsx +2 -1
- package/corpus/templates/design/app/routes/settings.tsx +14 -22
- package/corpus/templates/design/changelog/2026-07-30-a-broken-inline-script-in-a-generated-screen-is-now-caught-o.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-design-html-is-now-validated-with-a-spec-grade-html-parser-i.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-designs-now-load-their-tailwind-and-alpine-runtimes-from-the.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-designs-with-a-broken-alpine-expression-are-now-caught-on-sa.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-editing-a-design-no-longer-strips-its-styling-the-canvas-kep.md +6 -0
- package/corpus/templates/design/changelog/2026-08-01-review-comments-replies-and-mentions-now-send-an-email-to-th.md +6 -0
- package/corpus/templates/design/package.json +4 -0
- package/corpus/templates/design/shared/html-integrity.ts +802 -556
- package/corpus/templates/design/vitest.config.ts +18 -12
- package/corpus/templates/dispatch/app/routes/settings.tsx +26 -40
- package/corpus/templates/dispatch/vitest.config.ts +11 -7
- package/corpus/templates/factory/app/routes/settings.tsx +14 -22
- package/corpus/templates/factory/vitest.config.ts +9 -0
- package/corpus/templates/forms/app/routes/_app.settings.tsx +14 -22
- package/corpus/templates/forms/vitest.config.ts +27 -23
- package/corpus/templates/macros/app/routes/settings.tsx +14 -22
- package/corpus/templates/macros/vitest.config.ts +16 -12
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +14 -16
- package/corpus/templates/mail/vitest.config.ts +16 -12
- package/corpus/templates/plan/app/routes/settings.tsx +30 -44
- package/corpus/templates/plan/vitest.config.ts +24 -20
- package/corpus/templates/slides/actions/add-slide-comment.ts +12 -1
- package/corpus/templates/slides/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/slides/app/hooks/use-slides-prefs.ts +55 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/routes/settings.tsx +45 -22
- package/corpus/templates/slides/changelog/2026-08-01-get-an-email-when-someone-comments-on-or-replies-in-your-dec.md +6 -0
- package/corpus/templates/slides/server/lib/comment-notifications.ts +182 -0
- package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.get.ts +16 -0
- package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.put.ts +36 -0
- package/corpus/templates/slides/shared/slides-user-prefs.ts +11 -0
- package/corpus/templates/slides/vitest.config.ts +17 -13
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +2 -0
- package/corpus/templates/tasks/app/routes/settings.tsx +14 -22
- package/corpus/templates/tasks/vitest.config.ts +17 -13
- package/corpus/toolkit/CHANGELOG.md +9 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/vitest.config.ts +3 -0
- package/dist/automations/service.d.ts +2 -0
- package/dist/automations/service.d.ts.map +1 -1
- package/dist/automations/service.js +29 -4
- package/dist/automations/service.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +24 -23
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.js +86 -29
- package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
- package/dist/client/agent-page/AutomationDetailsDialog.d.ts +21 -0
- package/dist/client/agent-page/AutomationDetailsDialog.d.ts.map +1 -0
- package/dist/client/agent-page/AutomationDetailsDialog.js +33 -0
- package/dist/client/agent-page/AutomationDetailsDialog.js.map +1 -0
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts +15 -0
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts.map +1 -0
- package/dist/client/agent-page/AutomationScheduleDialog.js +46 -0
- package/dist/client/agent-page/AutomationScheduleDialog.js.map +1 -0
- package/dist/client/agent-page/TimezoneSelect.d.ts +17 -0
- package/dist/client/agent-page/TimezoneSelect.d.ts.map +1 -0
- package/dist/client/agent-page/TimezoneSelect.js +107 -0
- package/dist/client/agent-page/TimezoneSelect.js.map +1 -0
- package/dist/client/agent-page/use-jobs.d.ts +20 -7
- package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
- package/dist/client/agent-page/use-jobs.js +24 -4
- package/dist/client/agent-page/use-jobs.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +8 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/settings/AccountSettingsCard.d.ts.map +1 -1
- package/dist/client/settings/AccountSettingsCard.js +10 -9
- package/dist/client/settings/AccountSettingsCard.js.map +1 -1
- package/dist/client/settings/SchedulingTimezoneField.d.ts +10 -0
- package/dist/client/settings/SchedulingTimezoneField.d.ts.map +1 -0
- package/dist/client/settings/SchedulingTimezoneField.js +30 -0
- package/dist/client/settings/SchedulingTimezoneField.js.map +1 -0
- package/dist/client/settings/SettingsRow.d.ts +36 -0
- package/dist/client/settings/SettingsRow.d.ts.map +1 -0
- package/dist/client/settings/SettingsRow.js +15 -0
- package/dist/client/settings/SettingsRow.js.map +1 -0
- package/dist/client/settings/agent-settings-search.d.ts.map +1 -1
- package/dist/client/settings/agent-settings-search.js +1 -1
- package/dist/client/settings/agent-settings-search.js.map +1 -1
- package/dist/client/settings/index.d.ts +1 -0
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js +1 -0
- package/dist/client/settings/index.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/identity.d.ts.map +1 -1
- package/dist/integrations/identity.js +2 -11
- package/dist/integrations/identity.js.map +1 -1
- package/dist/jobs/actions/list-automation-runs.d.ts +8 -0
- package/dist/jobs/actions/list-automation-runs.d.ts.map +1 -0
- package/dist/jobs/actions/list-automation-runs.js +29 -0
- package/dist/jobs/actions/list-automation-runs.js.map +1 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts +2 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
- package/dist/jobs/actions/list-recurring-jobs.js +20 -7
- package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
- package/dist/jobs/actions/manage-recurring-job.d.ts +2 -0
- package/dist/jobs/actions/manage-recurring-job.js +30 -9
- package/dist/jobs/actions/manage-recurring-job.js.map +1 -1
- package/dist/jobs/background-automation-runner.d.ts.map +1 -1
- package/dist/jobs/background-automation-runner.js +60 -0
- package/dist/jobs/background-automation-runner.js.map +1 -1
- package/dist/jobs/cron.d.ts +16 -2
- package/dist/jobs/cron.d.ts.map +1 -1
- package/dist/jobs/cron.js +43 -6
- package/dist/jobs/cron.js.map +1 -1
- package/dist/jobs/frontmatter.d.ts +12 -0
- package/dist/jobs/frontmatter.d.ts.map +1 -1
- package/dist/jobs/frontmatter.js +8 -0
- package/dist/jobs/frontmatter.js.map +1 -1
- package/dist/jobs/run-history.d.ts +56 -0
- package/dist/jobs/run-history.d.ts.map +1 -0
- package/dist/jobs/run-history.js +169 -0
- package/dist/jobs/run-history.js.map +1 -0
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +51 -18
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +37 -6
- package/dist/jobs/tools.js.map +1 -1
- package/dist/localization/actions/get-localization-preference.d.ts +1 -2
- package/dist/localization/actions/get-localization-preference.d.ts.map +1 -1
- package/dist/localization/actions/get-localization-preference.js.map +1 -1
- package/dist/localization/actions/set-localization-preference.d.ts +3 -3
- package/dist/localization/actions/set-localization-preference.d.ts.map +1 -1
- package/dist/localization/actions/set-localization-preference.js +33 -8
- package/dist/localization/actions/set-localization-preference.js.map +1 -1
- package/dist/localization/default-messages.d.ts +25 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +25 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/localization/shared.d.ts +16 -1
- package/dist/localization/shared.d.ts.map +1 -1
- package/dist/localization/shared.js +22 -4
- package/dist/localization/shared.js.map +1 -1
- package/dist/localization/user-timezone.d.ts +11 -0
- package/dist/localization/user-timezone.d.ts.map +1 -0
- package/dist/localization/user-timezone.js +31 -0
- package/dist/localization/user-timezone.js.map +1 -0
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +1 -1
- package/dist/org/app-roles-handlers.d.ts.map +1 -1
- package/dist/org/app-roles-handlers.js +1 -8
- package/dist/org/app-roles-handlers.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/membership.d.ts +6 -0
- package/dist/org/membership.d.ts.map +1 -0
- package/dist/org/membership.js +16 -0
- package/dist/org/membership.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +10 -10
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/review/actions/create-review-comment.d.ts +32 -1
- package/dist/review/actions/create-review-comment.d.ts.map +1 -1
- package/dist/review/actions/create-review-comment.js +3 -1
- package/dist/review/actions/create-review-comment.js.map +1 -1
- package/dist/review/actions/reply-review-comment.d.ts +32 -1
- package/dist/review/actions/reply-review-comment.d.ts.map +1 -1
- package/dist/review/actions/reply-review-comment.js +3 -1
- package/dist/review/actions/reply-review-comment.js.map +1 -1
- package/dist/review/index.d.ts +1 -0
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +1 -0
- package/dist/review/index.js.map +1 -1
- package/dist/review/notifications.d.ts +24 -0
- package/dist/review/notifications.d.ts.map +1 -0
- package/dist/review/notifications.js +123 -0
- package/dist/review/notifications.js.map +1 -0
- package/dist/review/types.d.ts +5 -0
- package/dist/review/types.d.ts.map +1 -1
- package/dist/review/types.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/activity-notifications.d.ts +61 -0
- package/dist/server/activity-notifications.d.ts.map +1 -0
- package/dist/server/activity-notifications.js +103 -0
- package/dist/server/activity-notifications.js.map +1 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/app-name.d.ts +18 -0
- package/dist/server/app-name.d.ts.map +1 -1
- package/dist/server/app-name.js +31 -0
- package/dist/server/app-name.js.map +1 -1
- package/dist/server/better-auth-instance.js +4 -4
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/email-templates.d.ts +12 -0
- package/dist/server/email-templates.d.ts.map +1 -1
- package/dist/server/email-templates.js +57 -14
- package/dist/server/email-templates.js.map +1 -1
- package/dist/server/email.d.ts +12 -0
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +52 -5
- package/dist/server/email.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/sharing/index.d.ts +1 -0
- package/dist/sharing/index.d.ts.map +1 -1
- package/dist/sharing/index.js +1 -0
- package/dist/sharing/index.js.map +1 -1
- package/dist/sharing/recipients.d.ts +31 -0
- package/dist/sharing/recipients.d.ts.map +1 -0
- package/dist/sharing/recipients.js +40 -0
- package/dist/sharing/recipients.js.map +1 -0
- package/dist/templates/chat/app/routes/settings.tsx +14 -22
- package/dist/templates/chat/vitest.config.ts +9 -0
- package/dist/triggers/actions/list-automations.d.ts +2 -0
- package/dist/triggers/actions/list-automations.d.ts.map +1 -1
- package/dist/triggers/actions/list-automations.js +19 -8
- package/dist/triggers/actions/list-automations.js.map +1 -1
- package/dist/triggers/actions/manage-automation.d.ts +6 -0
- package/dist/triggers/actions/manage-automation.js +12 -6
- package/dist/triggers/actions/manage-automation.js.map +1 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +15 -4
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +19 -17
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/routes.d.ts.map +1 -1
- package/dist/triggers/routes.js +6 -6
- package/dist/triggers/routes.js.map +1 -1
- package/dist/vitest-config.d.ts +10 -0
- package/dist/vitest-config.d.ts.map +1 -0
- package/dist/vitest-config.js +55 -0
- package/dist/vitest-config.js.map +1 -0
- package/docs/content/template-content-developers.mdx +1 -1
- package/package.json +5 -4
- package/src/automations/service.ts +41 -4
- package/src/cli/mcp-config-writers.ts +27 -21
- package/src/client/agent-page/AgentJobsTab.tsx +187 -85
- package/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
- package/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
- package/src/client/agent-page/TimezoneSelect.tsx +241 -0
- package/src/client/agent-page/use-jobs.ts +50 -10
- package/src/client/org/OrgSwitcher.tsx +26 -0
- package/src/client/settings/AccountSettingsCard.tsx +35 -31
- package/src/client/settings/SchedulingTimezoneField.tsx +71 -0
- package/src/client/settings/SettingsRow.tsx +113 -0
- package/src/client/settings/agent-settings-search.ts +2 -1
- package/src/client/settings/index.ts +6 -0
- package/src/integrations/identity.ts +2 -12
- package/src/jobs/actions/list-automation-runs.ts +33 -0
- package/src/jobs/actions/list-recurring-jobs.ts +27 -6
- package/src/jobs/actions/manage-recurring-job.ts +41 -9
- package/src/jobs/background-automation-runner.ts +88 -0
- package/src/jobs/cron.ts +52 -6
- package/src/jobs/frontmatter.ts +20 -0
- package/src/jobs/run-history.ts +242 -0
- package/src/jobs/scheduler.ts +73 -18
- package/src/jobs/tools.ts +54 -6
- package/src/localization/actions/get-localization-preference.ts +2 -2
- package/src/localization/actions/set-localization-preference.ts +49 -11
- package/src/localization/default-messages.ts +27 -0
- package/src/localization/shared.ts +39 -6
- package/src/localization/user-timezone.ts +36 -0
- package/src/org/app-roles-handlers.ts +1 -9
- package/src/org/index.ts +2 -0
- package/src/org/membership.ts +18 -0
- package/src/review/actions/create-review-comment.ts +4 -1
- package/src/review/actions/reply-review-comment.ts +4 -1
- package/src/review/index.ts +5 -0
- package/src/review/notifications.ts +163 -0
- package/src/review/types.ts +7 -0
- package/src/server/action-discovery.ts +4 -0
- package/src/server/activity-notifications.ts +174 -0
- package/src/server/app-name.ts +31 -0
- package/src/server/better-auth-instance.ts +4 -4
- package/src/server/email-templates.ts +70 -14
- package/src/server/email.ts +66 -3
- package/src/server/index.ts +10 -0
- package/src/sharing/index.ts +5 -0
- package/src/sharing/recipients.ts +67 -0
- package/src/templates/chat/app/routes/settings.tsx +14 -22
- package/src/templates/chat/vitest.config.ts +9 -0
- package/src/triggers/actions/list-automations.ts +27 -8
- package/src/triggers/actions/manage-automation.ts +17 -6
- package/src/triggers/actions.ts +16 -4
- package/src/triggers/dispatcher.ts +44 -30
- package/src/triggers/routes.ts +19 -6
- package/src/vitest-config.ts +68 -0
- package/corpus/templates/content/actions/delete-database-items.ts +0 -89
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button } from "@agent-native/toolkit/ui/button";
|
|
3
|
-
import { IconBolt, IconCalendarEvent, IconClock, IconEye, IconLoader2, IconPlayerPause, IconPlayerPlay, IconTrash, } from "@tabler/icons-react";
|
|
3
|
+
import { IconBolt, IconCalendarEvent, IconClock, IconAlertTriangle, IconEye, IconLoader2, IconPencil, IconPlayerPause, IconPlayerPlay, IconTrash, } from "@tabler/icons-react";
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import { AgentAskPopover } from "../AgentAskPopover.js";
|
|
6
6
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../components/ui/dialog.js";
|
|
@@ -8,6 +8,8 @@ import { useFormatters, useT } from "../i18n.js";
|
|
|
8
8
|
import { automationCreationContext } from "../settings/AutomationsSection.js";
|
|
9
9
|
import { AgentEmptyState } from "./AgentEmptyState.js";
|
|
10
10
|
import { AgentTabFrame } from "./AgentTabFrame.js";
|
|
11
|
+
import { AutomationDetailsDialog, } from "./AutomationDetailsDialog.js";
|
|
12
|
+
import { AutomationScheduleDialog } from "./AutomationScheduleDialog.js";
|
|
11
13
|
import { useAutomations, useManageAutomation, useManageRecurringJob, useRecurringJobs, } from "./use-jobs.js";
|
|
12
14
|
function listRecurringJobs(jobs) {
|
|
13
15
|
return jobs.map((resource) => ({
|
|
@@ -23,6 +25,74 @@ function listAutomations(automations) {
|
|
|
23
25
|
triggerType: resource.triggerType,
|
|
24
26
|
}));
|
|
25
27
|
}
|
|
28
|
+
function describeTrigger(entry, t) {
|
|
29
|
+
if (entry.kind === "automation" && entry.triggerType === "event") {
|
|
30
|
+
return t("jobs.automationEventDetails", {
|
|
31
|
+
defaultValue: "Runs when {{event}}.",
|
|
32
|
+
event: entry.resource.event ?? "an event fires",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return (entry.resource.scheduleDescription ||
|
|
36
|
+
entry.resource.schedule ||
|
|
37
|
+
t("jobs.scheduledTrigger", { defaultValue: "Scheduled" }));
|
|
38
|
+
}
|
|
39
|
+
function detailsFields(entry, t, formatDateTime) {
|
|
40
|
+
const resource = entry.resource;
|
|
41
|
+
const unset = t("jobs.notSet", { defaultValue: "—" });
|
|
42
|
+
const fields = [
|
|
43
|
+
{
|
|
44
|
+
label: t("jobs.status", { defaultValue: "Status" }),
|
|
45
|
+
value: resource.enabled
|
|
46
|
+
? t("jobs.enabled", { defaultValue: "Enabled" })
|
|
47
|
+
: t("jobs.paused", { defaultValue: "Paused" }),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: t("jobs.trigger", { defaultValue: "Trigger" }),
|
|
51
|
+
value: entry.triggerType === "event"
|
|
52
|
+
? t("jobs.eventTrigger", { defaultValue: "Event-triggered" })
|
|
53
|
+
: t("jobs.scheduledTrigger", { defaultValue: "Scheduled" }),
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
if (entry.triggerType === "schedule") {
|
|
57
|
+
fields.push({
|
|
58
|
+
label: t("jobs.cronExpression", { defaultValue: "Cron expression" }),
|
|
59
|
+
value: resource.schedule || unset,
|
|
60
|
+
mono: true,
|
|
61
|
+
}, {
|
|
62
|
+
label: t("jobs.timezone", { defaultValue: "Timezone" }),
|
|
63
|
+
value: resource.timezone || unset,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
fields.push({
|
|
67
|
+
label: t("jobs.nextRun", { defaultValue: "Next run" }),
|
|
68
|
+
value: formatDateTime(resource.nextRun) ?? unset,
|
|
69
|
+
}, {
|
|
70
|
+
label: t("jobs.lastRun", { defaultValue: "Last run" }),
|
|
71
|
+
value: formatDateTime(resource.lastRun) ??
|
|
72
|
+
t("jobs.neverRan", { defaultValue: "Never" }),
|
|
73
|
+
}, {
|
|
74
|
+
label: t("jobs.lastChecked", { defaultValue: "Last checked" }),
|
|
75
|
+
value: formatDateTime(resource.lastCheck) ?? unset,
|
|
76
|
+
}, {
|
|
77
|
+
label: t("jobs.lastStatus", { defaultValue: "Last status" }),
|
|
78
|
+
value: resource.lastStatus || unset,
|
|
79
|
+
}, {
|
|
80
|
+
label: t("jobs.scope", { defaultValue: "Scope" }),
|
|
81
|
+
value: resource.scope === "organization"
|
|
82
|
+
? t("jobs.organization", { defaultValue: "Organization" })
|
|
83
|
+
: t("jobs.personal", { defaultValue: "Personal" }),
|
|
84
|
+
}, {
|
|
85
|
+
label: t("jobs.createdBy", { defaultValue: "Created by" }),
|
|
86
|
+
value: resource.createdBy || unset,
|
|
87
|
+
});
|
|
88
|
+
if (entry.kind === "automation") {
|
|
89
|
+
fields.push({
|
|
90
|
+
label: t("jobs.model", { defaultValue: "Model" }),
|
|
91
|
+
value: entry.resource.model || unset,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return fields;
|
|
95
|
+
}
|
|
26
96
|
export function organizationAutomationCreationContext() {
|
|
27
97
|
return "The user wants to create a new organization automation. Use manage-automations with action=define and scope=organization to create it. Ask clarifying questions if needed about whether it runs on a schedule or event, any conditions, and what actions to take.";
|
|
28
98
|
}
|
|
@@ -39,6 +109,7 @@ export function AgentJobsTab({ canManageOrg = false }) {
|
|
|
39
109
|
const organizationAutomationsMutation = useManageAutomation("org");
|
|
40
110
|
const [deleteTarget, setDeleteTarget] = useState(null);
|
|
41
111
|
const [detailsTarget, setDetailsTarget] = useState(null);
|
|
112
|
+
const [scheduleTarget, setScheduleTarget] = useState(null);
|
|
42
113
|
const formatDateTime = (value) => {
|
|
43
114
|
if (!value || Number.isNaN(new Date(value).getTime()))
|
|
44
115
|
return null;
|
|
@@ -61,12 +132,12 @@ export function AgentJobsTab({ canManageOrg = false }) {
|
|
|
61
132
|
personalAutomationsMutation.isPending ||
|
|
62
133
|
organizationJobsMutation.isPending ||
|
|
63
134
|
organizationAutomationsMutation.isPending;
|
|
64
|
-
const mutateEntry = (entry, operation,
|
|
135
|
+
const mutateEntry = (entry, operation, patch, onSuccess) => {
|
|
65
136
|
const input = {
|
|
66
137
|
operation,
|
|
67
138
|
name: entry.resource.name,
|
|
68
139
|
scope: entry.resource.scope,
|
|
69
|
-
...
|
|
140
|
+
...patch,
|
|
70
141
|
};
|
|
71
142
|
const options = onSuccess ? { onSuccess } : undefined;
|
|
72
143
|
if (entry.kind === "automation") {
|
|
@@ -111,6 +182,7 @@ export function AgentJobsTab({ canManageOrg = false }) {
|
|
|
111
182
|
}) })) })) : (_jsx("div", { className: "divide-y divide-border/60 border-y border-border/60", children: entries.map((entry) => {
|
|
112
183
|
const resource = entry.resource;
|
|
113
184
|
const lastRun = formatDateTime(resource.lastRun);
|
|
185
|
+
const lastCheck = formatDateTime(resource.lastCheck);
|
|
114
186
|
const nextRun = formatDateTime(resource.nextRun);
|
|
115
187
|
const triggerDescription = entry.kind === "automation" && entry.triggerType === "event"
|
|
116
188
|
? t("jobs.automationEventTrigger", {
|
|
@@ -135,7 +207,12 @@ export function AgentJobsTab({ canManageOrg = false }) {
|
|
|
135
207
|
? "rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400"
|
|
136
208
|
: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: resource.enabled
|
|
137
209
|
? t("jobs.enabled", { defaultValue: "Enabled" })
|
|
138
|
-
: t("jobs.paused", { defaultValue: "Paused" }) }), resource.lastStatus ? (_jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: resource.lastStatus })) : null] }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: triggerDescription }), _jsx("p", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground/80", children: instructions }), lastRun || nextRun ? (_jsxs("div", { className: "mt-2 flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground", children: [nextRun ? (_jsxs("span", { children: [t("jobs.nextRun", { defaultValue: "Next run" }), ":", " ", nextRun] })) : null,
|
|
210
|
+
: t("jobs.paused", { defaultValue: "Paused" }) }), resource.lastStatus ? (_jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: resource.lastStatus })) : null] }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: triggerDescription }), _jsx("p", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground/80", children: instructions }), lastRun || nextRun || lastCheck ? (_jsxs("div", { className: "mt-2 flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground", children: [nextRun ? (_jsxs("span", { children: [t("jobs.nextRun", { defaultValue: "Next run" }), ":", " ", nextRun] })) : null, _jsxs("span", { children: [t("jobs.lastRun", { defaultValue: "Last run" }), ":", " ", lastRun ??
|
|
211
|
+
t("jobs.neverRan", { defaultValue: "Never" })] }), !lastRun && lastCheck ? (_jsxs("span", { children: [t("jobs.lastChecked", {
|
|
212
|
+
defaultValue: "Last checked",
|
|
213
|
+
}), ": ", lastCheck] })) : null] })) : null, resource.lastError ? (_jsxs("p", { className: "mt-2 flex items-start gap-1.5 text-[11px] text-destructive", children: [_jsx(IconAlertTriangle, { className: "mt-px size-3 shrink-0" }), _jsx("span", { className: "min-w-0 break-words", children: resource.lastError })] })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", onClick: () => setDetailsTarget(entry), children: [_jsx(IconEye, { className: "size-3.5" }), t("jobs.details", { defaultValue: "Details" })] }), resource.canUpdate ? (_jsxs(_Fragment, { children: [entry.triggerType === "schedule" ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending, onClick: () => setScheduleTarget(entry), children: [_jsx(IconPencil, { className: "size-3.5" }), t("jobs.edit", { defaultValue: "Edit" })] })) : null, _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending, onClick: () => mutateEntry(entry, "update", {
|
|
214
|
+
enabled: !resource.enabled,
|
|
215
|
+
}), children: [resource.enabled ? (_jsx(IconPlayerPause, { className: "size-3.5" })) : (_jsx(IconPlayerPlay, { className: "size-3.5" })), resource.enabled
|
|
139
216
|
? t("jobs.pause", { defaultValue: "Pause" })
|
|
140
217
|
: t("jobs.resume", { defaultValue: "Resume" })] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 cursor-pointer text-muted-foreground hover:text-destructive", "aria-label": t("jobs.delete", {
|
|
141
218
|
defaultValue: "Delete",
|
|
@@ -191,30 +268,10 @@ export function AgentJobsTab({ canManageOrg = false }) {
|
|
|
191
268
|
if (!deleteTarget)
|
|
192
269
|
return;
|
|
193
270
|
mutateEntry(deleteTarget, "delete", undefined, () => setDeleteTarget(null));
|
|
194
|
-
}, children: [mutationPending ? (_jsx(IconLoader2, { className: "size-4 animate-spin" })) : null, t("jobs.delete", { defaultValue: "Delete" })] })] })] }) }), _jsx(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
defaultValue: "Automation details",
|
|
200
|
-
}) }), _jsx(DialogDescription, { children: detailsTarget
|
|
201
|
-
? detailsTarget.triggerType === "event"
|
|
202
|
-
? t("jobs.automationEventDetails", {
|
|
203
|
-
defaultValue: "Runs when {{event}}.",
|
|
204
|
-
event: detailsTarget.kind === "automation"
|
|
205
|
-
? (detailsTarget.resource.event ?? "an event fires")
|
|
206
|
-
: "an event fires",
|
|
207
|
-
})
|
|
208
|
-
: detailsTarget.resource.scheduleDescription ||
|
|
209
|
-
detailsTarget.resource.schedule ||
|
|
210
|
-
t("jobs.scheduledTrigger", {
|
|
211
|
-
defaultValue: "Scheduled",
|
|
212
|
-
})
|
|
213
|
-
: null })] }), detailsTarget ? (_jsxs("div", { className: "space-y-3", children: [detailsTarget.kind === "automation" &&
|
|
214
|
-
detailsTarget.resource.condition ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.condition", { defaultValue: "Condition" }) }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: detailsTarget.resource.condition })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.instructions", { defaultValue: "Instructions" }) }), _jsx("p", { className: "mt-1 whitespace-pre-wrap text-sm text-muted-foreground", children: detailsTarget.kind === "automation"
|
|
215
|
-
? detailsTarget.resource.body
|
|
216
|
-
: detailsTarget.resource.instructions })] }), (detailsTarget.resource.mcpTools ?? []).length > 0 ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.mcpTools", {
|
|
217
|
-
defaultValue: "Connected MCP tools",
|
|
218
|
-
}) }), _jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: (detailsTarget.resource.mcpTools ?? []).map((toolName) => (_jsx("code", { className: "rounded bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground", children: toolName }, toolName))) })] })) : null] })) : null] }) })] }));
|
|
271
|
+
}, children: [mutationPending ? (_jsx(IconLoader2, { className: "size-4 animate-spin" })) : null, t("jobs.delete", { defaultValue: "Delete" })] })] })] }) }), detailsTarget ? (_jsx(AutomationDetailsDialog, { open: true, name: detailsTarget.resource.name, scope: detailsTarget.resource.scope === "organization" ? "org" : "user", triggerSummary: describeTrigger(detailsTarget, t), fields: detailsFields(detailsTarget, t, formatDateTime), condition: detailsTarget.kind === "automation"
|
|
272
|
+
? detailsTarget.resource.condition
|
|
273
|
+
: null, instructions: detailsTarget.kind === "automation"
|
|
274
|
+
? detailsTarget.resource.body
|
|
275
|
+
: detailsTarget.resource.instructions, mcpTools: detailsTarget.resource.mcpTools ?? [], lastError: detailsTarget.resource.lastError, formatTimestamp: (value) => formatDateTime(new Date(value).toISOString()) ?? String(value), onClose: () => setDetailsTarget(null) })) : null, scheduleTarget ? (_jsx(AutomationScheduleDialog, { open: true, name: scheduleTarget.resource.name, schedule: scheduleTarget.resource.schedule ?? "", timezone: scheduleTarget.resource.timezone ?? null, saving: mutationPending, error: mutationError ? mutationError.message : null, onCancel: () => setScheduleTarget(null), onSave: (next) => mutateEntry(scheduleTarget, "update", next, () => setScheduleTarget(null)) })) : null] }));
|
|
219
276
|
}
|
|
220
277
|
//# sourceMappingURL=AgentJobsTab.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentJobsTab.js","sourceRoot":"","sources":["../../../src/client/agent-page/AgentJobsTab.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Button } from \"@agent-native/toolkit/ui/button\";\nimport {\n IconBolt,\n IconCalendarEvent,\n IconClock,\n IconEye,\n IconLoader2,\n IconPlayerPause,\n IconPlayerPlay,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\n\nimport { AgentAskPopover } from \"../AgentAskPopover.js\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../components/ui/dialog.js\";\nimport { useFormatters, useT } from \"../i18n.js\";\nimport { automationCreationContext } from \"../settings/AutomationsSection.js\";\nimport { AgentEmptyState } from \"./AgentEmptyState.js\";\nimport { AgentTabFrame } from \"./AgentTabFrame.js\";\nimport type { AgentPageTabProps } from \"./types.js\";\nimport {\n useAutomations,\n useManageAutomation,\n useManageRecurringJob,\n useRecurringJobs,\n type Automation,\n type RecurringJob,\n} from \"./use-jobs.js\";\n\ntype ListedAutomation =\n | {\n kind: \"recurring\";\n resource: RecurringJob;\n triggerType: \"schedule\";\n }\n | {\n kind: \"automation\";\n resource: Automation;\n triggerType: \"event\" | \"schedule\";\n };\n\nfunction listRecurringJobs(jobs: RecurringJob[]): ListedAutomation[] {\n return jobs.map((resource) => ({\n kind: \"recurring\",\n resource,\n triggerType: \"schedule\",\n }));\n}\n\nfunction listAutomations(automations: Automation[]): ListedAutomation[] {\n return automations.map((resource) => ({\n kind: \"automation\",\n resource,\n triggerType: resource.triggerType,\n }));\n}\n\nexport function organizationAutomationCreationContext(): string {\n return \"The user wants to create a new organization automation. Use manage-automations with action=define and scope=organization to create it. Ask clarifying questions if needed about whether it runs on a schedule or event, any conditions, and what actions to take.\";\n}\n\nexport function AgentJobsTab({ canManageOrg = false }: AgentPageTabProps) {\n const t = useT();\n const formatters = useFormatters();\n const personalJobsQuery = useRecurringJobs(\"user\");\n const personalAutomationsQuery = useAutomations(\"user\");\n const organizationJobsQuery = useRecurringJobs(\"org\");\n const organizationAutomationsQuery = useAutomations(\"org\");\n const personalJobsMutation = useManageRecurringJob(\"user\");\n const personalAutomationsMutation = useManageAutomation(\"user\");\n const organizationJobsMutation = useManageRecurringJob(\"org\");\n const organizationAutomationsMutation = useManageAutomation(\"org\");\n const [deleteTarget, setDeleteTarget] = useState<ListedAutomation | null>(\n null,\n );\n const [detailsTarget, setDetailsTarget] = useState<ListedAutomation | null>(\n null,\n );\n\n const formatDateTime = (value: string | null) => {\n if (!value || Number.isNaN(new Date(value).getTime())) return null;\n return formatters.formatDate(value, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n };\n\n const personalEntries = [\n ...listRecurringJobs(personalJobsQuery.data ?? []),\n ...listAutomations(personalAutomationsQuery.data ?? []),\n ];\n const organizationEntries = [\n ...listRecurringJobs(organizationJobsQuery.data ?? []),\n ...listAutomations(organizationAutomationsQuery.data ?? []),\n ];\n const mutationPending =\n personalJobsMutation.isPending ||\n personalAutomationsMutation.isPending ||\n organizationJobsMutation.isPending ||\n organizationAutomationsMutation.isPending;\n\n const mutateEntry = (\n entry: ListedAutomation,\n operation: \"update\" | \"delete\",\n enabled?: boolean,\n onSuccess?: () => void,\n ) => {\n const input = {\n operation,\n name: entry.resource.name,\n scope: entry.resource.scope,\n ...(enabled === undefined ? {} : { enabled }),\n };\n const options = onSuccess ? { onSuccess } : undefined;\n\n if (entry.kind === \"automation\") {\n const mutation =\n entry.resource.scope === \"organization\"\n ? organizationAutomationsMutation\n : personalAutomationsMutation;\n mutation.mutate(input, options);\n } else if (entry.resource.scope === \"organization\") {\n organizationJobsMutation.mutate(input, options);\n } else {\n personalJobsMutation.mutate(input, options);\n }\n };\n\n const renderSection = ({\n title,\n description,\n entries,\n loading,\n errors,\n organization = false,\n }: {\n title: string;\n description: string;\n entries: ListedAutomation[];\n loading: boolean;\n errors: unknown[];\n organization?: boolean;\n }) => (\n <section className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end justify-between gap-3\">\n <div className=\"min-w-0\">\n <h2 className=\"text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground/70\">\n {title}\n </h2>\n <p className=\"mt-2 max-w-2xl text-sm text-muted-foreground\">\n {description}\n </p>\n </div>\n {organization ? (\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n {!canManageOrg ? (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"jobs.organizationMemberNote\", {\n defaultValue: \"You can manage automations you created.\",\n })}\n </span>\n ) : null}\n <AgentAskPopover\n context={organizationAutomationCreationContext()}\n prompt={t(\"jobs.organizationPrompt\", {\n defaultValue:\n \"Create a shared organization automation that does this: \",\n })}\n title={t(\"jobs.automationsCreateTitle\", {\n defaultValue: \"Create an automation\",\n })}\n label={t(\"jobs.newAutomation\", {\n defaultValue: \"New automation\",\n })}\n />\n </div>\n ) : null}\n </div>\n\n {errors.length > 0 ? (\n <p className=\"text-sm text-destructive\">\n {t(\"jobs.loadError\", {\n defaultValue: \"Could not load all automations.\",\n })}\n </p>\n ) : null}\n\n {loading && entries.length === 0 ? (\n <div\n className=\"flex items-center gap-2 text-sm text-muted-foreground\"\n aria-busy=\"true\"\n >\n <IconLoader2 className=\"size-4 animate-spin\" />\n {t(\"jobs.loading\", { defaultValue: \"Loading…\" })}\n </div>\n ) : entries.length === 0 && errors.length === 0 ? (\n <AgentEmptyState\n icon={IconCalendarEvent}\n title={\n organization\n ? t(\"jobs.organizationEmptyTitle\", {\n defaultValue: \"No organization automations yet\",\n })\n : t(\"jobs.automationsEmptyTitle\", {\n defaultValue: \"No automations yet\",\n })\n }\n description={\n organization\n ? t(\"jobs.organizationEmptyDescription\", {\n defaultValue:\n \"Describe a scheduled or event-triggered automation for this organization.\",\n })\n : t(\"jobs.automationsEmptyDescription\", {\n defaultValue: \"Describe what should happen and when.\",\n })\n }\n action={\n organization ? null : (\n <AgentAskPopover\n context={automationCreationContext()}\n prompt={t(\"jobs.automationPrompt\", {\n defaultValue: \"Create an automation that does this: \",\n })}\n title={t(\"jobs.automationsCreateTitle\", {\n defaultValue: \"Create an automation\",\n })}\n />\n )\n }\n />\n ) : (\n <div className=\"divide-y divide-border/60 border-y border-border/60\">\n {entries.map((entry) => {\n const resource = entry.resource;\n const lastRun = formatDateTime(resource.lastRun);\n const nextRun = formatDateTime(resource.nextRun);\n const triggerDescription =\n entry.kind === \"automation\" && entry.triggerType === \"event\"\n ? t(\"jobs.automationEventTrigger\", {\n defaultValue: \"On {{event}}\",\n event: entry.resource.event ?? \"event\",\n })\n : resource.scheduleDescription ||\n resource.schedule ||\n t(\"jobs.scheduledTrigger\", {\n defaultValue: \"Scheduled\",\n });\n const instructions =\n entry.kind === \"automation\"\n ? entry.resource.body\n : entry.resource.instructions;\n\n return (\n <article\n key={`${entry.kind}:${resource.id}`}\n className=\"py-4 first:pt-5 last:pb-5\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-0.5 text-muted-foreground\">\n {entry.triggerType === \"event\" ? (\n <IconBolt className=\"size-4\" />\n ) : (\n <IconClock className=\"size-4\" />\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h3 className=\"truncate text-sm font-medium\">\n {resource.name.replace(/-/g, \" \")}\n </h3>\n <span className=\"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\">\n {entry.triggerType === \"event\"\n ? t(\"jobs.eventTrigger\", {\n defaultValue: \"Event-triggered\",\n })\n : t(\"jobs.scheduledTrigger\", {\n defaultValue: \"Scheduled\",\n })}\n </span>\n <span\n className={\n resource.enabled\n ? \"rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400\"\n : \"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\"\n }\n >\n {resource.enabled\n ? t(\"jobs.enabled\", { defaultValue: \"Enabled\" })\n : t(\"jobs.paused\", { defaultValue: \"Paused\" })}\n </span>\n {resource.lastStatus ? (\n <span className=\"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\">\n {resource.lastStatus}\n </span>\n ) : null}\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {triggerDescription}\n </p>\n <p className=\"mt-1 line-clamp-2 text-xs text-muted-foreground/80\">\n {instructions}\n </p>\n {lastRun || nextRun ? (\n <div className=\"mt-2 flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground\">\n {nextRun ? (\n <span>\n {t(\"jobs.nextRun\", { defaultValue: \"Next run\" })}:{\" \"}\n {nextRun}\n </span>\n ) : null}\n {lastRun ? (\n <span>\n {t(\"jobs.lastRun\", { defaultValue: \"Last run\" })}:{\" \"}\n {lastRun}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"cursor-pointer px-2 text-xs\"\n onClick={() => setDetailsTarget(entry)}\n >\n <IconEye className=\"size-3.5\" />\n {t(\"jobs.details\", { defaultValue: \"Details\" })}\n </Button>\n {resource.canUpdate ? (\n <>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"cursor-pointer px-2 text-xs\"\n disabled={mutationPending}\n onClick={() =>\n mutateEntry(entry, \"update\", !resource.enabled)\n }\n >\n {resource.enabled ? (\n <IconPlayerPause className=\"size-3.5\" />\n ) : (\n <IconPlayerPlay className=\"size-3.5\" />\n )}\n {resource.enabled\n ? t(\"jobs.pause\", { defaultValue: \"Pause\" })\n : t(\"jobs.resume\", { defaultValue: \"Resume\" })}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 cursor-pointer text-muted-foreground hover:text-destructive\"\n aria-label={t(\"jobs.delete\", {\n defaultValue: \"Delete\",\n })}\n onClick={() => setDeleteTarget(entry)}\n >\n <IconTrash className=\"size-3.5\" />\n </Button>\n </>\n ) : null}\n </div>\n </div>\n </article>\n );\n })}\n </div>\n )}\n </section>\n );\n\n const mutationError =\n personalJobsMutation.error ||\n personalAutomationsMutation.error ||\n organizationJobsMutation.error ||\n organizationAutomationsMutation.error;\n\n return (\n <AgentTabFrame\n title={t(\"jobs.pageTitle\", { defaultValue: \"Automations\" })}\n description={t(\"jobs.pageDescription\", {\n defaultValue:\n \"Manage agent tasks that run on a schedule or in response to events.\",\n })}\n actions={\n <AgentAskPopover\n context={automationCreationContext()}\n prompt={t(\"jobs.automationPrompt\", {\n defaultValue: \"Create an automation that does this: \",\n })}\n title={t(\"jobs.automationsCreateTitle\", {\n defaultValue: \"Create an automation\",\n })}\n label={t(\"jobs.newAutomation\", {\n defaultValue: \"New automation\",\n })}\n />\n }\n >\n <div className=\"space-y-7\">\n {renderSection({\n title: t(\"jobs.personal\", { defaultValue: \"Personal\" }),\n description: t(\"jobs.personalDescription\", {\n defaultValue:\n \"Scheduled and event-triggered automations that run for you.\",\n }),\n entries: personalEntries,\n loading:\n personalJobsQuery.isLoading || personalAutomationsQuery.isLoading,\n errors: [\n personalJobsQuery.error,\n personalAutomationsQuery.error,\n ].filter(Boolean),\n })}\n <div className=\"border-t border-border/70 pt-6\">\n {renderSection({\n title: t(\"jobs.organization\", { defaultValue: \"Organization\" }),\n description: t(\"jobs.organizationDescription\", {\n defaultValue:\n \"Scheduled and event-triggered automations shared with this organization.\",\n }),\n entries: organizationEntries,\n loading:\n organizationJobsQuery.isLoading ||\n organizationAutomationsQuery.isLoading,\n errors: [\n organizationJobsQuery.error,\n organizationAutomationsQuery.error,\n ].filter(Boolean),\n organization: true,\n })}\n </div>\n {mutationError ? (\n <p className=\"text-sm text-destructive\">\n {mutationError.message ||\n t(\"jobs.updateError\", {\n defaultValue: \"Could not update automation.\",\n })}\n </p>\n ) : null}\n </div>\n\n <Dialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open && !mutationPending) setDeleteTarget(null);\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {t(\"jobs.deleteAutomationTitle\", {\n defaultValue: \"Delete automation?\",\n })}\n </DialogTitle>\n <DialogDescription>\n {t(\"jobs.deleteAutomationDescription\", {\n defaultValue:\n \"This permanently removes the automation and cannot be undone.\",\n })}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"cursor-pointer\"\n disabled={mutationPending}\n onClick={() => setDeleteTarget(null)}\n >\n {t(\"jobs.cancel\", { defaultValue: \"Cancel\" })}\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n className=\"cursor-pointer\"\n disabled={mutationPending}\n onClick={() => {\n if (!deleteTarget) return;\n mutateEntry(deleteTarget, \"delete\", undefined, () =>\n setDeleteTarget(null),\n );\n }}\n >\n {mutationPending ? (\n <IconLoader2 className=\"size-4 animate-spin\" />\n ) : null}\n {t(\"jobs.delete\", { defaultValue: \"Delete\" })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n <Dialog\n open={detailsTarget !== null}\n onOpenChange={(open) => {\n if (!open) setDetailsTarget(null);\n }}\n >\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>\n {detailsTarget?.resource.name.replace(/-/g, \" \") ??\n t(\"jobs.automationDetails\", {\n defaultValue: \"Automation details\",\n })}\n </DialogTitle>\n <DialogDescription>\n {detailsTarget\n ? detailsTarget.triggerType === \"event\"\n ? t(\"jobs.automationEventDetails\", {\n defaultValue: \"Runs when {{event}}.\",\n event:\n detailsTarget.kind === \"automation\"\n ? (detailsTarget.resource.event ?? \"an event fires\")\n : \"an event fires\",\n })\n : detailsTarget.resource.scheduleDescription ||\n detailsTarget.resource.schedule ||\n t(\"jobs.scheduledTrigger\", {\n defaultValue: \"Scheduled\",\n })\n : null}\n </DialogDescription>\n </DialogHeader>\n {detailsTarget ? (\n <div className=\"space-y-3\">\n {detailsTarget.kind === \"automation\" &&\n detailsTarget.resource.condition ? (\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.condition\", { defaultValue: \"Condition\" })}\n </p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {detailsTarget.resource.condition}\n </p>\n </div>\n ) : null}\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.instructions\", { defaultValue: \"Instructions\" })}\n </p>\n <p className=\"mt-1 whitespace-pre-wrap text-sm text-muted-foreground\">\n {detailsTarget.kind === \"automation\"\n ? detailsTarget.resource.body\n : detailsTarget.resource.instructions}\n </p>\n </div>\n {(detailsTarget.resource.mcpTools ?? []).length > 0 ? (\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.mcpTools\", {\n defaultValue: \"Connected MCP tools\",\n })}\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1.5\">\n {(detailsTarget.resource.mcpTools ?? []).map((toolName) => (\n <code\n key={toolName}\n className=\"rounded bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground\"\n >\n {toolName}\n </code>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n ) : null}\n </DialogContent>\n </Dialog>\n </AgentTabFrame>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AgentJobsTab.js","sourceRoot":"","sources":["../../../src/client/agent-page/AgentJobsTab.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Button } from \"@agent-native/toolkit/ui/button\";\nimport {\n IconBolt,\n IconCalendarEvent,\n IconClock,\n IconAlertTriangle,\n IconEye,\n IconLoader2,\n IconPencil,\n IconPlayerPause,\n IconPlayerPlay,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\n\nimport { AgentAskPopover } from \"../AgentAskPopover.js\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../components/ui/dialog.js\";\nimport { useFormatters, useT } from \"../i18n.js\";\nimport { automationCreationContext } from \"../settings/AutomationsSection.js\";\nimport { AgentEmptyState } from \"./AgentEmptyState.js\";\nimport { AgentTabFrame } from \"./AgentTabFrame.js\";\nimport {\n AutomationDetailsDialog,\n type AutomationDetailsField,\n} from \"./AutomationDetailsDialog.js\";\nimport { AutomationScheduleDialog } from \"./AutomationScheduleDialog.js\";\nimport type { AgentPageTabProps } from \"./types.js\";\nimport {\n useAutomations,\n useManageAutomation,\n useManageRecurringJob,\n useRecurringJobs,\n type Automation,\n type RecurringJob,\n} from \"./use-jobs.js\";\n\ntype ListedAutomation =\n | {\n kind: \"recurring\";\n resource: RecurringJob;\n triggerType: \"schedule\";\n }\n | {\n kind: \"automation\";\n resource: Automation;\n triggerType: \"event\" | \"schedule\";\n };\n\nfunction listRecurringJobs(jobs: RecurringJob[]): ListedAutomation[] {\n return jobs.map((resource) => ({\n kind: \"recurring\",\n resource,\n triggerType: \"schedule\",\n }));\n}\n\nfunction listAutomations(automations: Automation[]): ListedAutomation[] {\n return automations.map((resource) => ({\n kind: \"automation\",\n resource,\n triggerType: resource.triggerType,\n }));\n}\n\ntype Translate = ReturnType<typeof useT>;\n\nfunction describeTrigger(entry: ListedAutomation, t: Translate): string {\n if (entry.kind === \"automation\" && entry.triggerType === \"event\") {\n return t(\"jobs.automationEventDetails\", {\n defaultValue: \"Runs when {{event}}.\",\n event: entry.resource.event ?? \"an event fires\",\n });\n }\n return (\n entry.resource.scheduleDescription ||\n entry.resource.schedule ||\n t(\"jobs.scheduledTrigger\", { defaultValue: \"Scheduled\" })\n );\n}\n\nfunction detailsFields(\n entry: ListedAutomation,\n t: Translate,\n formatDateTime: (value: string | null) => string | null,\n): AutomationDetailsField[] {\n const resource = entry.resource;\n const unset = t(\"jobs.notSet\", { defaultValue: \"—\" });\n const fields: AutomationDetailsField[] = [\n {\n label: t(\"jobs.status\", { defaultValue: \"Status\" }),\n value: resource.enabled\n ? t(\"jobs.enabled\", { defaultValue: \"Enabled\" })\n : t(\"jobs.paused\", { defaultValue: \"Paused\" }),\n },\n {\n label: t(\"jobs.trigger\", { defaultValue: \"Trigger\" }),\n value:\n entry.triggerType === \"event\"\n ? t(\"jobs.eventTrigger\", { defaultValue: \"Event-triggered\" })\n : t(\"jobs.scheduledTrigger\", { defaultValue: \"Scheduled\" }),\n },\n ];\n\n if (entry.triggerType === \"schedule\") {\n fields.push(\n {\n label: t(\"jobs.cronExpression\", { defaultValue: \"Cron expression\" }),\n value: resource.schedule || unset,\n mono: true,\n },\n {\n label: t(\"jobs.timezone\", { defaultValue: \"Timezone\" }),\n value: resource.timezone || unset,\n },\n );\n }\n\n fields.push(\n {\n label: t(\"jobs.nextRun\", { defaultValue: \"Next run\" }),\n value: formatDateTime(resource.nextRun) ?? unset,\n },\n {\n label: t(\"jobs.lastRun\", { defaultValue: \"Last run\" }),\n value:\n formatDateTime(resource.lastRun) ??\n t(\"jobs.neverRan\", { defaultValue: \"Never\" }),\n },\n {\n label: t(\"jobs.lastChecked\", { defaultValue: \"Last checked\" }),\n value: formatDateTime(resource.lastCheck) ?? unset,\n },\n {\n label: t(\"jobs.lastStatus\", { defaultValue: \"Last status\" }),\n value: resource.lastStatus || unset,\n },\n {\n label: t(\"jobs.scope\", { defaultValue: \"Scope\" }),\n value:\n resource.scope === \"organization\"\n ? t(\"jobs.organization\", { defaultValue: \"Organization\" })\n : t(\"jobs.personal\", { defaultValue: \"Personal\" }),\n },\n {\n label: t(\"jobs.createdBy\", { defaultValue: \"Created by\" }),\n value: resource.createdBy || unset,\n },\n );\n\n if (entry.kind === \"automation\") {\n fields.push({\n label: t(\"jobs.model\", { defaultValue: \"Model\" }),\n value: entry.resource.model || unset,\n });\n }\n\n return fields;\n}\n\nexport function organizationAutomationCreationContext(): string {\n return \"The user wants to create a new organization automation. Use manage-automations with action=define and scope=organization to create it. Ask clarifying questions if needed about whether it runs on a schedule or event, any conditions, and what actions to take.\";\n}\n\nexport function AgentJobsTab({ canManageOrg = false }: AgentPageTabProps) {\n const t = useT();\n const formatters = useFormatters();\n const personalJobsQuery = useRecurringJobs(\"user\");\n const personalAutomationsQuery = useAutomations(\"user\");\n const organizationJobsQuery = useRecurringJobs(\"org\");\n const organizationAutomationsQuery = useAutomations(\"org\");\n const personalJobsMutation = useManageRecurringJob(\"user\");\n const personalAutomationsMutation = useManageAutomation(\"user\");\n const organizationJobsMutation = useManageRecurringJob(\"org\");\n const organizationAutomationsMutation = useManageAutomation(\"org\");\n const [deleteTarget, setDeleteTarget] = useState<ListedAutomation | null>(\n null,\n );\n const [detailsTarget, setDetailsTarget] = useState<ListedAutomation | null>(\n null,\n );\n const [scheduleTarget, setScheduleTarget] = useState<ListedAutomation | null>(\n null,\n );\n\n const formatDateTime = (value: string | null) => {\n if (!value || Number.isNaN(new Date(value).getTime())) return null;\n return formatters.formatDate(value, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n };\n\n const personalEntries = [\n ...listRecurringJobs(personalJobsQuery.data ?? []),\n ...listAutomations(personalAutomationsQuery.data ?? []),\n ];\n const organizationEntries = [\n ...listRecurringJobs(organizationJobsQuery.data ?? []),\n ...listAutomations(organizationAutomationsQuery.data ?? []),\n ];\n const mutationPending =\n personalJobsMutation.isPending ||\n personalAutomationsMutation.isPending ||\n organizationJobsMutation.isPending ||\n organizationAutomationsMutation.isPending;\n\n const mutateEntry = (\n entry: ListedAutomation,\n operation: \"update\" | \"delete\",\n patch?: { enabled?: boolean; schedule?: string },\n onSuccess?: () => void,\n ) => {\n const input = {\n operation,\n name: entry.resource.name,\n scope: entry.resource.scope,\n ...patch,\n };\n const options = onSuccess ? { onSuccess } : undefined;\n\n if (entry.kind === \"automation\") {\n const mutation =\n entry.resource.scope === \"organization\"\n ? organizationAutomationsMutation\n : personalAutomationsMutation;\n mutation.mutate(input, options);\n } else if (entry.resource.scope === \"organization\") {\n organizationJobsMutation.mutate(input, options);\n } else {\n personalJobsMutation.mutate(input, options);\n }\n };\n\n const renderSection = ({\n title,\n description,\n entries,\n loading,\n errors,\n organization = false,\n }: {\n title: string;\n description: string;\n entries: ListedAutomation[];\n loading: boolean;\n errors: unknown[];\n organization?: boolean;\n }) => (\n <section className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end justify-between gap-3\">\n <div className=\"min-w-0\">\n <h2 className=\"text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground/70\">\n {title}\n </h2>\n <p className=\"mt-2 max-w-2xl text-sm text-muted-foreground\">\n {description}\n </p>\n </div>\n {organization ? (\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n {!canManageOrg ? (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"jobs.organizationMemberNote\", {\n defaultValue: \"You can manage automations you created.\",\n })}\n </span>\n ) : null}\n <AgentAskPopover\n context={organizationAutomationCreationContext()}\n prompt={t(\"jobs.organizationPrompt\", {\n defaultValue:\n \"Create a shared organization automation that does this: \",\n })}\n title={t(\"jobs.automationsCreateTitle\", {\n defaultValue: \"Create an automation\",\n })}\n label={t(\"jobs.newAutomation\", {\n defaultValue: \"New automation\",\n })}\n />\n </div>\n ) : null}\n </div>\n\n {errors.length > 0 ? (\n <p className=\"text-sm text-destructive\">\n {t(\"jobs.loadError\", {\n defaultValue: \"Could not load all automations.\",\n })}\n </p>\n ) : null}\n\n {loading && entries.length === 0 ? (\n <div\n className=\"flex items-center gap-2 text-sm text-muted-foreground\"\n aria-busy=\"true\"\n >\n <IconLoader2 className=\"size-4 animate-spin\" />\n {t(\"jobs.loading\", { defaultValue: \"Loading…\" })}\n </div>\n ) : entries.length === 0 && errors.length === 0 ? (\n <AgentEmptyState\n icon={IconCalendarEvent}\n title={\n organization\n ? t(\"jobs.organizationEmptyTitle\", {\n defaultValue: \"No organization automations yet\",\n })\n : t(\"jobs.automationsEmptyTitle\", {\n defaultValue: \"No automations yet\",\n })\n }\n description={\n organization\n ? t(\"jobs.organizationEmptyDescription\", {\n defaultValue:\n \"Describe a scheduled or event-triggered automation for this organization.\",\n })\n : t(\"jobs.automationsEmptyDescription\", {\n defaultValue: \"Describe what should happen and when.\",\n })\n }\n action={\n organization ? null : (\n <AgentAskPopover\n context={automationCreationContext()}\n prompt={t(\"jobs.automationPrompt\", {\n defaultValue: \"Create an automation that does this: \",\n })}\n title={t(\"jobs.automationsCreateTitle\", {\n defaultValue: \"Create an automation\",\n })}\n />\n )\n }\n />\n ) : (\n <div className=\"divide-y divide-border/60 border-y border-border/60\">\n {entries.map((entry) => {\n const resource = entry.resource;\n const lastRun = formatDateTime(resource.lastRun);\n const lastCheck = formatDateTime(resource.lastCheck);\n const nextRun = formatDateTime(resource.nextRun);\n const triggerDescription =\n entry.kind === \"automation\" && entry.triggerType === \"event\"\n ? t(\"jobs.automationEventTrigger\", {\n defaultValue: \"On {{event}}\",\n event: entry.resource.event ?? \"event\",\n })\n : resource.scheduleDescription ||\n resource.schedule ||\n t(\"jobs.scheduledTrigger\", {\n defaultValue: \"Scheduled\",\n });\n const instructions =\n entry.kind === \"automation\"\n ? entry.resource.body\n : entry.resource.instructions;\n\n return (\n <article\n key={`${entry.kind}:${resource.id}`}\n className=\"py-4 first:pt-5 last:pb-5\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-0.5 text-muted-foreground\">\n {entry.triggerType === \"event\" ? (\n <IconBolt className=\"size-4\" />\n ) : (\n <IconClock className=\"size-4\" />\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h3 className=\"truncate text-sm font-medium\">\n {resource.name.replace(/-/g, \" \")}\n </h3>\n <span className=\"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\">\n {entry.triggerType === \"event\"\n ? t(\"jobs.eventTrigger\", {\n defaultValue: \"Event-triggered\",\n })\n : t(\"jobs.scheduledTrigger\", {\n defaultValue: \"Scheduled\",\n })}\n </span>\n <span\n className={\n resource.enabled\n ? \"rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400\"\n : \"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\"\n }\n >\n {resource.enabled\n ? t(\"jobs.enabled\", { defaultValue: \"Enabled\" })\n : t(\"jobs.paused\", { defaultValue: \"Paused\" })}\n </span>\n {resource.lastStatus ? (\n <span className=\"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\">\n {resource.lastStatus}\n </span>\n ) : null}\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {triggerDescription}\n </p>\n <p className=\"mt-1 line-clamp-2 text-xs text-muted-foreground/80\">\n {instructions}\n </p>\n {lastRun || nextRun || lastCheck ? (\n <div className=\"mt-2 flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground\">\n {nextRun ? (\n <span>\n {t(\"jobs.nextRun\", { defaultValue: \"Next run\" })}:{\" \"}\n {nextRun}\n </span>\n ) : null}\n <span>\n {t(\"jobs.lastRun\", { defaultValue: \"Last run\" })}:{\" \"}\n {lastRun ??\n t(\"jobs.neverRan\", { defaultValue: \"Never\" })}\n </span>\n {!lastRun && lastCheck ? (\n <span>\n {t(\"jobs.lastChecked\", {\n defaultValue: \"Last checked\",\n })}\n : {lastCheck}\n </span>\n ) : null}\n </div>\n ) : null}\n {resource.lastError ? (\n <p className=\"mt-2 flex items-start gap-1.5 text-[11px] text-destructive\">\n <IconAlertTriangle className=\"mt-px size-3 shrink-0\" />\n <span className=\"min-w-0 break-words\">\n {resource.lastError}\n </span>\n </p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"cursor-pointer px-2 text-xs\"\n onClick={() => setDetailsTarget(entry)}\n >\n <IconEye className=\"size-3.5\" />\n {t(\"jobs.details\", { defaultValue: \"Details\" })}\n </Button>\n {resource.canUpdate ? (\n <>\n {entry.triggerType === \"schedule\" ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"cursor-pointer px-2 text-xs\"\n disabled={mutationPending}\n onClick={() => setScheduleTarget(entry)}\n >\n <IconPencil className=\"size-3.5\" />\n {t(\"jobs.edit\", { defaultValue: \"Edit\" })}\n </Button>\n ) : null}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"cursor-pointer px-2 text-xs\"\n disabled={mutationPending}\n onClick={() =>\n mutateEntry(entry, \"update\", {\n enabled: !resource.enabled,\n })\n }\n >\n {resource.enabled ? (\n <IconPlayerPause className=\"size-3.5\" />\n ) : (\n <IconPlayerPlay className=\"size-3.5\" />\n )}\n {resource.enabled\n ? t(\"jobs.pause\", { defaultValue: \"Pause\" })\n : t(\"jobs.resume\", { defaultValue: \"Resume\" })}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 cursor-pointer text-muted-foreground hover:text-destructive\"\n aria-label={t(\"jobs.delete\", {\n defaultValue: \"Delete\",\n })}\n onClick={() => setDeleteTarget(entry)}\n >\n <IconTrash className=\"size-3.5\" />\n </Button>\n </>\n ) : null}\n </div>\n </div>\n </article>\n );\n })}\n </div>\n )}\n </section>\n );\n\n const mutationError =\n personalJobsMutation.error ||\n personalAutomationsMutation.error ||\n organizationJobsMutation.error ||\n organizationAutomationsMutation.error;\n\n return (\n <AgentTabFrame\n title={t(\"jobs.pageTitle\", { defaultValue: \"Automations\" })}\n description={t(\"jobs.pageDescription\", {\n defaultValue:\n \"Manage agent tasks that run on a schedule or in response to events.\",\n })}\n actions={\n <AgentAskPopover\n context={automationCreationContext()}\n prompt={t(\"jobs.automationPrompt\", {\n defaultValue: \"Create an automation that does this: \",\n })}\n title={t(\"jobs.automationsCreateTitle\", {\n defaultValue: \"Create an automation\",\n })}\n label={t(\"jobs.newAutomation\", {\n defaultValue: \"New automation\",\n })}\n />\n }\n >\n <div className=\"space-y-7\">\n {renderSection({\n title: t(\"jobs.personal\", { defaultValue: \"Personal\" }),\n description: t(\"jobs.personalDescription\", {\n defaultValue:\n \"Scheduled and event-triggered automations that run for you.\",\n }),\n entries: personalEntries,\n loading:\n personalJobsQuery.isLoading || personalAutomationsQuery.isLoading,\n errors: [\n personalJobsQuery.error,\n personalAutomationsQuery.error,\n ].filter(Boolean),\n })}\n <div className=\"border-t border-border/70 pt-6\">\n {renderSection({\n title: t(\"jobs.organization\", { defaultValue: \"Organization\" }),\n description: t(\"jobs.organizationDescription\", {\n defaultValue:\n \"Scheduled and event-triggered automations shared with this organization.\",\n }),\n entries: organizationEntries,\n loading:\n organizationJobsQuery.isLoading ||\n organizationAutomationsQuery.isLoading,\n errors: [\n organizationJobsQuery.error,\n organizationAutomationsQuery.error,\n ].filter(Boolean),\n organization: true,\n })}\n </div>\n {mutationError ? (\n <p className=\"text-sm text-destructive\">\n {mutationError.message ||\n t(\"jobs.updateError\", {\n defaultValue: \"Could not update automation.\",\n })}\n </p>\n ) : null}\n </div>\n\n <Dialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open && !mutationPending) setDeleteTarget(null);\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {t(\"jobs.deleteAutomationTitle\", {\n defaultValue: \"Delete automation?\",\n })}\n </DialogTitle>\n <DialogDescription>\n {t(\"jobs.deleteAutomationDescription\", {\n defaultValue:\n \"This permanently removes the automation and cannot be undone.\",\n })}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"cursor-pointer\"\n disabled={mutationPending}\n onClick={() => setDeleteTarget(null)}\n >\n {t(\"jobs.cancel\", { defaultValue: \"Cancel\" })}\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n className=\"cursor-pointer\"\n disabled={mutationPending}\n onClick={() => {\n if (!deleteTarget) return;\n mutateEntry(deleteTarget, \"delete\", undefined, () =>\n setDeleteTarget(null),\n );\n }}\n >\n {mutationPending ? (\n <IconLoader2 className=\"size-4 animate-spin\" />\n ) : null}\n {t(\"jobs.delete\", { defaultValue: \"Delete\" })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {detailsTarget ? (\n <AutomationDetailsDialog\n open\n name={detailsTarget.resource.name}\n scope={\n detailsTarget.resource.scope === \"organization\" ? \"org\" : \"user\"\n }\n triggerSummary={describeTrigger(detailsTarget, t)}\n fields={detailsFields(detailsTarget, t, formatDateTime)}\n condition={\n detailsTarget.kind === \"automation\"\n ? detailsTarget.resource.condition\n : null\n }\n instructions={\n detailsTarget.kind === \"automation\"\n ? detailsTarget.resource.body\n : detailsTarget.resource.instructions\n }\n mcpTools={detailsTarget.resource.mcpTools ?? []}\n lastError={detailsTarget.resource.lastError}\n formatTimestamp={(value) =>\n formatDateTime(new Date(value).toISOString()) ?? String(value)\n }\n onClose={() => setDetailsTarget(null)}\n />\n ) : null}\n\n {scheduleTarget ? (\n <AutomationScheduleDialog\n open\n name={scheduleTarget.resource.name}\n schedule={scheduleTarget.resource.schedule ?? \"\"}\n timezone={scheduleTarget.resource.timezone ?? null}\n saving={mutationPending}\n error={mutationError ? mutationError.message : null}\n onCancel={() => setScheduleTarget(null)}\n onSave={(next) =>\n mutateEntry(scheduleTarget, \"update\", next, () =>\n setScheduleTarget(null),\n )\n }\n />\n ) : null}\n </AgentTabFrame>\n );\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type JobsScope } from "./use-jobs.js";
|
|
2
|
+
export interface AutomationDetailsField {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
mono?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface AutomationDetailsDialogProps {
|
|
8
|
+
open: boolean;
|
|
9
|
+
name: string;
|
|
10
|
+
triggerSummary: string;
|
|
11
|
+
fields: AutomationDetailsField[];
|
|
12
|
+
condition: string | null;
|
|
13
|
+
instructions: string;
|
|
14
|
+
mcpTools: string[];
|
|
15
|
+
lastError: string | null;
|
|
16
|
+
scope: JobsScope;
|
|
17
|
+
formatTimestamp: (value: number) => string;
|
|
18
|
+
onClose: () => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function AutomationDetailsDialog({ open, name, triggerSummary, fields, condition, instructions, mcpTools, lastError, scope, formatTimestamp, onClose, }: AutomationDetailsDialogProps): import("react").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=AutomationDetailsDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutomationDetailsDialog.d.ts","sourceRoot":"","sources":["../../../src/client/agent-page/AutomationDetailsDialog.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,sBAAsB,EAAE,CAAC;IACjC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAgBD,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,IAAI,EACJ,cAAc,EACd,MAAM,EACN,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,KAAK,EACL,eAAe,EACf,OAAO,GACR,EAAE,4BAA4B,+BAqJ9B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconAlertTriangle, IconLoader2 } from "@tabler/icons-react";
|
|
3
|
+
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "../components/ui/dialog.js";
|
|
4
|
+
import { useT } from "../i18n.js";
|
|
5
|
+
import { useAutomationRuns } from "./use-jobs.js";
|
|
6
|
+
function RunStatusDot({ status }) {
|
|
7
|
+
const tone = status === "success"
|
|
8
|
+
? "bg-emerald-500"
|
|
9
|
+
: status === "error"
|
|
10
|
+
? "bg-destructive"
|
|
11
|
+
: // An interrupted run never reported an outcome, so it reads as
|
|
12
|
+
// unknown rather than as still making progress.
|
|
13
|
+
status === "interrupted"
|
|
14
|
+
? "bg-muted-foreground"
|
|
15
|
+
: "bg-amber-500";
|
|
16
|
+
return _jsx("span", { className: `size-1.5 shrink-0 rounded-full ${tone}` });
|
|
17
|
+
}
|
|
18
|
+
export function AutomationDetailsDialog({ open, name, triggerSummary, fields, condition, instructions, mcpTools, lastError, scope, formatTimestamp, onClose, }) {
|
|
19
|
+
const t = useT();
|
|
20
|
+
const runsQuery = useAutomationRuns(scope, open ? name : null, open);
|
|
21
|
+
const runs = runsQuery.data ?? [];
|
|
22
|
+
return (_jsx(Dialog, { open: open, onOpenChange: (next) => {
|
|
23
|
+
if (!next)
|
|
24
|
+
onClose();
|
|
25
|
+
}, children: _jsxs(DialogContent, { className: "max-h-[85vh] max-w-2xl overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: name.replace(/-/g, " ") }), _jsx(DialogDescription, { children: triggerSummary })] }), _jsxs("div", { className: "space-y-4", children: [lastError ? (_jsxs("div", { className: "flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/5 p-2.5", children: [_jsx(IconAlertTriangle, { className: "mt-0.5 size-4 shrink-0 text-destructive" }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-xs font-medium text-destructive", children: t("jobs.blockedTitle", {
|
|
26
|
+
defaultValue: "This automation is not running",
|
|
27
|
+
}) }), _jsx("p", { className: "mt-0.5 break-words text-xs text-muted-foreground", children: lastError })] })] })) : null, _jsx("dl", { className: "grid grid-cols-2 gap-x-4 gap-y-2", children: fields.map((field) => (_jsxs("div", { className: "min-w-0", children: [_jsx("dt", { className: "text-[11px] uppercase tracking-wide text-muted-foreground/70", children: field.label }), _jsx("dd", { className: `mt-0.5 break-words text-sm ${field.mono ? "font-mono text-xs" : ""}`, children: field.value })] }, field.label))) }), condition ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.condition", { defaultValue: "Condition" }) }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: condition })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.instructions", { defaultValue: "Instructions" }) }), _jsx("p", { className: "mt-1 max-h-56 overflow-y-auto whitespace-pre-wrap rounded-md bg-muted/50 p-2.5 text-sm text-muted-foreground", children: instructions })] }), mcpTools.length > 0 ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.mcpTools", { defaultValue: "Connected MCP tools" }) }), _jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: mcpTools.map((toolName) => (_jsx("code", { className: "rounded bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground", children: toolName }, toolName))) })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.pastRuns", { defaultValue: "Past runs" }) }), runsQuery.isLoading ? (_jsxs("div", { className: "mt-2 flex items-center gap-2 text-xs text-muted-foreground", "aria-busy": "true", children: [_jsx(IconLoader2, { className: "size-3.5 animate-spin" }), t("jobs.loading", { defaultValue: "Loading…" })] })) : runsQuery.error ? (_jsx("p", { className: "mt-1 text-xs text-destructive", children: t("jobs.runsLoadError", {
|
|
28
|
+
defaultValue: "Could not load run history.",
|
|
29
|
+
}) })) : runs.length === 0 ? (_jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("jobs.noRuns", {
|
|
30
|
+
defaultValue: "This automation has not executed yet. Only real executions are recorded here.",
|
|
31
|
+
}) })) : (_jsx("ul", { className: "mt-2 divide-y divide-border/60 border-y border-border/60", children: runs.map((run) => (_jsxs("li", { className: "flex items-center gap-2 py-1.5 text-xs", children: [_jsx(RunStatusDot, { status: run.status }), _jsx("span", { className: "shrink-0 text-muted-foreground", children: formatTimestamp(run.startedAt) }), _jsx("span", { className: "shrink-0 font-medium", children: run.status }), run.error ? (_jsx("span", { className: "min-w-0 flex-1 truncate text-muted-foreground", title: run.error, children: run.error })) : (_jsx("span", { className: "min-w-0 flex-1" })), run.finishedAt ? (_jsxs("span", { className: "shrink-0 tabular-nums text-muted-foreground", children: [Math.round((run.finishedAt - run.startedAt) / 1000), "s"] })) : null] }, run.id))) }))] })] })] }) }));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=AutomationDetailsDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutomationDetailsDialog.js","sourceRoot":"","sources":["../../../src/client/agent-page/AutomationDetailsDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconAlertTriangle, IconLoader2 } from \"@tabler/icons-react\";\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../components/ui/dialog.js\";\nimport { useT } from \"../i18n.js\";\nimport { useAutomationRuns, type JobsScope } from \"./use-jobs.js\";\n\nexport interface AutomationDetailsField {\n label: string;\n value: string;\n mono?: boolean;\n}\n\nexport interface AutomationDetailsDialogProps {\n open: boolean;\n name: string;\n triggerSummary: string;\n fields: AutomationDetailsField[];\n condition: string | null;\n instructions: string;\n mcpTools: string[];\n lastError: string | null;\n scope: JobsScope;\n formatTimestamp: (value: number) => string;\n onClose: () => void;\n}\n\nfunction RunStatusDot({ status }: { status: string }) {\n const tone =\n status === \"success\"\n ? \"bg-emerald-500\"\n : status === \"error\"\n ? \"bg-destructive\"\n : // An interrupted run never reported an outcome, so it reads as\n // unknown rather than as still making progress.\n status === \"interrupted\"\n ? \"bg-muted-foreground\"\n : \"bg-amber-500\";\n return <span className={`size-1.5 shrink-0 rounded-full ${tone}`} />;\n}\n\nexport function AutomationDetailsDialog({\n open,\n name,\n triggerSummary,\n fields,\n condition,\n instructions,\n mcpTools,\n lastError,\n scope,\n formatTimestamp,\n onClose,\n}: AutomationDetailsDialogProps) {\n const t = useT();\n const runsQuery = useAutomationRuns(scope, open ? name : null, open);\n const runs = runsQuery.data ?? [];\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (!next) onClose();\n }}\n >\n <DialogContent className=\"max-h-[85vh] max-w-2xl overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>{name.replace(/-/g, \" \")}</DialogTitle>\n <DialogDescription>{triggerSummary}</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n {lastError ? (\n <div className=\"flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/5 p-2.5\">\n <IconAlertTriangle className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium text-destructive\">\n {t(\"jobs.blockedTitle\", {\n defaultValue: \"This automation is not running\",\n })}\n </p>\n <p className=\"mt-0.5 break-words text-xs text-muted-foreground\">\n {lastError}\n </p>\n </div>\n </div>\n ) : null}\n\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-2\">\n {fields.map((field) => (\n <div key={field.label} className=\"min-w-0\">\n <dt className=\"text-[11px] uppercase tracking-wide text-muted-foreground/70\">\n {field.label}\n </dt>\n <dd\n className={`mt-0.5 break-words text-sm ${\n field.mono ? \"font-mono text-xs\" : \"\"\n }`}\n >\n {field.value}\n </dd>\n </div>\n ))}\n </dl>\n\n {condition ? (\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.condition\", { defaultValue: \"Condition\" })}\n </p>\n <p className=\"mt-1 text-sm text-muted-foreground\">{condition}</p>\n </div>\n ) : null}\n\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.instructions\", { defaultValue: \"Instructions\" })}\n </p>\n <p className=\"mt-1 max-h-56 overflow-y-auto whitespace-pre-wrap rounded-md bg-muted/50 p-2.5 text-sm text-muted-foreground\">\n {instructions}\n </p>\n </div>\n\n {mcpTools.length > 0 ? (\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.mcpTools\", { defaultValue: \"Connected MCP tools\" })}\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1.5\">\n {mcpTools.map((toolName) => (\n <code\n key={toolName}\n className=\"rounded bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground\"\n >\n {toolName}\n </code>\n ))}\n </div>\n </div>\n ) : null}\n\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.pastRuns\", { defaultValue: \"Past runs\" })}\n </p>\n {runsQuery.isLoading ? (\n <div\n className=\"mt-2 flex items-center gap-2 text-xs text-muted-foreground\"\n aria-busy=\"true\"\n >\n <IconLoader2 className=\"size-3.5 animate-spin\" />\n {t(\"jobs.loading\", { defaultValue: \"Loading…\" })}\n </div>\n ) : runsQuery.error ? (\n <p className=\"mt-1 text-xs text-destructive\">\n {t(\"jobs.runsLoadError\", {\n defaultValue: \"Could not load run history.\",\n })}\n </p>\n ) : runs.length === 0 ? (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {t(\"jobs.noRuns\", {\n defaultValue:\n \"This automation has not executed yet. Only real executions are recorded here.\",\n })}\n </p>\n ) : (\n <ul className=\"mt-2 divide-y divide-border/60 border-y border-border/60\">\n {runs.map((run) => (\n <li\n key={run.id}\n className=\"flex items-center gap-2 py-1.5 text-xs\"\n >\n <RunStatusDot status={run.status} />\n <span className=\"shrink-0 text-muted-foreground\">\n {formatTimestamp(run.startedAt)}\n </span>\n <span className=\"shrink-0 font-medium\">{run.status}</span>\n {run.error ? (\n <span\n className=\"min-w-0 flex-1 truncate text-muted-foreground\"\n title={run.error}\n >\n {run.error}\n </span>\n ) : (\n <span className=\"min-w-0 flex-1\" />\n )}\n {run.finishedAt ? (\n <span className=\"shrink-0 tabular-nums text-muted-foreground\">\n {Math.round((run.finishedAt - run.startedAt) / 1000)}s\n </span>\n ) : null}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface AutomationScheduleDialogProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
name: string;
|
|
4
|
+
schedule: string;
|
|
5
|
+
timezone: string | null;
|
|
6
|
+
saving: boolean;
|
|
7
|
+
error?: string | null;
|
|
8
|
+
onCancel: () => void;
|
|
9
|
+
onSave: (next: {
|
|
10
|
+
schedule: string;
|
|
11
|
+
timezone: string;
|
|
12
|
+
}) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function AutomationScheduleDialog({ open, name, schedule, timezone, saving, error, onCancel, onSave, }: AutomationScheduleDialogProps): import("react").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=AutomationScheduleDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutomationScheduleDialog.d.ts","sourceRoot":"","sources":["../../../src/client/agent-page/AutomationScheduleDialog.tsx"],"names":[],"mappings":"AA6BA,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChE;AAED,wBAAgB,wBAAwB,CAAC,EACvC,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,GACP,EAAE,6BAA6B,+BAkI/B"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@agent-native/toolkit/ui/button";
|
|
3
|
+
import { Input } from "@agent-native/toolkit/ui/input";
|
|
4
|
+
import { IconLoader2 } from "@tabler/icons-react";
|
|
5
|
+
import { useEffect, useState } from "react";
|
|
6
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../components/ui/dialog.js";
|
|
7
|
+
import { useT } from "../i18n.js";
|
|
8
|
+
import { TimezoneSelect, browserTimezone } from "./TimezoneSelect.js";
|
|
9
|
+
const PRESETS = [
|
|
10
|
+
{ label: "Every hour", cron: "0 * * * *" },
|
|
11
|
+
{ label: "Every day at 8:00", cron: "0 8 * * *" },
|
|
12
|
+
{ label: "Every weekday at 9:00", cron: "0 9 * * 1-5" },
|
|
13
|
+
{ label: "Every Monday at 8:00", cron: "0 8 * * 1" },
|
|
14
|
+
];
|
|
15
|
+
const CRON_FIELD_COUNT = 5;
|
|
16
|
+
function looksLikeCron(value) {
|
|
17
|
+
return value.trim().split(/\s+/).length === CRON_FIELD_COUNT;
|
|
18
|
+
}
|
|
19
|
+
export function AutomationScheduleDialog({ open, name, schedule, timezone, saving, error, onCancel, onSave, }) {
|
|
20
|
+
const t = useT();
|
|
21
|
+
const [value, setValue] = useState(schedule);
|
|
22
|
+
const [zone, setZone] = useState(timezone || browserTimezone());
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!open)
|
|
25
|
+
return;
|
|
26
|
+
setValue(schedule);
|
|
27
|
+
setZone(timezone || browserTimezone());
|
|
28
|
+
}, [open, schedule, timezone]);
|
|
29
|
+
const trimmed = value.trim();
|
|
30
|
+
const valid = looksLikeCron(trimmed);
|
|
31
|
+
const changed = trimmed !== schedule.trim() || zone !== (timezone || browserTimezone());
|
|
32
|
+
return (_jsx(Dialog, { open: open, onOpenChange: (next) => {
|
|
33
|
+
if (!next && !saving)
|
|
34
|
+
onCancel();
|
|
35
|
+
}, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t("jobs.editScheduleTitle", {
|
|
36
|
+
defaultValue: "Edit schedule — {{name}}",
|
|
37
|
+
name: name.replace(/-/g, " "),
|
|
38
|
+
}) }), _jsx(DialogDescription, { children: t("jobs.editScheduleDescription", {
|
|
39
|
+
defaultValue: "The clock time below is read in the timezone you pick, so 8:00 means 8:00 there.",
|
|
40
|
+
}) })] }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("label", { className: "text-xs font-medium text-foreground", htmlFor: "automation-schedule", children: t("jobs.cronExpression", { defaultValue: "Cron expression" }) }), _jsx(Input, { id: "automation-schedule", className: "mt-1 font-mono text-sm", value: value, spellCheck: false, autoComplete: "off", disabled: saving, onChange: (event) => setValue(event.target.value) }), _jsx("p", { className: "mt-1 text-[11px] text-muted-foreground", children: t("jobs.cronFormatHint", {
|
|
41
|
+
defaultValue: "minute hour day-of-month month day-of-week",
|
|
42
|
+
}) })] }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: PRESETS.map((preset) => (_jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 cursor-pointer text-[11px]", disabled: saving, onClick: () => setValue(preset.cron), children: preset.label }, preset.cron))) }), _jsxs("div", { children: [_jsx("label", { className: "text-xs font-medium text-foreground", htmlFor: "automation-timezone", children: t("jobs.timezone", { defaultValue: "Timezone" }) }), _jsx("div", { className: "mt-1", children: _jsx(TimezoneSelect, { id: "automation-timezone", value: zone, disabled: saving, onChange: setZone, suggested: [browserTimezone()] }) })] }), trimmed && !valid ? (_jsx("p", { className: "text-xs text-destructive", children: t("jobs.cronFieldCount", {
|
|
43
|
+
defaultValue: "A cron expression needs exactly 5 fields.",
|
|
44
|
+
}) })) : null, error ? _jsx("p", { className: "text-xs text-destructive", children: error }) : null] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "outline", className: "cursor-pointer", disabled: saving, onClick: onCancel, children: t("jobs.cancel", { defaultValue: "Cancel" }) }), _jsxs(Button, { type: "button", className: "cursor-pointer", disabled: saving || !valid || !changed, onClick: () => onSave({ schedule: trimmed, timezone: zone }), children: [saving ? _jsx(IconLoader2, { className: "size-4 animate-spin" }) : null, t("jobs.saveSchedule", { defaultValue: "Save schedule" })] })] })] }) }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=AutomationScheduleDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutomationScheduleDialog.js","sourceRoot":"","sources":["../../../src/client/agent-page/AutomationScheduleDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Button } from \"@agent-native/toolkit/ui/button\";\nimport { Input } from \"@agent-native/toolkit/ui/input\";\nimport { IconLoader2 } from \"@tabler/icons-react\";\nimport { useEffect, useState } from \"react\";\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../components/ui/dialog.js\";\nimport { useT } from \"../i18n.js\";\nimport { TimezoneSelect, browserTimezone } from \"./TimezoneSelect.js\";\n\nconst PRESETS: { label: string; cron: string }[] = [\n { label: \"Every hour\", cron: \"0 * * * *\" },\n { label: \"Every day at 8:00\", cron: \"0 8 * * *\" },\n { label: \"Every weekday at 9:00\", cron: \"0 9 * * 1-5\" },\n { label: \"Every Monday at 8:00\", cron: \"0 8 * * 1\" },\n];\n\nconst CRON_FIELD_COUNT = 5;\n\nfunction looksLikeCron(value: string): boolean {\n return value.trim().split(/\\s+/).length === CRON_FIELD_COUNT;\n}\n\nexport interface AutomationScheduleDialogProps {\n open: boolean;\n name: string;\n schedule: string;\n timezone: string | null;\n saving: boolean;\n error?: string | null;\n onCancel: () => void;\n onSave: (next: { schedule: string; timezone: string }) => void;\n}\n\nexport function AutomationScheduleDialog({\n open,\n name,\n schedule,\n timezone,\n saving,\n error,\n onCancel,\n onSave,\n}: AutomationScheduleDialogProps) {\n const t = useT();\n const [value, setValue] = useState(schedule);\n const [zone, setZone] = useState(timezone || browserTimezone());\n\n useEffect(() => {\n if (!open) return;\n setValue(schedule);\n setZone(timezone || browserTimezone());\n }, [open, schedule, timezone]);\n\n const trimmed = value.trim();\n const valid = looksLikeCron(trimmed);\n const changed =\n trimmed !== schedule.trim() || zone !== (timezone || browserTimezone());\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (!next && !saving) onCancel();\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {t(\"jobs.editScheduleTitle\", {\n defaultValue: \"Edit schedule — {{name}}\",\n name: name.replace(/-/g, \" \"),\n })}\n </DialogTitle>\n <DialogDescription>\n {t(\"jobs.editScheduleDescription\", {\n defaultValue:\n \"The clock time below is read in the timezone you pick, so 8:00 means 8:00 there.\",\n })}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-3\">\n <div>\n <label\n className=\"text-xs font-medium text-foreground\"\n htmlFor=\"automation-schedule\"\n >\n {t(\"jobs.cronExpression\", { defaultValue: \"Cron expression\" })}\n </label>\n <Input\n id=\"automation-schedule\"\n className=\"mt-1 font-mono text-sm\"\n value={value}\n spellCheck={false}\n autoComplete=\"off\"\n disabled={saving}\n onChange={(event) => setValue(event.target.value)}\n />\n <p className=\"mt-1 text-[11px] text-muted-foreground\">\n {t(\"jobs.cronFormatHint\", {\n defaultValue: \"minute hour day-of-month month day-of-week\",\n })}\n </p>\n </div>\n\n <div className=\"flex flex-wrap gap-1.5\">\n {PRESETS.map((preset) => (\n <Button\n key={preset.cron}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 cursor-pointer text-[11px]\"\n disabled={saving}\n onClick={() => setValue(preset.cron)}\n >\n {preset.label}\n </Button>\n ))}\n </div>\n\n <div>\n <label\n className=\"text-xs font-medium text-foreground\"\n htmlFor=\"automation-timezone\"\n >\n {t(\"jobs.timezone\", { defaultValue: \"Timezone\" })}\n </label>\n <div className=\"mt-1\">\n <TimezoneSelect\n id=\"automation-timezone\"\n value={zone}\n disabled={saving}\n onChange={setZone}\n suggested={[browserTimezone()]}\n />\n </div>\n </div>\n\n {trimmed && !valid ? (\n <p className=\"text-xs text-destructive\">\n {t(\"jobs.cronFieldCount\", {\n defaultValue: \"A cron expression needs exactly 5 fields.\",\n })}\n </p>\n ) : null}\n {error ? <p className=\"text-xs text-destructive\">{error}</p> : null}\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"cursor-pointer\"\n disabled={saving}\n onClick={onCancel}\n >\n {t(\"jobs.cancel\", { defaultValue: \"Cancel\" })}\n </Button>\n <Button\n type=\"button\"\n className=\"cursor-pointer\"\n disabled={saving || !valid || !changed}\n onClick={() => onSave({ schedule: trimmed, timezone: zone })}\n >\n {saving ? <IconLoader2 className=\"size-4 animate-spin\" /> : null}\n {t(\"jobs.saveSchedule\", { defaultValue: \"Save schedule\" })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The browser's IANA zone, or UTC when the runtime cannot report one. */
|
|
2
|
+
export declare function browserTimezone(): string;
|
|
3
|
+
export interface TimezoneSelectProps {
|
|
4
|
+
value: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
onChange: (timezone: string) => void;
|
|
7
|
+
/** Zones to surface above the full list, e.g. the currently stored one. */
|
|
8
|
+
suggested?: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Label for a leading `system` choice. Settings offer it so the preference
|
|
11
|
+
* stays revertible; a schedule must name a concrete zone and omits it.
|
|
12
|
+
*/
|
|
13
|
+
systemLabel?: string;
|
|
14
|
+
id?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function TimezoneSelect({ value, disabled, onChange, suggested, systemLabel, id, }: TimezoneSelectProps): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=TimezoneSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimezoneSelect.d.ts","sourceRoot":"","sources":["../../../src/client/agent-page/TimezoneSelect.tsx"],"names":[],"mappings":"AAmBA,0EAA0E;AAC1E,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAqED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAc,EACd,WAAW,EACX,EAAE,GACH,EAAE,mBAAmB,+BA4HrB"}
|