@hualinge/relay-web 1.0.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/LICENSE +21 -0
- package/README.md +31 -0
- package/dist/assets/AgentsPage-2u2kFBCH.js +68 -0
- package/dist/assets/AgentsPage-2u2kFBCH.js.map +1 -0
- package/dist/assets/AgentsPage-BGbbVmeL.css +1 -0
- package/dist/assets/Alert-D88Fk6to.js +2 -0
- package/dist/assets/Alert-D88Fk6to.js.map +1 -0
- package/dist/assets/AppModal-BYZTSuch.js +2 -0
- package/dist/assets/AppModal-BYZTSuch.js.map +1 -0
- package/dist/assets/CenteredLoadingState-DHor-9vF.js +2 -0
- package/dist/assets/CenteredLoadingState-DHor-9vF.js.map +1 -0
- package/dist/assets/ChannelsPage-CbI0kqkd.js +2 -0
- package/dist/assets/ChannelsPage-CbI0kqkd.js.map +1 -0
- package/dist/assets/EmptyDataState-6mNx2Xhl.js +2 -0
- package/dist/assets/EmptyDataState-6mNx2Xhl.js.map +1 -0
- package/dist/assets/HelpPrompt-BPzDcC8F.js +2 -0
- package/dist/assets/HelpPrompt-BPzDcC8F.js.map +1 -0
- package/dist/assets/HomePage-t78sDDUj.js +2 -0
- package/dist/assets/HomePage-t78sDDUj.js.map +1 -0
- package/dist/assets/InspirationPage-BTqLpcHY.js +3 -0
- package/dist/assets/InspirationPage-BTqLpcHY.js.map +1 -0
- package/dist/assets/ModelsPage-YF0gpUxy.js +2 -0
- package/dist/assets/ModelsPage-YF0gpUxy.js.map +1 -0
- package/dist/assets/NameInitialIcon-DP-6_HQY.js +7 -0
- package/dist/assets/NameInitialIcon-DP-6_HQY.js.map +1 -0
- package/dist/assets/NoSearchResultsState-BiiYdZ_Z.js +2 -0
- package/dist/assets/NoSearchResultsState-BiiYdZ_Z.js.map +1 -0
- package/dist/assets/OverflowTooltip-CE5PjAb-.js +2 -0
- package/dist/assets/OverflowTooltip-CE5PjAb-.js.map +1 -0
- package/dist/assets/PasswordField-DmzjtnCg.js +2 -0
- package/dist/assets/PasswordField-DmzjtnCg.js.map +1 -0
- package/dist/assets/RefreshButton-BzYzeo5A.js +2 -0
- package/dist/assets/RefreshButton-BzYzeo5A.js.map +1 -0
- package/dist/assets/RightContentHeader-DoNDQ9Lo.js +3 -0
- package/dist/assets/RightContentHeader-DoNDQ9Lo.js.map +1 -0
- package/dist/assets/SchedulePage-CfW6lZVI.js +2 -0
- package/dist/assets/SchedulePage-CfW6lZVI.js.map +1 -0
- package/dist/assets/SearchInput-tux8xXH1.js +2 -0
- package/dist/assets/SearchInput-tux8xXH1.js.map +1 -0
- package/dist/assets/SkillAvatar-DwGvsY4f.js +2 -0
- package/dist/assets/SkillAvatar-DwGvsY4f.js.map +1 -0
- package/dist/assets/SkillsPage-ppqwKMvj.js +2 -0
- package/dist/assets/SkillsPage-ppqwKMvj.js.map +1 -0
- package/dist/assets/SkillsTab-c_As1DIr.css +1 -0
- package/dist/assets/SkillsTab-kY7MNdxy.js +2 -0
- package/dist/assets/SkillsTab-kY7MNdxy.js.map +1 -0
- package/dist/assets/Tab-FE0F2EQP.js +2 -0
- package/dist/assets/Tab-FE0F2EQP.js.map +1 -0
- package/dist/assets/ThreadPage-B0jElW5R.js +53 -0
- package/dist/assets/ThreadPage-B0jElW5R.js.map +1 -0
- package/dist/assets/UploadSkillModal-DHZL12vm.js +8 -0
- package/dist/assets/UploadSkillModal-DHZL12vm.js.map +1 -0
- package/dist/assets/XlsxDocumentPreview-BY-ht09K.js +5 -0
- package/dist/assets/XlsxDocumentPreview-BY-ht09K.js.map +1 -0
- package/dist/assets/_commonjs-dynamic-modules-TDtrdbi3.js +2 -0
- package/dist/assets/_commonjs-dynamic-modules-TDtrdbi3.js.map +1 -0
- package/dist/assets/chat-input-options-CpkOtPgQ.js +2 -0
- package/dist/assets/chat-input-options-CpkOtPgQ.js.map +1 -0
- package/dist/assets/docx-preview-zfB-orwa.js +28 -0
- package/dist/assets/docx-preview-zfB-orwa.js.map +1 -0
- package/dist/assets/exceljs.min-BY7KKJsM.js +58 -0
- package/dist/assets/exceljs.min-BY7KKJsM.js.map +1 -0
- package/dist/assets/helpers-CCilgpNy.js +2 -0
- package/dist/assets/helpers-CCilgpNy.js.map +1 -0
- package/dist/assets/hub-agent-editor.client-2DmCRGuY.js +2 -0
- package/dist/assets/hub-agent-editor.client-2DmCRGuY.js.map +1 -0
- package/dist/assets/hub-agent-editor.payload-D4sgJRSH.js +4 -0
- package/dist/assets/hub-agent-editor.payload-D4sgJRSH.js.map +1 -0
- package/dist/assets/hub-tag-editor-BBdd-aHK.js +2 -0
- package/dist/assets/hub-tag-editor-BBdd-aHK.js.map +1 -0
- package/dist/assets/index-Bed0I5IL.css +1 -0
- package/dist/assets/index-Bxf2_cvh.js +2 -0
- package/dist/assets/index-Bxf2_cvh.js.map +1 -0
- package/dist/assets/index-Cb4fQgom.js +103 -0
- package/dist/assets/index-Cb4fQgom.js.map +1 -0
- package/dist/assets/index-DQ2vVjmV.js +30 -0
- package/dist/assets/index-DQ2vVjmV.js.map +1 -0
- package/dist/assets/index-UBJEdbMO.js +2 -0
- package/dist/assets/index-UBJEdbMO.js.map +1 -0
- package/dist/assets/jszip.min-DPdj3o0t.js +13 -0
- package/dist/assets/jszip.min-DPdj3o0t.js.map +1 -0
- package/dist/assets/quick-actions-DzZE-zyP.js +2 -0
- package/dist/assets/quick-actions-DzZE-zyP.js.map +1 -0
- package/dist/assets/skill-options-cache-D1BJGTCU.js +2 -0
- package/dist/assets/skill-options-cache-D1BJGTCU.js.map +1 -0
- package/dist/assets/status-helpers-BILdm2MI.js +2 -0
- package/dist/assets/status-helpers-BILdm2MI.js.map +1 -0
- package/dist/assets/thread-title-Cerb2mHa.js +2 -0
- package/dist/assets/thread-title-Cerb2mHa.js.map +1 -0
- package/dist/assets/thread-utils-Ct3yp4R3.js +2 -0
- package/dist/assets/thread-utils-Ct3yp4R3.js.map +1 -0
- package/dist/assets/useAgentData-D-k9cXfg.js +2 -0
- package/dist/assets/useAgentData-D-k9cXfg.js.map +1 -0
- package/dist/assets/useEscapeKey-CEQ6-8GR.js +2 -0
- package/dist/assets/useEscapeKey-CEQ6-8GR.js.map +1 -0
- package/dist/assets/useExpertCatalog-BZdw1CYs.js +2 -0
- package/dist/assets/useExpertCatalog-BZdw1CYs.js.map +1 -0
- package/dist/assets/usePromptBlocks-5sz8Qh51.js +2 -0
- package/dist/assets/usePromptBlocks-5sz8Qh51.js.map +1 -0
- package/dist/assets/useSocket-YigidotN.css +1 -0
- package/dist/assets/useSocket-y3-zWhVL.js +11 -0
- package/dist/assets/useSocket-y3-zWhVL.js.map +1 -0
- package/dist/assets/utils--_pbLpCq.js +2 -0
- package/dist/assets/utils--_pbLpCq.js.map +1 -0
- package/dist/assets/vad-web-C_R267y1.js +2 -0
- package/dist/assets/vad-web-C_R267y1.js.map +1 -0
- package/dist/avatars/agent-avatar-1.png +0 -0
- package/dist/avatars/agent-avatar-2.png +0 -0
- package/dist/avatars/agent-avatar-3.png +0 -0
- package/dist/avatars/agent-avatar-4.png +0 -0
- package/dist/avatars/agent-avatar-5.png +0 -0
- package/dist/avatars/agent-avatar-6.png +0 -0
- package/dist/avatars/agent-avatar-7.png +0 -0
- package/dist/avatars/agent-avatar-8.png +0 -0
- package/dist/avatars/agent-avatar-9.png +0 -0
- package/dist/avatars/agentteams.png +0 -0
- package/dist/avatars/antig-opus.png +0 -0
- package/dist/avatars/antigravity.png +0 -0
- package/dist/avatars/assistant.svg +17 -0
- package/dist/avatars/codex-kawaii.png +0 -0
- package/dist/avatars/codex.png +0 -0
- package/dist/avatars/codex_box.png +0 -0
- package/dist/avatars/codex_iquid.png +0 -0
- package/dist/avatars/dare.png +0 -0
- package/dist/avatars/gemini-kawaii.png +0 -0
- package/dist/avatars/gemini.png +0 -0
- package/dist/avatars/gemini25.png +0 -0
- package/dist/avatars/gpt52.png +0 -0
- package/dist/avatars/jiuwenclaw.png +0 -0
- package/dist/avatars/office.svg +17 -0
- package/dist/avatars/opencode.png +0 -0
- package/dist/avatars/opus-45.png +0 -0
- package/dist/avatars/opus-kawaii.png +0 -0
- package/dist/avatars/opus.png +0 -0
- package/dist/avatars/sonnet.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/icons/arrow-left.svg +3 -0
- package/dist/icons/arrow-right.svg +3 -0
- package/dist/icons/attach.svg +9 -0
- package/dist/icons/chart/dislike.svg +3 -0
- package/dist/icons/chart/disliked.svg +3 -0
- package/dist/icons/chart/folder.svg +15 -0
- package/dist/icons/chart/home-loading.webp +0 -0
- package/dist/icons/chart/like.svg +3 -0
- package/dist/icons/chart/liked.svg +5 -0
- package/dist/icons/chart/loading.svg +26 -0
- package/dist/icons/chart/success.svg +7 -0
- package/dist/icons/check-line.svg +3 -0
- package/dist/icons/chevron-left.svg +3 -0
- package/dist/icons/chevron-right.svg +3 -0
- package/dist/icons/collapse.svg +14 -0
- package/dist/icons/common-delete.svg +4 -0
- package/dist/icons/common-folder.svg +4 -0
- package/dist/icons/copy.svg +4 -0
- package/dist/icons/cross-line.svg +4 -0
- package/dist/icons/data-analysis.svg +7 -0
- package/dist/icons/data-visualization.svg +10 -0
- package/dist/icons/deep-research.svg +4 -0
- package/dist/icons/document-processing.svg +5 -0
- package/dist/icons/edit.svg +4 -0
- package/dist/icons/expand.svg +6 -0
- package/dist/icons/expert-debate.svg +4 -0
- package/dist/icons/eye.svg +4 -0
- package/dist/icons/favicon.svg +7 -0
- package/dist/icons/file-docx.svg +60 -0
- package/dist/icons/file-folder.svg +4 -0
- package/dist/icons/file-gitignore.svg +35 -0
- package/dist/icons/file-html.svg +6 -0
- package/dist/icons/file-ini.svg +63 -0
- package/dist/icons/file-json.svg +4 -0
- package/dist/icons/file-md.svg +68 -0
- package/dist/icons/file-py.svg +4 -0
- package/dist/icons/file-sh.svg +7 -0
- package/dist/icons/file-txt.svg +37 -0
- package/dist/icons/file-zip.svg +21 -0
- package/dist/icons/file.svg +4 -0
- package/dist/icons/files-csv.svg +14 -0
- package/dist/icons/files-docx.svg +10 -0
- package/dist/icons/files-pdf.svg +14 -0
- package/dist/icons/files-ppt.svg +14 -0
- package/dist/icons/files-txt.svg +16 -0
- package/dist/icons/files-xlsx.svg +14 -0
- package/dist/icons/financial-services.svg +8 -0
- package/dist/icons/flie-html.svg +60 -0
- package/dist/icons/guided-mode.svg +9 -0
- package/dist/icons/icon-192x192.png +0 -0
- package/dist/icons/icon-512x512.png +0 -0
- package/dist/icons/icon-arrow-down.svg +4 -0
- package/dist/icons/icon-arrow-up.svg +4 -0
- package/dist/icons/icon-clear-all.svg +3 -0
- package/dist/icons/icon-close.svg +4 -0
- package/dist/icons/icon-code.svg +38 -0
- package/dist/icons/icon-drag-file.svg +26 -0
- package/dist/icons/icon-help.svg +4 -0
- package/dist/icons/icon-md.svg +53 -0
- package/dist/icons/icon-refresh.svg +4 -0
- package/dist/icons/icon-toggle.svg +6 -0
- package/dist/icons/icon-top.svg +7 -0
- package/dist/icons/icon-upload.svg +5 -0
- package/dist/icons/information.svg +6 -0
- package/dist/icons/inspiration/icon-excel.svg +14 -0
- package/dist/icons/inspiration/icon-inspiration.svg +5 -0
- package/dist/icons/inspiration/icon-markdown.svg +12 -0
- package/dist/icons/inspiration/icon-word.svg +10 -0
- package/dist/icons/link.svg +6 -0
- package/dist/icons/lock.svg +4 -0
- package/dist/icons/menu/agents.svg +39 -0
- package/dist/icons/menu/channels.svg +4 -0
- package/dist/icons/menu/icon-inspiration.svg +5 -0
- package/dist/icons/menu/models.svg +4 -0
- package/dist/icons/menu/new-chat.svg +59 -0
- package/dist/icons/menu/schedule.svg +4 -0
- package/dist/icons/menu/skills.svg +4 -0
- package/dist/icons/message-error.svg +6 -0
- package/dist/icons/message-prompt.svg +9 -0
- package/dist/icons/message-success.svg +6 -0
- package/dist/icons/message-warn.svg +8 -0
- package/dist/icons/more-trigger.svg +4 -0
- package/dist/icons/nss/1.svg +14 -0
- package/dist/icons/nss/2.svg +14 -0
- package/dist/icons/nss/3.svg +14 -0
- package/dist/icons/outline.svg +6 -0
- package/dist/icons/query_the_optical_power_border.svg +99 -0
- package/dist/icons/schedule.svg +4 -0
- package/dist/icons/settings-feedback/feedback-bug.svg +20 -0
- package/dist/icons/settings-feedback/feedback-file.svg +4 -0
- package/dist/icons/settings-feedback/feedback-idea.svg +14 -0
- package/dist/icons/settings-feedback/settings-gear.svg +4 -0
- package/dist/icons/settings-feedback/settings-link.svg +4 -0
- package/dist/icons/settings-feedback/settings-memory.svg +7 -0
- package/dist/icons/settings-feedback/settings-privacy.svg +37 -0
- package/dist/icons/settings-feedback/settings-search.svg +2 -0
- package/dist/icons/slides.svg +4 -0
- package/dist/icons/status/info-error.svg +9 -0
- package/dist/icons/style-template.svg +11 -0
- package/dist/icons/tool-error.svg +4 -0
- package/dist/icons/userprofile/help.svg +5 -0
- package/dist/icons/userprofile/keep-awake.svg +4 -0
- package/dist/icons/userprofile/question.svg +4 -0
- package/dist/icons/userprofile/security.svg +7 -0
- package/dist/icons/userprofile/style-template.svg +11 -0
- package/dist/icons/userprofile/theme.svg +14 -0
- package/dist/icons/userprofile/usage.svg +4 -0
- package/dist/icons/userprofile/version.svg +85 -0
- package/dist/icons/video-generation.svg +4 -0
- package/dist/images/OfficeClaw.svg +21 -0
- package/dist/images/add.svg +4 -0
- package/dist/images/agent-management-icons/agent-check.svg +23 -0
- package/dist/images/agent-management-icons/agent-close.svg +4 -0
- package/dist/images/agent-management-icons/agent-collab.svg +4 -0
- package/dist/images/agent-management-icons/agent-delete.svg +18 -0
- package/dist/images/agent-management-icons/agent-edit.svg +18 -0
- package/dist/images/agent-management-icons/agent-more.svg +4 -0
- package/dist/images/agent-management-icons/agent-persona.svg +4 -0
- package/dist/images/agent-management-icons/agent-random-avatar.svg +39 -0
- package/dist/images/agent-management-icons/agent-refresh.svg +4 -0
- package/dist/images/agent-management-icons/agent-skills.svg +4 -0
- package/dist/images/agent-management-icons/agent-template.svg +12 -0
- package/dist/images/agent-management-icons/anchor-current.svg +5 -0
- package/dist/images/agent-management-icons/anchor-other.svg +4 -0
- package/dist/images/chat-empty-agent.svg +12 -0
- package/dist/images/chat-empty-im.svg +14 -0
- package/dist/images/connectors/dingtalk.png +0 -0
- package/dist/images/connectors/dingtalk.svg +18 -0
- package/dist/images/connectors/feishu.png +0 -0
- package/dist/images/connectors/feishu.svg +12 -0
- package/dist/images/connectors/imessage.png +0 -0
- package/dist/images/connectors/wecom-agent.png +0 -0
- package/dist/images/connectors/wecom-bot.png +0 -0
- package/dist/images/connectors/weixin.png +0 -0
- package/dist/images/connectors/weixin.svg +19 -0
- package/dist/images/connectors/xiaoyi.png +0 -0
- package/dist/images/connectors/xiaoyi.svg +12 -0
- package/dist/images/create-agent-random-avatar.svg +39 -0
- package/dist/images/deepseek.svg +1 -0
- package/dist/images/default-ppt-template.png +0 -0
- package/dist/images/file-browser-tree/code.svg +60 -0
- package/dist/images/file-browser-tree/gitignore.svg +35 -0
- package/dist/images/file-browser-tree/image.svg +12 -0
- package/dist/images/file-browser-tree/markdown.svg +68 -0
- package/dist/images/file-browser-tree/pdf.svg +4 -0
- package/dist/images/file-browser-tree/ppt.svg +4 -0
- package/dist/images/file-browser-tree/public-file.svg +37 -0
- package/dist/images/file-browser-tree/word.svg +60 -0
- package/dist/images/file-browser-tree/xlsx.svg +4 -0
- package/dist/images/html-preview-toolbar/copy.svg +4 -0
- package/dist/images/html-preview-toolbar/open-external.svg +4 -0
- package/dist/images/html-preview-toolbar/refresh.svg +4 -0
- package/dist/images/information.svg +4 -0
- package/dist/images/inspiration/blue-bg.png +0 -0
- package/dist/images/inspiration/doc-example.png +0 -0
- package/dist/images/inspiration/excel-example.png +0 -0
- package/dist/images/inspiration/green-bg.png +0 -0
- package/dist/images/inspiration/markdown-example.png +0 -0
- package/dist/images/inspiration/orange-bg.png +0 -0
- package/dist/images/inspiration/purple-bg.png +0 -0
- package/dist/images/inspiration/task-bg.png +0 -0
- package/dist/images/inspiration-bg.png +0 -0
- package/dist/images/inspiration-products/default.svg +11 -0
- package/dist/images/invitation-background-4x.png +0 -0
- package/dist/images/kimi.svg +1 -0
- package/dist/images/link-blue.svg +4 -0
- package/dist/images/link.svg +4 -0
- package/dist/images/lobster.svg +118 -0
- package/dist/images/login1.svg +93 -0
- package/dist/images/login2.svg +80 -0
- package/dist/images/login3.svg +44 -0
- package/dist/images/login4.svg +18 -0
- package/dist/images/mode-default-icon.svg +22 -0
- package/dist/images/no-data.svg +26 -0
- package/dist/images/no-search-results.svg +25 -0
- package/dist/images/ppt-preview/placeholder-main.webp +0 -0
- package/dist/images/ppt-preview/placeholder-thumb.webp +0 -0
- package/dist/images/ppt-template/dark-tech.png +0 -0
- package/dist/images/ppt-template/huawei.png +0 -0
- package/dist/images/ppt-template/light-tech.png +0 -0
- package/dist/images/ppt-template/paper-humanities.png +0 -0
- package/dist/images/ppt-template/template-default.png +0 -0
- package/dist/images/ppt-template/template-error.png +0 -0
- package/dist/images/ppt-template/template-generate-bg.svg +9639 -0
- package/dist/images/qwen.svg +1 -0
- package/dist/images/task-list/empty-state.svg +4 -0
- package/dist/images/task-list.svg +1 -0
- package/dist/images/vendor.svg +4 -0
- package/dist/images/version-bg.svg +85 -0
- package/dist/images/version.svg +9 -0
- package/dist/images/zhipu.svg +1 -0
- package/dist/index.html +74 -0
- package/dist/loading-point-style.webp +0 -0
- package/dist/loading-small.webp +0 -0
- package/dist/manifest.json +25 -0
- package/package.json +126 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchedulePage-CfW6lZVI.js","sources":["../../src/components/schedule/schedule-template-catalog.ts","../../src/components/schedule/utils.ts","../../src/components/schedule/hooks/useTaskState.ts","../../src/components/schedule/hooks/useTaskActions.ts","../../src/components/schedule/hooks/useTaskCalendar.ts","../../src/components/schedule/hooks/useTaskModal.ts","../../src/components/schedule/components/Toolbar.tsx","../../src/components/schedule/components/ScheduleUnsupportedEditTooltip.tsx","../../src/components/schedule/components/TaskCard.tsx","../../src/components/schedule/components/TaskList.tsx","../../src/components/schedule/components/CalendarView.tsx","../../src/components/schedule/components/EmptyState.tsx","../../src/components/schedule/components/DetailModal.tsx","../../src/components/schedule/components/DeleteModal.tsx","../../src/components/schedule/utils/editor.ts","../../src/components/schedule/components/TimePickerField.tsx","../../src/components/schedule/components/DatePickerField.tsx","../../src/components/schedule/components/PickerFieldButton.tsx","../../src/components/schedule/components/IntervalUnitSelectField.tsx","../../src/components/schedule/components/SessionSelectField.tsx","../../src/components/schedule/hooks/useEditorState.ts","../../src/components/schedule/hooks/useSessionOptions.ts","../../src/components/schedule/components/ScheduleTaskEditorModal.tsx","../../src/components/schedule/components/ScheduleTemplatePickerModal.tsx","../../src/components/schedule/SchedulePanelView.tsx","../../src/components/schedule/SchedulePanel.tsx","../../src/pages/SchedulePage.tsx"],"sourcesContent":["import type { ScheduleTaskDraft, ScheduleTemplateDefinition } from './schedule-template-types';\n\nconst STATIC_SCHEDULE_TEMPLATE_CATALOG: ScheduleTemplateDefinition[] = [\n {\n id: 'daily-ai-news',\n title: '每日 AI 新闻推送',\n description: '关注当天 AI 领域的重要动态、模型发布与产品更新,整理重点信息后定时推送。',\n draft: {\n taskName: '每日 AI 新闻推送',\n prompt: '每天汇总 AI 领域的重要新闻、产品更新和模型发布,输出 3 到 5 条重点内容与简短点评。',\n frequency: { type: 'daily', time: '09:00:00' },\n enabled: true,\n },\n },\n {\n id: 'daily-english-words',\n title: '每日 5 个英语单词',\n description: '每天推荐 5 个高频实用英语单词,帮助积累词汇并保持稳定输入。',\n draft: {\n taskName: '每日 5 个英语单词',\n prompt: '每天推荐 5 个高频实用英文单词,包含音标、词义、例句和简短记忆提示。',\n frequency: { type: 'daily', time: '08:00:00' },\n enabled: true,\n },\n },\n {\n id: 'bedtime-story',\n title: '每日儿童睡前故事',\n description: '生成 3 到 5 分钟可读的温和睡前故事,适合在夜间固定时间播放或阅读。',\n draft: {\n taskName: '每日儿童睡前故事',\n prompt: '每天生成一篇适合儿童睡前阅读的温和短故事,语气轻松,结尾积极。',\n frequency: { type: 'daily', time: '20:30:00' },\n enabled: true,\n },\n },\n {\n id: 'weekly-work-report',\n title: '每周工作周报',\n description: '每周五汇总本周工作进展、PR 与 Issue 处理情况,并整理成简明周报。',\n draft: {\n taskName: '每周工作周报',\n prompt: '每周汇总本周工作进展、完成事项、风险问题和下周计划,输出结构化周报。',\n frequency: { type: 'weekday', time: '18:00:00', weekdays: ['5'] },\n enabled: true,\n },\n },\n {\n id: 'classic-movie',\n title: '经典电影推荐',\n description: '推荐一部高分经典电影,提供简要介绍、推荐理由和观看建议。',\n draft: {\n taskName: '经典电影推荐',\n prompt: '定期推荐一部经典电影,包含剧情简介、推荐理由和适合观看的人群。',\n frequency: { type: 'weekday', time: '20:00:00', weekdays: ['6'] },\n enabled: true,\n },\n },\n {\n id: 'today-in-history',\n title: '历史上的今天',\n description: '从科技、电影、音乐等领域挑选当天对应的历史事件,生成轻量内容推送。',\n draft: {\n taskName: '历史上的今天',\n prompt: '每天推送历史上的今天发生的重要事件,覆盖科技、电影、音乐等领域。',\n frequency: { type: 'daily', time: '10:00:00' },\n enabled: true,\n },\n },\n {\n id: 'family-reminder',\n title: '父母联系提醒',\n description: '每周固定提醒联系家人,避免忙碌时忘记主动问候。',\n draft: {\n taskName: '父母联系提醒',\n prompt: '提醒我主动联系父母,语气自然简短。',\n frequency: { type: 'weekday', time: '10:00:00', weekdays: ['7'] },\n enabled: true,\n },\n },\n {\n id: 'medical-checkup-reminder',\n title: '体检预约提醒',\n description: '在预约日期前提醒关注体检安排、准备事项与时间节点。',\n draft: {\n taskName: '体检预约提醒',\n prompt: '提醒我关注体检预约时间和准备事项。',\n frequency: { type: 'once', executeTime: '2026-04-20 09:00:00' },\n enabled: true,\n },\n },\n {\n id: 'interview-preparation',\n title: '面试准备提醒',\n description: '工作日提醒复习面试题、项目经历和表达材料,保持准备节奏。',\n draft: {\n taskName: '面试准备提醒',\n prompt: '在工作日定时提醒我复习面试题、项目经历和自我介绍。',\n frequency: { type: 'weekday', time: '20:00:00', weekdays: ['1', '2', '3', '4', '5'] },\n enabled: true,\n },\n },\n {\n id: 'meeting-prep',\n title: '会议前准备',\n description: '在固定工作日时间提醒整理会议议题、材料和待确认事项。',\n draft: {\n taskName: '会议前准备',\n prompt: '在会议开始前提醒我整理议题、材料和待确认问题。',\n frequency: { type: 'weekday', time: '09:30:00', weekdays: ['1', '2', '3', '4', '5'] },\n enabled: true,\n },\n },\n {\n id: 'pet-wallpaper',\n title: '可爱萌宠手机壁纸',\n description: '随机从不同风格中挑选一张可爱萌宠壁纸,定期更新手机背景灵感。',\n draft: {\n taskName: '可爱萌宠手机壁纸',\n prompt: '定期推荐一张可爱萌宠风格的手机壁纸,风格清新,适合移动端。',\n frequency: { type: 'weekday', time: '08:30:00', weekdays: ['1'] },\n enabled: true,\n },\n },\n {\n id: 'scheduled-data-fetch',\n title: '定时数据抓取',\n description: '定期抓取指定数据源并输出摘要,适合监控日常数据变化与异常波动。',\n draft: {\n taskName: '定时数据抓取',\n prompt: '定时抓取指定数据源并输出简要结果摘要,标记异常变化。',\n frequency: { type: 'daily', time: '09:00:00' },\n enabled: true,\n },\n },\n];\n\nexport async function loadScheduleTemplateCatalog(): Promise<ScheduleTemplateDefinition[]> {\n return STATIC_SCHEDULE_TEMPLATE_CATALOG;\n}\n\nexport function createScheduleTaskDraft(template: ScheduleTemplateDefinition): ScheduleTaskDraft {\n return {\n source: 'template',\n templateId: template.id,\n ...template.draft,\n sessionId: null,\n };\n}\n\nexport function createEmptyCustomScheduleTaskDraft(): ScheduleTaskDraft {\n return {\n source: 'custom',\n taskName: '',\n prompt: '',\n frequency: { type: 'daily', time: '' },\n enabled: true,\n sessionId: null,\n };\n}\n","import type { ScheduleTrigger, ScheduledTaskItem } from './types';\nimport type { ScheduleTaskDraft } from './schedule-template-types';\nimport type { ScheduleIntervalUnit } from './schedule-template-types';\nimport type { ScheduleRunItem, ScheduleRunOutcome } from './types';\n\n// =============================================================================\n// Interval Utils (from scheduled-task-interval-utils.ts)\n// =============================================================================\n\nconst INTERVAL_MS_BY_UNIT: Record<ScheduleIntervalUnit, number> = {\n hour: 60 * 60 * 1000,\n minute: 60 * 1000,\n second: 1000,\n};\n\nconst INTERVAL_UNIT_LABELS: Record<ScheduleIntervalUnit, string> = {\n hour: '小时',\n minute: '分钟',\n second: '秒',\n};\n\nexport function intervalValueToMs(value: number, unit: ScheduleIntervalUnit): number {\n return value * INTERVAL_MS_BY_UNIT[unit];\n}\n\nexport function normalizeIntervalMs(\n ms: number,\n): { interval: number; unit: ScheduleIntervalUnit } | null {\n if (!Number.isFinite(ms) || ms < 10_000) return null;\n if (ms % INTERVAL_MS_BY_UNIT.hour === 0) {\n return { interval: ms / INTERVAL_MS_BY_UNIT.hour, unit: 'hour' };\n }\n if (ms % INTERVAL_MS_BY_UNIT.minute === 0) {\n return { interval: ms / INTERVAL_MS_BY_UNIT.minute, unit: 'minute' };\n }\n if (ms % INTERVAL_MS_BY_UNIT.second === 0) {\n return { interval: ms / INTERVAL_MS_BY_UNIT.second, unit: 'second' };\n }\n return null;\n}\n\nexport function formatIntervalFrequency(ms: number): string {\n const normalized = normalizeIntervalMs(ms);\n if (normalized) {\n return `每隔 ${normalized.interval} ${INTERVAL_UNIT_LABELS[normalized.unit]}`;\n }\n return `每隔 ${ms} 毫秒`;\n}\n\n// =============================================================================\n// Cron Frequency Formatting (from scheduled-task-frequency.ts)\n// =============================================================================\n\ntype ParsedField =\n | { kind: 'any'; raw: string }\n | { kind: 'single'; raw: string; value: number }\n | { kind: 'list'; raw: string; values: number[] }\n | { kind: 'range'; raw: string; from: number; to: number }\n | { kind: 'step'; raw: string; step: number }\n | { kind: 'range-step'; raw: string; from: number; to: number; step: number }\n | { kind: 'mixed'; raw: string };\n\ntype ParseFieldOptions = {\n min: number;\n max: number;\n nameMap?: Record<string, number>;\n normalize?: (value: number) => number;\n};\n\nconst WEEKDAY_NAME_TO_NUM: Record<string, number> = {\n SUN: 0, SUNDAY: 0,\n MON: 1, MONDAY: 1,\n TUE: 2, TUESDAY: 2,\n WED: 3, WEDNESDAY: 3,\n THU: 4, THURSDAY: 4,\n FRI: 5, FRIDAY: 5,\n SAT: 6, SATURDAY: 6,\n};\n\nconst MONTH_NAME_TO_NUM: Record<string, number> = {\n JAN: 1, JANUARY: 1,\n FEB: 2, FEBRUARY: 2,\n MAR: 3, MARCH: 3,\n APR: 4, APRIL: 4,\n MAY: 5,\n JUN: 6, JUNE: 6,\n JUL: 7, JULY: 7,\n AUG: 8, AUGUST: 8,\n SEP: 9, SEPTEMBER: 9,\n OCT: 10, OCTOBER: 10,\n NOV: 11, NOVEMBER: 11,\n DEC: 12, DECEMBER: 12,\n};\n\nconst WEEKDAY_LABELS = ['日', '一', '二', '三', '四', '五', '六'] as const;\nconst LIST_SEPARATOR = '、';\n\nfunction formatClock(hour: number, minute: number, second?: number): string {\n const period = hour < 12 ? '上午' : '下午';\n const hour12 = ((hour + 11) % 12) + 1;\n const minuteText = String(minute).padStart(2, '0');\n if (typeof second === 'number') {\n const secondText = String(second).padStart(2, '0');\n return `${period} ${hour12}:${minuteText}:${secondText}`;\n }\n return `${period} ${hour12}:${minuteText}`;\n}\n\nfunction parseToken(rawToken: string, options: ParseFieldOptions): number | null {\n const token = rawToken.trim().toUpperCase();\n if (!token) return null;\n const mapped = options.nameMap?.[token];\n const numeric = mapped ?? Number(token);\n if (!Number.isFinite(numeric)) return null;\n const normalized = options.normalize ? options.normalize(numeric) : numeric;\n if (normalized < options.min || normalized > options.max) return null;\n return normalized;\n}\n\nfunction dedupeKeepOrder(values: number[]): number[] {\n const seen = new Set<number>();\n const result: number[] = [];\n for (const value of values) {\n if (seen.has(value)) continue;\n seen.add(value);\n result.push(value);\n }\n return result;\n}\n\nfunction parseCronField(rawValue: string, options: ParseFieldOptions): ParsedField {\n const raw = rawValue.trim();\n const upper = raw.toUpperCase();\n if (!raw) return { kind: 'mixed', raw };\n if (upper === '*' || upper === '?') return { kind: 'any', raw };\n\n if (upper.includes(',')) {\n const values: number[] = [];\n for (const part of upper.split(',')) {\n const segment = part.trim();\n if (!segment || segment.includes('/') || segment.includes('-')) return { kind: 'mixed', raw };\n const value = parseToken(segment, options);\n if (value === null) return { kind: 'mixed', raw };\n values.push(value);\n }\n return { kind: 'list', raw, values: dedupeKeepOrder(values) };\n }\n\n const stepMatch = upper.match(/^(.+)\\/(\\d+)$/);\n if (stepMatch) {\n const step = Number(stepMatch[2]);\n if (!Number.isFinite(step) || step <= 0) return { kind: 'mixed', raw };\n const left = stepMatch[1]!.trim();\n if (left === '*' || left === '?') {\n return { kind: 'step', raw, step };\n }\n const rangeMatch = left.match(/^([A-Z0-9]+)-([A-Z0-9]+)$/);\n if (rangeMatch) {\n const from = parseToken(rangeMatch[1]!, options);\n const to = parseToken(rangeMatch[2]!, options);\n if (from === null || to === null || from > to) return { kind: 'mixed', raw };\n return { kind: 'range-step', raw, from, to, step };\n }\n const start = parseToken(left, options);\n if (start === null) return { kind: 'mixed', raw };\n return { kind: 'range-step', raw, from: start, to: options.max, step };\n }\n\n const rangeMatch = upper.match(/^([A-Z0-9]+)-([A-Z0-9]+)$/);\n if (rangeMatch) {\n const from = parseToken(rangeMatch[1]!, options);\n const to = parseToken(rangeMatch[2]!, options);\n if (from === null || to === null || from > to) return { kind: 'mixed', raw };\n return { kind: 'range', raw, from, to };\n }\n\n const single = parseToken(upper, options);\n if (single !== null) return { kind: 'single', raw, value: single };\n return { kind: 'mixed', raw };\n}\n\nfunction isAny(field: ParsedField): field is { kind: 'any'; raw: string } {\n return field.kind === 'any';\n}\n\nfunction formatValues(values: number[]): string {\n return values.join(LIST_SEPARATOR);\n}\n\nfunction formatMonthText(field: ParsedField): string | null {\n switch (field.kind) {\n case 'single':\n return `${field.value}月`;\n case 'list':\n return `${field.values.map((value) => `${value}月`).join(LIST_SEPARATOR)}`;\n case 'range':\n return `${field.from}月至${field.to}月`;\n case 'step':\n return `每隔 ${field.step} 个月`;\n case 'range-step':\n return `${field.from}月至${field.to}月每隔 ${field.step} 个月`;\n default:\n return null;\n }\n}\n\nfunction formatDayOfMonthText(field: ParsedField): string | null {\n switch (field.kind) {\n case 'single':\n return `${field.value}号`;\n case 'list':\n return `${field.values.map((value) => `${value}号`).join(LIST_SEPARATOR)}`;\n case 'range':\n return `${field.from}号至${field.to}号`;\n case 'step':\n return `每隔 ${field.step} 天`;\n case 'range-step':\n return `${field.from}号至${field.to}号每隔 ${field.step} 天`;\n default:\n return null;\n }\n}\n\nfunction formatWeekdaySpan(field: ParsedField): string | null {\n const toLabel = (value: number): string => WEEKDAY_LABELS[value] ?? String(value);\n switch (field.kind) {\n case 'single':\n return toLabel(field.value);\n case 'list':\n return field.values.map((value) => toLabel(value)).join(LIST_SEPARATOR);\n case 'range':\n return `${toLabel(field.from)}至${toLabel(field.to)}`;\n case 'step':\n return `每隔 ${field.step} 天`;\n case 'range-step':\n return `${toLabel(field.from)}至${toLabel(field.to)}每隔 ${field.step} 天`;\n default:\n return null;\n }\n}\n\nfunction formatSecondText(field: ParsedField): string | null {\n switch (field.kind) {\n case 'any':\n return '每秒';\n case 'single':\n return `第${field.value}秒`;\n case 'list':\n return `第${formatValues(field.values)}秒`;\n case 'range':\n return `${field.from}-${field.to}秒`;\n case 'step':\n return `每隔 ${field.step} 秒`;\n case 'range-step':\n return `${field.from}-${field.to}秒每隔 ${field.step} 秒`;\n default:\n return null;\n }\n}\n\nfunction formatMinuteText(field: ParsedField): string | null {\n switch (field.kind) {\n case 'any':\n return '每分钟';\n case 'single':\n return `第${field.value}分钟`;\n case 'list':\n return `第${formatValues(field.values)}分钟`;\n case 'range':\n return `${field.from}-${field.to}分钟`;\n case 'step':\n return `每隔 ${field.step} 分钟`;\n case 'range-step':\n return `${field.from}-${field.to}分钟每隔 ${field.step} 分钟`;\n default:\n return null;\n }\n}\n\nfunction secondSuffix(field: ParsedField, hasExplicitSeconds: boolean): string {\n if (!hasExplicitSeconds) return '';\n if (field.kind === 'single' && field.value === 0) return '';\n const text = formatSecondText(field);\n if (!text) return '';\n return `(${text})`;\n}\n\nfunction formatDatePart(month: ParsedField, dayOfMonth: ParsedField, dayOfWeek: ParsedField): string | null {\n const monthAny = isAny(month);\n const dayOfMonthAny = isAny(dayOfMonth);\n const dayOfWeekAny = isAny(dayOfWeek);\n\n if (monthAny && dayOfMonthAny && dayOfWeekAny) return null;\n\n if (monthAny && dayOfMonthAny && !dayOfWeekAny) {\n const dayOfWeekText = formatWeekdaySpan(dayOfWeek);\n if (!dayOfWeekText) return null;\n return `每周${dayOfWeekText}`;\n }\n\n if (monthAny && !dayOfMonthAny && dayOfWeekAny) {\n const dayOfMonthText = formatDayOfMonthText(dayOfMonth);\n if (!dayOfMonthText) return null;\n if (dayOfMonth.kind === 'step' || dayOfMonth.kind === 'range-step') return dayOfMonthText;\n return `每月${dayOfMonthText}`;\n }\n\n if (!monthAny && dayOfMonthAny && dayOfWeekAny) {\n const monthText = formatMonthText(month);\n if (!monthText) return null;\n if (month.kind === 'step' || month.kind === 'range-step') return monthText;\n return `每年${monthText}`;\n }\n\n if (!monthAny && !dayOfMonthAny && dayOfWeekAny) {\n const monthText = formatMonthText(month);\n const dayOfMonthText = formatDayOfMonthText(dayOfMonth);\n if (!monthText || !dayOfMonthText) return null;\n const yearPrefix = month.kind === 'step' || month.kind === 'range-step' ? monthText : `每年${monthText}`;\n return `${yearPrefix}${dayOfMonthText}`;\n }\n\n if (monthAny && !dayOfMonthAny && !dayOfWeekAny) {\n const dayOfMonthText = formatDayOfMonthText(dayOfMonth);\n const dayOfWeekText = formatWeekdaySpan(dayOfWeek);\n if (!dayOfMonthText || !dayOfWeekText) return null;\n return `每月${dayOfMonthText},每周${dayOfWeekText}`;\n }\n\n if (!monthAny && dayOfMonthAny && !dayOfWeekAny) {\n const monthText = formatMonthText(month);\n const dayOfWeekText = formatWeekdaySpan(dayOfWeek);\n if (!monthText || !dayOfWeekText) return null;\n const yearPrefix = month.kind === 'step' || month.kind === 'range-step' ? monthText : `每年${monthText}`;\n return `${yearPrefix},每周${dayOfWeekText}`;\n }\n\n if (!monthAny && !dayOfMonthAny && !dayOfWeekAny) {\n const monthText = formatMonthText(month);\n const dayOfMonthText = formatDayOfMonthText(dayOfMonth);\n const dayOfWeekText = formatWeekdaySpan(dayOfWeek);\n if (!monthText || !dayOfMonthText || !dayOfWeekText) return null;\n const yearPrefix = month.kind === 'step' || month.kind === 'range-step' ? monthText : `每年${monthText}`;\n return `${yearPrefix}${dayOfMonthText},每周${dayOfWeekText}`;\n }\n\n return null;\n}\n\nfunction formatFixedTimesForHours(hours: number[], minute: number, second?: number): string {\n return hours.map((hour) => formatClock(hour, minute, second)).join(LIST_SEPARATOR);\n}\n\nfunction formatTimePart(\n hour: ParsedField,\n minute: ParsedField,\n second: ParsedField,\n hasExplicitSeconds: boolean,\n hasDateConstraint: boolean,\n): string | null {\n const hourAny = isAny(hour);\n const minuteAny = isAny(minute);\n\n if (hourAny && minuteAny) {\n if (!hasExplicitSeconds) return '每分钟';\n if (second.kind === 'single' && second.value === 0) return '每分钟';\n if (second.kind === 'any') return '每秒';\n if (second.kind === 'step') return `每隔 ${second.step} 秒`;\n const secondText = formatSecondText(second);\n return secondText ? `每分钟${secondText}` : null;\n }\n\n if (hourAny) {\n const minuteText = formatMinuteText(minute);\n if (!minuteText) return null;\n let base = minuteText;\n if (minute.kind !== 'step' && minute.kind !== 'any') {\n base = `每小时${minuteText}`;\n }\n return `${base}${secondSuffix(second, hasExplicitSeconds)}`.trim();\n }\n\n if (hour.kind === 'step') {\n if (minute.kind === 'single') {\n return `每隔 ${hour.step} 小时(第${minute.value}分钟)${secondSuffix(second, hasExplicitSeconds)}`.trim();\n }\n const minuteText = formatMinuteText(minute);\n if (!minuteText) return null;\n return `每隔 ${hour.step} 小时(${minuteText})${secondSuffix(second, hasExplicitSeconds)}`.trim();\n }\n\n if (hour.kind === 'range-step') {\n const minuteText = formatMinuteText(minute);\n if (!minuteText) return null;\n return `每天${hour.from}点至${hour.to}点每隔 ${hour.step} 小时(${minuteText})${secondSuffix(second, hasExplicitSeconds)}`.trim();\n }\n\n if (hour.kind === 'single' && minute.kind === 'single') {\n const secondValue = hasExplicitSeconds && second.kind === 'single' ? second.value : undefined;\n const prefix = hasDateConstraint ? '' : '每天 ';\n const base = `${prefix}${formatClock(hour.value, minute.value, secondValue)}`;\n if (!hasExplicitSeconds || second.kind === 'single') return base;\n return `${base}${secondSuffix(second, hasExplicitSeconds)}`;\n }\n\n if (hour.kind === 'list' && minute.kind === 'single') {\n const secondValue = hasExplicitSeconds && second.kind === 'single' ? second.value : undefined;\n const prefix = hasDateConstraint ? '' : '每天 ';\n const times = formatFixedTimesForHours(hour.values, minute.value, secondValue);\n if (!hasExplicitSeconds || second.kind === 'single') return `${prefix}${times}`;\n return `${prefix}${times}${secondSuffix(second, hasExplicitSeconds)}`;\n }\n\n if (hour.kind === 'range' && minute.kind === 'single') {\n const prefix = hasDateConstraint ? '' : '每天 ';\n const base = `${prefix}${hour.from}点至${hour.to}点第${minute.value}分钟`;\n return `${base}${secondSuffix(second, hasExplicitSeconds)}`;\n }\n\n if (hour.kind === 'range') {\n const minuteText = formatMinuteText(minute);\n if (!minuteText) return null;\n const prefix = hasDateConstraint ? '' : '每天 ';\n const base = `${prefix}${hour.from}点至${hour.to}点${minuteText}`;\n return `${base}${secondSuffix(second, hasExplicitSeconds)}`;\n }\n\n if (hour.kind === 'single') {\n const minuteText = formatMinuteText(minute);\n if (!minuteText) return null;\n const prefix = hasDateConstraint ? '' : '每天 ';\n const base = `${prefix}${hour.value}点${minuteText}`;\n return `${base}${secondSuffix(second, hasExplicitSeconds)}`;\n }\n\n return null;\n}\n\nexport function formatCronFrequency(expression: string): string {\n const parts = expression.trim().split(/\\s+/);\n if (parts.length < 5) return expression;\n\n let secondRaw = '0';\n let minuteRaw = '*';\n let hourRaw = '*';\n let dayOfMonthRaw = '*';\n let monthRaw = '*';\n let dayOfWeekRaw = '*';\n let hasExplicitSeconds = false;\n\n if (parts.length === 5) {\n [minuteRaw, hourRaw, dayOfMonthRaw, monthRaw, dayOfWeekRaw] = parts;\n } else {\n [secondRaw, minuteRaw, hourRaw, dayOfMonthRaw, monthRaw, dayOfWeekRaw] = parts;\n hasExplicitSeconds = true;\n }\n\n const second = parseCronField(secondRaw, { min: 0, max: 59 });\n const minute = parseCronField(minuteRaw, { min: 0, max: 59 });\n const hour = parseCronField(hourRaw, { min: 0, max: 23 });\n const dayOfMonth = parseCronField(dayOfMonthRaw, { min: 1, max: 31 });\n const month = parseCronField(monthRaw, { min: 1, max: 12, nameMap: MONTH_NAME_TO_NUM });\n const dayOfWeek = parseCronField(dayOfWeekRaw, {\n min: 0,\n max: 6,\n nameMap: WEEKDAY_NAME_TO_NUM,\n normalize: (value) => (value === 7 ? 0 : value),\n });\n\n const hasDateConstraint = !(isAny(month) && isAny(dayOfMonth) && isAny(dayOfWeek));\n const datePart = formatDatePart(month, dayOfMonth, dayOfWeek);\n const timePart = formatTimePart(hour, minute, second, hasExplicitSeconds, hasDateConstraint);\n\n if (datePart && timePart) return `${datePart} ${timePart}`.replace(/\\s+/g, ' ').trim();\n if (datePart) return datePart;\n if (timePart) return timePart;\n return expression;\n}\n\n// =============================================================================\n// Calendar Utils (from scheduled-tasks-calendar-utils.ts)\n// =============================================================================\n\nexport type CalendarDisplayMode = 'single' | 'recurring';\nexport type CalendarTaskState = 'pending' | 'completed' | 'failed' | 'paused' | 'skipped';\n\nexport type CalendarOccurrence = {\n taskId: string;\n sourceTaskId: string;\n taskName: string;\n mode: CalendarDisplayMode;\n timeLabel: string;\n state: CalendarTaskState;\n lastExecutionText?: string;\n nextExecutionText?: string;\n latestRunAt?: string;\n latestRunOutcome?: ScheduleRunOutcome;\n runCount?: number;\n};\n\nexport type CalendarDayColumn = {\n date: Date;\n dayIndex: number;\n labelZh: string;\n labelEn: string;\n dayOfMonth: number;\n occurrences: CalendarOccurrence[];\n};\n\nconst WEEKDAY_ZH = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] as const;\nconst WEEKDAY_EN = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'] as const;\n\ntype ParsedCron = {\n second: string;\n minute: string;\n hour: string;\n dayOfMonth: string;\n month: string;\n dayOfWeek: string;\n};\n\ntype DailyRunSummary = {\n latestRun: ScheduleRunItem;\n latestStartedAt: Date;\n runCount: number;\n state: CalendarTaskState;\n};\n\nfunction pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nfunction toHm(date: Date): string {\n return `${pad2(date.getHours())}:${pad2(date.getMinutes())}`;\n}\n\nfunction startOfDay(date: Date): Date {\n const out = new Date(date);\n out.setHours(0, 0, 0, 0);\n return out;\n}\n\nfunction compareDateOnly(a: Date, b: Date): number {\n const av = startOfDay(a).getTime();\n const bv = startOfDay(b).getTime();\n if (av < bv) return -1;\n if (av > bv) return 1;\n return 0;\n}\n\nfunction parseCron(expression: string): ParsedCron | null {\n const parts = expression.trim().split(/\\s+/);\n if (parts.length < 5) return null;\n if (parts.length === 5) {\n const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;\n return { second: '0', minute, hour, dayOfMonth, month, dayOfWeek };\n }\n const [second, minute, hour, dayOfMonth, month, dayOfWeek] = parts;\n return { second, minute, hour, dayOfMonth, month, dayOfWeek };\n}\n\nfunction isSameDate(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\nfunction localDateKey(date: Date): string {\n return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;\n}\n\nfunction isValidDate(date: Date): boolean {\n return Number.isFinite(date.getTime());\n}\n\nfunction isPastDay(date: Date, now: Date): boolean {\n return compareDateOnly(date, now) < 0;\n}\n\nfunction hasStepSyntax(field: string): boolean {\n return field.includes('/');\n}\n\nfunction parseCalendarToken(token: string, map?: Record<string, number>): number | null {\n const upper = token.trim().toUpperCase();\n if (!upper) return null;\n if (map && upper in map) return map[upper]!;\n const num = Number(upper);\n if (!Number.isFinite(num)) return null;\n return num;\n}\n\nfunction matchField(\n rawField: string,\n value: number,\n min: number,\n max: number,\n map?: Record<string, number>,\n normalize?: (num: number) => number,\n): boolean {\n const field = rawField.trim().toUpperCase();\n if (field === '*' || field === '?') return true;\n const items = field.split(',');\n for (const item of items) {\n const segment = item.trim();\n if (!segment) continue;\n const stepMatch = segment.match(/^(.+)\\/(\\d+)$/);\n if (stepMatch) {\n const left = stepMatch[1]!.trim();\n const step = Number(stepMatch[2]!);\n if (!Number.isFinite(step) || step <= 0) continue;\n let rangeStart = min;\n let rangeEnd = max;\n if (left !== '*' && left !== '?') {\n const rangeMatch = left.match(/^([A-Z0-9]+)-([A-Z0-9]+)$/);\n if (rangeMatch) {\n const fromRaw = parseCalendarToken(rangeMatch[1]!, map);\n const toRaw = parseCalendarToken(rangeMatch[2]!, map);\n if (fromRaw === null || toRaw === null) continue;\n rangeStart = normalize ? normalize(fromRaw) : fromRaw;\n rangeEnd = normalize ? normalize(toRaw) : toRaw;\n } else {\n const startRaw = parseCalendarToken(left, map);\n if (startRaw === null) continue;\n rangeStart = normalize ? normalize(startRaw) : startRaw;\n rangeEnd = max;\n }\n }\n if (rangeStart > rangeEnd) continue;\n if (value < rangeStart || value > rangeEnd) continue;\n if ((value - rangeStart) % step === 0) return true;\n continue;\n }\n const rangeMatch = segment.match(/^([A-Z0-9]+)-([A-Z0-9]+)$/);\n if (rangeMatch) {\n const fromRaw = parseCalendarToken(rangeMatch[1]!, map);\n const toRaw = parseCalendarToken(rangeMatch[2]!, map);\n if (fromRaw === null || toRaw === null) continue;\n const from = normalize ? normalize(fromRaw) : fromRaw;\n const to = normalize ? normalize(toRaw) : toRaw;\n if (value >= from && value <= to) return true;\n continue;\n }\n const singleRaw = parseCalendarToken(segment, map);\n if (singleRaw === null) continue;\n const single = normalize ? normalize(singleRaw) : singleRaw;\n if (single === value) return true;\n }\n return false;\n}\n\nfunction expandNoStepField(rawField: string, min: number, max: number): number[] | null {\n const field = rawField.trim().toUpperCase();\n if (field.includes('/')) return null;\n if (field === '*' || field === '?') return Array.from({ length: max - min + 1 }, (_, idx) => min + idx);\n const out = new Set<number>();\n for (const item of field.split(',')) {\n const segment = item.trim();\n if (!segment) continue;\n const rangeMatch = segment.match(/^(\\d+)-(\\d+)$/);\n if (rangeMatch) {\n const from = Number(rangeMatch[1]);\n const to = Number(rangeMatch[2]);\n if (from > to) continue;\n for (let i = from; i <= to; i += 1) {\n if (i >= min && i <= max) out.add(i);\n }\n continue;\n }\n const n = Number(segment);\n if (Number.isFinite(n) && n >= min && n <= max) out.add(n);\n }\n return Array.from(out).sort((a, b) => a - b);\n}\n\nfunction expandFieldWithStep(rawField: string, min: number, max: number): number[] {\n const field = rawField.trim().toUpperCase();\n if (field === '*' || field === '?') return Array.from({ length: max - min + 1 }, (_, idx) => min + idx);\n const out = new Set<number>();\n for (const item of field.split(',')) {\n const segment = item.trim();\n if (!segment) continue;\n const stepMatch = segment.match(/^(.+)\\/(\\d+)$/);\n if (stepMatch) {\n const left = stepMatch[1]!.trim();\n const step = Number(stepMatch[2]!);\n if (!Number.isFinite(step) || step <= 0) continue;\n let start = min;\n let end = max;\n if (left !== '*' && left !== '?') {\n const rangeMatch = left.match(/^(\\d+)-(\\d+)$/);\n if (rangeMatch) {\n start = Number(rangeMatch[1]);\n end = Number(rangeMatch[2]);\n } else {\n const n = Number(left);\n if (!Number.isFinite(n)) continue;\n start = n;\n end = max;\n }\n }\n if (start > end) continue;\n for (let i = Math.max(start, min); i <= Math.min(end, max); i += step) out.add(i);\n continue;\n }\n const rangeMatch = segment.match(/^(\\d+)-(\\d+)$/);\n if (rangeMatch) {\n const from = Number(rangeMatch[1]);\n const to = Number(rangeMatch[2]);\n if (from > to) continue;\n for (let i = from; i <= to; i += 1) if (i >= min && i <= max) out.add(i);\n continue;\n }\n const n = Number(segment);\n if (Number.isFinite(n) && n >= min && n <= max) out.add(n);\n }\n return Array.from(out).sort((a, b) => a - b);\n}\n\nexport function classifyCronDisplayMode(expression: string): CalendarDisplayMode {\n const parsed = parseCron(expression);\n if (!parsed) return 'single';\n if (hasStepSyntax(parsed.second) || hasStepSyntax(parsed.minute) || hasStepSyntax(parsed.hour)) {\n return 'recurring';\n }\n const seconds = expandNoStepField(parsed.second, 0, 59);\n const times = cronTimesForDay(parsed);\n if (!seconds || seconds.length !== 1) return 'recurring';\n if (times.length !== 1) return 'recurring';\n return 'single';\n}\n\nfunction startOfWeekMonday(baseDate: Date, weekOffset: number): Date {\n const date = new Date(baseDate);\n date.setHours(0, 0, 0, 0);\n const jsDay = date.getDay();\n const mondayOffset = jsDay === 0 ? -6 : 1 - jsDay;\n date.setDate(date.getDate() + mondayOffset + weekOffset * 7);\n return date;\n}\n\nexport function getCalendarWeekRange(baseDate: Date, weekOffset: number): { start: Date; end: Date } {\n const start = startOfWeekMonday(baseDate, weekOffset);\n const end = new Date(start);\n end.setDate(end.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return { start, end };\n}\n\nexport function formatWeekRangeText(baseDate: Date, weekOffset: number): string {\n const { start, end } = getCalendarWeekRange(baseDate, weekOffset);\n return `${start.getFullYear()}年${start.getMonth() + 1}月${start.getDate()}日- ${end.getFullYear()}年${end.getMonth() + 1}月${end.getDate()}日`;\n}\n\nfunction computeNextCronExecutionAt(parsed: ParsedCron, from: Date, lookaheadDays = 370): Date | null {\n const secondValues = expandFieldWithStep(parsed.second, 0, 59);\n const minuteValues = expandFieldWithStep(parsed.minute, 0, 59);\n const hourValues = expandFieldWithStep(parsed.hour, 0, 23);\n if (secondValues.length === 0 || minuteValues.length === 0 || hourValues.length === 0) return null;\n\n const cursor = new Date(from.getTime() + 1000);\n cursor.setMilliseconds(0);\n const cursorStartDay = startOfDay(cursor);\n\n for (let dayOffset = 0; dayOffset <= lookaheadDays; dayOffset += 1) {\n const day = new Date(cursorStartDay);\n day.setDate(cursorStartDay.getDate() + dayOffset);\n if (!cronMatchesDay(parsed, day)) continue;\n\n const minHour = dayOffset === 0 ? cursor.getHours() : 0;\n for (const hour of hourValues) {\n if (hour < minHour) continue;\n const minMinute = dayOffset === 0 && hour === cursor.getHours() ? cursor.getMinutes() : 0;\n for (const minute of minuteValues) {\n if (minute < minMinute) continue;\n const minSecond =\n dayOffset === 0 && hour === cursor.getHours() && minute === cursor.getMinutes() ? cursor.getSeconds() : 0;\n for (const second of secondValues) {\n if (second < minSecond) continue;\n const candidate = new Date(day);\n candidate.setHours(hour, minute, second, 0);\n if (candidate.getTime() > from.getTime()) return candidate;\n }\n }\n }\n }\n return null;\n}\n\nexport function getNextExecutionAt(trigger: ScheduleTrigger, from: Date = new Date()): Date | null {\n if (trigger.type === 'interval') {\n return new Date(from.getTime() + trigger.ms);\n }\n if (trigger.type === 'once') {\n const fireAt = new Date(trigger.fireAt);\n if (!isValidDate(fireAt)) return null;\n return fireAt.getTime() > from.getTime() ? fireAt : null;\n }\n const parsed = parseCron(trigger.expression);\n if (!parsed) return null;\n return computeNextCronExecutionAt(parsed, from);\n}\n\nfunction stateForRunOutcome(outcome: ScheduleRunOutcome | string): CalendarTaskState {\n if (outcome === 'RUN_FAILED') return 'failed';\n if (outcome === 'RUN_DELIVERED') return 'completed';\n if (outcome.startsWith('SKIP_')) return 'skipped';\n return 'skipped';\n}\n\nfunction runStatusText(state: CalendarTaskState): string {\n if (state === 'failed') return '执行失败';\n if (state === 'completed') return '执行成功';\n if (state === 'skipped') return '已跳过';\n if (state === 'paused') return '已暂停';\n return '待执行';\n}\n\nfunction runSummaryKey(taskId: string, date: Date): string {\n return `${taskId}|${localDateKey(date)}`;\n}\n\nfunction buildRunSummaryMap(runs: ScheduleRunItem[]): Map<string, DailyRunSummary> {\n const summaries = new Map<string, DailyRunSummary>();\n for (const run of runs) {\n const startedAt = new Date(run.startedAt);\n if (!isValidDate(startedAt)) continue;\n const key = runSummaryKey(run.taskId, startedAt);\n const existing = summaries.get(key);\n if (!existing) {\n summaries.set(key, {\n latestRun: run,\n latestStartedAt: startedAt,\n runCount: 1,\n state: stateForRunOutcome(run.outcome),\n });\n continue;\n }\n existing.runCount += 1;\n if (startedAt.getTime() > existing.latestStartedAt.getTime()) {\n existing.latestRun = run;\n existing.latestStartedAt = startedAt;\n existing.state = stateForRunOutcome(run.outcome);\n }\n }\n return summaries;\n}\n\nfunction getDailyRunSummary(\n summaries: Map<string, DailyRunSummary>,\n taskId: string,\n date: Date,\n): DailyRunSummary | undefined {\n return summaries.get(runSummaryKey(taskId, date));\n}\n\nfunction triggerForRun(run: ScheduleRunItem, task?: ScheduledTaskItem): ScheduleTrigger | null {\n return task?.trigger ?? run.task?.trigger ?? null;\n}\n\nfunction taskNameForRun(run: ScheduleRunItem, task?: ScheduledTaskItem): string {\n const snapshotLabel = run.task?.label?.trim();\n return task?.taskName ?? (snapshotLabel || run.taskId);\n}\n\nfunction isRecurringTrigger(trigger: ScheduleTrigger | null | undefined): boolean {\n if (!trigger) return false;\n if (trigger.type === 'interval') return true;\n if (trigger.type === 'cron') return classifyCronDisplayMode(trigger.expression) === 'recurring';\n return false;\n}\n\nfunction runTimeLabel(startedAt: string): string {\n const date = new Date(startedAt);\n if (!isValidDate(date)) return '--:--';\n return toHm(date);\n}\n\nfunction getSingleOccurrenceRunSummary(\n occurrenceAt: Date,\n runSummary?: DailyRunSummary,\n): DailyRunSummary | undefined {\n if (!runSummary) return undefined;\n if (runSummary.latestStartedAt.getTime() < occurrenceAt.getTime()) return undefined;\n return runSummary;\n}\n\nfunction computeSingleOccurrenceState(\n task: ScheduledTaskItem,\n occurrenceAt: Date,\n runSummary?: DailyRunSummary,\n): CalendarTaskState {\n if (!task.effectiveEnabled) return 'paused';\n const matchedRunSummary = getSingleOccurrenceRunSummary(occurrenceAt, runSummary);\n if (matchedRunSummary) return matchedRunSummary.state;\n return 'pending';\n}\n\nfunction recurringTimeRangeForCron(parsed: ParsedCron): string {\n const hours = expandFieldWithStep(parsed.hour, 0, 23);\n if (!hours || hours.length === 0) return '00:00-23:59';\n const start = hours[0]!;\n const end = hours[hours.length - 1]!;\n return `${pad2(start)}:00-${pad2(end)}:59`;\n}\n\nfunction computeNextIntervalTimeLabel(\n task: ScheduledTaskItem,\n dayDate: Date,\n now: Date,\n latestRunAt?: string,\n): string {\n if (task.trigger.type !== 'interval') return '--:--';\n if (isSameDate(dayDate, now)) {\n const base = latestRunAt ? new Date(latestRunAt).getTime() : task.lastRunAt ? new Date(task.lastRunAt).getTime() : now.getTime();\n return toHm(new Date(base + task.trigger.ms));\n }\n return '00:00';\n}\n\nfunction computeNextCronTimeLabel(parsed: ParsedCron, dayDate: Date, now: Date): string {\n const hours = expandFieldWithStep(parsed.hour, 0, 23);\n const minutes = expandFieldWithStep(parsed.minute, 0, 59);\n if (hours.length === 0 || minutes.length === 0) return '--:--';\n const currentMinute = isSameDate(dayDate, now) ? now.getHours() * 60 + now.getMinutes() : -1;\n const candidates: string[] = [];\n for (const h of hours) {\n for (const m of minutes) {\n const value = h * 60 + m;\n if (value >= currentMinute) candidates.push(`${pad2(h)}:${pad2(m)}`);\n }\n }\n if (candidates.length > 0) return candidates.sort()[0]!;\n return `${pad2(hours[0]!)}:${pad2(minutes[0]!)}`;\n}\n\nfunction stateLabel(state: CalendarTaskState): string {\n if (state === 'failed') return '已失败';\n if (state === 'completed') return '已完成';\n if (state === 'skipped') return '已跳过';\n if (state === 'paused') return '已暂停';\n return '待执行';\n}\n\nfunction computeRecurringState(\n task: ScheduledTaskItem,\n dayDate: Date,\n now: Date,\n runSummary?: DailyRunSummary,\n): CalendarTaskState {\n if (!task.effectiveEnabled) return 'paused';\n const dateCmp = compareDateOnly(dayDate, now);\n if (dateCmp < 0) return runSummary?.state ?? 'pending';\n if (dateCmp > 0) return 'pending';\n if (runSummary) return runSummary.state;\n return 'pending';\n}\n\nfunction makeRecurringOccurrence(\n task: ScheduledTaskItem,\n parsedCron: ParsedCron | null,\n dayDate: Date,\n now: Date,\n runSummary?: DailyRunSummary,\n): CalendarOccurrence {\n const state = computeRecurringState(task, dayDate, now, runSummary);\n const latestRunAt = runSummary?.latestRun.startedAt ?? task.lastRunAt;\n const latestRunState =\n runSummary?.state ?? (task.lastRunOutcome ? stateForRunOutcome(task.lastRunOutcome) : null);\n const lastExecutionText =\n latestRunAt && latestRunState\n ? `上次 ${toHm(new Date(latestRunAt))} ${runStatusText(latestRunState)}`\n : latestRunAt\n ? `上次 ${toHm(new Date(latestRunAt))} 执行`\n : stateLabel(state);\n const nextHm =\n task.trigger.type === 'interval'\n ? computeNextIntervalTimeLabel(task, dayDate, now, latestRunAt ?? undefined)\n : parsedCron\n ? computeNextCronTimeLabel(parsedCron, dayDate, now)\n : '--:--';\n const isToday = isSameDate(dayDate, now);\n const shouldShowNext = isToday || state === 'pending';\n return {\n taskId: task.taskId,\n sourceTaskId: task.taskId,\n taskName: task.taskName,\n mode: 'recurring',\n timeLabel:\n task.trigger.type === 'interval'\n ? '00:00-23:59'\n : parsedCron\n ? recurringTimeRangeForCron(parsedCron)\n : '00:00-23:59',\n state,\n lastExecutionText: isToday ? lastExecutionText : stateLabel(state),\n nextExecutionText: shouldShowNext ? `下次 ${nextHm} 执行` : undefined,\n latestRunAt: runSummary?.latestRun.startedAt,\n latestRunOutcome: runSummary?.latestRun.outcome,\n runCount: runSummary?.runCount,\n };\n}\n\nfunction cronMatchesDay(parsed: ParsedCron, date: Date): boolean {\n const month = date.getMonth() + 1;\n const dom = date.getDate();\n const dow = date.getDay();\n const monthMatch = matchField(parsed.month, month, 1, 12, MONTH_NAME_TO_NUM);\n const domMatch = matchField(parsed.dayOfMonth, dom, 1, 31);\n const dowMatch = matchField(parsed.dayOfWeek, dow, 0, 6, WEEKDAY_NAME_TO_NUM, (v) => (v === 7 ? 0 : v));\n return monthMatch && domMatch && dowMatch;\n}\n\nfunction cronTimesForDay(parsed: ParsedCron): Array<{ h: number; m: number }> {\n const hours = expandNoStepField(parsed.hour, 0, 23);\n const minutes = expandNoStepField(parsed.minute, 0, 59);\n if (!hours || !minutes || !hours.length || !minutes.length) return [];\n const out: Array<{ h: number; m: number }> = [];\n for (const h of hours) {\n for (const m of minutes) out.push({ h, m });\n }\n return out.sort((a, b) => (a.h === b.h ? a.m - b.m : a.h - b.h));\n}\n\nfunction expandFixedCronForWeek(\n task: ScheduledTaskItem,\n parsed: ParsedCron,\n days: CalendarDayColumn[],\n runSummaries: Map<string, DailyRunSummary>,\n) {\n const now = new Date();\n const seconds = expandNoStepField(parsed.second, 0, 59);\n const second = seconds && seconds.length > 0 ? seconds[0]! : 0;\n for (const day of days) {\n if (!cronMatchesDay(parsed, day.date)) continue;\n const runSummary = getDailyRunSummary(runSummaries, task.taskId, day.date);\n const times = cronTimesForDay(parsed);\n for (const time of times) {\n const occurrenceAt = new Date(day.date);\n occurrenceAt.setHours(time.h, time.m, second, 0);\n const matchedRunSummary = getSingleOccurrenceRunSummary(occurrenceAt, runSummary);\n if (!matchedRunSummary && isSameDate(day.date, now) && occurrenceAt.getTime() < now.getTime()) continue;\n const state = computeSingleOccurrenceState(task, occurrenceAt, runSummary);\n day.occurrences.push({\n taskId: `${task.taskId}-${day.dayOfMonth}-${time.h}-${time.m}`,\n sourceTaskId: task.taskId,\n taskName: task.taskName,\n mode: 'single',\n timeLabel: `${pad2(time.h)}:${pad2(time.m)}`,\n state,\n latestRunAt: matchedRunSummary?.latestRun.startedAt,\n latestRunOutcome: matchedRunSummary?.latestRun.outcome,\n runCount: matchedRunSummary?.runCount,\n });\n }\n }\n}\n\nfunction expandOnceForWeek(\n task: ScheduledTaskItem,\n days: CalendarDayColumn[],\n runSummaries: Map<string, DailyRunSummary>,\n) {\n if (task.trigger.type !== 'once') return;\n const fireAt = new Date(task.trigger.fireAt);\n const now = new Date();\n for (const day of days) {\n if (\n fireAt.getFullYear() === day.date.getFullYear() &&\n fireAt.getMonth() === day.date.getMonth() &&\n fireAt.getDate() === day.date.getDate()\n ) {\n const runSummary = getDailyRunSummary(runSummaries, task.taskId, day.date);\n const matchedRunSummary = getSingleOccurrenceRunSummary(fireAt, runSummary);\n if (!matchedRunSummary && isSameDate(day.date, now) && fireAt.getTime() < now.getTime()) continue;\n const state = computeSingleOccurrenceState(task, fireAt, runSummary);\n day.occurrences.push({\n taskId: task.taskId,\n sourceTaskId: task.taskId,\n taskName: task.taskName,\n mode: 'single',\n timeLabel: toHm(fireAt),\n state,\n latestRunAt: matchedRunSummary?.latestRun.startedAt,\n latestRunOutcome: matchedRunSummary?.latestRun.outcome,\n runCount: matchedRunSummary?.runCount,\n });\n }\n }\n}\n\nfunction timeLabelStartMinutes(label: string): number {\n const head = label.split('-')[0]?.trim() ?? '';\n const match = head.match(/^(\\d{1,2}):(\\d{2})$/);\n if (!match) return Number.POSITIVE_INFINITY;\n const h = Number(match[1]);\n const m = Number(match[2]);\n if (!Number.isFinite(h) || !Number.isFinite(m)) return Number.POSITIVE_INFINITY;\n return h * 60 + m;\n}\n\nfunction compareOccurrence(a: CalendarOccurrence, b: CalendarOccurrence): number {\n const modeOrder = a.mode === b.mode ? 0 : a.mode === 'recurring' ? -1 : 1;\n if (modeOrder !== 0) return modeOrder;\n\n const startDiff = timeLabelStartMinutes(a.timeLabel) - timeLabelStartMinutes(b.timeLabel);\n if (startDiff !== 0) return startDiff;\n\n const nameOrder = a.taskName.localeCompare(b.taskName, 'zh-CN');\n if (nameOrder !== 0) return nameOrder;\n return a.taskId.localeCompare(b.taskId);\n}\n\nfunction buildRunsByDay(monday: Date, runs: ScheduleRunItem[]): Map<number, ScheduleRunItem[]> {\n const out = new Map<number, ScheduleRunItem[]>();\n const weekStart = startOfDay(monday).getTime();\n const dayMs = 24 * 60 * 60 * 1000;\n for (const run of runs) {\n const runDate = new Date(run.startedAt);\n if (!isValidDate(runDate)) continue;\n const dayStart = startOfDay(runDate).getTime();\n const index = Math.floor((dayStart - weekStart) / dayMs);\n if (index < 0 || index > 6) continue;\n const bucket = out.get(index);\n if (bucket) {\n bucket.push(run);\n } else {\n out.set(index, [run]);\n }\n }\n return out;\n}\n\nfunction appendRunBackedOccurrences(\n day: CalendarDayColumn,\n runs: ScheduleRunItem[],\n taskById: Map<string, ScheduledTaskItem>,\n runSummaries: Map<string, DailyRunSummary>,\n opts: { missingTasksOnly: boolean },\n): void {\n const recurringTaskIds = new Set<string>();\n const singleRuns: Array<{ run: ScheduleRunItem; task?: ScheduledTaskItem }> = [];\n\n for (const run of runs) {\n const task = taskById.get(run.taskId);\n if (opts.missingTasksOnly && task) continue;\n const trigger = triggerForRun(run, task);\n const summary = getDailyRunSummary(runSummaries, run.taskId, day.date);\n const isLegacyRecurringWithoutSnapshot = !trigger && !task && (summary?.runCount ?? 0) > 1;\n if (isRecurringTrigger(trigger)) {\n recurringTaskIds.add(run.taskId);\n continue;\n }\n if (isLegacyRecurringWithoutSnapshot) {\n recurringTaskIds.add(run.taskId);\n continue;\n }\n singleRuns.push({ run, task });\n }\n\n for (const taskId of recurringTaskIds) {\n const summary = getDailyRunSummary(runSummaries, taskId, day.date);\n if (!summary) continue;\n const task = taskById.get(taskId);\n if (opts.missingTasksOnly && task) continue;\n const trigger = triggerForRun(summary.latestRun, task);\n const parsedCron = trigger?.type === 'cron' ? parseCron(trigger.expression) : null;\n day.occurrences.push({\n taskId,\n sourceTaskId: taskId,\n taskName: taskNameForRun(summary.latestRun, task),\n mode: 'recurring',\n timeLabel:\n trigger?.type === 'interval'\n ? '00:00-23:59'\n : parsedCron\n ? recurringTimeRangeForCron(parsedCron)\n : '00:00-23:59',\n state: summary.state,\n lastExecutionText: `上次 ${runTimeLabel(summary.latestRun.startedAt)} ${runStatusText(summary.state)}`,\n latestRunAt: summary.latestRun.startedAt,\n latestRunOutcome: summary.latestRun.outcome,\n runCount: summary.runCount,\n });\n }\n\n singleRuns\n .sort((a, b) => new Date(a.run.startedAt).getTime() - new Date(b.run.startedAt).getTime())\n .forEach(({ run, task }) => {\n day.occurrences.push({\n taskId: `${run.taskId}-${run.id}`,\n sourceTaskId: run.taskId,\n taskName: taskNameForRun(run, task),\n mode: 'single',\n timeLabel: runTimeLabel(run.startedAt),\n state: stateForRunOutcome(run.outcome),\n latestRunAt: run.startedAt,\n latestRunOutcome: run.outcome,\n runCount: 1,\n });\n });\n}\n\nexport function buildCalendarWeek(\n baseDate: Date,\n weekOffset: number,\n tasks: ScheduledTaskItem[],\n runs: ScheduleRunItem[] = [],\n): CalendarDayColumn[] {\n const monday = startOfWeekMonday(baseDate, weekOffset);\n const now = new Date();\n const days: CalendarDayColumn[] = Array.from({ length: 7 }, (_, idx) => {\n const date = new Date(monday);\n date.setDate(monday.getDate() + idx);\n return {\n date,\n dayIndex: idx,\n labelZh: WEEKDAY_ZH[idx]!,\n labelEn: WEEKDAY_EN[idx]!,\n dayOfMonth: date.getDate(),\n occurrences: [],\n };\n });\n const taskById = new Map(tasks.map((task) => [task.taskId, task]));\n const runSummaries = buildRunSummaryMap(runs);\n const runsByDay = buildRunsByDay(monday, runs);\n\n for (const task of tasks) {\n const applicableDays = days.filter((day) => !isPastDay(day.date, now));\n if (task.trigger.type === 'interval') {\n for (const day of applicableDays) {\n day.occurrences.push(\n makeRecurringOccurrence(task, null, day.date, now, getDailyRunSummary(runSummaries, task.taskId, day.date)),\n );\n }\n continue;\n }\n if (task.trigger.type === 'once') {\n expandOnceForWeek(task, applicableDays, runSummaries);\n continue;\n }\n if (task.trigger.type !== 'cron') continue;\n const parsed = parseCron(task.trigger.expression);\n if (!parsed) continue;\n const mode = classifyCronDisplayMode(task.trigger.expression);\n if (mode === 'recurring') {\n for (const day of applicableDays) {\n if (!cronMatchesDay(parsed, day.date)) continue;\n day.occurrences.push(\n makeRecurringOccurrence(task, parsed, day.date, now, getDailyRunSummary(runSummaries, task.taskId, day.date)),\n );\n }\n continue;\n }\n expandFixedCronForWeek(task, parsed, applicableDays, runSummaries);\n }\n\n for (const day of days) {\n const dayRuns = runsByDay.get(day.dayIndex) ?? [];\n if (dayRuns.length === 0) continue;\n appendRunBackedOccurrences(day, dayRuns, taskById, runSummaries, {\n missingTasksOnly: !isPastDay(day.date, now),\n });\n }\n\n for (const day of days) {\n day.occurrences.sort(compareOccurrence);\n }\n return days;\n}\n\n// =============================================================================\n// Edit Utils (from scheduled-task-edit-utils.ts)\n// =============================================================================\n\nexport const SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON = '该定时任务仅支持通过对话进行编辑';\n\nexport type ScheduleTaskEditability =\n | { editable: true; draft: ScheduleTaskDraft; reason: null }\n | { editable: false; draft: null; reason: string };\n\nfunction formatDateTimeLocal(date: Date): string {\n return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(\n date.getMinutes(),\n )}:${pad2(date.getSeconds())}`;\n}\n\nfunction parseCronWeekdayField(raw: string): string[] | null {\n const normalized = raw.trim().toUpperCase();\n if (!normalized || normalized === '*' || normalized === '?') return null;\n if (normalized.includes('/') || normalized.includes('-')) return null;\n\n const out = new Set<string>();\n for (const item of normalized.split(',')) {\n const text = item.trim();\n if (!text) continue;\n const num = Number(text);\n if (!Number.isFinite(num)) return null;\n if (num === 0 || num === 7) {\n out.add('7');\n continue;\n }\n if (num >= 1 && num <= 6) {\n out.add(String(num));\n continue;\n }\n return null;\n }\n return Array.from(out).sort((left, right) => Number(left) - Number(right));\n}\n\nfunction toDraftFrequency(\n trigger: ScheduleTrigger | null | undefined,\n localTimezone: string | undefined,\n): ScheduleTaskDraft['frequency'] | null {\n if (!trigger || typeof trigger !== 'object' || !('type' in trigger)) return null;\n if (trigger.type === 'once') {\n return {\n type: 'once',\n executeTime: formatDateTimeLocal(new Date(trigger.fireAt)),\n };\n }\n\n if (trigger.type === 'interval') {\n const normalized = normalizeIntervalMs(trigger.ms);\n if (!normalized) return null;\n return {\n type: 'interval',\n interval: normalized.interval,\n unit: normalized.unit,\n };\n }\n\n if (trigger.type !== 'cron') return null;\n if (trigger.timezone && localTimezone && trigger.timezone !== localTimezone) {\n return null;\n }\n\n const parts = trigger.expression.trim().split(/\\s+/);\n let secondField = '0';\n let minuteField = '';\n let hourField = '';\n let dayOfMonthField = '';\n let monthField = '';\n let dayOfWeekField = '';\n\n if (parts.length === 5) {\n [minuteField, hourField, dayOfMonthField, monthField, dayOfWeekField] = parts;\n } else if (parts.length === 6) {\n [secondField, minuteField, hourField, dayOfMonthField, monthField, dayOfWeekField] = parts;\n } else {\n return null;\n }\n\n if (secondField !== '0') return null;\n\n const minute = Number(minuteField);\n const hour = Number(hourField);\n if (!Number.isFinite(minute) || !Number.isFinite(hour) || minute < 0 || minute > 59 || hour < 0 || hour > 23) {\n return null;\n }\n const time = `${pad2(hour)}:${pad2(minute)}:00`;\n\n const normalizedDayOfMonth = dayOfMonthField.trim();\n const normalizedMonth = monthField.trim();\n const normalizedDayOfWeek = dayOfWeekField.trim();\n if (normalizedMonth !== '*') return null;\n\n if (normalizedDayOfMonth !== '*') return null;\n if (normalizedDayOfWeek === '*' || normalizedDayOfWeek === '?') {\n return { type: 'daily', time };\n }\n\n const weekdays = parseCronWeekdayField(normalizedDayOfWeek);\n if (!weekdays || weekdays.length === 0) return null;\n if (weekdays.length === 7) return { type: 'daily', time };\n return { type: 'weekday', time, weekdays };\n}\n\nfunction resolveLocalTimezone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function getScheduleTaskEditability(\n task: ScheduledTaskItem,\n localTimezone = resolveLocalTimezone(),\n): ScheduleTaskEditability {\n const frequency = toDraftFrequency(task.trigger, localTimezone);\n if (!frequency) {\n return {\n editable: false,\n draft: null,\n reason: SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON,\n };\n }\n return {\n editable: true,\n reason: null,\n draft: {\n source: 'custom',\n taskName: task.taskName,\n prompt: task.prompt,\n frequency,\n enabled: task.enabled,\n sessionId: task.deliveryThreadId ?? null,\n },\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { apiFetch } from '@/utils/api-client';\nimport type { ScheduleRunItem, ScheduleTrigger, ScheduledTaskItem } from '../types';\nimport { formatCronFrequency } from '../utils';\nimport { formatIntervalFrequency } from '../utils';\nimport { getScheduleTaskEditability, SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON, type ScheduleTaskEditability } from '../utils';\n\ntype ScheduleTaskSummaryResponse = {\n tasks: Array<{\n id: string;\n dynamicTaskId?: string;\n deliveryThreadId?: string | null;\n threadTitle?: string | null;\n source: 'builtin' | 'dynamic';\n trigger: ScheduleTrigger;\n enabled: boolean;\n effectiveEnabled: boolean;\n display?: {\n label?: string;\n description?: string;\n };\n lastRun: {\n started_at: string;\n subject_key: string;\n outcome: string;\n } | null;\n subjectPreview: string | null;\n }>;\n};\n\ntype ScheduleRunsResponse = {\n runs: ScheduleRunItem[];\n nextCursor: number | null;\n hasMore: boolean;\n};\n\ntype UseTaskStateOptions = {\n viewMode: 'card' | 'calendar';\n weekOffset: number;\n};\n\nfunction extractThreadId(subjectKey: string | null | undefined): string | null {\n if (!subjectKey) return null;\n if (subjectKey.startsWith('thread-')) return subjectKey.slice(7);\n if (subjectKey.startsWith('thread:')) return subjectKey.slice(7);\n return null;\n}\n\nfunction formatFrequency(trigger: ScheduleTrigger): string {\n if (trigger.type === 'interval') {\n return formatIntervalFrequency(trigger.ms);\n }\n if (trigger.type === 'once') {\n const date = new Date(trigger.fireAt);\n return date.toLocaleString('zh-CN');\n }\n if (trigger.type === 'cron') {\n return formatCronFrequency(trigger.expression);\n }\n return '任务类型: 未知';\n}\n\nfunction toViewTask(task: ScheduleTaskSummaryResponse['tasks'][number]): ScheduledTaskItem {\n const id = task.dynamicTaskId ?? task.id;\n const threadId = task.deliveryThreadId ?? extractThreadId(task.lastRun?.subject_key);\n const threadName = task.threadTitle?.trim() || threadId || '-';\n const isOnce = task.trigger.type === 'once';\n const fireAtTime = isOnce ? (task.trigger as { type: 'once'; fireAt: number }).fireAt : null;\n return {\n taskId: id,\n dynamicTaskId: task.dynamicTaskId,\n source: task.source,\n deliveryThreadId: threadId,\n taskName: task.display?.label?.trim() || task.id,\n prompt: task.display?.description?.trim() || '暂无描述',\n frequency: formatFrequency(task.trigger),\n nextExcuteTime: '-',\n effectiveTime: isOnce && fireAtTime ? new Date(fireAtTime).toLocaleString('zh-CN') : '长期有效',\n status: task.effectiveEnabled ? 'running' : 'paused',\n enabled: task.enabled,\n effectiveEnabled: task.effectiveEnabled,\n createTime: task.lastRun?.started_at ?? '',\n sessionName: threadName,\n trigger: task.trigger,\n lastRunAt: task.lastRun?.started_at ?? null,\n lastRunOutcome: task.lastRun?.outcome ?? null,\n };\n}\n\nconst MAX_RUNS_PAGES = 20;\n\nexport function useTaskState({ viewMode, weekOffset }: UseTaskStateOptions) {\n const [tasks, setTasks] = useState<ScheduledTaskItem[]>([]);\n const [calendarRuns, setCalendarRuns] = useState<ScheduleRunItem[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isRunsLoading, setIsRunsLoading] = useState(false);\n\n const loadTasks = useCallback(async (): Promise<ScheduledTaskItem[] | null> => {\n const tasksRes = await apiFetch('/api/schedule/tasks');\n if (!tasksRes.ok) return null;\n const data = (await tasksRes.json()) as ScheduleTaskSummaryResponse;\n const mapped = (data.tasks ?? []).map(toViewTask);\n setTasks(mapped);\n return mapped;\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n const load = async () => {\n setIsLoading(true);\n try {\n if (cancelled) return;\n await loadTasks();\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n };\n\n void load();\n return () => {\n cancelled = true;\n };\n }, [loadTasks]);\n\n useEffect(() => {\n if (viewMode !== 'calendar') return;\n\n let cancelled = false;\n const loadRuns = async () => {\n setIsRunsLoading(true);\n try {\n const now = new Date();\n const mondayOffset = now.getDay() === 0 ? -6 : 1 - now.getDay();\n const weekStart = new Date(now);\n weekStart.setDate(now.getDate() + mondayOffset + weekOffset * 7);\n weekStart.setHours(0, 0, 0, 0);\n const weekEnd = new Date(weekStart);\n weekEnd.setDate(weekStart.getDate() + 6);\n weekEnd.setHours(23, 59, 59, 999);\n\n const since = weekStart.toISOString();\n const until = weekEnd.toISOString();\n let cursor: number | null = null;\n const allRuns: ScheduleRunItem[] = [];\n const seenCursors = new Set<number>();\n let pageCount = 0;\n\n while (!cancelled) {\n if (pageCount >= MAX_RUNS_PAGES) break;\n if (cursor != null && seenCursors.has(cursor)) break;\n if (cursor != null) seenCursors.add(cursor);\n const query = new URLSearchParams({\n limit: '200',\n since,\n until,\n });\n if (cursor != null) query.set('cursor', String(cursor));\n const res = await apiFetch(`/api/schedule/runs?${query.toString()}`);\n if (!res.ok) break;\n const payload = (await res.json()) as ScheduleRunsResponse;\n allRuns.push(...(payload.runs ?? []));\n pageCount += 1;\n if (!payload.hasMore || payload.nextCursor == null) break;\n if (payload.nextCursor === cursor) break;\n cursor = payload.nextCursor;\n }\n\n if (!cancelled) setCalendarRuns(allRuns);\n } finally {\n if (!cancelled) setIsRunsLoading(false);\n }\n };\n\n void loadRuns();\n return () => {\n cancelled = true;\n };\n }, [viewMode, weekOffset]);\n\n const taskEditabilityById = useMemo(() => {\n const unsupported: ScheduleTaskEditability = {\n editable: false,\n draft: null,\n reason: SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON,\n };\n return new Map(\n tasks.map((task) => [\n task.taskId,\n task.source === 'dynamic' ? getScheduleTaskEditability(task) : unsupported,\n ]),\n );\n }, [tasks]);\n\n return {\n tasks,\n calendarRuns,\n isLoading,\n isRunsLoading,\n taskEditabilityById,\n reloadTasks: loadTasks,\n setTasks,\n };\n}\n","import { useCallback, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useChatStore } from '@/stores/chatStore';\nimport { useToastStore } from '@/stores/toastStore';\nimport { apiFetch } from '@/utils/api-client';\nimport type { ScheduledTaskItem } from '../types';\nimport type { ScheduleTaskDraft } from '../schedule-template-types';\nimport { intervalValueToMs } from '../utils';\n\ntype UseTaskActionsOptions = {\n reloadTasks: () => Promise<ScheduledTaskItem[] | null>;\n setTasks: React.Dispatch<React.SetStateAction<ScheduledTaskItem[]>>;\n getEditingTask: () => ScheduledTaskItem | null;\n closeEditor: () => void;\n};\n\nfunction resolveTaskIdentifier(task: ScheduledTaskItem): string {\n return task.dynamicTaskId ?? task.taskId;\n}\n\nfunction buildScheduleTaskChatEditText(task: ScheduledTaskItem): string {\n const taskId = resolveTaskIdentifier(task);\n return `按照以下要求修改定时任务「${task.taskName}」(任务ID:${taskId}):`;\n}\n\nfunction parseTimeParts(value: string): { hour: number; minute: number } {\n const [hourText = '0', minuteText = '0'] = value.split(':');\n return {\n hour: Number(hourText) || 0,\n minute: Number(minuteText) || 0,\n };\n}\n\nfunction parseDateTimeToTimestamp(value: string): number {\n const [dateText = '', timeText = '00:00:00'] = value.split(' ');\n const [yearText = '0', monthText = '1', dayText = '1'] = dateText.split('-');\n const [hourText = '0', minuteText = '0', secondText = '0'] = timeText.split(':');\n return new Date(\n Number(yearText),\n Number(monthText) - 1,\n Number(dayText),\n Number(hourText),\n Number(minuteText),\n Number(secondText),\n ).getTime();\n}\n\nfunction toCronWeekday(value: string): string {\n return value === '7' ? '0' : value;\n}\n\nfunction buildTaskTrigger(draft: ScheduleTaskDraft, timezoneOverride?: string | null) {\n const timezone = timezoneOverride === null ? undefined : (timezoneOverride ?? (Intl.DateTimeFormat().resolvedOptions().timeZone || undefined));\n\n if (draft.frequency.type === 'once') {\n return {\n type: 'once' as const,\n fireAt: parseDateTimeToTimestamp(draft.frequency.executeTime),\n };\n }\n\n if (draft.frequency.type === 'interval') {\n return {\n type: 'interval' as const,\n ms: intervalValueToMs(draft.frequency.interval, draft.frequency.unit),\n };\n }\n\n const { hour, minute } = parseTimeParts(draft.frequency.time);\n\n if (draft.frequency.type === 'weekday') {\n return {\n type: 'cron' as const,\n expression: `${minute} ${hour} * * ${draft.frequency.weekdays.map(toCronWeekday).join(',')}`,\n ...(timezone ? { timezone } : {}),\n };\n }\n\n return {\n type: 'cron' as const,\n expression: `${minute} ${hour} * * *`,\n ...(timezone ? { timezone } : {}),\n };\n}\n\ntype CreateScheduleTaskPayload = {\n templateId: string;\n trigger: ReturnType<typeof buildTaskTrigger>;\n params: {\n message: string;\n };\n display: {\n label: string;\n category: 'system';\n description: string;\n };\n deliveryThreadId: string;\n};\n\nfunction buildCreateScheduleTaskPayload(\n draft: ScheduleTaskDraft,\n deliveryThreadId: string,\n): CreateScheduleTaskPayload {\n return {\n templateId: 'reminder',\n trigger: buildTaskTrigger(draft),\n params: {\n message: draft.prompt.trim(),\n },\n display: {\n label: draft.taskName.trim(),\n category: 'system',\n description: draft.prompt.trim(),\n },\n deliveryThreadId,\n };\n}\n\nexport function useTaskActions({ reloadTasks, setTasks, getEditingTask, closeEditor }: UseTaskActionsOptions) {\n const navigate = useNavigate();\n const addToast = useToastStore((state) => state.addToast);\n const setPendingChatInsert = useChatStore((state) => state.setPendingChatInsert);\n\n const [togglingTaskIds, setTogglingTaskIds] = useState<Set<string>>(new Set());\n const [isDeletingTask, setIsDeletingTask] = useState(false);\n\n const handleToggleTask = useCallback(async (task: ScheduledTaskItem) => {\n const apiTaskId = task.taskId;\n if (!apiTaskId) return;\n if (togglingTaskIds.has(apiTaskId)) return;\n\n const targetEffectiveEnabled = !task.effectiveEnabled;\n const nextEnabled = targetEffectiveEnabled;\n setTogglingTaskIds((prev) => new Set(prev).add(apiTaskId));\n setTasks((prev) =>\n prev.map((item) =>\n item.taskId === apiTaskId\n ? {\n ...item,\n enabled: nextEnabled,\n effectiveEnabled: targetEffectiveEnabled,\n status: targetEffectiveEnabled ? 'running' : 'paused',\n }\n : item,\n ),\n );\n\n try {\n if (task.source === 'dynamic') {\n const res = await apiFetch(`/api/schedule/tasks/${encodeURIComponent(task.dynamicTaskId ?? apiTaskId)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ enabled: nextEnabled }),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n if (targetEffectiveEnabled) {\n const clearOverrideRes = await apiFetch(`/api/schedule/control/tasks/${encodeURIComponent(apiTaskId)}`, {\n method: 'DELETE',\n });\n if (!clearOverrideRes.ok && clearOverrideRes.status !== 404) {\n throw new Error(`HTTP ${clearOverrideRes.status}`);\n }\n }\n } else {\n if (nextEnabled) {\n const res = await apiFetch(`/api/schedule/control/tasks/${encodeURIComponent(apiTaskId)}`, {\n method: 'DELETE',\n });\n if (!res.ok && res.status !== 404) throw new Error(`HTTP ${res.status}`);\n } else {\n const res = await apiFetch(`/api/schedule/control/tasks/${encodeURIComponent(apiTaskId)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ enabled: false }),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n }\n }\n const latest = await reloadTasks();\n if (targetEffectiveEnabled) {\n const changedTask = latest?.find((item) => item.taskId === apiTaskId);\n if (changedTask && !changedTask.effectiveEnabled) {\n await reloadTasks();\n }\n }\n } catch {\n await reloadTasks();\n } finally {\n setTogglingTaskIds((prev) => {\n const next = new Set(prev);\n next.delete(apiTaskId);\n return next;\n });\n }\n }, [togglingTaskIds, setTasks, reloadTasks]);\n\n const handleDeleteConfirm = useCallback(async (deleteTargetTask: ScheduledTaskItem | null, onSuccess?: () => void) => {\n if (!deleteTargetTask) return;\n const apiTaskId = deleteTargetTask.dynamicTaskId ?? deleteTargetTask.taskId;\n if (!apiTaskId) return;\n const taskName = deleteTargetTask.taskName;\n\n setIsDeletingTask(true);\n try {\n const res = await apiFetch(`/api/schedule/tasks/${encodeURIComponent(apiTaskId)}`, {\n method: 'DELETE',\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n\n setTasks((prev) => prev.filter((task) => task.taskId !== deleteTargetTask.taskId));\n addToast({\n type: 'success',\n title: '删除成功',\n message: `定时任务「${taskName}」已删除`,\n duration: 2600,\n });\n onSuccess?.();\n } catch {\n addToast({\n type: 'error',\n title: '删除失败',\n message: '定时任务删除失败,请稍后重试',\n duration: 2600,\n });\n } finally {\n setIsDeletingTask(false);\n }\n }, [setTasks, addToast]);\n\n const handleTaskEditorConfirm = useCallback(async (\n draft: ScheduleTaskDraft,\n _editingTask?: ScheduledTaskItem | null,\n onSuccess?: () => void,\n ) => {\n const editingTask = _editingTask ?? getEditingTask();\n const isEditing = !!editingTask;\n const taskName = draft.taskName.trim();\n closeEditor();\n try {\n let deliveryThreadId = draft.sessionId?.trim() ?? '';\n let createdNewThread = false;\n\n if (deliveryThreadId.startsWith('mock-new-session')) {\n const createThreadRes = await apiFetch('/api/threads', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title: draft.taskName.trim() }),\n });\n if (!createThreadRes.ok) {\n throw new Error(`create_thread_failed_${createThreadRes.status}`);\n }\n\n const createdThread = (await createThreadRes.json()) as { id?: string };\n if (!createdThread.id) {\n throw new Error('create_thread_missing_id');\n }\n deliveryThreadId = createdThread.id;\n createdNewThread = true;\n }\n\n if (isEditing) {\n const apiTaskId = editingTask?.dynamicTaskId ?? editingTask?.taskId;\n if (!apiTaskId) throw new Error('edit_schedule_task_missing_id');\n const editTimezone =\n editingTask?.trigger.type === 'cron' ? (editingTask.trigger.timezone ?? null) : undefined;\n const editRes = await apiFetch(`/api/schedule/tasks/${encodeURIComponent(apiTaskId)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n trigger: buildTaskTrigger(draft, editTimezone),\n params: { message: draft.prompt.trim() },\n display: {\n label: draft.taskName.trim(),\n description: draft.prompt.trim(),\n },\n deliveryThreadId: deliveryThreadId || null,\n enabled: draft.enabled,\n }),\n });\n if (!editRes.ok) {\n throw new Error(`edit_schedule_task_failed_${editRes.status}`);\n }\n } else {\n const createRes = await apiFetch('/api/schedule/tasks', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(buildCreateScheduleTaskPayload(draft, deliveryThreadId)),\n });\n if (!createRes.ok) {\n throw new Error(`create_schedule_task_failed_${createRes.status}`);\n }\n }\n\n if (createdNewThread && typeof window !== 'undefined') {\n window.dispatchEvent(new Event('office-claw:threads-refresh'));\n }\n\n onSuccess?.();\n await reloadTasks();\n addToast({\n type: 'success',\n title: isEditing ? '编辑成功' : '创建成功',\n message: isEditing ? `定时任务「${taskName}」已更新` : `定时任务「${taskName}」已创建`,\n duration: 2600,\n });\n } catch (error) {\n addToast({\n type: 'error',\n title: isEditing ? '编辑失败' : '创建失败',\n message: isEditing ? '定时任务编辑失败,请稍后重试' : '定时任务创建失败,请稍后重试',\n duration: 2600,\n });\n console.error(isEditing ? '[schedule-task-edit]' : '[schedule-task-create]', error);\n }\n }, [reloadTasks, addToast, getEditingTask, closeEditor]);\n\n const handleEditTaskInConversation = useCallback((task: ScheduledTaskItem) => {\n const threadId = task.deliveryThreadId?.trim() ?? '';\n if (!threadId) {\n addToast({\n type: 'error',\n title: '无法跳转编辑',\n message: '该任务未绑定会话,无法通过对话编辑',\n duration: 2600,\n });\n return;\n }\n\n setPendingChatInsert({\n threadId,\n text: buildScheduleTaskChatEditText(task),\n });\n navigate(threadId === 'default' ? '/' : `/thread/${threadId}`, { preventScrollReset: true });\n }, [navigate, setPendingChatInsert, addToast]);\n\n return {\n togglingTaskIds,\n isDeletingTask,\n handleToggleTask,\n handleDeleteConfirm,\n handleTaskEditorConfirm,\n handleEditTaskInConversation,\n };\n}\n","import { useMemo } from 'react';\nimport { buildCalendarWeek, formatWeekRangeText, getCalendarWeekRange, type CalendarDayColumn } from '../utils';\nimport type { ScheduleRunItem, ScheduledTaskItem } from '../types';\n\ntype UseTaskCalendarOptions = {\n baseDate: Date;\n weekOffset: number;\n tasks: ScheduledTaskItem[];\n runs: ScheduleRunItem[];\n};\n\nexport function useTaskCalendar({ baseDate, weekOffset, tasks, runs }: UseTaskCalendarOptions) {\n const days = useMemo(\n () => buildCalendarWeek(baseDate, weekOffset, tasks, runs),\n [baseDate, weekOffset, tasks, runs],\n );\n\n const weekRangeText = useMemo(\n () => formatWeekRangeText(baseDate, weekOffset),\n [baseDate, weekOffset],\n );\n\n const weekRange = useMemo(\n () => getCalendarWeekRange(baseDate, weekOffset),\n [baseDate, weekOffset],\n );\n\n return {\n days,\n weekRangeText,\n weekRange,\n };\n}\n","import { useMemo, useState } from 'react';\nimport type { ScheduledTaskItem } from '../types';\nimport type { ScheduleTaskDraft } from '../schedule-template-types';\nimport { getScheduleTaskEditability } from '../utils';\n\nexport function useTaskModal() {\n const [selectedTask, setSelectedTask] = useState<ScheduledTaskItem | null>(null);\n const [deleteTargetTask, setDeleteTargetTask] = useState<ScheduledTaskItem | null>(null);\n const [deleteDialogSourceView, setDeleteDialogSourceView] = useState<'card' | 'calendar'>('card');\n const [templatePickerOpen, setTemplatePickerOpen] = useState(false);\n const [taskEditorOpen, setTaskEditorOpen] = useState(false);\n const [editorDraft, setEditorDraft] = useState<ScheduleTaskDraft | null>(null);\n const [editingTask, setEditingTask] = useState<ScheduledTaskItem | null>(null);\n\n const closeTaskEditor = () => {\n setTaskEditorOpen(false);\n setEditorDraft(null);\n setEditingTask(null);\n };\n\n const openEditTask = (task: ScheduledTaskItem) => {\n const editability = getScheduleTaskEditability(task);\n if (!editability.editable) {\n return false;\n }\n setSelectedTask(null);\n setEditingTask(task);\n setEditorDraft(editability.draft);\n setTaskEditorOpen(true);\n return true;\n };\n\n const openCreateTask = (draft: ScheduleTaskDraft) => {\n setEditingTask(null);\n setEditorDraft(draft);\n setTaskEditorOpen(true);\n };\n\n const openDeleteTask = (task: ScheduledTaskItem, sourceView: 'card' | 'calendar') => {\n if (task.source !== 'dynamic') return;\n setDeleteDialogSourceView(sourceView);\n setDeleteTargetTask(task);\n };\n\n const closeDeleteDialog = () => {\n setDeleteTargetTask(null);\n };\n\n const selectedTaskEditability = useMemo(\n () => (selectedTask ? getScheduleTaskEditability(selectedTask) : null),\n [selectedTask],\n );\n\n return {\n selectedTask,\n setSelectedTask,\n deleteTargetTask,\n setDeleteTargetTask,\n deleteDialogSourceView,\n templatePickerOpen,\n setTemplatePickerOpen,\n taskEditorOpen,\n editorDraft,\n editingTask,\n closeTaskEditor,\n openEditTask,\n openCreateTask,\n openDeleteTask,\n closeDeleteDialog,\n selectedTaskEditability,\n getEditingTask: () => editingTask,\n };\n}\n","'use client';\n\nimport { useEffect, useRef, useState } from 'react';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\n\ntype ViewMode = 'card' | 'calendar';\n\ntype ToolbarProps = {\n viewMode: ViewMode;\n weekRangeText: string;\n onChangeView: (next: ViewMode) => void;\n onPrevWeek: () => void;\n onNextWeek: () => void;\n onResetWeek: () => void;\n onCreateFromConversation: () => void;\n onCreateFromTemplate: () => void;\n onCreateCustom: () => void;\n};\n\nexport function Toolbar({\n viewMode,\n weekRangeText,\n onChangeView,\n onPrevWeek,\n onNextWeek,\n onResetWeek,\n onCreateFromConversation,\n onCreateFromTemplate,\n onCreateCustom,\n}: ToolbarProps) {\n const [isCreateMenuOpen, setIsCreateMenuOpen] = useState(false);\n const createMenuRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (!isCreateMenuOpen) return;\n\n const handlePointerDown = (event: MouseEvent) => {\n if (createMenuRef.current?.contains(event.target as Node)) return;\n setIsCreateMenuOpen(false);\n };\n\n document.addEventListener('mousedown', handlePointerDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown);\n };\n }, [isCreateMenuOpen]);\n\n return (\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <ViewToggle viewMode={viewMode} onChangeView={onChangeView} />\n {viewMode === 'calendar' ? (\n <WeekRangeSwitcher\n weekRangeText={weekRangeText}\n onPrevWeek={onPrevWeek}\n onNextWeek={onNextWeek}\n onResetWeek={onResetWeek}\n />\n ) : null}\n </div>\n <div ref={createMenuRef} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setIsCreateMenuOpen((prev) => !prev)}\n aria-haspopup=\"menu\"\n aria-expanded={isCreateMenuOpen}\n data-testid=\"scheduled-task-toolbar-create\"\n className=\"inline-flex h-[32px] min-h-[32px] min-w-[112px] shrink-0 items-center justify-center gap-1.5 whitespace-nowrap break-keep rounded-full border border-[#2C3340] bg-[#181B21] px-4 text-[12px] font-medium leading-none text-white\"\n >\n <span>创建定时任务</span>\n <svg\n className={`h-3.5 w-3.5 transition-transform ${isCreateMenuOpen ? 'rotate-180' : ''}`}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </button>\n {isCreateMenuOpen ? (\n <div className=\"absolute right-0 top-full z-20 mt-2 w-[160px] rounded-[12px] border border-[#ECEFF3] bg-white p-2 shadow-[0_6px_20px_rgba(31,35,41,0.12)]\">\n <button\n type=\"button\"\n onClick={() => {\n setIsCreateMenuOpen(false);\n onCreateFromConversation();\n }}\n data-testid=\"scheduled-task-toolbar-create-conversation\"\n className=\"flex h-8 w-full items-center rounded-[8px] px-3 text-left text-[12px] font-medium text-[#1F2329] transition-colors hover:bg-[#F5F7FA]\"\n >\n 从对话创建\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setIsCreateMenuOpen(false);\n onCreateFromTemplate();\n }}\n data-testid=\"scheduled-task-toolbar-create-template\"\n className=\"flex h-8 w-full items-center rounded-[8px] px-3 text-left text-[12px] font-medium text-[#1F2329] transition-colors hover:bg-[#F5F7FA]\"\n >\n 从模板创建\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setIsCreateMenuOpen(false);\n onCreateCustom();\n }}\n data-testid=\"scheduled-task-toolbar-create-custom\"\n className=\"flex h-8 w-full items-center rounded-[8px] px-3 text-left text-[12px] font-medium text-[#1F2329] transition-colors hover:bg-[#F5F7FA]\"\n >\n 自定义创建\n </button>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\ntype ViewToggleProps = {\n viewMode: ViewMode;\n onChangeView: (next: ViewMode) => void;\n};\n\nfunction ViewToggle({ viewMode, onChangeView }: ViewToggleProps) {\n const base = 'inline-flex h-full min-w-[96px] items-center justify-center whitespace-nowrap px-[18px] text-[12px] leading-none';\n return (\n <div className=\"inline-flex h-7 items-center rounded-[6px] border border-[#ECECEC] bg-[#F7F7F8]\">\n <button\n type=\"button\"\n onClick={() => onChangeView('calendar')}\n className={`${base} rounded-[6px] ${\n viewMode === 'calendar'\n ? 'border border-[#ECECEC] bg-white font-semibold text-[#1F2329]'\n : 'font-medium text-[#4C5563]'\n }`}\n >\n 日历视图\n </button>\n <button\n type=\"button\"\n onClick={() => onChangeView('card')}\n className={`${base} rounded-[6px] ${\n viewMode === 'card' ? 'border border-[#ECECEC] bg-white font-semibold text-[#1F2329]' : 'font-medium text-[#4C5563]'\n }`}\n >\n 卡片视图\n </button>\n </div>\n );\n}\n\ntype WeekRangeSwitcherProps = {\n weekRangeText: string;\n onPrevWeek: () => void;\n onNextWeek: () => void;\n onResetWeek: () => void;\n};\n\nfunction WeekRangeSwitcher({ weekRangeText, onPrevWeek, onNextWeek, onResetWeek }: WeekRangeSwitcherProps) {\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"inline-flex h-7 items-center gap-[31.5px] rounded-[6px] border border-[#F0F0F0] px-2\">\n <button type=\"button\" onClick={onPrevWeek} className=\"inline-flex h-5 w-5 items-center justify-center text-[#A8A8A8]\">\n <MaskIcon name=\"chevronLeft\" className=\"h-3.5 w-3.5\" />\n </button>\n <span className=\"text-[12px] font-normal text-[#191919]\">{weekRangeText}</span>\n <button type=\"button\" onClick={onNextWeek} className=\"inline-flex h-5 w-5 items-center justify-center text-[#A8A8A8]\">\n <MaskIcon name=\"chevronRight\" className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <button\n type=\"button\"\n onClick={onResetWeek}\n className=\"inline-flex h-7 min-h-[28px] min-w-[84px] shrink-0 items-center justify-center whitespace-nowrap break-keep rounded-[6px] border border-[#F0F0F0] px-[10px] text-[12px] font-normal leading-none text-[#191919]\"\n >\n 回到本周\n </button>\n </div>\n );\n}\n","'use client';\n\nimport type { ReactElement } from 'react';\nimport { OverflowTooltip } from '../../shared/OverflowTooltip';\nimport { SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON } from '../utils';\n\ninterface ScheduledTaskUnsupportedEditTooltipProps {\n children: ReactElement;\n reason?: string | null;\n onGoEdit: () => void;\n className?: string;\n buttonTestId?: string;\n}\n\nexport function ScheduledTaskUnsupportedEditTooltip({\n children,\n reason,\n onGoEdit,\n className,\n buttonTestId,\n}: ScheduledTaskUnsupportedEditTooltipProps) {\n const content = reason ?? SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON;\n\n return (\n <OverflowTooltip\n content={content}\n forceShow\n className={className}\n customContent={\n <div className=\"w-[260px]\" data-schedule-unsupported-edit-tooltip=\"1\">\n <p className=\"text-xs leading-5 text-[var(--tooltip-text)]\">{content}</p>\n <div className=\"mt-2 flex justify-end\">\n <button\n type=\"button\"\n onMouseDown={(event) => {\n event.stopPropagation();\n }}\n onPointerDown={(event) => {\n event.stopPropagation();\n }}\n onClick={(event) => {\n event.stopPropagation();\n onGoEdit();\n }}\n className=\"ui-button-primary !h-7 !min-w-[72px] !px-4 !py-1 text-xs font-normal\"\n data-testid={buttonTestId}\n >\n 去编辑\n </button>\n </div>\n </div>\n }\n >\n {children}\n </OverflowTooltip>\n );\n}\n","'use client';\n\nimport type { CSSProperties } from 'react';\nimport { SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON, type ScheduleTaskEditability } from '../utils';\nimport { ScheduledTaskUnsupportedEditTooltip } from './ScheduleUnsupportedEditTooltip';\nimport type { ScheduledTaskItem } from '../types';\n\ntype TaskCardProps = {\n task: ScheduledTaskItem;\n taskIconMaskStyle: CSSProperties;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n isToggling: boolean;\n editability: ScheduleTaskEditability;\n modalOpen?: boolean;\n};\n\nexport function TaskCard({\n task,\n taskIconMaskStyle,\n onSelectTask,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n isToggling,\n editability,\n modalOpen = false,\n}: TaskCardProps) {\n return (\n <article\n role=\"button\"\n tabIndex={0}\n onClick={() => onSelectTask(task)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onSelectTask(task);\n }\n }}\n className={`group h-[194px] cursor-pointer rounded-[16px] border border-[var(--card-border)] bg-[var(--card-bg)] p-6 transition-shadow hover:bg-[var(--card-hover-bg)] hover:shadow-[0_4px_16px_0_rgba(0,0,0,0.08)] ${modalOpen ? 'force-hover' : ''}`}\n >\n <div className=\"flex h-full flex-col gap-4\">\n <div className=\"flex h-[48px] items-center justify-between gap-3\">\n <div className=\"flex h-full min-w-0 items-center gap-3\">\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-[8px] bg-[var(--surface-card-muted)]\">\n <img src=\"/icons/schedule.svg\" alt=\"\" aria-hidden=\"true\" className=\"h-6 w-6 shrink-0\" />\n </div>\n <h3 className=\"line-clamp-1 min-w-0 text-[16px] font-semibold text-[var(--text-primary)]\">{task.taskName}</h3>\n </div>\n {task.source === 'dynamic' ? (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={task.effectiveEnabled}\n aria-label={`${task.taskName}开关`}\n onClick={async (event) => {\n event.stopPropagation();\n await onToggleTask(task);\n }}\n disabled={isToggling}\n className={`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors duration-200 ease-out disabled:cursor-not-allowed disabled:opacity-60 ${\n task.effectiveEnabled ? 'bg-[var(--text-accent)]' : 'bg-[var(--border-default)]'\n }`}\n >\n <span\n className={`absolute left-1 h-4 w-4 rounded-full bg-white shadow-[0_1px_2px_rgba(15,23,42,0.25)] transition-transform duration-200 ease-out motion-reduce:transition-none ${\n task.effectiveEnabled ? 'translate-x-5' : 'translate-x-0'\n }`}\n />\n </button>\n ) : null}\n </div>\n\n <p className=\"line-clamp-2 h-[44px] text-[14px] leading-[22px] text-[var(--text-secondary)]\">{task.prompt}</p>\n\n <div className=\"relative h-[24px]\">\n <div className={`absolute inset-0 flex items-center gap-1.5 text-[12px] leading-6 text-[var(--text-muted)] transition-opacity ${modalOpen ? '' : 'group-hover:opacity-0 group-hover:pointer-events-none'}`}>\n <span aria-hidden=\"true\" className=\"h-4 w-4 shrink-0\" style={taskIconMaskStyle} />\n <span>{task.frequency}</span>\n </div>\n <div className={`absolute inset-0 flex items-center transition-opacity ${modalOpen ? 'opacity-0 pointer-events-none' : 'opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:pointer-events-auto'}`}>\n {task.source === 'dynamic' ? (\n <div className=\"flex items-center gap-4\">\n {editability.editable ? (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={(event) => {\n event.stopPropagation();\n onEditTask(task);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.stopPropagation();\n onEditTask(task);\n }\n }}\n className=\"bg-transparent p-0 text-[14px] font-normal leading-6 text-[var(--text-accent)] hover:underline\"\n data-testid={`scheduled-task-card-edit-${task.taskId}`}\n >\n 编辑\n </div>\n ) : (\n <ScheduledTaskUnsupportedEditTooltip\n reason={editability.reason ?? SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON}\n onGoEdit={() => onEditTaskInConversation(task)}\n className=\"inline-flex\"\n buttonTestId={`scheduled-task-card-go-edit-${task.taskId}`}\n >\n <span className=\"inline-flex\">\n <div\n role=\"button\"\n tabIndex={0}\n aria-disabled=\"true\"\n onClick={(event) => {\n event.stopPropagation();\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.stopPropagation();\n }\n }}\n className=\"cursor-not-allowed bg-transparent p-0 text-[14px] font-normal leading-6 text-[var(--text-disabled)]\"\n data-testid={`scheduled-task-card-edit-${task.taskId}`}\n >\n 编辑\n </div>\n </span>\n </ScheduledTaskUnsupportedEditTooltip>\n )}\n <div\n role=\"button\"\n tabIndex={0}\n onClick={(event) => {\n event.stopPropagation();\n onDeleteTask(task);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.stopPropagation();\n onDeleteTask(task);\n }\n }}\n className=\"bg-transparent p-0 text-[14px] font-normal leading-6 text-[var(--text-accent)] hover:underline\"\n >\n 删除\n </div>\n </div>\n ) : (\n <div className=\"flex items-center gap-4\">\n <div\n role=\"button\"\n tabIndex={0}\n aria-disabled=\"true\"\n onClick={(event) => {\n event.stopPropagation();\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.stopPropagation();\n }\n }}\n className=\"cursor-not-allowed bg-transparent p-0 text-[14px] font-normal leading-6 text-[var(--text-disabled)]\"\n >\n 删除\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n </article>\n );\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport type { CSSProperties } from 'react';\nimport type { ScheduledTaskItem } from '../types';\nimport type { ScheduleTaskEditability } from '../utils';\nimport { getNextExecutionAt } from '../utils';\nimport { TaskCard } from './TaskCard';\n\ntype TaskListProps = {\n tasks: ScheduledTaskItem[];\n taskIconMaskStyle: CSSProperties;\n togglingTaskIds: Set<string>;\n taskEditabilityById: Map<string, ScheduleTaskEditability>;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n isModalOpen?: boolean;\n};\n\nfunction taskSortMeta(task: ScheduledTaskItem, now: Date): { bucket: 0 | 1; timeKey: number } {\n if (task.trigger.type === 'interval') {\n return { bucket: 1, timeKey: Number.POSITIVE_INFINITY };\n }\n const nextExecution = getNextExecutionAt(task.trigger, now);\n return { bucket: 0, timeKey: nextExecution ? nextExecution.getTime() : Number.POSITIVE_INFINITY };\n}\n\nexport function TaskList({\n tasks,\n taskIconMaskStyle,\n togglingTaskIds,\n taskEditabilityById,\n onSelectTask,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n isModalOpen = false,\n}: TaskListProps) {\n const sortedTasks = useMemo(\n () => {\n const now = new Date();\n return tasks\n .map((task, index) => {\n const meta = taskSortMeta(task, now);\n return { task, index, ...meta };\n })\n .sort((a, b) => {\n if (a.bucket !== b.bucket) return a.bucket - b.bucket;\n if (a.timeKey !== b.timeKey) return a.timeKey - b.timeKey;\n return a.index - b.index;\n })\n .map((item) => item.task);\n },\n [tasks],\n );\n\n return (\n <div className=\"px-1 pb-4\">\n <div className=\"grid grid-cols-3 gap-x-4 gap-y-6\">\n {sortedTasks.map((task) => (\n <TaskCard\n key={task.taskId}\n task={task}\n taskIconMaskStyle={taskIconMaskStyle}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n isToggling={togglingTaskIds.has(task.taskId)}\n editability={taskEditabilityById.get(task.taskId) ?? { editable: false, draft: null, reason: '' }}\n modalOpen={isModalOpen}\n />\n ))}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { ScheduledTaskItem } from '../types';\nimport type { ScheduleRunItem } from '../types';\nimport type { CalendarDayColumn, CalendarOccurrence, CalendarTaskState, ScheduleTaskEditability } from '../utils';\nimport { buildCalendarWeek, SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON } from '../utils';\nimport { MaskIcon } from '@/components/shared/MaskIcon';\nimport { ScheduledTaskUnsupportedEditTooltip } from './ScheduleUnsupportedEditTooltip';\nimport { OverflowTooltip } from '../../shared/OverflowTooltip';\n\ntype CalendarViewProps = {\n tasks: ScheduledTaskItem[];\n runs: ScheduleRunItem[];\n baseDate: Date;\n weekOffset: number;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n togglingTaskIds: Set<string>;\n taskEditabilityById: Map<string, ScheduleTaskEditability>;\n};\n\ntype MenuPosition = {\n top: number;\n left: number;\n};\n\nconst MENU_WIDTH = 140;\nconst MENU_HEIGHT = 128;\nconst MENU_OFFSET = 4;\nconst MENU_VIEWPORT_PADDING = 12;\nconst SCHEDULE_TASK_EDIT_ENTRANCE_ENABLED = true;\n\nconst ACTION_MENU_ITEM_CLASS =\n 'group flex h-8 w-full items-center gap-2 rounded-[6px] px-[16px] py-[7px] text-left text-[12px] font-medium text-[var(--overlay-text)] transition-colors enabled:hover:bg-[var(--overlay-item-hover-bg)]';\nconst ACTION_MENU_DELETE_ITEM_CLASS = `${ACTION_MENU_ITEM_CLASS} enabled:hover:text-[var(--state-error-text)]`;\nconst AGENT_CARD_MENU_BUTTON_CLASS = 'inline-flex h-6 w-6 items-center justify-center rounded-[4px] transition-colors';\nconst AGENT_CARD_MENU_BUTTON_ACTIVE_CLASS = 'bg-[var(--overlay-item-hover-bg)] text-[var(--text-accent)]';\nconst AGENT_CARD_MENU_BUTTON_IDLE_CLASS =\n 'text-[var(--text-muted)] hover:bg-[var(--overlay-item-hover-bg)] hover:text-[var(--text-accent)]';\n\nfunction stateConfig(state: CalendarTaskState): { label: string; dot: string; showTimeIcon: boolean } {\n if (state === 'completed') return { label: '已完成', dot: 'rgba(173,217,127,1)', showTimeIcon: false };\n if (state === 'failed') return { label: '已失败', dot: '#C62828', showTimeIcon: false };\n if (state === 'skipped') return { label: '已跳过', dot: '#C2C2C2', showTimeIcon: false };\n if (state === 'paused') return { label: '已暂停', dot: '#C2C2C2', showTimeIcon: false };\n return { label: '待执行', dot: '#C2C2C2', showTimeIcon: true };\n}\n\ntype CardActionsProps = {\n item: CalendarOccurrence;\n occurrenceKey: string;\n taskById: Map<string, ScheduledTaskItem>;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n togglingTaskIds: Set<string>;\n taskEditabilityById: Map<string, ScheduleTaskEditability>;\n openMenuKey: string | null;\n menuPosition: MenuPosition | null;\n onOpenMenu: (key: string, triggerRect: DOMRect) => void;\n onCloseMenu: () => void;\n};\n\nfunction CardActions({\n item,\n occurrenceKey,\n taskById,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n togglingTaskIds,\n taskEditabilityById,\n openMenuKey,\n menuPosition,\n onOpenMenu,\n onCloseMenu,\n}: CardActionsProps) {\n if (item.state !== 'pending' && item.state !== 'paused') return null;\n const task = taskById.get(item.sourceTaskId);\n if (!task) return null;\n const canOperate = task.source === 'dynamic';\n const editability = taskEditabilityById.get(task.taskId);\n const isToggling = togglingTaskIds.has(task.taskId);\n const menuOpen = openMenuKey === occurrenceKey;\n\n return (\n <div data-schedule-menu-root=\"1\" className=\"shrink-0\">\n <button\n type=\"button\"\n aria-label={`操作 ${task.taskName}`}\n aria-expanded={menuOpen}\n aria-haspopup=\"menu\"\n onClick={(event) => {\n event.stopPropagation();\n if (menuOpen) {\n onCloseMenu();\n return;\n }\n onOpenMenu(occurrenceKey, event.currentTarget.getBoundingClientRect());\n }}\n className={`${AGENT_CARD_MENU_BUTTON_CLASS} ${\n menuOpen ? AGENT_CARD_MENU_BUTTON_ACTIVE_CLASS : AGENT_CARD_MENU_BUTTON_IDLE_CLASS\n }`}\n >\n <MaskIcon name=\"more\" className=\"h-4 w-4\" />\n </button>\n {menuOpen && menuPosition ? (\n <div\n role=\"menu\"\n className=\"ui-overlay-card fixed z-40 w-[140px] rounded-[6px] px-0 py-2 shadow-[0_12px_28px_rgba(15,23,42,0.18)]\"\n style={{ top: menuPosition.top, left: menuPosition.left }}\n >\n <div className={`${ACTION_MENU_ITEM_CLASS} justify-between`}>\n <span className={canOperate ? '' : 'text-[var(--text-disabled)]'}>启停用</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={task.effectiveEnabled}\n aria-label={`${task.taskName}开关`}\n disabled={!canOperate || isToggling}\n onClick={async (event) => {\n event.stopPropagation();\n if (!canOperate) return;\n await onToggleTask(task);\n onCloseMenu();\n }}\n className={`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors duration-200 ease-out disabled:cursor-not-allowed disabled:opacity-60 ${\n task.effectiveEnabled ? 'bg-[var(--text-accent)]' : 'bg-[var(--border-default)]'\n }`}\n >\n <span\n className={`absolute left-1 h-4 w-4 rounded-full bg-white shadow-[0_1px_2px_rgba(15,23,42,0.25)] transition-transform duration-200 ease-out motion-reduce:transition-none ${\n task.effectiveEnabled ? 'translate-x-5' : 'translate-x-0'\n }`}\n />\n </button>\n </div>\n {SCHEDULE_TASK_EDIT_ENTRANCE_ENABLED && canOperate ? (\n editability?.editable ? (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={(event) => {\n event.stopPropagation();\n onEditTask(task);\n onCloseMenu();\n }}\n className={ACTION_MENU_ITEM_CLASS}\n data-testid={`scheduled-task-calendar-edit-${task.taskId}`}\n >\n 编辑\n </button>\n ) : (\n <ScheduledTaskUnsupportedEditTooltip\n reason={editability?.reason ?? SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON}\n onGoEdit={() => onEditTaskInConversation(task)}\n className=\"block\"\n buttonTestId={`scheduled-task-calendar-go-edit-${task.taskId}`}\n >\n <span className=\"block\">\n <button\n type=\"button\"\n role=\"menuitem\"\n disabled\n aria-disabled=\"true\"\n onClick={(event) => {\n event.stopPropagation();\n }}\n className={`${ACTION_MENU_ITEM_CLASS} cursor-not-allowed text-[var(--text-disabled)]`}\n data-testid={`scheduled-task-calendar-edit-${task.taskId}`}\n >\n 编辑\n </button>\n </span>\n </ScheduledTaskUnsupportedEditTooltip>\n )\n ) : null}\n <button\n type=\"button\"\n role=\"menuitem\"\n disabled={!canOperate}\n onClick={(event) => {\n event.stopPropagation();\n if (!canOperate) return;\n onDeleteTask(task);\n onCloseMenu();\n }}\n className={`${ACTION_MENU_DELETE_ITEM_CLASS} ${\n canOperate ? '' : 'cursor-not-allowed text-[var(--text-disabled)]'\n }`}\n >\n 删除\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n\ntype RecurringTaskCardProps = {\n item: CalendarOccurrence;\n occurrenceKey: string;\n taskById: Map<string, ScheduledTaskItem>;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n togglingTaskIds: Set<string>;\n taskEditabilityById: Map<string, ScheduleTaskEditability>;\n openMenuKey: string | null;\n menuPosition: MenuPosition | null;\n onOpenMenu: (key: string, triggerRect: DOMRect) => void;\n onCloseMenu: () => void;\n};\n\nfunction RecurringTaskCard({\n item,\n occurrenceKey,\n taskById,\n onSelectTask,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n togglingTaskIds,\n taskEditabilityById,\n openMenuKey,\n menuPosition,\n onOpenMenu,\n onCloseMenu,\n}: RecurringTaskCardProps) {\n const cfg = stateConfig(item.state);\n const task = taskById.get(item.sourceTaskId);\n const canSelect = !!task;\n return (\n <article\n role={canSelect ? 'button' : undefined}\n tabIndex={canSelect ? 0 : undefined}\n onClick={() => {\n if (task) onSelectTask(task);\n }}\n onKeyDown={(event) => {\n if (!task) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onSelectTask(task);\n }\n }}\n className={`relative flex w-full flex-col gap-2 rounded-[8px] border p-3 ${\n item.state === 'pending' ? 'border-[#B6D4F2] bg-[#F4F9FF]' : 'border-[#E9E9E9] bg-white'\n }`}\n >\n <div className=\"text-[12px] font-semibold text-[#C2C2C2]\">{item.timeLabel}</div>\n <OverflowTooltip content={item.taskName}>\n <div\n className={`text-[14px] font-normal ${\n item.state === 'pending' ? 'text-[rgba(25,25,25,1)]' : 'text-[#808080]'\n }`}\n style={{ display: '-webkit-box', WebkitLineClamp: 3, WebkitBoxOrient: 'vertical', overflow: 'hidden' } as React.CSSProperties}\n >\n {item.taskName}\n </div>\n </OverflowTooltip>\n <div className=\"space-y-2 text-[10px] text-[#C2C2C2]\">\n <div className={`flex items-center gap-1 ${item.nextExecutionText ? '' : 'justify-between'}`}>\n <div className=\"flex min-w-0 items-center gap-1\">\n <span className=\"h-2 w-2 rounded-full \" style={{ backgroundColor: cfg.dot }} />\n <span className='text-[12px]'>{item.lastExecutionText}</span>\n </div>\n {!item.nextExecutionText ? (\n <CardActions\n item={item}\n occurrenceKey={occurrenceKey}\n taskById={taskById}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n openMenuKey={openMenuKey}\n menuPosition={menuPosition}\n onOpenMenu={onOpenMenu}\n onCloseMenu={onCloseMenu}\n />\n ) : null}\n </div>\n {item.nextExecutionText ? (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex min-w-0 items-center gap-1\">\n <img src=\"/icons/schedule.svg\" alt=\"\" className=\"h-3 w-3\" />\n <span className='text-[12px]'>{item.nextExecutionText}</span>\n </div>\n <CardActions\n item={item}\n occurrenceKey={occurrenceKey}\n taskById={taskById}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n openMenuKey={openMenuKey}\n menuPosition={menuPosition}\n onOpenMenu={onOpenMenu}\n onCloseMenu={onCloseMenu}\n />\n </div>\n ) : null}\n </div>\n </article>\n );\n}\n\ntype SingleTaskCardProps = {\n item: CalendarOccurrence;\n occurrenceKey: string;\n taskById: Map<string, ScheduledTaskItem>;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n togglingTaskIds: Set<string>;\n taskEditabilityById: Map<string, ScheduleTaskEditability>;\n openMenuKey: string | null;\n menuPosition: MenuPosition | null;\n onOpenMenu: (key: string, triggerRect: DOMRect) => void;\n onCloseMenu: () => void;\n};\n\nfunction SingleTaskCard({\n item,\n occurrenceKey,\n taskById,\n onSelectTask,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n togglingTaskIds,\n taskEditabilityById,\n openMenuKey,\n menuPosition,\n onOpenMenu,\n onCloseMenu,\n}: SingleTaskCardProps) {\n const cfg = stateConfig(item.state);\n const task = taskById.get(item.sourceTaskId);\n const canSelect = !!task;\n return (\n <article\n role={canSelect ? 'button' : undefined}\n tabIndex={canSelect ? 0 : undefined}\n onClick={() => {\n if (task) onSelectTask(task);\n }}\n onKeyDown={(event) => {\n if (!task) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onSelectTask(task);\n }\n }}\n className={`relative flex w-full flex-col gap-2 rounded-[8px] border p-3 ${item.state === 'pending' ? 'border-[#B6D4F2] bg-[#F4F9FF]' : 'border-[#E9E9E9] bg-white'}`}\n >\n <div className=\"text-[12px] font-semibold text-[#C2C2C2]\">{item.timeLabel}</div>\n <OverflowTooltip content={item.taskName}>\n <div\n className={`text-[14px] font-normal ${\n item.state === 'pending' ? 'text-[rgba(25,25,25,1)]' : 'text-[#808080]'\n }`}\n style={{ display: '-webkit-box', WebkitLineClamp: 3, WebkitBoxOrient: 'vertical', overflow: 'hidden' } as React.CSSProperties}\n >\n {item.taskName}\n </div>\n </OverflowTooltip>\n <div className=\"flex items-center justify-between gap-1 text-[12px] font-normal text-[#C2C2C2]\">\n <div className=\"flex min-w-0 items-center gap-1\">\n {cfg.showTimeIcon ? (\n <img src=\"/icons/schedule.svg\" alt=\"\" className=\"h-3 w-3\" />\n ) : (\n <span className=\"h-2 w-2 rounded-full\" style={{ backgroundColor: cfg.dot }} />\n )}\n <span>{cfg.label}</span>\n </div>\n <CardActions\n item={item}\n occurrenceKey={occurrenceKey}\n taskById={taskById}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n openMenuKey={openMenuKey}\n menuPosition={menuPosition}\n onOpenMenu={onOpenMenu}\n onCloseMenu={onCloseMenu}\n />\n </div>\n </article>\n );\n}\n\ntype DayColumnProps = {\n day: CalendarDayColumn;\n taskById: Map<string, ScheduledTaskItem>;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n togglingTaskIds: Set<string>;\n taskEditabilityById: Map<string, ScheduleTaskEditability>;\n openMenuKey: string | null;\n menuPosition: MenuPosition | null;\n onOpenMenu: (key: string, triggerRect: DOMRect) => void;\n onCloseMenu: () => void;\n};\n\nfunction DayColumn({\n day,\n taskById,\n onSelectTask,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n togglingTaskIds,\n taskEditabilityById,\n openMenuKey,\n menuPosition,\n onOpenMenu,\n onCloseMenu,\n}: DayColumnProps) {\n const today = new Date();\n const isToday =\n day.date.getFullYear() === today.getFullYear() &&\n day.date.getMonth() === today.getMonth() &&\n day.date.getDate() === today.getDate();\n\n return (\n <div className=\"flex h-full min-h-0 flex-col border-r border-[#E9E9E9] last:border-r-0\">\n <div className={`border-b border-[#E9E9E9] px-3 py-2 ${isToday ? 'bg-[#F5F5F5]' : 'bg-[#F9F9F9]'}`}>\n <div className=\"flex items-center gap-1 text-[12px] font-semibold text-[#4C5563]\">\n {day.labelZh}/{day.labelEn}\n {isToday ? <span className=\"text-[12px] font-normal text-[#5cb300]\">今日</span> : null}\n </div>\n <div className=\"text-[20px] font-semibold text-[#4C5563]\">{day.dayOfMonth}</div>\n </div>\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3\">\n {day.occurrences.map((item) => {\n const occurrenceKey = `${day.dayIndex}-${item.taskId}`;\n return (\n item.mode === 'recurring' ? (\n <RecurringTaskCard\n key={item.taskId}\n item={item}\n occurrenceKey={occurrenceKey}\n taskById={taskById}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n openMenuKey={openMenuKey}\n menuPosition={menuPosition}\n onOpenMenu={onOpenMenu}\n onCloseMenu={onCloseMenu}\n />\n ) : (\n <SingleTaskCard\n key={item.taskId}\n item={item}\n occurrenceKey={occurrenceKey}\n taskById={taskById}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n openMenuKey={openMenuKey}\n menuPosition={menuPosition}\n onOpenMenu={onOpenMenu}\n onCloseMenu={onCloseMenu}\n />\n )\n );\n })}\n </div>\n </div>\n );\n}\n\nexport function CalendarView({\n tasks,\n runs,\n baseDate,\n weekOffset,\n onSelectTask,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n togglingTaskIds,\n taskEditabilityById,\n}: CalendarViewProps) {\n const [openMenuKey, setOpenMenuKey] = useState<string | null>(null);\n const [menuPosition, setMenuPosition] = useState<MenuPosition | null>(null);\n const days = buildCalendarWeek(baseDate, weekOffset, tasks, runs);\n const taskById = new Map(tasks.map((task) => [task.taskId, task]));\n\n const computeMenuPosition = (triggerRect: DOMRect): MenuPosition => {\n const preferredLeft = triggerRect.right;\n const canOpenRight = preferredLeft + MENU_WIDTH <= window.innerWidth - MENU_VIEWPORT_PADDING;\n const fallbackLeft = triggerRect.left - MENU_WIDTH;\n const desiredLeft = canOpenRight ? preferredLeft : fallbackLeft;\n const minLeft = MENU_VIEWPORT_PADDING;\n const maxLeft = Math.max(minLeft, window.innerWidth - MENU_WIDTH - MENU_VIEWPORT_PADDING);\n const left = Math.min(Math.max(desiredLeft, minLeft), maxLeft);\n\n const belowTop = triggerRect.top + MENU_OFFSET;\n const canOpenBelow = belowTop + MENU_HEIGHT <= window.innerHeight - MENU_VIEWPORT_PADDING;\n const preferredTop = canOpenBelow ? belowTop : triggerRect.top - MENU_HEIGHT - MENU_OFFSET;\n const minTop = MENU_VIEWPORT_PADDING;\n const maxTop = Math.max(minTop, window.innerHeight - MENU_HEIGHT - MENU_VIEWPORT_PADDING);\n const top = Math.min(Math.max(preferredTop, minTop), maxTop);\n\n return { top, left };\n };\n\n useEffect(() => {\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as HTMLElement | null;\n if (target?.closest('[data-schedule-menu-root=\"1\"]')) return;\n if (target?.closest('[data-schedule-unsupported-edit-tooltip=\"1\"]')) return;\n setOpenMenuKey(null);\n setMenuPosition(null);\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpenMenuKey(null);\n setMenuPosition(null);\n }\n };\n document.addEventListener('mousedown', onPointerDown);\n document.addEventListener('keydown', onKeyDown);\n return () => {\n document.removeEventListener('mousedown', onPointerDown);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, []);\n\n useEffect(() => {\n setOpenMenuKey(null);\n setMenuPosition(null);\n }, [weekOffset]);\n\n return (\n <div className=\"h-full min-h-0 w-full overflow-x-auto\">\n <div className=\"mx-auto h-full w-full min-w-[1248px]\">\n <div className=\"h-full overflow-hidden rounded-[12px] border border-[#E6EAF0]\">\n <div className=\"grid h-full min-h-0 grid-cols-7\">\n {days.map((day) => (\n <DayColumn\n key={day.dayIndex}\n day={day}\n taskById={taskById}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n openMenuKey={openMenuKey}\n menuPosition={menuPosition}\n onOpenMenu={(key, triggerRect) => {\n setOpenMenuKey(key);\n setMenuPosition(computeMenuPosition(triggerRect));\n }}\n onCloseMenu={() => {\n setOpenMenuKey(null);\n setMenuPosition(null);\n }}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { EmptyDataState } from '../../shared/EmptyDataState';\n\ntype EmptyStateProps = {\n title: string;\n description?: string;\n showTemplates?: boolean;\n templateCards?: Array<{\n id: string;\n title: string;\n description: string;\n }>;\n onTemplateClick?: (templateId: string) => void;\n emptyTemplateSectionExpanded?: boolean;\n onToggleTemplates?: () => void;\n};\n\nexport function EmptyState({\n title,\n description,\n showTemplates,\n templateCards,\n onTemplateClick,\n emptyTemplateSectionExpanded,\n onToggleTemplates,\n}: EmptyStateProps) {\n return (\n <div className=\"flex h-full min-h-[320px] flex-col\">\n <div className=\"flex flex-1 items-center justify-center\">\n <div className=\"text-center\">\n <EmptyDataState title={title} />\n {description && (\n <p className=\"mt-2 text-[12px] text-[var(--text-muted)]\">{description}</p>\n )}\n </div>\n </div>\n {showTemplates && templateCards && templateCards.length > 0 && (\n <div className=\"w-full px-6 pb-6 pt-5\">\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 text-[14px] text-[rgba(89,89,89,1)]\"\n onClick={onToggleTemplates}\n aria-expanded={emptyTemplateSectionExpanded}\n data-testid=\"scheduled-task-empty-template-toggle\"\n >\n <span>热门模板推荐</span>\n <svg\n className={['h-4 w-4 transition-transform', emptyTemplateSectionExpanded ? 'rotate-180' : ''].join(' ')}\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5 12.5L10 7.5L15 12.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n {emptyTemplateSectionExpanded ? (\n <div className=\"mt-3 grid grid-cols-4 gap-4\">\n {templateCards.map((template) => (\n <button\n key={template.id}\n type=\"button\"\n onClick={() => onTemplateClick?.(template.id)}\n className=\"flex h-[214px] min-h-[214px] w-full flex-col items-start gap-5 rounded-[24px] border border-[rgba(222,236,255,0.6)] bg-[rgba(222,236,255,0.2)] px-6 pb-7 pt-7 text-left transition-colors\"\n data-testid={`scheduled-task-empty-template-${template.id}`}\n >\n <span className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-[8px] bg-[rgba(222,236,255,1)]\">\n <img src=\"/icons/schedule.svg\" alt=\"\" aria-hidden=\"true\" className=\"h-6 w-6 shrink-0\" />\n </span>\n <span className=\"block w-full text-[16px] font-bold leading-6 text-[rgba(25,25,25,1)]\">\n {template.title}\n </span>\n <span\n className=\"block w-full overflow-hidden text-[14px] leading-5 text-[rgba(89,89,89,1)]\"\n style={{\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n }}\n >\n {template.description}\n </span>\n </button>\n ))}\n </div>\n ) : null}\n </div>\n )}\n </div>\n );\n}\n","import { AppModal } from '../../AppModal';\nimport { OverflowTooltip } from '../../shared/OverflowTooltip';\nimport { ScheduledTaskUnsupportedEditTooltip } from './ScheduleUnsupportedEditTooltip';\nimport { SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON } from '../utils';\nimport type { ScheduledTaskItem } from '../types';\nimport type { ScheduleTaskEditability } from '../utils';\n\ntype DetailModalProps = {\n task: ScheduledTaskItem | null;\n editability: ScheduleTaskEditability | null;\n onClose: () => void;\n onEdit: (task: ScheduledTaskItem) => void;\n onEditInConversation: (task: ScheduledTaskItem) => void;\n};\n\nexport function DetailModal({ task, editability, onClose, onEdit, onEditInConversation }: DetailModalProps) {\n return (\n <AppModal\n open={!!task}\n onClose={onClose}\n title={task?.taskName ?? '任务详情'}\n panelClassName=\"w-[520px] max-w-[92vw] rounded-[12px] border border-[#E6EAF0] bg-white\"\n bodyClassName=\"pt-4 text-left\"\n >\n {task ? (\n <div className=\"space-y-4 text-left text-[14px] text-[#4B5565]\">\n <div className=\"flex items-start gap-6\">\n <div className=\"w-[72px] shrink-0 text-[12px] leading-6 text-[#98A1AF]\">执行频率</div>\n <div className=\"min-w-0 flex-1 leading-6\">{task.frequency}</div>\n </div>\n <div className=\"flex items-start gap-6\">\n <div className=\"w-[72px] shrink-0 text-[12px] leading-6 text-[#98A1AF]\">生效时间</div>\n <div className=\"min-w-0 flex-1 leading-6\">{task.effectiveTime}</div>\n </div>\n <div className=\"flex items-start gap-6\">\n <div className=\"w-[72px] shrink-0 text-[12px] leading-6 text-[#98A1AF]\">描述</div>\n <div className=\"min-w-0 flex-1\">\n <OverflowTooltip content={task.prompt} className=\"inline-flex max-w-full align-top\">\n <div className=\"min-w-0 leading-6 line-clamp-2\">{task.prompt}</div>\n </OverflowTooltip>\n </div>\n </div>\n <div className=\"flex items-start gap-6\">\n <div className=\"w-[72px] shrink-0 text-[12px] leading-6 text-[#98A1AF]\">执行会话</div>\n <div className=\"min-w-0 flex-1\">\n <OverflowTooltip content={task.sessionName} className=\"inline-flex max-w-full align-top\">\n <div className=\"min-w-0 max-w-full truncate text-[14px] leading-6 text-[#2F3A4B]\">\n {task.sessionName}\n </div>\n </OverflowTooltip>\n </div>\n </div>\n <div className=\"flex justify-end gap-2 pt-2\">\n {task.source === 'dynamic' ? (\n editability?.editable ? (\n <button\n type=\"button\"\n onClick={() => onEdit(task)}\n className=\"ui-button-default\"\n data-testid=\"scheduled-task-detail-edit\"\n >\n 编辑\n </button>\n ) : (\n <ScheduledTaskUnsupportedEditTooltip\n reason={editability?.reason}\n onGoEdit={() => onEditInConversation(task)}\n className=\"inline-flex\"\n buttonTestId=\"scheduled-task-detail-go-edit\"\n >\n <span className=\"inline-flex\">\n <button\n type=\"button\"\n disabled\n aria-disabled=\"true\"\n className=\"ui-button-default cursor-not-allowed opacity-45\"\n data-testid=\"scheduled-task-detail-edit\"\n >\n 编辑\n </button>\n </span>\n </ScheduledTaskUnsupportedEditTooltip>\n )\n ) : null}\n <button type=\"button\" onClick={onClose} className=\"ui-button-primary\">\n 确定\n </button>\n </div>\n </div>\n ) : null}\n </AppModal>\n );\n}\n","import { AppModal } from '../../AppModal';\nimport type { ScheduledTaskItem } from '../types';\n\ntype DeleteModalProps = {\n task: ScheduledTaskItem | null;\n isDeleting: boolean;\n sourceView: 'card' | 'calendar';\n onClose: () => void;\n onConfirm: () => void;\n};\n\nexport function DeleteModal({ task, isDeleting, sourceView, onClose, onConfirm }: DeleteModalProps) {\n return (\n <AppModal\n open={!!task}\n onClose={() => {\n if (isDeleting) return;\n onClose();\n }}\n disableBackdropClose={isDeleting}\n title={\n <div className=\"flex items-center gap-2\">\n <svg className=\"h-6 w-6 text-[#FAAD14]\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12.866 3.5a1 1 0 0 0-1.732 0l-8.25 14.5A1 1 0 0 0 3.75 19.5h16.5a1 1 0 0 0 .866-1.5l-8.25-14.5ZM12 8a1 1 0 0 1 1 1v4a1 1 0 1 1-2 0V9a1 1 0 0 1 1-1Zm0 9a1.25 1.25 0 1 1 0-2.5A1.25 1.25 0 0 1 12 17Z\" />\n </svg>\n <h3 className=\"text-[16px] font-bold text-gray-900\">确认删除任务</h3>\n </div>\n }\n panelClassName=\"w-[500px]\"\n bodyClassName=\"pt-5\"\n >\n <div className=\"flex flex-col gap-5\">\n <div className=\"space-y-1\">\n <p className=\"text-sm text-gray-600\">\n {sourceView === 'calendar'\n ? '删除后,该任务在后续所有日期的计划都会一并删除,且不可恢复。'\n : '删除后,该任务将不可恢复。'}\n </p>\n </div>\n <div className=\"flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isDeleting}\n className=\"ui-button-default\"\n >\n 取消\n </button>\n <button\n type=\"button\"\n onClick={onConfirm}\n disabled={isDeleting}\n className=\"ui-button-primary\"\n >\n {isDeleting ? '删除中...' : '删除'}\n </button>\n </div>\n </div>\n </AppModal>\n );\n}\n","import type { ScheduleIntervalUnit, ScheduleEffectiveTime } from '../schedule-template-types';\n\nexport const ALL_WEEKDAYS = ['1', '2', '3', '4', '5', '6', '7'] as const;\n\nexport const WEEKDAY_OPTIONS = [\n { value: '1', label: '一' },\n { value: '2', label: '二' },\n { value: '3', label: '三' },\n { value: '4', label: '四' },\n { value: '5', label: '五' },\n { value: '6', label: '六' },\n { value: '7', label: '日' },\n] as const;\n\nexport const INTERVAL_UNIT_OPTIONS: ReadonlyArray<{ value: ScheduleIntervalUnit; label: string }> = [\n { value: 'hour', label: '小时' },\n { value: 'minute', label: '分钟' },\n { value: 'second', label: '秒' },\n];\n\nexport const EFFECTIVE_PRESET_OPTIONS = [\n { value: 'week', label: '近一周' },\n { value: 'month', label: '近一个月' },\n { value: 'quarter', label: '近三个月' },\n { value: 'year', label: '近一年' },\n] as const;\n\nexport const NEW_SESSION_ID = 'mock-new-session-001';\n\nexport const HOURS = Array.from({ length: 24 }, (_, index) => `${index}`.padStart(2, '0'));\nexport const MINUTES = Array.from({ length: 60 }, (_, index) => `${index}`.padStart(2, '0'));\n\nexport const PROMPT_MIN_HEIGHT = 112;\nexport const PROMPT_DEFAULT_HEIGHT = 140;\nexport const PROMPT_INFO_ROW_HEIGHT = 24;\nexport const SHOW_EFFECTIVE_DATE_RANGE_UI = false;\n\nexport const INPUT_BOX_CLASS =\n 'h-7 rounded-[6px] border border-[rgba(194,194,194,1)] bg-white text-[14px] text-[#101828] transition hover:border-[rgba(194,194,194,1)]';\n\nexport function normalizeTimeValue(value: string): string {\n if (!value) return '00:00:00';\n return value.length === 5 ? `${value}:00` : value;\n}\n\nexport function trimSeconds(value: string): string {\n return value.length >= 5 ? value.slice(0, 5) : value;\n}\n\nexport function formatDateTime(date: Date): string {\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, '0');\n const day = `${date.getDate()}`.padStart(2, '0');\n const hours = `${date.getHours()}`.padStart(2, '0');\n const minutes = `${date.getMinutes()}`.padStart(2, '0');\n const seconds = `${date.getSeconds()}`.padStart(2, '0');\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\nexport function formatDateDisplay(value: string): string {\n return value ? value.replace(/-/g, '/') : '';\n}\n\nexport function parseDateValue(value: string): Date | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return null;\n const [yearText, monthText, dayText] = value.split('-');\n const year = Number(yearText);\n const month = Number(monthText);\n const day = Number(dayText);\n const date = new Date(year, month - 1, day, 12);\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return null;\n }\n return date;\n}\n\nexport function toDateValue(date: Date): string {\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, '0');\n const day = `${date.getDate()}`.padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\nexport function addMonths(date: Date, amount: number): Date {\n return new Date(date.getFullYear(), date.getMonth() + amount, 1, 12);\n}\n\nexport function addYears(date: Date, amount: number): Date {\n return new Date(date.getFullYear() + amount, date.getMonth(), 1, 12);\n}\n\nexport function formatCalendarMonthLabel(date: Date): string {\n return `${date.getFullYear()}年 ${date.getMonth() + 1}月`;\n}\n\nexport function splitTimeValue(value: string): { hour: string; minute: string } {\n const [hour = '00', minute = '00'] = trimSeconds(value || '00:00').split(':');\n return { hour, minute };\n}\n\nexport function joinTimeValue(hour: string, minute: string): string {\n return `${hour}:${minute}`;\n}\n\nexport function parsePositiveInteger(value: string): number | null {\n if (!/^\\d+$/.test(value.trim())) return null;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) return null;\n return parsed;\n}\n\nexport type EffectivePreset = '' | 'week' | 'month' | 'quarter' | 'year';\n\nexport function addPresetRange(baseDate: Date, preset: EffectivePreset): Date {\n const next = new Date(baseDate);\n if (preset === 'week') next.setDate(next.getDate() + 7);\n if (preset === 'month') next.setMonth(next.getMonth() + 1);\n if (preset === 'quarter') next.setMonth(next.getMonth() + 3);\n if (preset === 'year') next.setFullYear(next.getFullYear() + 1);\n return next;\n}\n\nexport function buildEffectiveTimeFromPreset(preset: EffectivePreset): ScheduleEffectiveTime | undefined {\n if (!preset) return undefined;\n const now = new Date();\n const end = addPresetRange(now, preset);\n return {\n startTime: formatDateTime(now),\n endTime: formatDateTime(end),\n };\n}\n\nexport function sortWeekdays(weekdays: string[]): string[] {\n return [...weekdays].sort((left, right) => Number(left) - Number(right));\n}\n\nexport function getDefaultSessionId(sessionMode: 'existing' | 'new'): string {\n return sessionMode === 'existing' ? '' : NEW_SESSION_ID;\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useCallback, useLayoutEffect, type RefObject } from 'react';\nimport { createPortal } from 'react-dom';\nimport { HOURS, MINUTES, INPUT_BOX_CLASS, joinTimeValue, splitTimeValue } from '../utils/editor';\n\ntype DropdownPanelPlacement = 'top' | 'bottom';\n\ninterface ResponsiveDropdownLayoutOptions {\n minimumPanelHeight: number;\n reservedHeight: number;\n minScrollableHeight: number;\n defaultPanelHeight: number;\n defaultScrollableHeight: number;\n}\n\nfunction useResponsiveDropdownLayout(\n open: boolean,\n containerRef: RefObject<HTMLDivElement | null>,\n options: ResponsiveDropdownLayoutOptions,\n) {\n const [panelPlacement, setPanelPlacement] = useState<DropdownPanelPlacement>('bottom');\n const [panelMaxHeight, setPanelMaxHeight] = useState(options.defaultPanelHeight);\n const [scrollableMaxHeight, setScrollableMaxHeight] = useState(options.defaultScrollableHeight);\n\n useLayoutEffect(() => {\n if (!open) return;\n\n const updatePanelLayout = () => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const gap = 8;\n const safeMargin = 16;\n const spaceBelow = viewportHeight - rect.bottom - gap - safeMargin;\n const spaceAbove = rect.top - gap - safeMargin;\n const openUpward = spaceBelow < options.minimumPanelHeight && spaceAbove > spaceBelow;\n const availableHeight = Math.max(openUpward ? spaceAbove : spaceBelow, options.minimumPanelHeight);\n\n setPanelPlacement(openUpward ? 'top' : 'bottom');\n setPanelMaxHeight(Math.max(availableHeight, options.minimumPanelHeight));\n setScrollableMaxHeight(Math.max(availableHeight - options.reservedHeight, options.minScrollableHeight));\n };\n\n updatePanelLayout();\n window.addEventListener('resize', updatePanelLayout);\n return () => window.removeEventListener('resize', updatePanelLayout);\n }, [\n containerRef,\n open,\n options.defaultPanelHeight,\n options.defaultScrollableHeight,\n options.minScrollableHeight,\n options.minimumPanelHeight,\n options.reservedHeight,\n ]);\n\n return { panelPlacement, panelMaxHeight, scrollableMaxHeight };\n}\n\nfunction useDropdownPortalPosition(\n open: boolean,\n containerRef: RefObject<HTMLDivElement | null>,\n panelPlacement: DropdownPanelPlacement,\n panelWidth?: number,\n) {\n const [panelPosition, setPanelPosition] = useState<{ top: number; left: number; width: number } | null>(null);\n\n const updatePanelPosition = useCallback(() => {\n if (!open) return;\n const trigger = containerRef.current;\n if (!trigger) return;\n const rect = trigger.getBoundingClientRect();\n setPanelPosition({\n top: panelPlacement === 'top' ? rect.top - 8 : rect.bottom + 8,\n left: rect.left,\n width: panelWidth ?? rect.width,\n });\n }, [containerRef, open, panelPlacement, panelWidth]);\n\n useLayoutEffect(() => {\n if (!open) {\n setPanelPosition(null);\n return;\n }\n updatePanelPosition();\n }, [open, updatePanelPosition]);\n\n useEffect(() => {\n if (!open) return;\n const handleViewportChange = () => updatePanelPosition();\n window.addEventListener('resize', handleViewportChange);\n window.addEventListener('scroll', handleViewportChange, true);\n return () => {\n window.removeEventListener('resize', handleViewportChange);\n window.removeEventListener('scroll', handleViewportChange, true);\n };\n }, [open, updatePanelPosition]);\n\n return panelPosition;\n}\n\ninterface TimePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n testIdPrefix: string;\n isHourDisabled?: (hour: string) => boolean;\n isMinuteDisabled?: (hour: string, minute: string) => boolean;\n}\n\nexport function TimePickerField({ value, onChange, testIdPrefix, isHourDisabled, isMinuteDisabled }: TimePickerFieldProps) {\n const [open, setOpen] = useState(false);\n const [draftHour, setDraftHour] = useState(splitTimeValue(value).hour);\n const [draftMinute, setDraftMinute] = useState(splitTimeValue(value).minute);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const panelRef = useRef<HTMLDivElement | null>(null);\n const { panelPlacement, panelMaxHeight, scrollableMaxHeight } = useResponsiveDropdownLayout(open, containerRef, {\n minimumPanelHeight: 320,\n reservedHeight: 188,\n minScrollableHeight: 120,\n defaultPanelHeight: 420,\n defaultScrollableHeight: 220,\n });\n const panelPosition = useDropdownPortalPosition(open, containerRef, panelPlacement, 320);\n\n useEffect(() => {\n const next = splitTimeValue(value);\n setDraftHour(next.hour);\n setDraftMinute(next.minute);\n }, [value]);\n\n useEffect(() => {\n if (!open) return;\n const handleDocumentClick = (event: MouseEvent) => {\n const target = event.target as Node;\n if (containerRef.current?.contains(target)) return;\n if (panelRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener('mousedown', handleDocumentClick);\n return () => document.removeEventListener('mousedown', handleDocumentClick);\n }, [open]);\n\n const getFirstAvailableHour = useCallback(() => {\n return HOURS.find((hour) => !(isHourDisabled?.(hour) ?? false)) ?? '00';\n }, [isHourDisabled]);\n\n const getFirstAvailableMinute = useCallback((hour: string) => {\n return MINUTES.find((minute) => !(isMinuteDisabled?.(hour, minute) ?? false)) ?? '00';\n }, [isMinuteDisabled]);\n\n const getNormalizedDraftTime = useCallback((hour: string, minute: string) => {\n let nextHour = hour;\n if (isHourDisabled?.(nextHour) ?? false) {\n nextHour = getFirstAvailableHour();\n }\n\n let nextMinute = minute;\n if (isMinuteDisabled?.(nextHour, nextMinute) ?? false) {\n nextMinute = getFirstAvailableMinute(nextHour);\n }\n\n return { hour: nextHour, minute: nextMinute };\n }, [getFirstAvailableHour, getFirstAvailableMinute, isHourDisabled, isMinuteDisabled]);\n\n useEffect(() => {\n if (!open) return;\n const normalized = getNormalizedDraftTime(draftHour, draftMinute);\n if (normalized.hour !== draftHour) {\n setDraftHour(normalized.hour);\n }\n if (normalized.minute !== draftMinute) {\n setDraftMinute(normalized.minute);\n }\n }, [draftHour, draftMinute, getNormalizedDraftTime, open]);\n\n return (\n <div ref={containerRef} className=\"relative w-[214px]\">\n <button\n type=\"button\"\n onClick={() => setOpen((current) => !current)}\n className={`flex w-full items-center justify-between px-3 text-[14px] ${INPUT_BOX_CLASS}`}\n data-testid={`${testIdPrefix}-trigger`}\n >\n <span className={value ? 'text-[#101828]' : 'text-[#98A2B3]'}>{value || '00:00'}</span>\n <img src=\"../icons/schedule.svg\" alt=\"\" aria-hidden=\"true\" className=\"w-4 h-4 shrink-0\" />\n </button>\n\n {open && panelPosition\n ? createPortal(\n <div\n className=\"fixed z-[70]\"\n style={{\n top: panelPosition.top,\n left: panelPosition.left,\n width: panelPosition.width,\n transform: panelPlacement === 'top' ? 'translateY(-100%)' : undefined,\n }}\n >\n <div\n ref={panelRef}\n className={[\n 'w-full rounded-[16px] border border-[rgba(194,194,194,1)] bg-white p-4 shadow-[0_12px_32px_rgba(16,24,40,0.14)]',\n panelPlacement === 'top' ? 'bottom-[calc(100%+8px)]' : 'top-[calc(100%+8px)]',\n ].join(' ')}\n style={{ maxHeight: `${panelMaxHeight}px` }}\n data-testid={`${testIdPrefix}-panel`}\n >\n <div className={`mb-4 flex items-center justify-between px-3 text-[14px] ${INPUT_BOX_CLASS}`}>\n <span>{joinTimeValue(draftHour, draftMinute)}</span>\n <img src=\"../icons/schedule.svg\" alt=\"\" aria-hidden=\"true\" className=\"w-4 h-4 shrink-0\" />\n </div>\n\n <div className=\"grid grid-cols-2 gap-6\">\n <div className=\"flex min-w-0 flex-col\">\n <div className=\"mb-3 flex h-6 items-center justify-center text-[14px] font-normal text-[#98A2B3]\">时</div>\n <div\n className=\"space-y-2 overflow-y-auto [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden\"\n style={{ maxHeight: `${scrollableMaxHeight}px` }}\n data-testid={`${testIdPrefix}-hour-scroll`}\n >\n {HOURS.map((hour) => {\n const selected = draftHour === hour;\n const disabled = isHourDisabled?.(hour) ?? false;\n return (\n <button\n key={hour}\n type=\"button\"\n onClick={() => {\n if (disabled) return;\n setDraftHour(hour);\n if (isMinuteDisabled?.(hour, draftMinute) ?? false) {\n setDraftMinute(getFirstAvailableMinute(hour));\n }\n }}\n disabled={disabled}\n className={[\n 'flex h-10 w-full items-center justify-center rounded-full text-[14px] font-normal transition',\n disabled\n ? 'cursor-not-allowed text-[#D0D5DD]'\n : selected\n ? 'bg-[#DCEBFF] text-[#101828]'\n : 'text-[#344054] hover:bg-[#F2F4F7]',\n ].join(' ')}\n data-testid={`${testIdPrefix}-hour-${hour}`}\n >\n {hour}\n </button>\n );\n })}\n </div>\n </div>\n <div className=\"flex min-w-0 flex-col\">\n <div className=\"mb-3 flex h-6 items-center justify-center text-[14px] font-normal text-[#98A2B3]\">分</div>\n <div\n className=\"space-y-2 overflow-y-auto [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden\"\n style={{ maxHeight: `${scrollableMaxHeight}px` }}\n data-testid={`${testIdPrefix}-minute-scroll`}\n >\n {MINUTES.map((minute) => {\n const selected = draftMinute === minute;\n const disabled = isMinuteDisabled?.(draftHour, minute) ?? false;\n return (\n <button\n key={minute}\n type=\"button\"\n onClick={() => {\n if (disabled) return;\n setDraftMinute(minute);\n }}\n disabled={disabled}\n className={[\n 'flex h-10 w-full items-center justify-center rounded-full text-[14px] font-normal transition',\n disabled\n ? 'cursor-not-allowed text-[#D0D5DD]'\n : selected\n ? 'bg-[#DCEBFF] text-[#101828]'\n : 'text-[#344054] hover:bg-[#F2F4F7]',\n ].join(' ')}\n data-testid={`${testIdPrefix}-minute-${minute}`}\n >\n {minute}\n </button>\n );\n })}\n </div>\n </div>\n </div>\n\n <div className=\"mt-4 flex justify-end border-t border-[rgba(194,194,194,1)] pt-4\">\n <button\n type=\"button\"\n onClick={() => {\n const normalized = getNormalizedDraftTime(draftHour, draftMinute);\n setDraftHour(normalized.hour);\n setDraftMinute(normalized.minute);\n onChange(joinTimeValue(normalized.hour, normalized.minute));\n setOpen(false);\n }}\n className=\"inline-flex h-10 items-center justify-center rounded-full border border-[rgba(194,194,194,1)] px-6 text-[14px] font-normal text-[#101828]\"\n data-testid={`${testIdPrefix}-confirm`}\n >\n 确定\n </button>\n </div>\n </div>\n </div>,\n document.body,\n )\n : null}\n </div>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useMemo, useLayoutEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n INPUT_BOX_CLASS,\n formatDateDisplay,\n parseDateValue,\n toDateValue,\n addMonths,\n addYears,\n formatCalendarMonthLabel,\n} from '../utils/editor';\n\nconst CALENDAR_WEEKDAY_LABELS = ['日', '一', '二', '三', '四', '五', '六'];\n\ninterface CalendarDayCell {\n date: Date;\n value: string;\n label: string;\n currentMonth: boolean;\n selected: boolean;\n disabled: boolean;\n}\n\nfunction buildCalendarDayCells(viewDate: Date, selectedValue: string): CalendarDayCell[] {\n const monthStart = new Date(viewDate.getFullYear(), viewDate.getMonth(), 1, 12);\n const gridStart = new Date(monthStart);\n gridStart.setDate(monthStart.getDate() - monthStart.getDay());\n const todayValue = toDateValue(new Date());\n\n return Array.from({ length: 42 }, (_, index) => {\n const date = new Date(gridStart);\n date.setDate(gridStart.getDate() + index);\n const value = toDateValue(date);\n return {\n date,\n value,\n label: `${date.getDate()}`,\n currentMonth: date.getMonth() === viewDate.getMonth(),\n selected: value === selectedValue,\n disabled: value < todayValue,\n };\n });\n}\n\ninterface DatePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n}\n\nexport function DatePickerField({ value, onChange }: DatePickerFieldProps) {\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const panelRef = useRef<HTMLDivElement | null>(null);\n const [panelPlacement, setPanelPlacement] = useState<'top' | 'bottom'>('bottom');\n const [panelMaxHeight, setPanelMaxHeight] = useState(560);\n const [calendarGridMaxHeight, setCalendarGridMaxHeight] = useState(336);\n const selectedDate = useMemo(() => parseDateValue(value), [value]);\n const [viewDate, setViewDate] = useState<Date>(() => selectedDate ?? new Date());\n const calendarDays = useMemo(() => buildCalendarDayCells(viewDate, value), [viewDate, value]);\n const [panelPosition, setPanelPosition] = useState<{ top: number; left: number; width: number } | null>(null);\n\n const updatePanelPosition = useCallback(() => {\n if (!open) return;\n const trigger = containerRef.current;\n if (!trigger) return;\n const rect = trigger.getBoundingClientRect();\n setPanelPosition({\n top: panelPlacement === 'top' ? rect.top - 8 : rect.bottom + 8,\n left: rect.left,\n width: rect.width,\n });\n }, [open, panelPlacement]);\n\n useLayoutEffect(() => {\n if (!open) {\n setPanelPosition(null);\n return;\n }\n updatePanelPosition();\n }, [open, updatePanelPosition]);\n\n useEffect(() => {\n if (!open) return;\n const handleViewportChange = () => updatePanelPosition();\n window.addEventListener('resize', handleViewportChange);\n window.addEventListener('scroll', handleViewportChange, true);\n return () => {\n window.removeEventListener('resize', handleViewportChange);\n window.removeEventListener('scroll', handleViewportChange, true);\n };\n }, [open, updatePanelPosition]);\n\n useEffect(() => {\n if (!open) return;\n const handleDocumentClick = (event: MouseEvent) => {\n const target = event.target as Node;\n if (containerRef.current?.contains(target)) return;\n if (panelRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener('mousedown', handleDocumentClick);\n return () => document.removeEventListener('mousedown', handleDocumentClick);\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n setViewDate(selectedDate ?? new Date());\n }, [open, selectedDate]);\n\n useLayoutEffect(() => {\n if (!open) return;\n\n const updatePanelLayout = () => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const gap = 8;\n const safeMargin = 16;\n const minimumPanelHeight = 320;\n const reservedPanelHeight = 224;\n const spaceBelow = viewportHeight - rect.bottom - gap - safeMargin;\n const spaceAbove = rect.top - gap - safeMargin;\n const openUpward = spaceBelow < minimumPanelHeight && spaceAbove > spaceBelow;\n const availableHeight = Math.max(openUpward ? spaceAbove : spaceBelow, minimumPanelHeight);\n\n setPanelPlacement(openUpward ? 'top' : 'bottom');\n setPanelMaxHeight(Math.max(availableHeight, minimumPanelHeight));\n setCalendarGridMaxHeight(Math.max(availableHeight - reservedPanelHeight, 144));\n };\n\n updatePanelLayout();\n window.addEventListener('resize', updatePanelLayout);\n return () => window.removeEventListener('resize', updatePanelLayout);\n }, [open]);\n\n return (\n <div ref={containerRef} className=\"relative w-[214px]\">\n <button\n type=\"button\"\n onClick={() => setOpen((current) => !current)}\n className={`relative flex w-full items-center px-3 pr-11 text-left text-[14px] ${INPUT_BOX_CLASS}`}\n data-testid=\"schedule-editor-once-date-trigger\"\n >\n <span className={value ? 'text-[#101828]' : 'text-[#98A2B3]'}>{value ? formatDateDisplay(value) : 'YYYY/MM/DD'}</span>\n <span className=\"pointer-events-none absolute right-4 top-1/2 -translate-y-1/2 text-[#98A2B3]\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M5.333 1.667V3M10.667 1.667V3M2.333 5H13.667M3.667 2.333H12.333C13.07 2.333 13.667 2.93 13.667 3.667V12.333C13.667 13.07 13.07 13.667 12.333 13.667H3.667C2.93 13.667 2.333 13.07 2.333 12.333V3.667C2.333 2.93 2.93 2.333 3.667 2.333Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n </button>\n\n {open && panelPosition\n ? createPortal(\n <div\n className=\"fixed z-[70]\"\n style={{\n top: panelPosition.top,\n left: panelPosition.left,\n width: panelPosition.width,\n minWidth: '340px',\n transform: panelPlacement === 'top' ? 'translateY(-100%)' : undefined,\n }}\n >\n <div\n ref={panelRef}\n className={[\n 'w-full overflow-hidden rounded-[16px] border border-[rgba(194,194,194,1)] bg-white shadow-[0_12px_32px_rgba(16,24,40,0.14)]',\n panelPlacement === 'top' ? 'bottom-[calc(100%+8px)]' : 'top-[calc(100%+8px)]',\n ].join(' ')}\n style={{ maxHeight: `${panelMaxHeight}px` }}\n data-testid=\"schedule-editor-once-date-panel\"\n >\n <div className=\"p-6 pb-5\">\n <div className={`flex items-center px-3 text-[14px] text-[#98A2B3] ${INPUT_BOX_CLASS}`}>\n {value ? formatDateDisplay(value) : 'YYYY/MM/DD'}\n </div>\n </div>\n\n <div className=\"flex items-center justify-between border-b border-[rgba(194,194,194,1)] px-6 pb-5\">\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setViewDate((current) => addYears(current, -1))}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-[6px] text-[22px] leading-none text-[#98A2B3] transition hover:bg-[#F9FAFB] hover:text-[#667085]\"\n data-testid=\"schedule-editor-once-date-prev-year\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M11.25 4.5L6.75 9L11.25 13.5\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M15 4.5L10.5 9L15 13.5\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => setViewDate((current) => addMonths(current, -1))}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-[6px] text-[22px] leading-none text-[#98A2B3] transition hover:bg-[#F9FAFB] hover:text-[#667085]\"\n data-testid=\"schedule-editor-once-date-prev-month\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M11.25 4.5L6.75 9L11.25 13.5\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div className=\"text-[16px] font-normal text-[#101828]\" data-testid=\"schedule-editor-once-date-month-label\">\n {formatCalendarMonthLabel(viewDate)}\n </div>\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setViewDate((current) => addMonths(current, 1))}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-[6px] text-[22px] leading-none text-[#98A2B3] transition hover:bg-[#F9FAFB] hover:text-[#667085]\"\n data-testid=\"schedule-editor-once-date-next-month\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6.75 4.5L11.25 9L6.75 13.5\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => setViewDate((current) => addYears(current, 1))}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-[6px] text-[22px] leading-none text-[#98A2B3] transition hover:bg-[#F9FAFB] hover:text-[#667085]\"\n data-testid=\"schedule-editor-once-date-next-year\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M3 4.5L7.5 9L3 13.5\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M6.75 4.5L11.25 9L6.75 13.5\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div className=\"px-6 py-5\">\n <div className=\"mb-4 grid grid-cols-7 text-center text-[14px] text-[#98A2B3]\">\n {CALENDAR_WEEKDAY_LABELS.map((label) => (\n <span key={label} className=\"flex h-10 items-center justify-center\">\n {label}\n </span>\n ))}\n </div>\n\n <div\n className=\"overflow-y-auto pr-1\"\n style={{ maxHeight: `${calendarGridMaxHeight}px` }}\n data-testid=\"schedule-editor-once-date-grid-scroll\"\n >\n <div className=\"grid grid-cols-7 gap-y-4\">\n {calendarDays.map((day) => (\n <button\n key={day.value}\n type=\"button\"\n onClick={() => {\n if (day.disabled) return;\n onChange(day.value);\n setOpen(false);\n }}\n disabled={day.disabled}\n className=\"flex h-14 items-center justify-center disabled:cursor-not-allowed\"\n data-testid={`schedule-editor-once-date-day-${day.value}`}\n >\n <span\n className={[\n 'inline-flex h-10 w-10 items-center justify-center rounded-[6px] border text-[14px] transition',\n day.disabled\n ? 'border-transparent text-[#D0D5DD]'\n : day.selected\n ? 'border-[1.5px] border-[rgba(20,118,255,1)] text-[#101828]'\n : day.currentMonth\n ? 'border-transparent text-[#101828] hover:bg-[#F9FAFB]'\n : 'border-transparent text-[#98A2B3] hover:bg-[#F9FAFB]',\n ].join(' ')}\n >\n {day.label}\n </span>\n </button>\n ))}\n </div>\n </div>\n </div>\n </div>\n </div>,\n document.body,\n )\n : null}\n </div>\n );\n}\n","import { INPUT_BOX_CLASS } from '../utils/editor';\n\ninterface PickerFieldButtonProps {\n value: string;\n placeholder: string;\n onClick: () => void;\n testId: string;\n}\n\nexport function PickerFieldButton({ value, placeholder, onClick, testId }: PickerFieldButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={`relative flex w-full items-center justify-between overflow-hidden px-3 text-left outline-none before:pointer-events-none before:absolute before:right-3 before:top-1/2 before:h-5 before:w-5 before:-translate-y-1/2 before:bg-white before:content-[''] after:pointer-events-none after:absolute after:right-[18px] after:top-1/2 after:h-[7px] after:w-[7px] after:-translate-y-[62%] after:rotate-45 after:border-b-[1.6px] after:border-r-[1.6px] after:border-[#98A2B3] after:content-[''] ${INPUT_BOX_CLASS}`}\n data-testid={testId}\n >\n <span className={`min-w-0 block truncate whitespace-nowrap ${value ? 'text-[#101828]' : 'text-[#98A2B3]'}`}>\n {value || placeholder}\n </span>\n <span className=\"text-[#98A2B3]\" aria-hidden=\"true\" />\n </button>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useCallback, useLayoutEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { INTERVAL_UNIT_OPTIONS, INPUT_BOX_CLASS } from '../utils/editor';\nimport type { ScheduleIntervalUnit } from '../schedule-template-types';\nimport { PickerFieldButton } from './PickerFieldButton';\n\ntype DropdownPanelPlacement = 'top' | 'bottom';\n\ninterface ResponsiveDropdownLayoutOptions {\n minimumPanelHeight: number;\n reservedHeight: number;\n minScrollableHeight: number;\n defaultPanelHeight: number;\n defaultScrollableHeight: number;\n}\n\nfunction useResponsiveDropdownLayout(\n open: boolean,\n containerRef: React.RefObject<HTMLDivElement | null>,\n options: ResponsiveDropdownLayoutOptions,\n) {\n const [panelPlacement, setPanelPlacement] = useState<DropdownPanelPlacement>('bottom');\n const [panelMaxHeight, setPanelMaxHeight] = useState(options.defaultPanelHeight);\n const [scrollableMaxHeight, setScrollableMaxHeight] = useState(options.defaultScrollableHeight);\n\n useLayoutEffect(() => {\n if (!open) return;\n\n const updatePanelLayout = () => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const gap = 8;\n const safeMargin = 16;\n const spaceBelow = viewportHeight - rect.bottom - gap - safeMargin;\n const spaceAbove = rect.top - gap - safeMargin;\n const openUpward = spaceBelow < options.minimumPanelHeight && spaceAbove > spaceBelow;\n const availableHeight = Math.max(openUpward ? spaceAbove : spaceBelow, options.minimumPanelHeight);\n\n setPanelPlacement(openUpward ? 'top' : 'bottom');\n setPanelMaxHeight(Math.max(availableHeight, options.minimumPanelHeight));\n setScrollableMaxHeight(Math.max(availableHeight - options.reservedHeight, options.minScrollableHeight));\n };\n\n updatePanelLayout();\n window.addEventListener('resize', updatePanelLayout);\n return () => window.removeEventListener('resize', updatePanelLayout);\n }, [\n containerRef,\n open,\n options.defaultPanelHeight,\n options.defaultScrollableHeight,\n options.minScrollableHeight,\n options.minimumPanelHeight,\n options.reservedHeight,\n ]);\n\n return { panelPlacement, panelMaxHeight, scrollableMaxHeight };\n}\n\nfunction useDropdownPortalPosition(\n open: boolean,\n containerRef: React.RefObject<HTMLDivElement | null>,\n panelPlacement: DropdownPanelPlacement,\n panelWidth?: number,\n) {\n const [panelPosition, setPanelPosition] = useState<{ top: number; left: number; width: number } | null>(null);\n\n const updatePanelPosition = useCallback(() => {\n if (!open) return;\n const trigger = containerRef.current;\n if (!trigger) return;\n const rect = trigger.getBoundingClientRect();\n setPanelPosition({\n top: panelPlacement === 'top' ? rect.top - 8 : rect.bottom + 8,\n left: rect.left,\n width: panelWidth ?? rect.width,\n });\n }, [containerRef, open, panelPlacement, panelWidth]);\n\n useLayoutEffect(() => {\n if (!open) {\n setPanelPosition(null);\n return;\n }\n updatePanelPosition();\n }, [open, updatePanelPosition]);\n\n useEffect(() => {\n if (!open) return;\n const handleViewportChange = () => updatePanelPosition();\n window.addEventListener('resize', handleViewportChange);\n window.addEventListener('scroll', handleViewportChange, true);\n return () => {\n window.removeEventListener('resize', handleViewportChange);\n window.removeEventListener('scroll', handleViewportChange, true);\n };\n }, [open, updatePanelPosition]);\n\n return panelPosition;\n}\n\ninterface IntervalUnitSelectFieldProps {\n value: ScheduleIntervalUnit;\n onChange: (value: ScheduleIntervalUnit) => void;\n}\n\nexport function IntervalUnitSelectField({ value, onChange }: IntervalUnitSelectFieldProps) {\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const panelRef = useRef<HTMLDivElement | null>(null);\n const { panelPlacement, panelMaxHeight, scrollableMaxHeight } = useResponsiveDropdownLayout(open, containerRef, {\n minimumPanelHeight: 160,\n reservedHeight: 16,\n minScrollableHeight: 120,\n defaultPanelHeight: 240,\n defaultScrollableHeight: 224,\n });\n const panelPosition = useDropdownPortalPosition(open, containerRef, panelPlacement);\n const label = INTERVAL_UNIT_OPTIONS.find((option) => option.value === value)?.label ?? '';\n\n useEffect(() => {\n if (!open) return;\n const handleDocumentClick = (event: MouseEvent) => {\n const target = event.target as Node;\n if (containerRef.current?.contains(target)) return;\n if (panelRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener('mousedown', handleDocumentClick);\n return () => document.removeEventListener('mousedown', handleDocumentClick);\n }, [open]);\n\n return (\n <div ref={containerRef} className=\"relative w-[132px]\">\n <PickerFieldButton value={label} placeholder=\"\" onClick={() => setOpen((current) => !current)} testId=\"schedule-editor-interval-unit\" />\n\n {open && panelPosition\n ? createPortal(\n <div\n className=\"fixed z-[70]\"\n style={{\n top: panelPosition.top,\n left: panelPosition.left,\n width: panelPosition.width,\n transform: panelPlacement === 'top' ? 'translateY(-100%)' : undefined,\n }}\n >\n <div\n ref={panelRef}\n className={[\n 'w-full rounded-[12px] border border-[rgba(194,194,194,1)] bg-white p-2 shadow-[0_12px_32px_rgba(16,24,40,0.12)]',\n panelPlacement === 'top' ? 'bottom-[calc(100%+8px)]' : 'top-[calc(100%+8px)]',\n ].join(' ')}\n style={{ maxHeight: `${panelMaxHeight}px` }}\n data-testid=\"schedule-editor-interval-unit-panel\"\n >\n <div style={{ maxHeight: `${scrollableMaxHeight}px` }} className=\"overflow-y-auto\" data-testid=\"schedule-editor-interval-unit-scroll\">\n {INTERVAL_UNIT_OPTIONS.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value);\n setOpen(false);\n }}\n className=\"flex h-10 w-full items-center rounded-[10px] px-3 text-left text-[14px] text-[#101828] hover:bg-[#F9FAFB]\"\n data-testid={`schedule-editor-interval-unit-option-${option.value}`}\n >\n {option.label}\n </button>\n ))}\n </div>\n </div>\n </div>,\n document.body,\n )\n : null}\n </div>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useMemo, useCallback, useLayoutEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useAgentData } from '@/hooks/useAgentData';\nimport { normalizeStoredThreadTitleOrNull } from '@/components/thread-sidebar/thread-title';\nimport { formatRelativeTime } from '@/components/thread-sidebar/thread-utils';\nimport { API_URL } from '@/utils/api-client';\nimport { PickerFieldButton } from './PickerFieldButton';\n\ninterface SessionSelectOption {\n value: string;\n label: string;\n participants: string[];\n lastActiveAt: number;\n}\n\nfunction resolveAvatarUrl(rawAvatar?: string): string | null {\n const avatar = rawAvatar?.trim();\n if (!avatar) return null;\n if (avatar.startsWith('/uploads/')) return `${API_URL}${avatar}`;\n return avatar;\n}\n\ntype DropdownPanelPlacement = 'top' | 'bottom';\n\ninterface ResponsiveDropdownLayoutOptions {\n minimumPanelHeight: number;\n reservedHeight: number;\n minScrollableHeight: number;\n defaultPanelHeight: number;\n defaultScrollableHeight: number;\n}\n\nfunction useResponsiveDropdownLayout(\n open: boolean,\n containerRef: React.RefObject<HTMLDivElement | null>,\n options: ResponsiveDropdownLayoutOptions,\n) {\n const [panelPlacement, setPanelPlacement] = useState<DropdownPanelPlacement>('bottom');\n const [panelMaxHeight, setPanelMaxHeight] = useState(options.defaultPanelHeight);\n const [scrollableMaxHeight, setScrollableMaxHeight] = useState(options.defaultScrollableHeight);\n\n useLayoutEffect(() => {\n if (!open) return;\n\n const updatePanelLayout = () => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const gap = 8;\n const safeMargin = 16;\n const spaceBelow = viewportHeight - rect.bottom - gap - safeMargin;\n const spaceAbove = rect.top - gap - safeMargin;\n const openUpward = spaceBelow < options.minimumPanelHeight && spaceAbove > spaceBelow;\n const availableHeight = Math.max(openUpward ? spaceAbove : spaceBelow, options.minimumPanelHeight);\n\n setPanelPlacement(openUpward ? 'top' : 'bottom');\n setPanelMaxHeight(Math.max(availableHeight, options.minimumPanelHeight));\n setScrollableMaxHeight(Math.max(availableHeight - options.reservedHeight, options.minScrollableHeight));\n };\n\n updatePanelLayout();\n window.addEventListener('resize', updatePanelLayout);\n return () => window.removeEventListener('resize', updatePanelLayout);\n }, [\n containerRef,\n open,\n options.defaultPanelHeight,\n options.defaultScrollableHeight,\n options.minScrollableHeight,\n options.minimumPanelHeight,\n options.reservedHeight,\n ]);\n\n return { panelPlacement, panelMaxHeight, scrollableMaxHeight };\n}\n\ninterface SessionSelectFieldProps {\n value: string;\n onChange: (value: string) => void;\n options: SessionSelectOption[];\n loading: boolean;\n hasError: boolean;\n}\n\nexport function SessionSelectField({ value, onChange, options, loading, hasError }: SessionSelectFieldProps) {\n const [open, setOpen] = useState(false);\n const [panelPosition, setPanelPosition] = useState<{ top: number; left: number; width: number } | null>(null);\n const label = options.find((option) => option.value === value)?.label ?? '';\n const containerRef = useRef<HTMLDivElement | null>(null);\n const panelRef = useRef<HTMLDivElement | null>(null);\n const { agents } = useAgentData();\n const { panelPlacement, panelMaxHeight, scrollableMaxHeight } = useResponsiveDropdownLayout(open, containerRef, {\n minimumPanelHeight: 180,\n reservedHeight: 16,\n minScrollableHeight: 120,\n defaultPanelHeight: 280,\n defaultScrollableHeight: 264,\n });\n\n const updatePanelPosition = useCallback(() => {\n if (!open) return;\n const trigger = containerRef.current;\n if (!trigger) return;\n const rect = trigger.getBoundingClientRect();\n setPanelPosition({\n top: panelPlacement === 'top' ? rect.top - 8 : rect.bottom + 8,\n left: rect.left,\n width: rect.width,\n });\n }, [open, panelPlacement]);\n\n useLayoutEffect(() => {\n if (!open) {\n setPanelPosition(null);\n return;\n }\n updatePanelPosition();\n }, [open, updatePanelPosition]);\n\n useEffect(() => {\n if (!open) return;\n const handleViewportChange = () => updatePanelPosition();\n window.addEventListener('resize', handleViewportChange);\n window.addEventListener('scroll', handleViewportChange, true);\n return () => {\n window.removeEventListener('resize', handleViewportChange);\n window.removeEventListener('scroll', handleViewportChange, true);\n };\n }, [open, updatePanelPosition]);\n\n useEffect(() => {\n if (!open) return;\n const handleDocumentClick = (event: MouseEvent) => {\n const target = event.target as Node;\n if (containerRef.current?.contains(target)) return;\n if (panelRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener('mousedown', handleDocumentClick);\n return () => document.removeEventListener('mousedown', handleDocumentClick);\n }, [open]);\n\n const agentById = useMemo(() => new Map(agents.map((agent) => [agent.id, agent])), [agents]);\n const fallbackAvatar =\n resolveAvatarUrl(\n agents.find((agent) => agent.id.toLowerCase() === 'office')?.avatar ??\n agents.find((agent) => agent.id.toLowerCase() === 'jiuwenclaw')?.avatar,\n ) ?? '/avatars/assistant.svg';\n const displayOptions = useMemo(\n () =>\n options.map((option) => {\n const participants = Array.isArray(option.participants) ? option.participants : [];\n const participantNames = participants\n .map((participantId) => agentById.get(participantId)?.displayName ?? participantId)\n .filter((name) => !!name.trim());\n const subtitle = participantNames.length > 0 ? participantNames.join(',') : '通用助手';\n const avatarSources = participants.slice(0, 4).map(\n (participantId) => resolveAvatarUrl(agentById.get(participantId)?.avatar) ?? fallbackAvatar,\n );\n return {\n ...option,\n subtitle,\n avatarSources,\n timeText: formatRelativeTime(Number(option.lastActiveAt) || 0, true),\n };\n }),\n [agentById, fallbackAvatar, options],\n );\n\n return (\n <div ref={containerRef} className=\"relative\">\n <PickerFieldButton\n value={label}\n placeholder=\"请选择\"\n onClick={() => setOpen((current) => !current)}\n testId=\"schedule-editor-session-select\"\n />\n\n {open && panelPosition\n ? createPortal(\n <div\n className=\"fixed z-[70]\"\n style={{\n top: panelPosition.top,\n left: panelPosition.left,\n width: panelPosition.width,\n transform: panelPlacement === 'top' ? 'translateY(-100%)' : undefined,\n }}\n >\n <div\n ref={panelRef}\n className={[\n 'w-full rounded-[12px] border border-[rgba(194,194,194,1)] bg-white p-2 shadow-[0_12px_32px_rgba(16,24,40,0.12)]',\n panelPlacement === 'top' ? 'bottom-[calc(100%+8px)]' : 'top-[calc(100%+8px)]',\n ].join(' ')}\n style={{ maxHeight: `${panelMaxHeight}px` }}\n data-testid=\"schedule-editor-session-panel\"\n >\n {loading ? <div className=\"px-3 py-2 text-[14px] text-[#667085]\">加载中...</div> : null}\n {!loading && hasError ? <div className=\"px-3 py-2 text-[14px] text-[#667085]\">加载失败</div> : null}\n {!loading && !hasError && options.length === 0 ? <div className=\"px-3 py-2 text-[14px] text-[#667085]\">暂无会话</div> : null}\n <div style={{ maxHeight: `${scrollableMaxHeight}px` }} className=\"overflow-y-auto\" data-testid=\"schedule-editor-session-scroll\">\n {!loading && !hasError\n ? displayOptions.map((option) => {\n const selected = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value);\n setOpen(false);\n }}\n className={[\n 'flex w-full items-center gap-2 rounded-[8px] px-2 py-2 text-left transition',\n selected ? 'bg-[#DCEBFF]' : 'hover:bg-[#F9FAFB]',\n ].join(' ')}\n data-testid={`schedule-editor-session-option-${option.value}`}\n >\n <div className=\"relative h-8 w-8 shrink-0\">\n {option.avatarSources.length <= 1 ? (\n <img src={option.avatarSources[0] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"h-8 w-8 rounded-full object-cover\" />\n ) : option.avatarSources.length === 2 ? (\n <>\n <img src={option.avatarSources[0] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-[1px] top-[6px] h-5 w-5 rounded-full object-cover\" />\n <img src={option.avatarSources[1] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-[11px] top-[6px] h-5 w-5 rounded-full object-cover\" />\n </>\n ) : option.avatarSources.length === 3 ? (\n <>\n <img src={option.avatarSources[0] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-[8px] top-0 h-4 w-4 rounded-full object-cover\" />\n <img src={option.avatarSources[1] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-0 top-[16px] h-4 w-4 rounded-full object-cover\" />\n <img src={option.avatarSources[2] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-[16px] top-[16px] h-4 w-4 rounded-full object-cover\" />\n </>\n ) : (\n <>\n <img src={option.avatarSources[0] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-0 top-0 h-4 w-4 rounded-full object-cover\" />\n <img src={option.avatarSources[1] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-[16px] top-0 h-4 w-4 rounded-full object-cover\" />\n <img src={option.avatarSources[2] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-0 top-[16px] h-4 w-4 rounded-full object-cover\" />\n <img src={option.avatarSources[3] ?? fallbackAvatar} alt=\"\" aria-hidden=\"true\" className=\"absolute left-[16px] top-[16px] h-4 w-4 rounded-full object-cover\" />\n </>\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span\n className=\"block min-w-0 truncate text-[14px] font-semibold leading-5 text-[#344054]\"\n data-testid={`schedule-editor-session-option-title-${option.value}`}\n >\n {option.label}\n </span>\n <span className=\"shrink-0 text-[14px] leading-5 text-[#344054]\">{option.timeText}</span>\n </div>\n <div className=\"mt-1 truncate text-[12px] leading-5 text-[#667085]\">{option.subtitle}</div>\n </div>\n </button>\n );\n })\n : null}\n </div>\n </div>\n </div>,\n document.body,\n )\n : null}\n </div>\n );\n}\n\nexport type { SessionSelectOption };\n","import { useState, useCallback } from 'react';\nimport type { ScheduleTaskDraft } from '../schedule-template-types';\nimport type { ScheduleIntervalUnit } from '../schedule-template-types';\nimport {\n ALL_WEEKDAYS,\n normalizeTimeValue,\n trimSeconds,\n sortWeekdays,\n getDefaultSessionId,\n buildEffectiveTimeFromPreset,\n parsePositiveInteger,\n joinTimeValue,\n toDateValue,\n EffectivePreset,\n splitTimeValue,\n} from '../utils/editor';\nimport { intervalValueToMs } from '../utils';\n\ntype EditorFrequencyMode = 'daily' | 'interval' | 'once';\ntype SessionMode = 'existing' | 'new';\n\nexport interface EditorState {\n source: ScheduleTaskDraft['source'];\n templateId?: string;\n taskName: string;\n prompt: string;\n frequencyMode: EditorFrequencyMode;\n time: string;\n intervalValue: string;\n intervalUnit: ScheduleIntervalUnit;\n onceDate: string;\n onceTime: string;\n weekdays: string[];\n effectivePreset: EffectivePreset;\n sessionMode: SessionMode;\n sessionId: string;\n enabled: boolean;\n}\n\nexport function createEditorState(draft: ScheduleTaskDraft | null): EditorState {\n if (!draft) {\n return {\n source: 'custom',\n taskName: '',\n prompt: '',\n frequencyMode: 'daily',\n time: '',\n intervalValue: '1',\n intervalUnit: 'minute',\n onceDate: '',\n onceTime: '',\n weekdays: [...ALL_WEEKDAYS],\n effectivePreset: '',\n sessionMode: 'existing',\n sessionId: getDefaultSessionId('existing'),\n enabled: true,\n };\n }\n\n const baseState: EditorState = {\n source: draft.source,\n templateId: draft.templateId,\n taskName: draft.taskName,\n prompt: draft.prompt,\n frequencyMode: 'daily',\n time: '',\n intervalValue: '1',\n intervalUnit: 'minute',\n onceDate: '',\n onceTime: '',\n weekdays: [...ALL_WEEKDAYS],\n effectivePreset: '',\n sessionMode: 'existing',\n sessionId: draft.sessionId ?? '',\n enabled: draft.enabled,\n };\n\n if ((draft.sessionId ?? '').startsWith('mock-new-session')) {\n baseState.sessionMode = 'new';\n }\n\n if (draft.frequency.type === 'daily') {\n baseState.frequencyMode = 'daily';\n baseState.time = trimSeconds(draft.frequency.time);\n baseState.weekdays = [...ALL_WEEKDAYS];\n }\n\n if (draft.frequency.type === 'weekday') {\n baseState.frequencyMode = 'daily';\n baseState.time = trimSeconds(draft.frequency.time);\n baseState.weekdays = sortWeekdays(draft.frequency.weekdays);\n }\n\n if (draft.frequency.type === 'interval') {\n baseState.frequencyMode = 'interval';\n baseState.intervalValue = `${draft.frequency.interval}`;\n baseState.intervalUnit = draft.frequency.unit;\n }\n\n if (draft.frequency.type === 'once') {\n const [date = '', time = ''] = draft.frequency.executeTime.split(' ');\n baseState.frequencyMode = 'once';\n baseState.onceDate = date;\n baseState.onceTime = trimSeconds(time);\n }\n\n return baseState;\n}\n\nexport function buildNormalizedDraft(state: EditorState): ScheduleTaskDraft {\n const normalizedTime = normalizeTimeValue(state.time);\n const effectiveTime = state.frequencyMode === 'once' ? undefined : buildEffectiveTimeFromPreset(state.effectivePreset);\n\n if (state.frequencyMode === 'interval') {\n return {\n source: state.source,\n ...(state.templateId ? { templateId: state.templateId } : {}),\n taskName: state.taskName.trim(),\n prompt: state.prompt.trim(),\n frequency: {\n type: 'interval',\n interval: Number(state.intervalValue),\n unit: state.intervalUnit,\n },\n enabled: state.enabled,\n ...(effectiveTime ? { effectiveTime } : {}),\n sessionId: state.sessionId,\n };\n }\n\n if (state.frequencyMode === 'once') {\n return {\n source: state.source,\n ...(state.templateId ? { templateId: state.templateId } : {}),\n taskName: state.taskName.trim(),\n prompt: state.prompt.trim(),\n frequency: {\n type: 'once',\n executeTime: `${state.onceDate} ${normalizeTimeValue(state.onceTime)}`,\n },\n enabled: state.enabled,\n sessionId: state.sessionId,\n };\n }\n\n const sortedWeekdays = sortWeekdays(state.weekdays);\n const frequency =\n sortedWeekdays.length === ALL_WEEKDAYS.length\n ? { type: 'daily' as const, time: normalizedTime }\n : { type: 'weekday' as const, time: normalizedTime, weekdays: sortedWeekdays };\n\n return {\n source: state.source,\n ...(state.templateId ? { templateId: state.templateId } : {}),\n taskName: state.taskName.trim(),\n prompt: state.prompt.trim(),\n frequency,\n enabled: state.enabled,\n ...(effectiveTime ? { effectiveTime } : {}),\n sessionId: state.sessionId,\n };\n}\n\nexport function useEditorState(initialDraft: ScheduleTaskDraft | null) {\n const [editorState, setEditorState] = useState<EditorState>(() => createEditorState(initialDraft));\n\n const resetEditorState = useCallback((draft: ScheduleTaskDraft | null) => {\n setEditorState(createEditorState(draft));\n }, []);\n\n const handleWeekdayToggle = useCallback((weekday: string) => {\n setEditorState((current) => {\n const exists = current.weekdays.includes(weekday);\n if (exists && current.weekdays.length === 1) return current;\n return {\n ...current,\n weekdays: exists ? current.weekdays.filter((item) => item !== weekday) : sortWeekdays([...current.weekdays, weekday]),\n };\n });\n }, []);\n\n const handleFrequencyModeChange = useCallback((mode: EditorFrequencyMode) => {\n setEditorState((current) => {\n if (mode === 'daily') {\n return {\n ...current,\n frequencyMode: 'daily',\n weekdays: current.weekdays.length > 0 ? current.weekdays : [...ALL_WEEKDAYS],\n };\n }\n return { ...current, frequencyMode: mode };\n });\n }, []);\n\n const handleSessionModeChange = useCallback((sessionMode: SessionMode) => {\n setEditorState((current) => ({\n ...current,\n sessionMode,\n sessionId: getDefaultSessionId(sessionMode),\n }));\n }, []);\n\n return {\n editorState,\n setEditorState,\n resetEditorState,\n handleWeekdayToggle,\n handleFrequencyModeChange,\n handleSessionModeChange,\n };\n}\n\nexport function useFormValidation(editorState: EditorState): boolean {\n if (!editorState.taskName.trim() || !editorState.prompt.trim() || !editorState.sessionId) return false;\n if (editorState.frequencyMode === 'daily') return editorState.weekdays.length > 0 && !!editorState.time;\n if (editorState.frequencyMode === 'interval') {\n const intervalValue = parsePositiveInteger(editorState.intervalValue);\n return intervalValue !== null && intervalValueToMs(intervalValue, editorState.intervalUnit) >= 10_000;\n }\n if (!editorState.onceDate || !editorState.onceTime) return false;\n const now = new Date();\n const todayValue = toDateValue(now);\n if (editorState.onceDate < todayValue) return false;\n if (editorState.onceDate > todayValue) return true;\n const { hour, minute } = splitTimeValue(editorState.onceTime);\n const currentHour = `${now.getHours()}`.padStart(2, '0');\n const currentMinute = `${now.getMinutes()}`.padStart(2, '0');\n return hour > currentHour || (hour === currentHour && minute >= currentMinute);\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { apiFetch } from '@/utils/api-client';\nimport type { Thread } from '@/stores/chat-types';\nimport { normalizeStoredThreadTitleOrNull } from '@/components/thread-sidebar/thread-title';\nimport type { SessionSelectOption } from '../components/SessionSelectField';\n\nexport function useSessionOptions(open: boolean) {\n const [sessionOptions, setSessionOptions] = useState<SessionSelectOption[]>([]);\n const [sessionsLoading, setSessionsLoading] = useState(false);\n const [sessionsError, setSessionsError] = useState(false);\n\n const loadThreads = useCallback(async () => {\n setSessionsLoading(true);\n setSessionsError(false);\n try {\n const res = await apiFetch('/api/threads');\n if (!res.ok) throw new Error('failed_to_load_threads');\n const data = (await res.json()) as { threads?: Thread[] };\n setSessionOptions(\n (data.threads ?? [])\n .filter((thread) => thread.id !== 'default')\n .map((thread) => ({\n value: thread.id,\n label: normalizeStoredThreadTitleOrNull(thread.title) ?? '未命名对话',\n participants: Array.isArray(thread.participants) ? thread.participants : [],\n lastActiveAt: thread.lastActiveAt ?? 0,\n })),\n );\n } catch {\n setSessionOptions([]);\n setSessionsError(true);\n } finally {\n setSessionsLoading(false);\n }\n }, []);\n\n useEffect(() => {\n if (!open) return;\n\n let cancelled = false;\n\n const load = async () => {\n await loadThreads();\n };\n\n void load();\n\n return () => {\n cancelled = true;\n };\n }, [open, loadThreads]);\n\n return {\n sessionOptions,\n sessionsLoading,\n sessionsError,\n reloadSessions: loadThreads,\n };\n}\n","'use client';\n\nimport { useEffect, useState, useCallback } from 'react';\nimport { AppModal } from '../../AppModal';\nimport { TimePickerField } from './TimePickerField';\nimport { DatePickerField } from './DatePickerField';\nimport { IntervalUnitSelectField } from './IntervalUnitSelectField';\nimport { PresetSelectField } from './PresetSelectField';\nimport { SessionSelectField } from './SessionSelectField';\nimport type { SessionSelectOption } from './SessionSelectField';\nimport type { ScheduleTaskDraft } from '../schedule-template-types';\nimport {\n WEEKDAY_OPTIONS,\n INPUT_BOX_CLASS,\n PROMPT_MIN_HEIGHT,\n PROMPT_DEFAULT_HEIGHT,\n PROMPT_INFO_ROW_HEIGHT,\n SHOW_EFFECTIVE_DATE_RANGE_UI,\n EffectivePreset,\n toDateValue,\n} from '../utils/editor';\nimport {\n useEditorState,\n buildNormalizedDraft,\n useFormValidation,\n type EditorState,\n} from '../hooks/useEditorState';\nimport { useSessionOptions } from '../hooks/useSessionOptions';\nimport { Button } from '@/components/shared/Button';\n\ninterface ScheduleTaskEditorModalProps {\n open: boolean;\n draft: ScheduleTaskDraft | null;\n title?: string;\n onClose: () => void;\n onConfirm: (draft: ScheduleTaskDraft) => void | Promise<void>;\n}\n\ntype EditorFrequencyMode = 'daily' | 'interval' | 'once';\ntype SessionMode = 'existing' | 'new';\n\nexport function ScheduleTaskEditorModal({\n open,\n draft,\n title = '创建定时任务',\n onClose,\n onConfirm,\n}: ScheduleTaskEditorModalProps) {\n const { editorState, setEditorState, resetEditorState, handleWeekdayToggle, handleFrequencyModeChange, handleSessionModeChange } = useEditorState(draft);\n const [promptHeight, setPromptHeight] = useState(PROMPT_DEFAULT_HEIGHT);\n const [submitting, setSubmitting] = useState(false);\n const { sessionOptions, sessionsLoading, sessionsError } = useSessionOptions(open);\n\n const isFormValid = useFormValidation(editorState);\n\n useEffect(() => {\n if (!open) return;\n resetEditorState(draft);\n setPromptHeight(PROMPT_DEFAULT_HEIGHT);\n setSubmitting(false);\n }, [draft, open, resetEditorState]);\n\n const handleConfirm = useCallback(async () => {\n if (!isFormValid) return;\n if (submitting) return;\n setSubmitting(true);\n try {\n await onConfirm(buildNormalizedDraft(editorState));\n } finally {\n setSubmitting(false);\n }\n }, [isFormValid, submitting, onConfirm, editorState]);\n\n const handlePromptResizeStart = useCallback((event: { clientY: number; preventDefault: () => void }) => {\n event.preventDefault();\n const startY = event.clientY;\n const startHeight = promptHeight;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n const nextHeight = startHeight + (moveEvent.clientY - startY);\n setPromptHeight(Math.max(PROMPT_MIN_HEIGHT, nextHeight));\n };\n\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n }, [promptHeight]);\n\n return (\n <AppModal\n open={open}\n onClose={onClose}\n title={title}\n panelClassName=\"w-[550px] max-h-[calc(100vh-4rem)] overflow-hidden\"\n bodyClassName=\"flex min-h-0 flex-1 flex-col overflow-hidden pt-4\"\n panelTestId=\"schedule-task-editor-modal\"\n bodyTestId=\"schedule-task-editor-modal-body\"\n >\n <div className=\"min-h-0 flex-1 space-y-5 overflow-y-auto\">\n <div>\n <label className=\"mb-2 block text-[14px] font-normal leading-5 text-[#101828]\">名称</label>\n <input\n type=\"text\"\n value={editorState.taskName}\n maxLength={64}\n onChange={(event) => setEditorState((current) => ({ ...current, taskName: event.target.value }))}\n className={`w-full px-3 outline-none focus:border-[#4C8DFF] ${INPUT_BOX_CLASS}`}\n data-testid=\"schedule-editor-task-name\"\n />\n </div>\n\n <div>\n <label className=\"mb-2 block text-[14px] font-normal leading-5 text-[#101828]\">提示词</label>\n <div\n className=\"relative rounded-[6px] border border-[rgba(194,194,194,1)] bg-white transition focus-within:border-[rgba(20,118,255,1)]\"\n data-testid=\"schedule-editor-prompt-container\"\n >\n <textarea\n value={editorState.prompt}\n maxLength={1000}\n onChange={(event) => setEditorState((current) => ({ ...current, prompt: event.target.value }))}\n className=\"w-full resize-none border-0 bg-transparent px-3 pt-3 text-[14px] leading-6 text-[#101828] outline-none\"\n style={{ height: `${promptHeight}px`, minHeight: `${PROMPT_MIN_HEIGHT}px`, paddingBottom: `${PROMPT_INFO_ROW_HEIGHT + 12}px`, paddingRight: '24px' }}\n data-testid=\"schedule-editor-prompt\"\n />\n <div className=\"absolute inset-x-0 bottom-0 flex h-6 items-center justify-end gap-2 rounded-b-[6px] bg-white px-3 pr-3 text-[12px] leading-none text-[#667085]\">\n <span data-testid=\"schedule-editor-prompt-count\">{editorState.prompt.length}/1000</span>\n <button\n type=\"button\"\n onMouseDown={handlePromptResizeStart}\n className=\"flex h-4 w-4 cursor-nwse-resize items-end justify-end text-[#667085]\"\n data-testid=\"schedule-editor-prompt-resize-handle\"\n aria-label=\"调整提示词输入框高度\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 10L10 4\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" />\n <path d=\"M7 10L10 7\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n\n <FrequencySection\n editorState={editorState}\n onFrequencyModeChange={handleFrequencyModeChange}\n onWeekdayToggle={handleWeekdayToggle}\n setEditorState={setEditorState}\n />\n\n {SHOW_EFFECTIVE_DATE_RANGE_UI && editorState.frequencyMode !== 'once' ? (\n <div>\n <label className=\"mb-2 block text-[14px] font-normal leading-5 text-[#101828]\">\n 生效日期区间\n <span className=\"ml-1 text-[12px] font-normal text-[#667085]\">(可选,留空表示始终生效)</span>\n </label>\n <PresetSelectField\n value={editorState.effectivePreset}\n onChange={(value) => setEditorState((current) => ({ ...current, effectivePreset: value }))}\n />\n </div>\n ) : null}\n\n <SessionSection\n editorState={editorState}\n onSessionModeChange={handleSessionModeChange}\n setEditorState={setEditorState}\n sessionOptions={sessionOptions}\n sessionsLoading={sessionsLoading}\n sessionsError={sessionsError}\n />\n </div>\n\n <div className=\"flex shrink-0 items-center justify-end gap-3 pt-5\">\n <Button\n variant=\"default\"\n onClick={onClose}\n data-testid=\"schedule-editor-cancel\"\n >\n 取消\n </Button>\n <Button\n variant=\"major\"\n onClick={handleConfirm}\n disabled={!isFormValid || submitting}\n data-testid=\"schedule-editor-confirm\"\n >\n 确定\n </Button>\n </div>\n </AppModal>\n );\n}\n\ninterface FrequencySectionProps {\n editorState: EditorState;\n onFrequencyModeChange: (mode: EditorFrequencyMode) => void;\n onWeekdayToggle: (weekday: string) => void;\n setEditorState: React.Dispatch<React.SetStateAction<EditorState>>;\n}\n\nfunction FrequencySection({ editorState, onFrequencyModeChange, onWeekdayToggle, setEditorState }: FrequencySectionProps) {\n const todayValue = toDateValue(new Date());\n const isOnceToday = editorState.onceDate === todayValue;\n const currentHour = `${new Date().getHours()}`.padStart(2, '0');\n const currentMinute = `${new Date().getMinutes()}`.padStart(2, '0');\n\n return (\n <div>\n <div className=\"mb-2 block text-[14px] font-normal leading-5 text-[#101828]\">执行频率</div>\n <div className=\"flex flex-wrap gap-3\">\n {[\n { value: 'daily' as const, label: '重复' },\n { value: 'interval' as const, label: '按间隔' },\n { value: 'once' as const, label: '单次' },\n ].map((option) => {\n const selected = editorState.frequencyMode === option.value;\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => onFrequencyModeChange(option.value)}\n className={[\n 'inline-flex items-center justify-center rounded-[6px] border px-6 py-[5px] text-[14px] font-normal transition',\n selected\n ? 'border-[1.5px] border-[rgba(20,118,255,1)] bg-[rgba(240,247,255,1)] text-[rgba(25,25,25,1)]'\n : 'border-[rgba(194,194,194,1)] text-[rgba(89,89,89,1)]',\n ].join(' ')}\n data-testid={`schedule-editor-frequency-${option.value}`}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n\n {editorState.frequencyMode === 'daily' ? (\n <div className=\"mt-3 flex items-start gap-3\">\n <TimePickerField\n value={editorState.time}\n onChange={(value) => setEditorState((current) => ({ ...current, time: value }))}\n testIdPrefix=\"schedule-editor-daily-time\"\n />\n <div className=\"flex min-w-0 flex-1 gap-2\">\n {WEEKDAY_OPTIONS.map((option) => {\n const selected = editorState.weekdays.includes(option.value);\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => onWeekdayToggle(option.value)}\n className={[\n 'inline-flex h-7 w-10 items-center justify-center rounded-[6px] border text-[14px] font-normal transition',\n selected\n ? 'border-[1.5px] border-[rgba(20,118,255,1)] bg-[rgba(240,247,255,1)] text-[rgba(25,25,25,1)]'\n : 'border-[rgba(194,194,194,1)] text-[rgba(89,89,89,1)]',\n ].join(' ')}\n data-testid={`schedule-editor-weekday-${option.value}`}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n </div>\n ) : null}\n\n {editorState.frequencyMode === 'interval' ? (\n <div className=\"mt-3 flex flex-wrap items-center gap-3\">\n <span className=\"text-[14px] leading-5 text-[#344054]\">每隔</span>\n <input\n type=\"number\"\n min=\"1\"\n step=\"1\"\n inputMode=\"numeric\"\n value={editorState.intervalValue}\n onChange={(event) => setEditorState((current) => ({ ...current, intervalValue: event.target.value }))}\n className={`w-[132px] px-3 outline-none focus:border-[rgba(20,118,255,1)] ${INPUT_BOX_CLASS}`}\n data-testid=\"schedule-editor-interval-value\"\n />\n <IntervalUnitSelectField\n value={editorState.intervalUnit}\n onChange={(value) => setEditorState((current) => ({ ...current, intervalUnit: value }))}\n />\n </div>\n ) : null}\n\n {editorState.frequencyMode === 'once' ? (\n <div className=\"mt-3 flex flex-col gap-3 sm:flex-row sm:items-start\">\n <div className=\"shrink-0\">\n <DatePickerField\n value={editorState.onceDate}\n onChange={(value) => setEditorState((current) => ({ ...current, onceDate: value }))}\n />\n </div>\n <div className=\"shrink-0\">\n <TimePickerField\n value={editorState.onceTime}\n onChange={(value) => setEditorState((current) => ({ ...current, onceTime: value }))}\n testIdPrefix=\"schedule-editor-once-time\"\n isHourDisabled={(hour) => isOnceToday && hour < currentHour}\n isMinuteDisabled={(hour, minute) => isOnceToday && hour === currentHour && minute < currentMinute}\n />\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\ninterface SessionSectionProps {\n editorState: EditorState;\n onSessionModeChange: (sessionMode: SessionMode) => void;\n setEditorState: React.Dispatch<React.SetStateAction<EditorState>>;\n sessionOptions: SessionSelectOption[];\n sessionsLoading: boolean;\n sessionsError: boolean;\n}\n\nfunction SessionSection({ editorState, onSessionModeChange, setEditorState, sessionOptions, sessionsLoading, sessionsError }: SessionSectionProps) {\n return (\n <div>\n <div className=\"mb-2 block text-[14px] font-normal leading-5 text-[#101828]\">选择会话</div>\n <div className=\"flex flex-wrap gap-3\">\n <button\n type=\"button\"\n onClick={() => onSessionModeChange('existing')}\n className={[\n 'inline-flex items-center justify-center rounded-[6px] border px-6 py-[5px] text-[14px] font-normal transition',\n editorState.sessionMode === 'existing'\n ? 'border-[1.5px] border-[rgba(20,118,255,1)] bg-[rgba(240,247,255,1)] text-[rgba(25,25,25,1)]'\n : 'border-[rgba(194,194,194,1)] text-[rgba(89,89,89,1)]',\n ].join(' ')}\n data-testid=\"schedule-editor-session-existing\"\n >\n 选择已有会话\n </button>\n <button\n type=\"button\"\n onClick={() => onSessionModeChange('new')}\n className={[\n 'inline-flex items-center justify-center rounded-[6px] border px-6 py-[5px] text-[14px] font-normal transition',\n editorState.sessionMode === 'new'\n ? 'border-[1.5px] border-[rgba(20,118,255,1)] bg-[rgba(240,247,255,1)] text-[rgba(25,25,25,1)]'\n : 'border-[rgba(194,194,194,1)] text-[rgba(89,89,89,1)]',\n ].join(' ')}\n data-testid=\"schedule-editor-session-new\"\n >\n 新建会话\n </button>\n </div>\n {editorState.sessionMode === 'existing' ? (\n <div className=\"mt-3\">\n <SessionSelectField\n value={editorState.sessionId}\n onChange={(value) => setEditorState((current) => ({ ...current, sessionId: value }))}\n options={sessionOptions}\n loading={sessionsLoading}\n hasError={sessionsError}\n />\n </div>\n ) : null}\n </div>\n );\n}\n","'use client';\n\nimport { AppModal } from '../../AppModal';\nimport type { ScheduleTemplateDefinition } from '../schedule-template-types';\nimport { Button } from '../../shared/Button';\n\ninterface ScheduleTemplatePickerModalProps {\n open: boolean;\n templates: ScheduleTemplateDefinition[];\n selectedTemplateId: string | null;\n loading?: boolean;\n onClose: () => void;\n onSelect: (templateId: string) => void;\n onConfirm: () => void;\n}\n\nfunction isTemplateSelected(selectedTemplateId: string | null, templateId: string) {\n return selectedTemplateId === templateId;\n}\n\nexport function ScheduleTemplatePickerModal({\n open,\n templates,\n selectedTemplateId,\n loading = false,\n onClose,\n onSelect,\n onConfirm,\n}: ScheduleTemplatePickerModalProps) {\n return (\n <AppModal\n open={open}\n onClose={onClose}\n title=\"选择模板\"\n panelClassName=\"w-[680px] max-w-[92vw]\"\n bodyClassName=\"p-0\"\n panelTestId=\"schedule-template-modal\"\n bodyTestId=\"schedule-template-modal-body\"\n >\n {loading ? (\n <div\n className=\"flex h-[420px] items-center justify-center text-[13px] text-[var(--text-secondary)]\"\n data-testid=\"schedule-template-loading\"\n >\n 正在加载模板...\n </div>\n ) : (\n <>\n <div\n className=\"grid max-h-[420px] grid-cols-2 justify-center gap-4 overflow-y-auto pr-1\"\n data-testid=\"schedule-template-grid\"\n >\n {templates.map((template) => {\n const selected = isTemplateSelected(selectedTemplateId, template.id);\n return (\n <button\n key={template.id}\n type=\"button\"\n className={[\n 'flex h-[74px] w-[300px] items-center gap-3 rounded-[8px] border bg-[rgba(250,250,250,1)] px-4 text-left transition',\n selected\n ? 'border-[1.5px] border-[rgba(20,118,255,1)] bg-[rgba(240,247,255,1)]'\n : 'border-[1px] border-[rgba(194,194,194,1)] hover:border-[rgba(20,118,255,1)]',\n ].join(' ')}\n onClick={() => onSelect(template.id)}\n aria-pressed={selected}\n data-testid={`schedule-template-option-${template.id}`}\n >\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-[8px] bg-[#F5F7FA]\">\n <img src=\"/icons/schedule.svg\" alt=\"\" aria-hidden=\"true\" className=\"h-4 w-4 shrink-0\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-[16px] leading-6 text-[rgba(25,25,25,1)]\">{template.title}</span>\n <span className=\"block truncate whitespace-nowrap text-ellipsis text-[14px] leading-5 text-[rgba(25,25,25,0.6)]\">\n {template.description}\n </span>\n </span>\n </button>\n );\n })}\n </div>\n\n <div className=\"mt-5 flex items-center justify-end gap-2\">\n <Button variant=\"default\" onClick={onClose} data-testid=\"schedule-template-cancel\">\n 取消\n </Button>\n <Button variant=\"major\" onClick={onConfirm} disabled={!selectedTemplateId} data-testid=\"schedule-template-confirm\">\n 确定\n </Button>\n </div>\n </>\n )}\n </AppModal>\n );\n}\n","'use client';\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport type { ScheduledTaskItem } from './types';\nimport type { ScheduleRunItem } from './types';\nimport type { ScheduleTaskEditability } from './utils';\nimport type { ScheduleTemplateDefinition, ScheduleTaskDraft } from './schedule-template-types';\nimport { EmptyDataState } from '../shared/EmptyDataState';\nimport { CenteredLoadingState } from '../shared/CenteredLoadingState';\nimport { Toolbar } from './components/Toolbar';\nimport { TaskList } from './components/TaskList';\nimport { CalendarView } from './components/CalendarView';\nimport { EmptyState } from './components/EmptyState';\nimport { DetailModal } from './components/DetailModal';\nimport { DeleteModal } from './components/DeleteModal';\nimport { ScheduleTaskEditorModal } from './components/ScheduleTaskEditorModal';\nimport { ScheduleTemplatePickerModal } from './components/ScheduleTemplatePickerModal';\n\ntype ViewMode = 'card' | 'calendar';\n\ntype ScheduledTaskPanelViewProps = {\n title: string;\n viewMode: ViewMode;\n weekRangeText: string;\n baseDate: Date;\n weekOffset: number;\n tasks: ScheduledTaskItem[];\n calendarRuns: ScheduleRunItem[];\n isLoading: boolean;\n isRunsLoading: boolean;\n togglingTaskIds: Set<string>;\n taskIconMaskStyle: CSSProperties;\n taskEditabilityById: Map<string, ScheduleTaskEditability>;\n selectedTask: ScheduledTaskItem | null;\n selectedTaskEditability: ScheduleTaskEditability | null;\n deleteTargetTask: ScheduledTaskItem | null;\n deleteDialogSourceView: 'card' | 'calendar';\n isDeletingTask: boolean;\n templatePickerOpen: boolean;\n templates: ScheduleTemplateDefinition[];\n templatesLoading: boolean;\n selectedTemplateId: string | null;\n taskEditorOpen: boolean;\n editorDraft: ScheduleTaskDraft | null;\n editingTask: ScheduledTaskItem | null;\n emptyTemplateSectionExpanded: boolean;\n emptyStateTemplateCards: ScheduleTemplateDefinition[];\n children?: ReactNode;\n onChangeView: (next: ViewMode) => void;\n onPrevWeek: () => void;\n onNextWeek: () => void;\n onResetWeek: () => void;\n onCreateFromConversation: () => void;\n onCreateFromTemplate: () => void;\n onCreateCustom: () => void;\n onSelectTask: (task: ScheduledTaskItem) => void;\n onEditTask: (task: ScheduledTaskItem) => void;\n onEditTaskInConversation: (task: ScheduledTaskItem) => void;\n onToggleTask: (task: ScheduledTaskItem) => Promise<void> | void;\n onDeleteTask: (task: ScheduledTaskItem) => void;\n onCloseDetailModal: () => void;\n onCloseDeleteDialog: () => void;\n onConfirmDelete: () => void;\n onCloseTemplatePicker: () => void;\n onSelectTemplate: (templateId: string | null) => void;\n onConfirmTemplateSelection: () => void;\n onCloseTaskEditor: () => void;\n onConfirmTaskEditor: (draft: ScheduleTaskDraft) => void;\n onCreateFromTemplateCard: (templateId: string) => void;\n onToggleEmptyTemplates: () => void;\n};\n\nexport function SchedulePanelView({\n title,\n viewMode,\n weekRangeText,\n baseDate,\n weekOffset,\n tasks,\n calendarRuns,\n isLoading,\n isRunsLoading,\n togglingTaskIds,\n taskIconMaskStyle,\n taskEditabilityById,\n selectedTask,\n selectedTaskEditability,\n deleteTargetTask,\n deleteDialogSourceView,\n isDeletingTask,\n templatePickerOpen,\n templates,\n templatesLoading,\n selectedTemplateId,\n taskEditorOpen,\n editorDraft,\n editingTask,\n emptyTemplateSectionExpanded,\n emptyStateTemplateCards,\n onChangeView,\n onPrevWeek,\n onNextWeek,\n onResetWeek,\n onCreateFromConversation,\n onCreateFromTemplate,\n onCreateCustom,\n onSelectTask,\n onEditTask,\n onEditTaskInConversation,\n onToggleTask,\n onDeleteTask,\n onCloseDetailModal,\n onCloseDeleteDialog,\n onConfirmDelete,\n onCloseTemplatePicker,\n onSelectTemplate,\n onConfirmTemplateSelection,\n onCloseTaskEditor,\n onConfirmTaskEditor,\n onCreateFromTemplateCard,\n onToggleEmptyTemplates,\n}: ScheduledTaskPanelViewProps) {\n const isCalendarLoading = viewMode === 'calendar' && isRunsLoading && tasks.length === 0;\n const showEmptyState = !isLoading && !isCalendarLoading && tasks.length === 0 && !(viewMode === 'calendar' && calendarRuns.length > 0);\n const showCalendarEmptyState = !isLoading && isCalendarLoading && tasks.length === 0;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col gap-6\">\n <div className=\"flex flex-col gap-6\">\n <h1 className=\"ui-page-title\">{title}</h1>\n <Toolbar\n viewMode={viewMode}\n weekRangeText={weekRangeText}\n onChangeView={onChangeView}\n onPrevWeek={onPrevWeek}\n onNextWeek={onNextWeek}\n onResetWeek={onResetWeek}\n onCreateFromConversation={onCreateFromConversation}\n onCreateFromTemplate={onCreateFromTemplate}\n onCreateCustom={onCreateCustom}\n />\n </div>\n\n <div className=\"ui-panel flex min-h-0 flex-1 flex-col border-0 shadow-none\">\n {isLoading || showCalendarEmptyState ? (\n <div className=\"flex min-h-[320px] items-center justify-center\">\n <CenteredLoadingState />\n </div>\n ) : viewMode === 'calendar' && tasks.length === 0 && calendarRuns.length === 0 ? (\n <div className=\"flex flex-1 items-center justify-center\">\n <div className=\"text-center\">\n <EmptyDataState title=\"本周暂无执行记录\" />\n </div>\n </div>\n ) : showEmptyState ? (\n <EmptyState\n title=\"暂无定时任务\"\n description=\"暂无数据,您可以点击创建按钮新增定时任务\"\n showTemplates={true}\n templateCards={emptyStateTemplateCards}\n onTemplateClick={onCreateFromTemplateCard}\n emptyTemplateSectionExpanded={emptyTemplateSectionExpanded}\n onToggleTemplates={onToggleEmptyTemplates}\n />\n ) : viewMode === 'card' ? (\n <TaskList\n tasks={tasks}\n taskIconMaskStyle={taskIconMaskStyle}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n isModalOpen={!!(deleteTargetTask || selectedTask || taskEditorOpen || templatePickerOpen)}\n />\n ) : (\n <CalendarView\n tasks={tasks}\n runs={calendarRuns}\n baseDate={baseDate}\n weekOffset={weekOffset}\n onSelectTask={onSelectTask}\n onEditTask={onEditTask}\n onEditTaskInConversation={onEditTaskInConversation}\n onToggleTask={onToggleTask}\n onDeleteTask={onDeleteTask}\n togglingTaskIds={togglingTaskIds}\n taskEditabilityById={taskEditabilityById}\n />\n )}\n </div>\n\n <DetailModal\n task={selectedTask}\n editability={selectedTaskEditability}\n onClose={onCloseDetailModal}\n onEdit={onEditTask}\n onEditInConversation={onEditTaskInConversation}\n />\n\n <DeleteModal\n task={deleteTargetTask}\n isDeleting={isDeletingTask}\n sourceView={deleteDialogSourceView}\n onClose={onCloseDeleteDialog}\n onConfirm={onConfirmDelete}\n />\n\n <ScheduleTemplatePickerModal\n open={templatePickerOpen}\n templates={templates}\n selectedTemplateId={selectedTemplateId}\n loading={templatesLoading}\n onClose={onCloseTemplatePicker}\n onSelect={onSelectTemplate}\n onConfirm={onConfirmTemplateSelection}\n />\n\n <ScheduleTaskEditorModal\n open={taskEditorOpen}\n draft={editorDraft}\n title={editingTask ? '编辑定时任务' : '创建定时任务'}\n onClose={onCloseTaskEditor}\n onConfirm={onConfirmTaskEditor}\n />\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useChatStore } from '@/stores/chatStore';\nimport { useToastStore } from '@/stores/toastStore';\nimport { loadScheduleTemplateCatalog } from './schedule-template-catalog';\nimport { createScheduleTaskDraft, createEmptyCustomScheduleTaskDraft } from './schedule-template-catalog';\nimport type { ScheduleTemplateDefinition } from './schedule-template-types';\nimport type { ScheduledTaskItem } from './types';\nimport { formatWeekRangeText } from './utils';\nimport { useTaskState } from './hooks/useTaskState';\nimport { useTaskActions } from './hooks/useTaskActions';\nimport { useTaskCalendar } from './hooks/useTaskCalendar';\nimport { useTaskModal } from './hooks/useTaskModal';\nimport { SchedulePanelView } from './SchedulePanelView';\n\ntype ScheduledTaskPanelProps = {\n onCreateTask?: () => void;\n};\n\nconst TASK_TIME_ICON = '/icons/schedule.svg';\n\nexport function SchedulePanel({ onCreateTask }: ScheduledTaskPanelProps) {\n const addToast = useToastStore((state) => state.addToast);\n const setPendingChatInsert = useChatStore((state) => state.setPendingChatInsert);\n\n const [viewMode, setViewMode] = useState<'card' | 'calendar'>('calendar');\n const [weekOffset, setWeekOffset] = useState(0);\n const [templates, setTemplates] = useState<ScheduleTemplateDefinition[]>([]);\n const [templatesLoading, setTemplatesLoading] = useState(false);\n const [selectedTemplateId, setSelectedTemplateId] = useState<string | null>(null);\n const [emptyTemplateSectionExpanded, setEmptyTemplateSectionExpanded] = useState(true);\n\n const baseDate = new Date();\n\n const { tasks, calendarRuns, isLoading, isRunsLoading, taskEditabilityById, reloadTasks, setTasks } = useTaskState({\n viewMode,\n weekOffset,\n });\n\n const { weekRangeText } = useTaskCalendar({\n baseDate,\n weekOffset,\n tasks,\n runs: calendarRuns,\n });\n\n const {\n selectedTask,\n setSelectedTask,\n deleteTargetTask,\n deleteDialogSourceView,\n templatePickerOpen,\n setTemplatePickerOpen,\n taskEditorOpen,\n editorDraft,\n editingTask,\n closeTaskEditor,\n openEditTask,\n openCreateTask,\n openDeleteTask,\n closeDeleteDialog,\n selectedTaskEditability,\n getEditingTask,\n } = useTaskModal();\n\n const {\n togglingTaskIds,\n isDeletingTask,\n handleToggleTask,\n handleDeleteConfirm,\n handleTaskEditorConfirm,\n handleEditTaskInConversation,\n } = useTaskActions({ reloadTasks, setTasks, getEditingTask, closeEditor: closeTaskEditor });\n\n const handleCreateFromConversation = () => {\n onCreateTask?.();\n };\n\n const handleCreateFromTemplate = () => {\n setSelectedTemplateId(null);\n setTemplatePickerOpen(true);\n };\n\n const handleCreateCustom = () => {\n openCreateTask(createEmptyCustomScheduleTaskDraft());\n };\n\n const confirmTemplateSelection = () => {\n if (!selectedTemplateId) return;\n const template = templates.find((item) => item.id === selectedTemplateId);\n if (!template) return;\n\n const draft = createScheduleTaskDraft(template);\n openCreateTask(draft);\n setTemplatePickerOpen(false);\n };\n\n const handleCreateFromTemplateCard = (templateId: string) => {\n const template = templates.find((item) => item.id === templateId);\n if (!template) {\n setSelectedTemplateId(templateId);\n setTemplatePickerOpen(true);\n return;\n }\n const draft = createScheduleTaskDraft(template);\n setSelectedTemplateId(templateId);\n openCreateTask(draft);\n };\n\n const handleEditTask = (task: ScheduledTaskItem) => {\n const success = openEditTask(task);\n if (!success) {\n addToast({\n type: 'error',\n title: '暂不支持编辑',\n message: '该定时任务仅支持通过对话进行编辑',\n duration: 2600,\n });\n }\n };\n\n const handleSelectTask = (task: ScheduledTaskItem) => {\n setSelectedTask(task);\n };\n\n const handleDeleteTask = (task: ScheduledTaskItem) => {\n openDeleteTask(task, viewMode);\n };\n\n const emptyStateTemplateCards = useMemo(() => templates.slice(0, 4), [templates]);\n\n useEffect(() => {\n if (viewMode !== 'card') return;\n if (tasks.length !== 0) return;\n if (templates.length > 0) return;\n\n let cancelled = false;\n\n const loadPreviewTemplates = async () => {\n try {\n const nextTemplates = await loadScheduleTemplateCatalog();\n if (cancelled) return;\n setTemplates(nextTemplates);\n } catch {\n // keep empty preview area on failure\n }\n };\n\n void loadPreviewTemplates();\n return () => {\n cancelled = true;\n };\n }, [tasks.length, templates.length, viewMode]);\n\n useEffect(() => {\n if (!templatePickerOpen) return;\n\n let cancelled = false;\n\n const loadTemplates = async () => {\n setTemplatesLoading(true);\n try {\n const nextTemplates = await loadScheduleTemplateCatalog();\n if (cancelled) return;\n setTemplates(nextTemplates);\n } finally {\n if (!cancelled) {\n setTemplatesLoading(false);\n }\n }\n };\n\n void loadTemplates();\n\n return () => {\n cancelled = true;\n };\n }, [templatePickerOpen]);\n\n const taskIconMaskStyle = useMemo(\n () =>\n ({\n WebkitMaskImage: `url(${TASK_TIME_ICON})`,\n maskImage: `url(${TASK_TIME_ICON})`,\n WebkitMaskRepeat: 'no-repeat',\n maskRepeat: 'no-repeat',\n WebkitMaskPosition: 'center',\n maskPosition: 'center',\n WebkitMaskSize: 'contain',\n maskSize: 'contain',\n backgroundColor: 'var(--text-muted)',\n }) as const,\n [],\n );\n\n return (\n <SchedulePanelView\n title=\"定时任务\"\n viewMode={viewMode}\n weekRangeText={weekRangeText}\n baseDate={baseDate}\n weekOffset={weekOffset}\n tasks={tasks}\n calendarRuns={calendarRuns}\n isLoading={isLoading}\n isRunsLoading={isRunsLoading}\n togglingTaskIds={togglingTaskIds}\n taskIconMaskStyle={taskIconMaskStyle}\n taskEditabilityById={taskEditabilityById}\n selectedTask={selectedTask}\n selectedTaskEditability={selectedTaskEditability}\n deleteTargetTask={deleteTargetTask}\n deleteDialogSourceView={deleteDialogSourceView}\n isDeletingTask={isDeletingTask}\n templatePickerOpen={templatePickerOpen}\n templates={templates}\n templatesLoading={templatesLoading}\n selectedTemplateId={selectedTemplateId}\n taskEditorOpen={taskEditorOpen}\n editorDraft={editorDraft}\n editingTask={editingTask}\n emptyTemplateSectionExpanded={emptyTemplateSectionExpanded}\n emptyStateTemplateCards={emptyStateTemplateCards}\n onChangeView={setViewMode}\n onPrevWeek={() => setWeekOffset((prev) => prev - 1)}\n onNextWeek={() => setWeekOffset((prev) => prev + 1)}\n onResetWeek={() => setWeekOffset(0)}\n onCreateFromConversation={handleCreateFromConversation}\n onCreateFromTemplate={handleCreateFromTemplate}\n onCreateCustom={handleCreateCustom}\n onSelectTask={handleSelectTask}\n onEditTask={handleEditTask}\n onEditTaskInConversation={handleEditTaskInConversation}\n onToggleTask={handleToggleTask}\n onDeleteTask={handleDeleteTask}\n onCloseDetailModal={() => setSelectedTask(null)}\n onCloseDeleteDialog={closeDeleteDialog}\n onConfirmDelete={() => handleDeleteConfirm(deleteTargetTask, closeDeleteDialog)}\n onCloseTemplatePicker={() => setTemplatePickerOpen(false)}\n onSelectTemplate={setSelectedTemplateId}\n onConfirmTemplateSelection={confirmTemplateSelection}\n onCloseTaskEditor={closeTaskEditor}\n onConfirmTaskEditor={handleTaskEditorConfirm}\n onCreateFromTemplateCard={handleCreateFromTemplateCard}\n onToggleEmptyTemplates={() => setEmptyTemplateSectionExpanded((prev) => !prev)}\n />\n );\n}\n","/*\n * *\n * * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.\n *\n */\n\nimport { useNavigate } from 'react-router-dom';\nimport { useMemo } from 'react';\nimport { QUICK_ACTIONS } from '@/config/quick-actions';\nimport { useChatStore } from '@/stores/chatStore';\nimport { SchedulePanel } from '@/components/schedule/SchedulePanel';\n\nconst HOME_DRAFT_THREAD_ID = '__new__';\nconst QUICK_ACTION_TOKEN_PREFIX = '[[quick_action:';\nconst QUICK_ACTION_TOKEN_SUFFIX = ']]';\nconst SCHEDULED_TASK_QUICK_ACTION_ICON = '/icons/schedule.svg';\n\nfunction buildScheduledTaskQuickActionInsertText(): string | null {\n const scheduledTaskAction = QUICK_ACTIONS.find((action) => action.icon === SCHEDULED_TASK_QUICK_ACTION_ICON);\n const label = scheduledTaskAction?.label?.trim();\n if (!label) return null;\n return `${QUICK_ACTION_TOKEN_PREFIX}${label}${QUICK_ACTION_TOKEN_SUFFIX} `;\n}\n\nexport default function SchedulePage() {\n const navigate = useNavigate();\n const setPendingChatInsert = useChatStore((s) => s.setPendingChatInsert);\n const scheduledTaskQuickActionInsertText = useMemo(() => buildScheduledTaskQuickActionInsertText(), []);\n\n const handleCreateTask = () => {\n if (!scheduledTaskQuickActionInsertText) return;\n setPendingChatInsert({\n threadId: HOME_DRAFT_THREAD_ID,\n text: scheduledTaskQuickActionInsertText,\n });\n navigate('/');\n };\n\n return (\n <div className=\"h-full overflow-y-auto ui-shell-surface px-8 py-8\">\n <SchedulePanel onCreateTask={handleCreateTask} />\n </div>\n );\n}\n"],"names":["STATIC_SCHEDULE_TEMPLATE_CATALOG","loadScheduleTemplateCatalog","createScheduleTaskDraft","template","createEmptyCustomScheduleTaskDraft","INTERVAL_MS_BY_UNIT","INTERVAL_UNIT_LABELS","intervalValueToMs","value","unit","normalizeIntervalMs","ms","formatIntervalFrequency","normalized","WEEKDAY_NAME_TO_NUM","MONTH_NAME_TO_NUM","WEEKDAY_LABELS","LIST_SEPARATOR","formatClock","hour","minute","second","period","hour12","minuteText","secondText","parseToken","rawToken","options","token","numeric","_a","dedupeKeepOrder","values","seen","result","parseCronField","rawValue","raw","upper","part","segment","stepMatch","step","left","rangeMatch","from","to","start","single","isAny","field","formatValues","formatMonthText","formatDayOfMonthText","formatWeekdaySpan","toLabel","formatSecondText","formatMinuteText","secondSuffix","hasExplicitSeconds","text","formatDatePart","month","dayOfMonth","dayOfWeek","monthAny","dayOfMonthAny","dayOfWeekAny","dayOfWeekText","dayOfMonthText","monthText","formatFixedTimesForHours","hours","formatTimePart","hasDateConstraint","hourAny","minuteAny","base","secondValue","prefix","times","formatCronFrequency","expression","parts","secondRaw","minuteRaw","hourRaw","dayOfMonthRaw","monthRaw","dayOfWeekRaw","datePart","timePart","WEEKDAY_ZH","WEEKDAY_EN","pad2","toHm","date","startOfDay","out","compareDateOnly","a","b","av","bv","parseCron","isSameDate","localDateKey","isValidDate","isPastDay","now","hasStepSyntax","parseCalendarToken","map","num","matchField","rawField","min","max","normalize","items","item","rangeStart","rangeEnd","fromRaw","toRaw","startRaw","singleRaw","expandNoStepField","_","idx","i","n","expandFieldWithStep","end","classifyCronDisplayMode","parsed","seconds","cronTimesForDay","startOfWeekMonday","baseDate","weekOffset","jsDay","mondayOffset","getCalendarWeekRange","formatWeekRangeText","computeNextCronExecutionAt","lookaheadDays","secondValues","minuteValues","hourValues","cursor","cursorStartDay","dayOffset","day","cronMatchesDay","minHour","minMinute","minSecond","candidate","getNextExecutionAt","trigger","fireAt","stateForRunOutcome","outcome","runStatusText","state","runSummaryKey","taskId","buildRunSummaryMap","runs","summaries","run","startedAt","key","existing","getDailyRunSummary","triggerForRun","task","taskNameForRun","snapshotLabel","_b","isRecurringTrigger","runTimeLabel","getSingleOccurrenceRunSummary","occurrenceAt","runSummary","computeSingleOccurrenceState","matchedRunSummary","recurringTimeRangeForCron","computeNextIntervalTimeLabel","dayDate","latestRunAt","computeNextCronTimeLabel","minutes","currentMinute","candidates","h","m","stateLabel","computeRecurringState","dateCmp","makeRecurringOccurrence","parsedCron","latestRunState","lastExecutionText","nextHm","isToday","shouldShowNext","dom","dow","monthMatch","domMatch","dowMatch","v","expandFixedCronForWeek","days","runSummaries","time","expandOnceForWeek","timeLabelStartMinutes","label","match","compareOccurrence","modeOrder","startDiff","nameOrder","buildRunsByDay","monday","weekStart","dayMs","runDate","dayStart","index","bucket","appendRunBackedOccurrences","taskById","opts","recurringTaskIds","singleRuns","summary","isLegacyRecurringWithoutSnapshot","buildCalendarWeek","tasks","runsByDay","applicableDays","dayRuns","SCHEDULE_TASK_EDIT_UNSUPPORTED_REASON","formatDateTimeLocal","parseCronWeekdayField","right","toDraftFrequency","localTimezone","secondField","minuteField","hourField","dayOfMonthField","monthField","dayOfWeekField","normalizedDayOfMonth","normalizedMonth","normalizedDayOfWeek","weekdays","resolveLocalTimezone","getScheduleTaskEditability","frequency","extractThreadId","subjectKey","formatFrequency","toViewTask","id","threadId","threadName","isOnce","fireAtTime","_d","_c","_f","_e","_g","_h","_i","MAX_RUNS_PAGES","useTaskState","viewMode","setTasks","useState","calendarRuns","setCalendarRuns","isLoading","setIsLoading","isRunsLoading","setIsRunsLoading","loadTasks","useCallback","tasksRes","apiFetch","mapped","useEffect","cancelled","weekEnd","since","until","allRuns","seenCursors","pageCount","query","res","payload","taskEditabilityById","useMemo","unsupported","resolveTaskIdentifier","buildScheduleTaskChatEditText","parseTimeParts","hourText","parseDateTimeToTimestamp","dateText","timeText","yearText","dayText","toCronWeekday","buildTaskTrigger","draft","timezoneOverride","timezone","buildCreateScheduleTaskPayload","deliveryThreadId","useTaskActions","reloadTasks","getEditingTask","closeEditor","navigate","useNavigate","addToast","useToastStore","setPendingChatInsert","useChatStore","togglingTaskIds","setTogglingTaskIds","isDeletingTask","setIsDeletingTask","handleToggleTask","apiTaskId","targetEffectiveEnabled","nextEnabled","prev","clearOverrideRes","latest","changedTask","next","handleDeleteConfirm","deleteTargetTask","onSuccess","taskName","handleTaskEditorConfirm","_editingTask","editingTask","isEditing","createdNewThread","createThreadRes","createdThread","editTimezone","editRes","createRes","error","handleEditTaskInConversation","useTaskCalendar","weekRangeText","weekRange","useTaskModal","selectedTask","setSelectedTask","setDeleteTargetTask","deleteDialogSourceView","setDeleteDialogSourceView","templatePickerOpen","setTemplatePickerOpen","taskEditorOpen","setTaskEditorOpen","editorDraft","setEditorDraft","setEditingTask","closeTaskEditor","openEditTask","editability","openCreateTask","openDeleteTask","sourceView","closeDeleteDialog","selectedTaskEditability","Toolbar","onChangeView","onPrevWeek","onNextWeek","onResetWeek","onCreateFromConversation","onCreateFromTemplate","onCreateCustom","isCreateMenuOpen","setIsCreateMenuOpen","createMenuRef","useRef","handlePointerDown","event","jsxs","jsx","ViewToggle","WeekRangeSwitcher","MaskIcon","ScheduledTaskUnsupportedEditTooltip","children","reason","onGoEdit","className","buttonTestId","content","OverflowTooltip","TaskCard","taskIconMaskStyle","onSelectTask","onEditTask","onEditTaskInConversation","onToggleTask","onDeleteTask","isToggling","modalOpen","taskSortMeta","nextExecution","TaskList","isModalOpen","sortedTasks","meta","MENU_WIDTH","MENU_HEIGHT","MENU_OFFSET","MENU_VIEWPORT_PADDING","ACTION_MENU_ITEM_CLASS","ACTION_MENU_DELETE_ITEM_CLASS","AGENT_CARD_MENU_BUTTON_CLASS","AGENT_CARD_MENU_BUTTON_ACTIVE_CLASS","AGENT_CARD_MENU_BUTTON_IDLE_CLASS","stateConfig","CardActions","occurrenceKey","openMenuKey","menuPosition","onOpenMenu","onCloseMenu","canOperate","menuOpen","RecurringTaskCard","cfg","canSelect","SingleTaskCard","DayColumn","today","CalendarView","setOpenMenuKey","setMenuPosition","computeMenuPosition","triggerRect","preferredLeft","canOpenRight","fallbackLeft","desiredLeft","minLeft","maxLeft","belowTop","preferredTop","minTop","maxTop","onPointerDown","target","onKeyDown","EmptyState","title","description","showTemplates","templateCards","onTemplateClick","emptyTemplateSectionExpanded","onToggleTemplates","EmptyDataState","DetailModal","onClose","onEdit","onEditInConversation","AppModal","DeleteModal","isDeleting","onConfirm","ALL_WEEKDAYS","WEEKDAY_OPTIONS","INTERVAL_UNIT_OPTIONS","NEW_SESSION_ID","HOURS","MINUTES","PROMPT_MIN_HEIGHT","PROMPT_DEFAULT_HEIGHT","PROMPT_INFO_ROW_HEIGHT","INPUT_BOX_CLASS","normalizeTimeValue","trimSeconds","formatDateTime","year","formatDateDisplay","parseDateValue","toDateValue","addMonths","amount","addYears","formatCalendarMonthLabel","splitTimeValue","joinTimeValue","parsePositiveInteger","addPresetRange","preset","buildEffectiveTimeFromPreset","sortWeekdays","getDefaultSessionId","sessionMode","useResponsiveDropdownLayout","open","containerRef","panelPlacement","setPanelPlacement","panelMaxHeight","setPanelMaxHeight","scrollableMaxHeight","setScrollableMaxHeight","useLayoutEffect","updatePanelLayout","container","rect","viewportHeight","gap","safeMargin","spaceBelow","spaceAbove","openUpward","availableHeight","useDropdownPortalPosition","panelWidth","panelPosition","setPanelPosition","updatePanelPosition","handleViewportChange","TimePickerField","onChange","testIdPrefix","isHourDisabled","isMinuteDisabled","setOpen","draftHour","setDraftHour","draftMinute","setDraftMinute","panelRef","handleDocumentClick","getFirstAvailableHour","getFirstAvailableMinute","getNormalizedDraftTime","nextHour","nextMinute","current","createPortal","selected","disabled","CALENDAR_WEEKDAY_LABELS","buildCalendarDayCells","viewDate","selectedValue","monthStart","gridStart","todayValue","DatePickerField","calendarGridMaxHeight","setCalendarGridMaxHeight","selectedDate","setViewDate","calendarDays","minimumPanelHeight","reservedPanelHeight","PickerFieldButton","placeholder","onClick","testId","IntervalUnitSelectField","option","resolveAvatarUrl","rawAvatar","avatar","API_URL","SessionSelectField","loading","hasError","agents","useAgentData","agentById","agent","fallbackAvatar","displayOptions","participants","participantNames","participantId","name","subtitle","avatarSources","formatRelativeTime","Fragment","createEditorState","baseState","buildNormalizedDraft","normalizedTime","effectiveTime","sortedWeekdays","useEditorState","initialDraft","editorState","setEditorState","resetEditorState","handleWeekdayToggle","weekday","exists","handleFrequencyModeChange","mode","handleSessionModeChange","useFormValidation","intervalValue","currentHour","useSessionOptions","sessionOptions","setSessionOptions","sessionsLoading","setSessionsLoading","sessionsError","setSessionsError","loadThreads","data","thread","normalizeStoredThreadTitleOrNull","ScheduleTaskEditorModal","promptHeight","setPromptHeight","submitting","setSubmitting","isFormValid","handleConfirm","handlePromptResizeStart","startY","startHeight","handleMouseMove","moveEvent","nextHeight","handleMouseUp","FrequencySection","SessionSection","Button","onFrequencyModeChange","onWeekdayToggle","isOnceToday","onSessionModeChange","isTemplateSelected","selectedTemplateId","templateId","ScheduleTemplatePickerModal","templates","onSelect","SchedulePanelView","templatesLoading","emptyStateTemplateCards","onCloseDetailModal","onCloseDeleteDialog","onConfirmDelete","onCloseTemplatePicker","onSelectTemplate","onConfirmTemplateSelection","onCloseTaskEditor","onConfirmTaskEditor","onCreateFromTemplateCard","onToggleEmptyTemplates","isCalendarLoading","showEmptyState","showCalendarEmptyState","CenteredLoadingState","TASK_TIME_ICON","SchedulePanel","onCreateTask","setViewMode","setWeekOffset","setTemplates","setTemplatesLoading","setSelectedTemplateId","setEmptyTemplateSectionExpanded","handleCreateFromConversation","handleCreateFromTemplate","handleCreateCustom","confirmTemplateSelection","handleCreateFromTemplateCard","handleEditTask","handleSelectTask","handleDeleteTask","nextTemplates","HOME_DRAFT_THREAD_ID","QUICK_ACTION_TOKEN_PREFIX","QUICK_ACTION_TOKEN_SUFFIX","SCHEDULED_TASK_QUICK_ACTION_ICON","buildScheduledTaskQuickActionInsertText","scheduledTaskAction","QUICK_ACTIONS","action","SchedulePage","s","scheduledTaskQuickActionInsertText","handleCreateTask"],"mappings":"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"}
|