@yancyyu/openhermit 1.6.37 → 1.6.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-renderer/assets/ProjectEditorOverlay-krO5vQxX.js +58 -0
- package/dist-renderer/assets/{TeamGraphOverlay-DYT3bwFR.js → TeamGraphOverlay-DqhQzcTr.js} +1 -1
- package/dist-renderer/assets/{_basePickBy-Dbt_EU-e.js → _basePickBy-B7kSYPxr.js} +1 -1
- package/dist-renderer/assets/{_baseUniq-DWo68sXI.js → _baseUniq-CnjxqwAk.js} +1 -1
- package/dist-renderer/assets/{arc-DXH1iZQK.js → arc-CLeZuINP.js} +1 -1
- package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-cjffS2Qr.js → architectureDiagram-VXUJARFQ-QKtqaqdY.js} +1 -1
- package/dist-renderer/assets/{blockDiagram-VD42YOAC-BKdZF02Y.js → blockDiagram-VD42YOAC-BqdrzO_f.js} +1 -1
- package/dist-renderer/assets/{c4Diagram-YG6GDRKO-CN27pqaI.js → c4Diagram-YG6GDRKO-gwPlCxDC.js} +1 -1
- package/dist-renderer/assets/channel-DpMHF50r.js +1 -0
- package/dist-renderer/assets/{chunk-4BX2VUAB-CXPCI7g_.js → chunk-4BX2VUAB-C6XLurL4.js} +1 -1
- package/dist-renderer/assets/{chunk-55IACEB6-BGAXQZRC.js → chunk-55IACEB6-Ds6quhEP.js} +1 -1
- package/dist-renderer/assets/{chunk-B4BG7PRW-TPDaA_KQ.js → chunk-B4BG7PRW-5UlA1_e9.js} +1 -1
- package/dist-renderer/assets/{chunk-DI55MBZ5-D1ADe_tq.js → chunk-DI55MBZ5-ywFrqIsY.js} +1 -1
- package/dist-renderer/assets/{chunk-FMBD7UC4-Beimtg3a.js → chunk-FMBD7UC4-C7ifUA17.js} +1 -1
- package/dist-renderer/assets/{chunk-QN33PNHL-OjNBu854.js → chunk-QN33PNHL-BxGCo80U.js} +1 -1
- package/dist-renderer/assets/{chunk-QZHKN3VN-DinqvbH8.js → chunk-QZHKN3VN-B2CuaZs6.js} +1 -1
- package/dist-renderer/assets/{chunk-TZMSLE5B-BfFtlPSZ.js → chunk-TZMSLE5B-Ds1hInvp.js} +1 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-CBYCBVRl.js +1 -0
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-CBYCBVRl.js +1 -0
- package/dist-renderer/assets/clone-DcMF6Psb.js +1 -0
- package/dist-renderer/assets/{cose-bilkent-S5V4N54A-D9z9Dgt7.js → cose-bilkent-S5V4N54A-Cz1GVtLp.js} +1 -1
- package/dist-renderer/assets/{dagre-6UL2VRFP-n1g-DhEE.js → dagre-6UL2VRFP-BrmR-P4h.js} +1 -1
- package/dist-renderer/assets/{diagram-PSM6KHXK-BvxFq-BE.js → diagram-PSM6KHXK-DbNjC5Rg.js} +1 -1
- package/dist-renderer/assets/{diagram-QEK2KX5R-wVnJuwza.js → diagram-QEK2KX5R-qkRX5_Mq.js} +1 -1
- package/dist-renderer/assets/{diagram-S2PKOQOG-B707WJQw.js → diagram-S2PKOQOG-CyL5rCv2.js} +1 -1
- package/dist-renderer/assets/{erDiagram-Q2GNP2WA-C-_1dGHs.js → erDiagram-Q2GNP2WA-Dox3-bA5.js} +1 -1
- package/dist-renderer/assets/{flowDiagram-NV44I4VS-CMTSi3H6.js → flowDiagram-NV44I4VS-BtkaxlDL.js} +1 -1
- package/dist-renderer/assets/{ganttDiagram-JELNMOA3-DZ0bNrAA.js → ganttDiagram-JELNMOA3-Dhy_d9GK.js} +1 -1
- package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-DNVfGooQ.js → gitGraphDiagram-V2S2FVAM-B5XRhIQA.js} +1 -1
- package/dist-renderer/assets/{graph-865j_tM_.js → graph-CsoEwUhS.js} +1 -1
- package/dist-renderer/assets/{index-C_F9N5x-.js → index-BWPWmJNo.js} +1 -1
- package/dist-renderer/assets/{index-LwDIsXJN.js → index-Bu2R-Se7.js} +586 -740
- package/dist-renderer/assets/index-CnWV3BhG.css +32 -0
- package/dist-renderer/assets/{index-DuUaf8at.js → index-D-3KgskL.js} +1 -1
- package/dist-renderer/assets/{index-BTx1nc4T.js → index-DGEBzLNT.js} +1 -1
- package/dist-renderer/assets/{index-2EW-eu3q.js → index-NhHNs2Oo.js} +1 -1
- package/dist-renderer/assets/{index-4dEMStJj.js → index-h17WuEyf.js} +1 -1
- package/dist-renderer/assets/{infoDiagram-HS3SLOUP-CyqtElLq.js → infoDiagram-HS3SLOUP-hMGmNojH.js} +1 -1
- package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-BvjQ0Hm0.js → journeyDiagram-XKPGCS4Q-DXV2rBDl.js} +1 -1
- package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-CJJ-k0zT.js → kanban-definition-3W4ZIXB7-Bf99WLRy.js} +1 -1
- package/dist-renderer/assets/{layout-CnV6rQAG.js → layout-C3XWrpwo.js} +1 -1
- package/dist-renderer/assets/{linear-Cw3UQgyX.js → linear-OEEcn8KN.js} +1 -1
- package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-C5tDaGSK.js → mindmap-definition-VGOIOE7T-Dpi3S2x4.js} +1 -1
- package/dist-renderer/assets/{pieDiagram-ADFJNKIX-CiIpPsau.js → pieDiagram-ADFJNKIX-xTPPhtNx.js} +1 -1
- package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-C3gtowNj.js → quadrantDiagram-AYHSOK5B-euniyDlz.js} +1 -1
- package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-CXBTrAnU.js → requirementDiagram-UZGBJVZJ-D9Uiw4kF.js} +1 -1
- package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-wziX77xG.js → sankeyDiagram-TZEHDZUN-CySU4nED.js} +1 -1
- package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-sYqopcrj.js → sequenceDiagram-WL72ISMW-JVGpET6V.js} +1 -1
- package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
- package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-Bl1-0_Cp.js → stateDiagram-FKZM4ZOC-B2FY5qqi.js} +1 -1
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-DcoMiR8H.js +1 -0
- package/dist-renderer/assets/{timeline-definition-IT6M3QCI-CIRjJUBo.js → timeline-definition-IT6M3QCI-DmycNUUe.js} +1 -1
- package/dist-renderer/assets/{treemap-GDKQZRPO-CVPuNe1n.js → treemap-GDKQZRPO-DPq4gZuB.js} +1 -1
- package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-3nT9yHwp.js → xychartDiagram-PRI3JC2R-J6VVJzRq.js} +1 -1
- package/dist-renderer/index.html +20 -53
- package/package.json +25 -18
- package/src/main/ipc/extensions.ts +30 -50
- package/src/main/server.ts +890 -247
- package/src/main/services/extensions/ExtensionFacadeService.ts +4 -56
- package/src/main/services/extensions/catalog/PluginCatalogService.ts +4 -2
- package/src/main/services/extensions/library/McpLibraryService.ts +243 -0
- package/src/main/services/session-intelligence/ConversationTelemetryService.ts +1101 -0
- package/src/main/services/session-intelligence/LocalSessionScanner.ts +512 -0
- package/src/main/services/session-intelligence/SessionUsageParser.ts +4 -4
- package/src/main/services/session-intelligence/UsageTelemetryService.ts +14 -1
- package/src/main/services/system-manager/SystemManagerConfigService.ts +122 -0
- package/src/main/services/system-manager/SystemManagerPtyService.ts +233 -0
- package/src/main/services/system-manager/WorkflowPromptService.ts +75 -0
- package/src/main/services/teams-mvp/TaskDispatchService.ts +32 -8
- package/src/main/services/teams-mvp/TeamProvisioningService.ts +39 -2
- package/src/main/services/teams-mvp/TeamWorkspaceService.ts +22 -4
- package/src/main/utils/teamProjectResolution.ts +15 -0
- package/src/renderer/App.tsx +8 -4
- package/src/renderer/api/httpClient.ts +174 -38
- package/src/renderer/api/providers.ts +23 -2
- package/src/renderer/assets/participant-avatars/01.svg +3 -0
- package/src/renderer/assets/participant-avatars/02.svg +3 -0
- package/src/renderer/assets/participant-avatars/03.svg +3 -0
- package/src/renderer/assets/participant-avatars/04.svg +3 -0
- package/src/renderer/assets/participant-avatars/05.svg +3 -0
- package/src/renderer/assets/participant-avatars/06.svg +3 -0
- package/src/renderer/assets/participant-avatars/07.svg +3 -0
- package/src/renderer/assets/participant-avatars/08.svg +3 -0
- package/src/renderer/assets/participant-avatars/09.svg +3 -0
- package/src/renderer/assets/participant-avatars/10.svg +3 -0
- package/src/renderer/assets/participant-avatars/11.svg +3 -0
- package/src/renderer/assets/participant-avatars/12.svg +3 -0
- package/src/renderer/assets/participant-avatars/13.svg +3 -0
- package/src/renderer/components/common/TerminalPane.tsx +213 -0
- package/src/renderer/components/dashboard/DashboardView.tsx +9 -36
- package/src/renderer/components/extensions/ExtensionStoreView.tsx +12 -221
- package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +1 -1
- package/src/renderer/components/extensions/mcp/McpLibraryEnableDialog.tsx +305 -0
- package/src/renderer/components/extensions/mcp/McpLibraryEntryDialog.tsx +418 -0
- package/src/renderer/components/extensions/mcp/McpLibraryPanel.tsx +404 -0
- package/src/renderer/components/extensions/plugins/PluginCard.tsx +10 -2
- package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +40 -22
- package/src/renderer/components/extensions/skills/SkillsLibraryPanel.tsx +335 -0
- package/src/renderer/components/layout/PaneContent.tsx +8 -1
- package/src/renderer/components/layout/Sidebar.tsx +11 -54
- package/src/renderer/components/layout/SortableTab.tsx +20 -31
- package/src/renderer/components/layout/TabBar.tsx +1 -1
- package/src/renderer/components/layout/TabContextMenu.tsx +1 -1
- package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +768 -157
- package/src/renderer/components/schedules/SchedulesView.tsx +51 -462
- package/src/renderer/components/schedules/calendar/CalendarDayView.tsx +173 -0
- package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +113 -0
- package/src/renderer/components/schedules/calendar/CalendarHeader.tsx +148 -0
- package/src/renderer/components/schedules/calendar/CalendarMonthView.tsx +142 -0
- package/src/renderer/components/schedules/calendar/CalendarWeekView.tsx +219 -0
- package/src/renderer/components/schedules/calendar/ScheduleCalendarBoard.tsx +41 -0
- package/src/renderer/components/schedules/calendar/TeamGanttView.tsx +405 -0
- package/src/renderer/components/schedules/calendar/computeOccurrences.ts +234 -0
- package/src/renderer/components/schedules/calendar/index.ts +2 -0
- package/src/renderer/components/schedules/calendar/types.ts +44 -0
- package/src/renderer/components/settings/SettingsTabs.tsx +50 -55
- package/src/renderer/components/settings/SettingsView.tsx +30 -35
- package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +5 -1
- package/src/renderer/components/settings/components/SettingsSelect.tsx +5 -3
- package/src/renderer/components/settings/components/SettingsToggle.tsx +2 -2
- package/src/renderer/components/settings/sections/AdvancedSection.tsx +11 -42
- package/src/renderer/components/settings/sections/CliStatusSection.tsx +71 -112
- package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
- package/src/renderer/components/settings/sections/GeneralSection.tsx +11 -3
- package/src/renderer/components/settings/sections/HarnessSection.tsx +18 -14
- package/src/renderer/components/settings/sections/PlatformsSection.tsx +3 -3
- package/src/renderer/components/settings/sections/TaskBusSection.tsx +33 -40
- package/src/renderer/components/settings/sections/index.ts +0 -1
- package/src/renderer/components/sidebar/SidebarSessions.tsx +182 -4
- package/src/renderer/components/sidebar/SidebarTaskItem.tsx +4 -4
- package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +39 -4
- package/src/renderer/components/splash/splashScene.ts +121 -929
- package/src/renderer/components/system-manager/FolderBrowser.tsx +163 -0
- package/src/renderer/components/system-manager/SystemManagerView.tsx +351 -0
- package/src/renderer/components/tasks/TasksView.tsx +112 -134
- package/src/renderer/components/team/CcSessionsSection.tsx +431 -89
- package/src/renderer/components/team/CollapsibleTeamSection.tsx +17 -32
- package/src/renderer/components/team/TeamDetailView.tsx +325 -114
- package/src/renderer/components/team/TeamListView.tsx +108 -123
- package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +2 -2
- package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +84 -306
- package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +259 -342
- package/src/renderer/components/team/dialogs/GlobalTaskDetailDialog.tsx +1 -1
- package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +17 -15
- package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +221 -0
- package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +7 -0
- package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +1 -1
- package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +361 -0
- package/src/renderer/components/team/dialogs/platformMeta.ts +122 -11
- package/src/renderer/components/team/dialogs/useTeamEditForm.ts +17 -5
- package/src/renderer/components/team/kanban/KanbanBoard.tsx +9 -9
- package/src/renderer/components/team/members/MemberCard.tsx +14 -47
- package/src/renderer/components/team/members/MemberDetailDialog.tsx +3 -95
- package/src/renderer/components/team/members/MemberDetailStats.tsx +50 -65
- package/src/renderer/components/team/messages/MessageComposer.tsx +8 -110
- package/src/renderer/components/team/messages/MessagesPanel.tsx +131 -114
- package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +2 -2
- package/src/renderer/components/team/tools/AddMcpInline.tsx +57 -0
- package/src/renderer/components/team/tools/AddSkillInline.tsx +61 -0
- package/src/renderer/components/team/tools/McpChip.tsx +45 -0
- package/src/renderer/components/team/tools/SkillChip.tsx +35 -0
- package/src/renderer/components/team/tools/ToolsSection.tsx +556 -0
- package/src/renderer/hooks/useExtensionsTabState.ts +3 -114
- package/src/renderer/index.css +39 -22
- package/src/renderer/index.html +17 -50
- package/src/renderer/store/index.ts +2 -1
- package/src/renderer/store/slices/scheduleSlice.ts +1 -1
- package/src/renderer/store/slices/teamSlice.ts +45 -168
- package/src/renderer/utils/claudeCodeOnlyProviders.ts +3 -10
- package/src/renderer/utils/memberHelpers.ts +5 -17
- package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +4 -2
- package/src/renderer/utils/providerSlashCommands.ts +0 -5
- package/src/renderer/utils/scheduleFormatters.ts +3 -1
- package/src/renderer/utils/teamMessageFiltering.ts +14 -1
- package/src/renderer/utils/teamModelAvailability.ts +18 -2
- package/src/shared/types/api.ts +121 -2
- package/src/shared/types/ccConnect.ts +2 -0
- package/src/shared/types/extensions/api.ts +9 -0
- package/src/shared/types/extensions/index.ts +4 -0
- package/src/shared/types/extensions/mcp.ts +41 -0
- package/src/shared/types/index.ts +3 -0
- package/src/shared/types/systemManager.ts +49 -0
- package/src/shared/types/team.ts +29 -0
- package/src/shared/types/terminal.ts +4 -2
- package/src/shared/utils/extensionNormalizers.ts +29 -0
- package/src/shared/utils/providerExtensionCapabilities.ts +2 -2
- package/dist-renderer/assets/ProjectEditorOverlay-Va_Vz-zz.js +0 -52
- package/dist-renderer/assets/channel-5dJIx68e.js +0 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-BMGXWJ2d.js +0 -1
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-BMGXWJ2d.js +0 -1
- package/dist-renderer/assets/clone-D7FWfGY9.js +0 -1
- package/dist-renderer/assets/index-B2z_IyRH.css +0 -1
- package/dist-renderer/assets/splashScene-C8lWNnm4.js +0 -1
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-DOYYvDbi.js +0 -1
- package/src/main/services/extensions/catalog/GlamaMcpEnrichmentService.ts +0 -190
- package/src/main/services/extensions/catalog/McpCatalogAggregator.ts +0 -150
- package/src/main/services/extensions/catalog/OfficialMcpRegistryService.ts +0 -381
- package/src/main/services/extensions/install/McpInstallService.ts +0 -407
- package/src/main/services/extensions/state/McpInstallationStateService.ts +0 -42
- package/src/renderer/components/extensions/mcp/McpServerCard.tsx +0 -314
- package/src/renderer/components/extensions/mcp/McpServerDetailDialog.tsx +0 -765
- package/src/renderer/components/extensions/mcp/McpServersPanel.tsx +0 -593
- package/src/renderer/components/extensions/skills/SkillDetailDialog.tsx +0 -372
- package/src/renderer/components/extensions/skills/SkillImportDialog.tsx +0 -343
- package/src/renderer/components/extensions/skills/SkillsPanel.tsx +0 -659
|
@@ -1,241 +1,23 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Button } from '@renderer/components/ui/button';
|
|
4
|
-
import { Input } from '@renderer/components/ui/input';
|
|
5
|
-
import { Popover, PopoverContent, PopoverTrigger } from '@renderer/components/ui/popover';
|
|
6
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
|
7
4
|
import { getTeamColorSet } from '@renderer/constants/teamColors';
|
|
8
5
|
import { useStore } from '@renderer/store';
|
|
9
6
|
import { nameColorSet } from '@renderer/utils/projectColor';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
AlertCircle,
|
|
13
|
-
Calendar,
|
|
14
|
-
ChevronDown,
|
|
15
|
-
ChevronRight,
|
|
16
|
-
Filter,
|
|
17
|
-
Loader2,
|
|
18
|
-
MoreHorizontal,
|
|
19
|
-
Pencil,
|
|
20
|
-
Play,
|
|
21
|
-
Plus,
|
|
22
|
-
Search,
|
|
23
|
-
Square,
|
|
24
|
-
Trash2,
|
|
25
|
-
} from 'lucide-react';
|
|
7
|
+
import { Calendar, Plus } from 'lucide-react';
|
|
26
8
|
import { useShallow } from 'zustand/react/shallow';
|
|
27
9
|
|
|
10
|
+
import { ScheduleCalendarBoard } from './calendar';
|
|
11
|
+
import type { CalendarViewMode } from './calendar';
|
|
28
12
|
import { CcCronScheduleDialog } from '../team/schedule/CcCronScheduleDialog';
|
|
29
|
-
import { ScheduleRunLogDialog } from '../team/schedule/ScheduleRunLogDialog';
|
|
30
|
-
import { ScheduleRunRow } from '../team/schedule/ScheduleRunRow';
|
|
31
|
-
import { ScheduleStatusBadge } from '../team/schedule/ScheduleStatusBadge';
|
|
32
13
|
|
|
33
|
-
import type { Schedule
|
|
34
|
-
|
|
35
|
-
// =============================================================================
|
|
36
|
-
// ScheduleListItem
|
|
37
|
-
// =============================================================================
|
|
38
|
-
|
|
39
|
-
interface ScheduleListItemProps {
|
|
40
|
-
schedule: Schedule;
|
|
41
|
-
onEdit: (schedule: Schedule) => void;
|
|
42
|
-
onDelete: (id: string) => void;
|
|
43
|
-
onPause: (id: string) => void;
|
|
44
|
-
onResume: (id: string) => void;
|
|
45
|
-
onTeamClick: (teamName: string) => void;
|
|
46
|
-
teamColor: string;
|
|
47
|
-
teamDisplayName: string;
|
|
48
|
-
deleting?: boolean;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const ScheduleListItem = ({
|
|
52
|
-
schedule,
|
|
53
|
-
onEdit,
|
|
54
|
-
onDelete,
|
|
55
|
-
onPause,
|
|
56
|
-
onResume,
|
|
57
|
-
onTeamClick,
|
|
58
|
-
teamColor,
|
|
59
|
-
teamDisplayName,
|
|
60
|
-
deleting = false,
|
|
61
|
-
}: ScheduleListItemProps): React.JSX.Element => {
|
|
62
|
-
const [expanded, setExpanded] = useState(false);
|
|
63
|
-
const [selectedRun, setSelectedRun] = useState<ScheduleRun | null>(null);
|
|
64
|
-
const runs = useStore(useShallow((s) => s.scheduleRuns[schedule.id] ?? []));
|
|
65
|
-
const runsLoading = useStore((s) => s.scheduleRunsLoading[schedule.id] ?? false);
|
|
66
|
-
const fetchRunHistory = useStore((s) => s.fetchRunHistory);
|
|
67
|
-
|
|
68
|
-
const handleExpand = useCallback(() => {
|
|
69
|
-
const next = !expanded;
|
|
70
|
-
setExpanded(next);
|
|
71
|
-
if (next && runs.length === 0 && !runsLoading) {
|
|
72
|
-
void fetchRunHistory(schedule.id);
|
|
73
|
-
}
|
|
74
|
-
}, [expanded, runs.length, runsLoading, fetchRunHistory, schedule.id]);
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<div className="rounded-xl border border-[var(--color-border-subtle)] bg-white/[0.025] font-sans shadow-[0_14px_32px_rgba(0,0,0,0.14)] transition-colors hover:border-[var(--color-border-emphasis)] hover:bg-white/[0.04]">
|
|
78
|
-
{/* Main row */}
|
|
79
|
-
<div className="flex items-center gap-3 px-4 py-3.5">
|
|
80
|
-
{/* Expand toggle */}
|
|
81
|
-
<button
|
|
82
|
-
type="button"
|
|
83
|
-
className="shrink-0 text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
84
|
-
onClick={handleExpand}
|
|
85
|
-
>
|
|
86
|
-
{expanded ? <ChevronDown className="size-4" /> : <ChevronRight className="size-4" />}
|
|
87
|
-
</button>
|
|
88
|
-
|
|
89
|
-
{/* Status badge */}
|
|
90
|
-
<ScheduleStatusBadge status={schedule.status} />
|
|
91
|
-
|
|
92
|
-
{/* Label & cron description */}
|
|
93
|
-
<div className="min-w-0 flex-1">
|
|
94
|
-
<div className="flex items-center gap-2">
|
|
95
|
-
<span className="truncate text-sm font-medium text-[var(--color-text)]">
|
|
96
|
-
{schedule.label || getCronDescription(schedule.cronExpression)}
|
|
97
|
-
</span>
|
|
98
|
-
</div>
|
|
99
|
-
{schedule.label ? (
|
|
100
|
-
<span className="text-xs text-[var(--color-text-muted)]">
|
|
101
|
-
{getCronDescription(schedule.cronExpression)}
|
|
102
|
-
</span>
|
|
103
|
-
) : null}
|
|
104
|
-
</div>
|
|
105
|
-
|
|
106
|
-
{/* Team badge */}
|
|
107
|
-
<button
|
|
108
|
-
type="button"
|
|
109
|
-
className="flex shrink-0 items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-xs text-[var(--color-text-secondary)] transition-colors hover:border-[var(--color-border-emphasis)] hover:text-[var(--color-text)]"
|
|
110
|
-
onClick={() => onTeamClick(schedule.teamName)}
|
|
111
|
-
>
|
|
112
|
-
<span className="size-2 shrink-0 rounded-full" style={{ backgroundColor: teamColor }} />
|
|
113
|
-
{teamDisplayName}
|
|
114
|
-
</button>
|
|
115
|
-
|
|
116
|
-
{/* Next run */}
|
|
117
|
-
<Tooltip>
|
|
118
|
-
<TooltipTrigger asChild>
|
|
119
|
-
<span className="shrink-0 rounded-full bg-white/[0.035] px-2 py-1 text-xs text-[var(--color-text-muted)]">
|
|
120
|
-
下次:{formatNextRun(schedule.nextRunAt)}
|
|
121
|
-
</span>
|
|
122
|
-
</TooltipTrigger>
|
|
123
|
-
{schedule.nextRunAt ? (
|
|
124
|
-
<TooltipContent side="top" className="text-xs">
|
|
125
|
-
{new Date(schedule.nextRunAt).toLocaleString()}
|
|
126
|
-
</TooltipContent>
|
|
127
|
-
) : null}
|
|
128
|
-
</Tooltip>
|
|
129
|
-
|
|
130
|
-
{/* Timezone */}
|
|
131
|
-
<span className="hidden shrink-0 text-xs text-[var(--color-text-muted)] lg:inline">
|
|
132
|
-
{schedule.timezone}
|
|
133
|
-
</span>
|
|
134
|
-
|
|
135
|
-
{/* Actions */}
|
|
136
|
-
<div className="flex shrink-0 items-center gap-1">
|
|
137
|
-
<Tooltip>
|
|
138
|
-
<TooltipTrigger asChild>
|
|
139
|
-
<Button
|
|
140
|
-
variant="ghost"
|
|
141
|
-
size="sm"
|
|
142
|
-
className="size-7 p-0 text-red-400 hover:bg-red-500/10 hover:text-red-300"
|
|
143
|
-
onClick={() => onDelete(schedule.id)}
|
|
144
|
-
disabled={deleting}
|
|
145
|
-
>
|
|
146
|
-
{deleting ? (
|
|
147
|
-
<Loader2 className="size-3.5 animate-spin" />
|
|
148
|
-
) : (
|
|
149
|
-
<Trash2 className="size-3.5" />
|
|
150
|
-
)}
|
|
151
|
-
</Button>
|
|
152
|
-
</TooltipTrigger>
|
|
153
|
-
<TooltipContent side="top">删除</TooltipContent>
|
|
154
|
-
</Tooltip>
|
|
155
|
-
|
|
156
|
-
<Popover>
|
|
157
|
-
<PopoverTrigger asChild>
|
|
158
|
-
<Button variant="ghost" size="sm" className="size-7 p-0">
|
|
159
|
-
<MoreHorizontal className="size-3.5" />
|
|
160
|
-
</Button>
|
|
161
|
-
</PopoverTrigger>
|
|
162
|
-
<PopoverContent align="end" className="w-40 p-1">
|
|
163
|
-
<button
|
|
164
|
-
type="button"
|
|
165
|
-
className="flex w-full items-center rounded-sm px-2 py-1.5 text-xs text-[var(--color-text)] hover:bg-[var(--color-surface-raised)]"
|
|
166
|
-
onClick={() => onEdit(schedule)}
|
|
167
|
-
>
|
|
168
|
-
<Pencil className="mr-2 size-3.5" />
|
|
169
|
-
编辑
|
|
170
|
-
</button>
|
|
171
|
-
{schedule.status === 'active' ? (
|
|
172
|
-
<button
|
|
173
|
-
type="button"
|
|
174
|
-
className="flex w-full items-center rounded-sm px-2 py-1.5 text-xs text-[var(--color-text)] hover:bg-[var(--color-surface-raised)]"
|
|
175
|
-
onClick={() => onPause(schedule.id)}
|
|
176
|
-
>
|
|
177
|
-
<Square className="mr-2 size-3.5" />
|
|
178
|
-
停止
|
|
179
|
-
</button>
|
|
180
|
-
) : (
|
|
181
|
-
<button
|
|
182
|
-
type="button"
|
|
183
|
-
className="flex w-full items-center rounded-sm px-2 py-1.5 text-xs text-[var(--color-text)] hover:bg-[var(--color-surface-raised)]"
|
|
184
|
-
onClick={() => onResume(schedule.id)}
|
|
185
|
-
>
|
|
186
|
-
<Play className="mr-2 size-3.5" />
|
|
187
|
-
启用
|
|
188
|
-
</button>
|
|
189
|
-
)}
|
|
190
|
-
</PopoverContent>
|
|
191
|
-
</Popover>
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
|
|
195
|
-
{/* Expanded: Run history */}
|
|
196
|
-
{expanded ? (
|
|
197
|
-
<div className="border-t border-white/[0.06] bg-black/10">
|
|
198
|
-
{runsLoading ? (
|
|
199
|
-
<div className="flex items-center justify-center py-4 text-xs text-[var(--color-text-muted)]">
|
|
200
|
-
正在加载运行历史...
|
|
201
|
-
</div>
|
|
202
|
-
) : runs.length === 0 ? (
|
|
203
|
-
<div className="flex items-center justify-center py-4 text-xs text-[var(--color-text-muted)]">
|
|
204
|
-
暂无运行记录
|
|
205
|
-
</div>
|
|
206
|
-
) : (
|
|
207
|
-
<div className="max-h-[240px] overflow-y-auto">
|
|
208
|
-
{runs.slice(0, 15).map((run) => (
|
|
209
|
-
<ScheduleRunRow key={run.id} run={run} onClick={setSelectedRun} />
|
|
210
|
-
))}
|
|
211
|
-
</div>
|
|
212
|
-
)}
|
|
213
|
-
</div>
|
|
214
|
-
) : null}
|
|
215
|
-
|
|
216
|
-
{/* Run Log Dialog */}
|
|
217
|
-
<ScheduleRunLogDialog
|
|
218
|
-
open={selectedRun != null}
|
|
219
|
-
run={selectedRun}
|
|
220
|
-
scheduleId={schedule.id}
|
|
221
|
-
onClose={() => setSelectedRun(null)}
|
|
222
|
-
/>
|
|
223
|
-
</div>
|
|
224
|
-
);
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
// =============================================================================
|
|
228
|
-
// SchedulesView
|
|
229
|
-
// =============================================================================
|
|
14
|
+
import type { Schedule } from '@shared/types';
|
|
230
15
|
|
|
231
16
|
export const SchedulesView = (): React.JSX.Element => {
|
|
232
17
|
const {
|
|
233
18
|
schedules,
|
|
234
19
|
schedulesLoading,
|
|
235
20
|
fetchSchedules,
|
|
236
|
-
pauseSchedule,
|
|
237
|
-
resumeSchedule,
|
|
238
|
-
deleteSchedule,
|
|
239
21
|
openTeamTab,
|
|
240
22
|
teamByName,
|
|
241
23
|
} = useStore(
|
|
@@ -243,15 +25,11 @@ export const SchedulesView = (): React.JSX.Element => {
|
|
|
243
25
|
schedules: s.schedules,
|
|
244
26
|
schedulesLoading: s.schedulesLoading,
|
|
245
27
|
fetchSchedules: s.fetchSchedules,
|
|
246
|
-
pauseSchedule: s.pauseSchedule,
|
|
247
|
-
resumeSchedule: s.resumeSchedule,
|
|
248
|
-
deleteSchedule: s.deleteSchedule,
|
|
249
28
|
openTeamTab: s.openTeamTab,
|
|
250
29
|
teamByName: s.teamByName,
|
|
251
30
|
}))
|
|
252
31
|
);
|
|
253
32
|
|
|
254
|
-
/** Resolve team color dot style for a given team name */
|
|
255
33
|
const getTeamColor = useCallback(
|
|
256
34
|
(teamName: string): string => {
|
|
257
35
|
const team = teamByName[teamName];
|
|
@@ -266,75 +44,27 @@ export const SchedulesView = (): React.JSX.Element => {
|
|
|
266
44
|
[teamByName]
|
|
267
45
|
);
|
|
268
46
|
|
|
269
|
-
const [
|
|
270
|
-
const [teamFilter, setTeamFilter] = useState<string | null>(null);
|
|
47
|
+
const [calendarView, setCalendarView] = useState<CalendarViewMode>('week');
|
|
271
48
|
const [dialogOpen, setDialogOpen] = useState(false);
|
|
272
49
|
const [editingSchedule, setEditingSchedule] = useState<Schedule | null>(null);
|
|
273
|
-
const [deletingScheduleId, setDeletingScheduleId] = useState<string | null>(null);
|
|
274
|
-
const [deleteError, setDeleteError] = useState<string | null>(null);
|
|
275
50
|
|
|
276
|
-
// Fetch schedules on mount
|
|
277
51
|
useEffect(() => {
|
|
278
52
|
void fetchSchedules();
|
|
279
53
|
}, [fetchSchedules]);
|
|
280
54
|
|
|
281
|
-
|
|
282
|
-
const teamNames = useMemo(
|
|
55
|
+
const sortedSchedules = useMemo(
|
|
283
56
|
() =>
|
|
284
|
-
[...
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (teamFilter) {
|
|
296
|
-
result = result.filter((s) => s.teamName === teamFilter);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Filter by search query
|
|
300
|
-
if (searchQuery.trim()) {
|
|
301
|
-
const query = searchQuery.toLowerCase();
|
|
302
|
-
result = result.filter((s) => {
|
|
303
|
-
const teamDisplayName = getTeamDisplayName(s.teamName).toLowerCase();
|
|
304
|
-
return (
|
|
305
|
-
(s.label ?? '').toLowerCase().includes(query) ||
|
|
306
|
-
teamDisplayName.includes(query) ||
|
|
307
|
-
s.teamName.toLowerCase().includes(query) ||
|
|
308
|
-
s.launchConfig.prompt.toLowerCase().includes(query) ||
|
|
309
|
-
getCronDescription(s.cronExpression).toLowerCase().includes(query)
|
|
310
|
-
);
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Sort: active first, then by next run ascending
|
|
315
|
-
return [...result].sort((a, b) => {
|
|
316
|
-
// Active schedules first
|
|
317
|
-
const statusOrder = { active: 0, paused: 1, disabled: 2 };
|
|
318
|
-
const statusDiff = statusOrder[a.status] - statusOrder[b.status];
|
|
319
|
-
if (statusDiff !== 0) return statusDiff;
|
|
320
|
-
|
|
321
|
-
// Then by next run (soonest first)
|
|
322
|
-
if (a.nextRunAt && b.nextRunAt) {
|
|
323
|
-
return new Date(a.nextRunAt).getTime() - new Date(b.nextRunAt).getTime();
|
|
324
|
-
}
|
|
325
|
-
if (a.nextRunAt) return -1;
|
|
326
|
-
if (b.nextRunAt) return 1;
|
|
327
|
-
return 0;
|
|
328
|
-
});
|
|
329
|
-
}, [getTeamDisplayName, schedules, teamFilter, searchQuery]);
|
|
330
|
-
|
|
331
|
-
const scheduleStats = useMemo(
|
|
332
|
-
() => ({
|
|
333
|
-
total: schedules.length,
|
|
334
|
-
active: schedules.filter((schedule) => schedule.status === 'active').length,
|
|
335
|
-
paused: schedules.filter((schedule) => schedule.status === 'paused').length,
|
|
336
|
-
teams: new Set(schedules.map((schedule) => schedule.teamName)).size,
|
|
337
|
-
}),
|
|
57
|
+
[...schedules].sort((a, b) => {
|
|
58
|
+
const statusOrder = { active: 0, paused: 1, disabled: 2 };
|
|
59
|
+
const statusDiff = statusOrder[a.status] - statusOrder[b.status];
|
|
60
|
+
if (statusDiff !== 0) return statusDiff;
|
|
61
|
+
if (a.nextRunAt && b.nextRunAt) {
|
|
62
|
+
return new Date(a.nextRunAt).getTime() - new Date(b.nextRunAt).getTime();
|
|
63
|
+
}
|
|
64
|
+
if (a.nextRunAt) return -1;
|
|
65
|
+
if (b.nextRunAt) return 1;
|
|
66
|
+
return 0;
|
|
67
|
+
}),
|
|
338
68
|
[schedules]
|
|
339
69
|
);
|
|
340
70
|
|
|
@@ -353,21 +83,6 @@ export const SchedulesView = (): React.JSX.Element => {
|
|
|
353
83
|
setEditingSchedule(null);
|
|
354
84
|
}, []);
|
|
355
85
|
|
|
356
|
-
const handleDelete = useCallback(
|
|
357
|
-
async (id: string) => {
|
|
358
|
-
setDeletingScheduleId(id);
|
|
359
|
-
setDeleteError(null);
|
|
360
|
-
try {
|
|
361
|
-
await deleteSchedule(id);
|
|
362
|
-
} catch (err) {
|
|
363
|
-
setDeleteError(err instanceof Error ? err.message : '删除计划失败');
|
|
364
|
-
} finally {
|
|
365
|
-
setDeletingScheduleId(null);
|
|
366
|
-
}
|
|
367
|
-
},
|
|
368
|
-
[deleteSchedule]
|
|
369
|
-
);
|
|
370
|
-
|
|
371
86
|
const handleTeamClick = useCallback(
|
|
372
87
|
(teamName: string) => {
|
|
373
88
|
openTeamTab(teamName);
|
|
@@ -376,179 +91,53 @@ export const SchedulesView = (): React.JSX.Element => {
|
|
|
376
91
|
);
|
|
377
92
|
|
|
378
93
|
return (
|
|
379
|
-
<div className="h-full
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
<div className="
|
|
383
|
-
<
|
|
384
|
-
<
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
<Calendar className="size-4" />
|
|
388
|
-
</span>
|
|
389
|
-
<div>
|
|
390
|
-
<h1 className="text-lg font-semibold text-[var(--color-text)]">定时任务</h1>
|
|
391
|
-
<p className="mt-0.5 text-xs text-[var(--color-text-muted)]">
|
|
392
|
-
集中管理所有团队的 Cron 计划、运行状态和历史记录。
|
|
393
|
-
</p>
|
|
394
|
-
</div>
|
|
395
|
-
</div>
|
|
396
|
-
{schedules.length > 0 ? (
|
|
397
|
-
<div className="mt-4 flex flex-wrap gap-2">
|
|
398
|
-
<span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-xs text-[var(--color-text-secondary)]">
|
|
399
|
-
全部 {scheduleStats.total}
|
|
400
|
-
</span>
|
|
401
|
-
<span className="rounded-full border border-emerald-400/15 bg-emerald-400/10 px-2.5 py-1 text-xs text-emerald-400">
|
|
402
|
-
运行中 {scheduleStats.active}
|
|
403
|
-
</span>
|
|
404
|
-
<span className="rounded-full border border-yellow-400/15 bg-yellow-400/10 px-2.5 py-1 text-xs text-yellow-400">
|
|
405
|
-
已暂停 {scheduleStats.paused}
|
|
406
|
-
</span>
|
|
407
|
-
<span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-xs text-[var(--color-text-secondary)]">
|
|
408
|
-
团队 {scheduleStats.teams}
|
|
409
|
-
</span>
|
|
410
|
-
</div>
|
|
411
|
-
) : null}
|
|
412
|
-
</div>
|
|
413
|
-
<Button size="sm" className="gap-1.5" onClick={handleCreate}>
|
|
414
|
-
<Plus className="size-3.5" />
|
|
415
|
-
添加计划
|
|
416
|
-
</Button>
|
|
417
|
-
</div>
|
|
418
|
-
|
|
419
|
-
{/* Filters row */}
|
|
94
|
+
<div className="flex h-full flex-col bg-[var(--color-surface)]">
|
|
95
|
+
{/* Minimal header */}
|
|
96
|
+
<div className="flex shrink-0 items-center justify-between px-4 pt-4 pb-2">
|
|
97
|
+
<div className="flex items-center gap-2">
|
|
98
|
+
<h1 className="flex items-center gap-2 text-xs font-medium uppercase tracking-wider" style={{ color: 'var(--color-text-muted)' }}>
|
|
99
|
+
<span className="text-cyan-400/40">#</span>
|
|
100
|
+
定时任务
|
|
101
|
+
</h1>
|
|
420
102
|
{schedules.length > 0 && (
|
|
421
|
-
<
|
|
422
|
-
{
|
|
423
|
-
|
|
424
|
-
<Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-[var(--color-text-muted)]" />
|
|
425
|
-
<Input
|
|
426
|
-
placeholder="搜索计划..."
|
|
427
|
-
value={searchQuery}
|
|
428
|
-
onChange={(e) => setSearchQuery(e.target.value)}
|
|
429
|
-
className="h-8 pl-8 text-xs"
|
|
430
|
-
/>
|
|
431
|
-
</div>
|
|
432
|
-
|
|
433
|
-
{/* Team filter */}
|
|
434
|
-
{teamNames.length > 1 && (
|
|
435
|
-
<Popover>
|
|
436
|
-
<PopoverTrigger asChild>
|
|
437
|
-
<Button variant="outline" size="sm" className="h-8 gap-1.5 text-xs">
|
|
438
|
-
<Filter className="size-3" />
|
|
439
|
-
{teamFilter ? (
|
|
440
|
-
<>
|
|
441
|
-
<span
|
|
442
|
-
className="size-2 shrink-0 rounded-full"
|
|
443
|
-
style={{ backgroundColor: getTeamColor(teamFilter) }}
|
|
444
|
-
/>
|
|
445
|
-
{getTeamDisplayName(teamFilter)}
|
|
446
|
-
</>
|
|
447
|
-
) : (
|
|
448
|
-
'全部团队'
|
|
449
|
-
)}
|
|
450
|
-
</Button>
|
|
451
|
-
</PopoverTrigger>
|
|
452
|
-
<PopoverContent align="start" className="w-48 p-1">
|
|
453
|
-
<button
|
|
454
|
-
type="button"
|
|
455
|
-
className={`flex w-full items-center rounded-sm px-2 py-1.5 text-xs ${
|
|
456
|
-
!teamFilter
|
|
457
|
-
? 'font-medium text-[var(--color-text)]'
|
|
458
|
-
: 'text-[var(--color-text-secondary)]'
|
|
459
|
-
} hover:bg-[var(--color-surface-raised)]`}
|
|
460
|
-
onClick={() => setTeamFilter(null)}
|
|
461
|
-
>
|
|
462
|
-
全部团队
|
|
463
|
-
</button>
|
|
464
|
-
{teamNames.map((name) => (
|
|
465
|
-
<button
|
|
466
|
-
key={name}
|
|
467
|
-
type="button"
|
|
468
|
-
className={`flex w-full items-center gap-1.5 rounded-sm px-2 py-1.5 text-xs ${
|
|
469
|
-
teamFilter === name
|
|
470
|
-
? 'font-medium text-[var(--color-text)]'
|
|
471
|
-
: 'text-[var(--color-text-secondary)]'
|
|
472
|
-
} hover:bg-[var(--color-surface-raised)]`}
|
|
473
|
-
onClick={() => setTeamFilter(name)}
|
|
474
|
-
>
|
|
475
|
-
<span
|
|
476
|
-
className="size-2 shrink-0 rounded-full"
|
|
477
|
-
style={{ backgroundColor: getTeamColor(name) }}
|
|
478
|
-
/>
|
|
479
|
-
{getTeamDisplayName(name)}
|
|
480
|
-
</button>
|
|
481
|
-
))}
|
|
482
|
-
</PopoverContent>
|
|
483
|
-
</Popover>
|
|
484
|
-
)}
|
|
485
|
-
</div>
|
|
103
|
+
<span className="rounded-full px-2 py-0.5 text-[10px]" style={{ color: 'var(--color-text-muted)', background: 'rgba(148,163,184,0.06)' }}>
|
|
104
|
+
{schedules.filter((s) => s.status === 'active').length} 运行中
|
|
105
|
+
</span>
|
|
486
106
|
)}
|
|
487
107
|
</div>
|
|
108
|
+
<Button size="sm" variant="ghost" className="gap-1.5 text-xs" onClick={handleCreate}>
|
|
109
|
+
<Plus className="size-3.5" />
|
|
110
|
+
添加计划
|
|
111
|
+
</Button>
|
|
112
|
+
</div>
|
|
488
113
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
<AlertCircle className="size-3.5 shrink-0" />
|
|
492
|
-
{deleteError}
|
|
493
|
-
</div>
|
|
494
|
-
) : null}
|
|
495
|
-
|
|
496
|
-
{/* Content */}
|
|
114
|
+
{/* Content — fills remaining space */}
|
|
115
|
+
<div className="flex-1 min-h-0 overflow-auto px-2 pb-4">
|
|
497
116
|
{schedulesLoading && schedules.length === 0 ? (
|
|
498
|
-
<div className="flex items-center justify-center py-
|
|
117
|
+
<div className="flex items-center justify-center py-24 text-sm text-[var(--color-text-muted)]">
|
|
499
118
|
正在加载计划...
|
|
500
119
|
</div>
|
|
501
120
|
) : schedules.length === 0 ? (
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
<
|
|
505
|
-
|
|
506
|
-
</
|
|
507
|
-
<
|
|
508
|
-
<p className="text-sm font-medium text-[var(--color-text-secondary)]">暂无定时任务</p>
|
|
509
|
-
<p className="max-w-sm text-xs text-[var(--color-text-muted)]">
|
|
510
|
-
在任意团队中创建计划,即可使用 Cron 表达式自动运行团队。
|
|
511
|
-
所有团队的计划都会显示在这里。
|
|
512
|
-
</p>
|
|
513
|
-
</div>
|
|
514
|
-
<Button size="sm" variant="outline" className="mt-2 gap-1.5" onClick={handleCreate}>
|
|
121
|
+
<div className="flex flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-[var(--color-border)] py-20 text-center">
|
|
122
|
+
<Calendar className="size-6" style={{ color: 'var(--color-text-muted)', opacity: 0.4 }} />
|
|
123
|
+
<p className="text-xs" style={{ color: 'var(--color-text-muted)' }}>
|
|
124
|
+
暂无定时任务。在团队中创建计划即可自动运行。
|
|
125
|
+
</p>
|
|
126
|
+
<Button size="sm" variant="ghost" className="mt-1 gap-1.5 text-xs" onClick={handleCreate}>
|
|
515
127
|
<Plus className="size-3.5" />
|
|
516
128
|
创建计划
|
|
517
129
|
</Button>
|
|
518
130
|
</div>
|
|
519
|
-
) : filteredSchedules.length === 0 ? (
|
|
520
|
-
/* No results for current filters */
|
|
521
|
-
<div className="flex flex-col items-center justify-center gap-2 rounded-xl border border-dashed border-[var(--color-border)] bg-white/[0.02] py-12 text-center">
|
|
522
|
-
<Search className="size-8 text-[var(--color-text-muted)]" />
|
|
523
|
-
<p className="text-sm text-[var(--color-text-muted)]">没有符合当前筛选条件的计划</p>
|
|
524
|
-
<button
|
|
525
|
-
type="button"
|
|
526
|
-
className="text-xs text-[var(--color-text-secondary)] underline hover:text-[var(--color-text)]"
|
|
527
|
-
onClick={() => {
|
|
528
|
-
setSearchQuery('');
|
|
529
|
-
setTeamFilter(null);
|
|
530
|
-
}}
|
|
531
|
-
>
|
|
532
|
-
清除筛选
|
|
533
|
-
</button>
|
|
534
|
-
</div>
|
|
535
131
|
) : (
|
|
536
|
-
<
|
|
537
|
-
{
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
onTeamClick={handleTeamClick}
|
|
546
|
-
teamColor={getTeamColor(schedule.teamName)}
|
|
547
|
-
teamDisplayName={getTeamDisplayName(schedule.teamName)}
|
|
548
|
-
deleting={deletingScheduleId === schedule.id}
|
|
549
|
-
/>
|
|
550
|
-
))}
|
|
551
|
-
</div>
|
|
132
|
+
<ScheduleCalendarBoard
|
|
133
|
+
schedules={sortedSchedules}
|
|
134
|
+
viewMode={calendarView}
|
|
135
|
+
onViewModeChange={setCalendarView}
|
|
136
|
+
onEdit={handleEdit}
|
|
137
|
+
onTeamClick={handleTeamClick}
|
|
138
|
+
getTeamColor={getTeamColor}
|
|
139
|
+
getTeamDisplayName={getTeamDisplayName}
|
|
140
|
+
/>
|
|
552
141
|
)}
|
|
553
142
|
</div>
|
|
554
143
|
|