@yancyyu/openhermit 1.6.30 → 1.6.31
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-DsQt4FHy.js → ProjectEditorOverlay-DkXfi2pg.js} +1 -1
- package/dist-renderer/assets/{TeamGraphOverlay-BjZC53xf.js → TeamGraphOverlay-CHNNVraw.js} +1 -1
- package/dist-renderer/assets/{_basePickBy-CrWocIjq.js → _basePickBy-Do-Ff83V.js} +1 -1
- package/dist-renderer/assets/{_baseUniq-B6d8ysWi.js → _baseUniq-nDLhSuJI.js} +1 -1
- package/dist-renderer/assets/{arc-DAIYCFP8.js → arc-Bp7fA6sx.js} +1 -1
- package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-B3UudXJh.js → architectureDiagram-VXUJARFQ-CPC1HdGy.js} +1 -1
- package/dist-renderer/assets/{blockDiagram-VD42YOAC-DbptKQ4W.js → blockDiagram-VD42YOAC-DTVKyNTO.js} +1 -1
- package/dist-renderer/assets/{c4Diagram-YG6GDRKO-C4WQuZpV.js → c4Diagram-YG6GDRKO-XVu-AN00.js} +1 -1
- package/dist-renderer/assets/channel-CIwbNcUO.js +1 -0
- package/dist-renderer/assets/{chunk-4BX2VUAB-Dp7fVpI_.js → chunk-4BX2VUAB-BcWmVyA-.js} +1 -1
- package/dist-renderer/assets/{chunk-55IACEB6-B8KGfbAy.js → chunk-55IACEB6-Co4Z2jsE.js} +1 -1
- package/dist-renderer/assets/{chunk-B4BG7PRW-BG1oJrjA.js → chunk-B4BG7PRW-C8q9gfDT.js} +1 -1
- package/dist-renderer/assets/{chunk-DI55MBZ5-DRmxNjht.js → chunk-DI55MBZ5-qDgb1gxO.js} +1 -1
- package/dist-renderer/assets/{chunk-FMBD7UC4-D6VLvy16.js → chunk-FMBD7UC4-Cm8Gu2gu.js} +1 -1
- package/dist-renderer/assets/{chunk-QN33PNHL-DZou1667.js → chunk-QN33PNHL-DYji1BRS.js} +1 -1
- package/dist-renderer/assets/{chunk-QZHKN3VN-CghmasSh.js → chunk-QZHKN3VN-DWAS568H.js} +1 -1
- package/dist-renderer/assets/{chunk-TZMSLE5B-B7apcMPK.js → chunk-TZMSLE5B-CLFzXLA8.js} +1 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-04A-pvql.js +1 -0
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-04A-pvql.js +1 -0
- package/dist-renderer/assets/clone-DQnvTIEM.js +1 -0
- package/dist-renderer/assets/{cose-bilkent-S5V4N54A-05e5uQDp.js → cose-bilkent-S5V4N54A-CZdGhX_3.js} +1 -1
- package/dist-renderer/assets/{dagre-6UL2VRFP-B06bRykF.js → dagre-6UL2VRFP-BVY-G6nO.js} +1 -1
- package/dist-renderer/assets/{diagram-PSM6KHXK-CY7VYQ7c.js → diagram-PSM6KHXK-CUACvAwG.js} +1 -1
- package/dist-renderer/assets/{diagram-QEK2KX5R-BjKEH7dD.js → diagram-QEK2KX5R-3SfnesSG.js} +1 -1
- package/dist-renderer/assets/{diagram-S2PKOQOG-Bf4ELS1_.js → diagram-S2PKOQOG-E3ksXClJ.js} +1 -1
- package/dist-renderer/assets/{erDiagram-Q2GNP2WA-DJ753_L9.js → erDiagram-Q2GNP2WA-aYjGXss7.js} +1 -1
- package/dist-renderer/assets/{flowDiagram-NV44I4VS-B71S-lC-.js → flowDiagram-NV44I4VS-JMHrrTQs.js} +1 -1
- package/dist-renderer/assets/{ganttDiagram-JELNMOA3-C_U42mSZ.js → ganttDiagram-JELNMOA3-CVQ-R5rN.js} +1 -1
- package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-DKUJU4Ns.js → gitGraphDiagram-V2S2FVAM-OLn9jq61.js} +1 -1
- package/dist-renderer/assets/{graph-DY3qbzqj.js → graph-BAb2J0l8.js} +1 -1
- package/dist-renderer/assets/{index-Dhsk3_DD.js → index-BSoCjBWn.js} +1 -1
- package/dist-renderer/assets/{index-Bs27J5gB.js → index-BtG3HbqP.js} +1 -1
- package/dist-renderer/assets/{index-BlOrAXp3.js → index-CH8e7g1f.js} +569 -569
- package/dist-renderer/assets/index-CSt8DTcn.css +1 -0
- package/dist-renderer/assets/{index-C8B_nKOF.js → index-Ca4iNkRA.js} +1 -1
- package/dist-renderer/assets/{index-GpUvV2xs.js → index-DU9PGgZJ.js} +1 -1
- package/dist-renderer/assets/{index-DLKyDr4T.js → index-DtMzIS9o.js} +1 -1
- package/dist-renderer/assets/{infoDiagram-HS3SLOUP-BNs0y3IG.js → infoDiagram-HS3SLOUP-CY_ptQNL.js} +1 -1
- package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-CqPnw4UV.js → journeyDiagram-XKPGCS4Q-C2vuHEo_.js} +1 -1
- package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-SLlzcUJ2.js → kanban-definition-3W4ZIXB7-mbdNfu8h.js} +1 -1
- package/dist-renderer/assets/{layout-BZLlNmbr.js → layout-Do_ArEB1.js} +1 -1
- package/dist-renderer/assets/{linear-qz6v45xy.js → linear-BMlMKyiq.js} +1 -1
- package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-B1-kmEWV.js → mindmap-definition-VGOIOE7T-Dfntn-o2.js} +1 -1
- package/dist-renderer/assets/{pieDiagram-ADFJNKIX-B8a02iNx.js → pieDiagram-ADFJNKIX-LiWHsGMV.js} +1 -1
- package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-BKv1Xfou.js → quadrantDiagram-AYHSOK5B-D87St8AF.js} +1 -1
- package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-B3DUpZi2.js → requirementDiagram-UZGBJVZJ-DAa6lHBx.js} +1 -1
- package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-DmPzuTsy.js → sankeyDiagram-TZEHDZUN-VOUngars.js} +1 -1
- package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-Bo7RelRb.js → sequenceDiagram-WL72ISMW-BzwzmFr2.js} +1 -1
- package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-1epX98gV.js → stateDiagram-FKZM4ZOC-BjAQEJ52.js} +1 -1
- package/dist-renderer/assets/{stateDiagram-v2-4FDKWEC3-03Ym9PTr.js → stateDiagram-v2-4FDKWEC3-BDwy4GJm.js} +1 -1
- package/dist-renderer/assets/{timeline-definition-IT6M3QCI-r6isC62H.js → timeline-definition-IT6M3QCI-Y5XBZt3W.js} +1 -1
- package/dist-renderer/assets/{treemap-GDKQZRPO-CGKpOUF2.js → treemap-GDKQZRPO-DzkdUEow.js} +1 -1
- package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-t4-rwdAw.js → xychartDiagram-PRI3JC2R-D-zbvJOv.js} +1 -1
- package/dist-renderer/index.html +2 -2
- package/package.json +1 -1
- package/src/renderer/components/extensions/ExtensionStoreView.tsx +4 -1
- package/src/renderer/components/extensions/mcp/McpServerDetailDialog.tsx +100 -15
- package/src/renderer/components/team/TeamDetailView.tsx +55 -139
- package/src/renderer/components/team/TeamListFilterPopover.tsx +0 -16
- package/src/renderer/components/team/TeamListView.tsx +7 -32
- package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +283 -409
- package/src/renderer/components/team/dialogs/useTeamEditForm.ts +283 -0
- package/src/renderer/utils/multimodelProviderVisibility.ts +17 -0
- package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +29 -9
- package/dist-renderer/assets/channel-DbjZvWii.js +0 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-D_FGxxsl.js +0 -1
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-D_FGxxsl.js +0 -1
- package/dist-renderer/assets/clone-CJ1kxO2J.js +0 -1
- package/dist-renderer/assets/index-CmZPUEhS.css +0 -1
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
DialogHeader,
|
|
23
23
|
DialogTitle,
|
|
24
24
|
} from '@renderer/components/ui/dialog';
|
|
25
|
+
import { Popover, PopoverContent, PopoverTrigger } from '@renderer/components/ui/popover';
|
|
25
26
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
|
26
27
|
import { getTeamColorSet, getThemedBadge } from '@renderer/constants/teamColors';
|
|
27
28
|
import { useTabIdOptional } from '@renderer/contexts/useTabUIContext';
|
|
@@ -69,6 +70,7 @@ import {
|
|
|
69
70
|
Trash2,
|
|
70
71
|
Loader2,
|
|
71
72
|
MessageSquare,
|
|
73
|
+
MoreHorizontal,
|
|
72
74
|
Shield,
|
|
73
75
|
Users,
|
|
74
76
|
} from 'lucide-react';
|
|
@@ -883,22 +885,7 @@ export const TeamDetailView = ({
|
|
|
883
885
|
const [updatingRoleLoading, setUpdatingRoleLoading] = useState(false);
|
|
884
886
|
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
|
885
887
|
const [envDialogOpen, setEnvDialogOpen] = useState(false);
|
|
886
|
-
const [
|
|
887
|
-
useEffect(() => {
|
|
888
|
-
if (!editDialogOpen || !teamName) return;
|
|
889
|
-
let cancelled = false;
|
|
890
|
-
void (async () => {
|
|
891
|
-
try {
|
|
892
|
-
const saved = await api.teams.getSavedRequest(teamName);
|
|
893
|
-
if (!cancelled) setSavedLaunchRequest(saved ?? null);
|
|
894
|
-
} catch {
|
|
895
|
-
if (!cancelled) setSavedLaunchRequest(null);
|
|
896
|
-
}
|
|
897
|
-
})();
|
|
898
|
-
return () => {
|
|
899
|
-
cancelled = true;
|
|
900
|
-
};
|
|
901
|
-
}, [editDialogOpen, teamName]);
|
|
888
|
+
const [headerMenuOpen, setHeaderMenuOpen] = useState(false);
|
|
902
889
|
const [launchDialogState, setLaunchDialogState] = useState<{
|
|
903
890
|
open: boolean;
|
|
904
891
|
mode: TeamLaunchDialogMode;
|
|
@@ -1643,11 +1630,7 @@ export const TeamDetailView = ({
|
|
|
1643
1630
|
|
|
1644
1631
|
const handleRestartTeamFromEdit = useCallback(async (): Promise<void> => {
|
|
1645
1632
|
await api.ccSettings.restart();
|
|
1646
|
-
|
|
1647
|
-
setTimeout(() => {
|
|
1648
|
-
void fetchTeams();
|
|
1649
|
-
void selectTeam(teamName);
|
|
1650
|
-
}, 3000);
|
|
1633
|
+
await Promise.all([fetchTeams(), selectTeam(teamName)]);
|
|
1651
1634
|
}, [fetchTeams, selectTeam, teamName]);
|
|
1652
1635
|
|
|
1653
1636
|
const handleSaveAndRestartFromEdit = useCallback(
|
|
@@ -2089,24 +2072,6 @@ export const TeamDetailView = ({
|
|
|
2089
2072
|
const headerColorSet = data.config.color
|
|
2090
2073
|
? getTeamColorSet(data.config.color)
|
|
2091
2074
|
: nameColorSet(data.config.name);
|
|
2092
|
-
const rawTeamSettings = (data.settings ?? {}) as Record<string, unknown>;
|
|
2093
|
-
const currentManagedSources =
|
|
2094
|
-
data.config.managedSources ??
|
|
2095
|
-
(typeof rawTeamSettings.admin_from === 'string' ? rawTeamSettings.admin_from : '*');
|
|
2096
|
-
const currentDisabledCommands =
|
|
2097
|
-
data.config.disabledCommands ??
|
|
2098
|
-
(Array.isArray(rawTeamSettings.disabled_commands)
|
|
2099
|
-
? rawTeamSettings.disabled_commands.filter(
|
|
2100
|
-
(entry): entry is string => typeof entry === 'string' && entry.trim().length > 0
|
|
2101
|
-
)
|
|
2102
|
-
: []);
|
|
2103
|
-
const currentPlatformAllowFrom =
|
|
2104
|
-
data.config.platformAllowFrom ??
|
|
2105
|
-
(typeof rawTeamSettings.platform_allow_from === 'object' &&
|
|
2106
|
-
rawTeamSettings.platform_allow_from !== null &&
|
|
2107
|
-
!Array.isArray(rawTeamSettings.platform_allow_from)
|
|
2108
|
-
? (rawTeamSettings.platform_allow_from as Record<string, string>)
|
|
2109
|
-
: {});
|
|
2110
2075
|
|
|
2111
2076
|
return (
|
|
2112
2077
|
<>
|
|
@@ -2158,52 +2123,55 @@ export const TeamDetailView = ({
|
|
|
2158
2123
|
</div>
|
|
2159
2124
|
</div>
|
|
2160
2125
|
<div className="flex shrink-0 items-center gap-1.5">
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
<TooltipContent side="bottom">环境变量</TooltipContent>
|
|
2174
|
-
</Tooltip>
|
|
2175
|
-
)}
|
|
2176
|
-
<Tooltip>
|
|
2177
|
-
<TooltipTrigger asChild>
|
|
2126
|
+
<Button
|
|
2127
|
+
variant="outline"
|
|
2128
|
+
size="sm"
|
|
2129
|
+
className="h-7 gap-1.5 px-2.5 text-xs text-[var(--color-text-secondary)]"
|
|
2130
|
+
disabled={isTeamProvisioning}
|
|
2131
|
+
onClick={() => setEditDialogOpen(true)}
|
|
2132
|
+
>
|
|
2133
|
+
<Pencil size={12} />
|
|
2134
|
+
编辑
|
|
2135
|
+
</Button>
|
|
2136
|
+
<Popover open={headerMenuOpen} onOpenChange={setHeaderMenuOpen}>
|
|
2137
|
+
<PopoverTrigger asChild>
|
|
2178
2138
|
<Button
|
|
2179
2139
|
variant="ghost"
|
|
2180
2140
|
size="sm"
|
|
2181
|
-
className="h-7
|
|
2182
|
-
disabled={isTeamProvisioning}
|
|
2183
|
-
onClick={() => setEditDialogOpen(true)}
|
|
2141
|
+
className="h-7 w-7 px-0 text-[var(--color-text-muted)]"
|
|
2184
2142
|
>
|
|
2185
|
-
<
|
|
2143
|
+
<MoreHorizontal size={14} />
|
|
2186
2144
|
</Button>
|
|
2187
|
-
</
|
|
2188
|
-
<
|
|
2189
|
-
{
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
size="sm"
|
|
2198
|
-
className="h-7 gap-1 px-2 text-xs text-red-400 hover:bg-red-500/10 hover:text-red-300"
|
|
2199
|
-
onClick={handleDeleteTeam}
|
|
2145
|
+
</PopoverTrigger>
|
|
2146
|
+
<PopoverContent align="end" className="w-44 p-1">
|
|
2147
|
+
{data.config.projectPath && (
|
|
2148
|
+
<button
|
|
2149
|
+
type="button"
|
|
2150
|
+
className="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-xs text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-raised)] hover:text-[var(--color-text)]"
|
|
2151
|
+
onClick={() => {
|
|
2152
|
+
setHeaderMenuOpen(false);
|
|
2153
|
+
setEnvDialogOpen(true);
|
|
2154
|
+
}}
|
|
2200
2155
|
>
|
|
2201
|
-
<
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2156
|
+
<Shield size={13} />
|
|
2157
|
+
环境变量
|
|
2158
|
+
</button>
|
|
2159
|
+
)}
|
|
2160
|
+
{teamName !== 'default' && teamName !== 'my-project' && (
|
|
2161
|
+
<button
|
|
2162
|
+
type="button"
|
|
2163
|
+
className="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-xs text-red-400 hover:bg-red-500/10"
|
|
2164
|
+
onClick={() => {
|
|
2165
|
+
setHeaderMenuOpen(false);
|
|
2166
|
+
handleDeleteTeam();
|
|
2167
|
+
}}
|
|
2168
|
+
>
|
|
2169
|
+
<Trash2 size={13} />
|
|
2170
|
+
删除团队
|
|
2171
|
+
</button>
|
|
2172
|
+
)}
|
|
2173
|
+
</PopoverContent>
|
|
2174
|
+
</Popover>
|
|
2207
2175
|
</div>
|
|
2208
2176
|
</div>
|
|
2209
2177
|
{data.config.description && (
|
|
@@ -2275,10 +2243,6 @@ export const TeamDetailView = ({
|
|
|
2275
2243
|
})()}
|
|
2276
2244
|
</div>
|
|
2277
2245
|
|
|
2278
|
-
{!data.isAlive && !isTeamProvisioning ? (
|
|
2279
|
-
<TeamOfflineStatusBanner teamName={teamName} onLaunch={handleStartCcConnectTeam} />
|
|
2280
|
-
) : null}
|
|
2281
|
-
|
|
2282
2246
|
<div ref={provisioningBannerRef}>
|
|
2283
2247
|
<TeamProvisioningBanner teamName={teamName} />
|
|
2284
2248
|
</div>
|
|
@@ -2616,62 +2580,6 @@ export const TeamDetailView = ({
|
|
|
2616
2580
|
}}
|
|
2617
2581
|
/>
|
|
2618
2582
|
|
|
2619
|
-
<EditTeamDialog
|
|
2620
|
-
open={editDialogOpen}
|
|
2621
|
-
teamName={teamName}
|
|
2622
|
-
currentName={data.config.name}
|
|
2623
|
-
currentDescription={data.config.description ?? ''}
|
|
2624
|
-
currentColor={data.config.color ?? ''}
|
|
2625
|
-
currentAgentType={data.config.agentType ?? data.harness ?? 'cursor'}
|
|
2626
|
-
currentWorkDir={data.workDir ?? data.config.projectPath ?? ''}
|
|
2627
|
-
currentPermissionMode={
|
|
2628
|
-
data.config.permissionMode ?? data.permissionMode ?? 'default'
|
|
2629
|
-
}
|
|
2630
|
-
currentLanguage={
|
|
2631
|
-
data.config.language ??
|
|
2632
|
-
(typeof rawTeamSettings.language === 'string' ? rawTeamSettings.language : 'zh')
|
|
2633
|
-
}
|
|
2634
|
-
currentShowContextIndicator={
|
|
2635
|
-
data.config.showContextIndicator ??
|
|
2636
|
-
(typeof rawTeamSettings.show_context_indicator === 'boolean'
|
|
2637
|
-
? rawTeamSettings.show_context_indicator
|
|
2638
|
-
: true)
|
|
2639
|
-
}
|
|
2640
|
-
currentReplyFooter={
|
|
2641
|
-
data.config.replyFooter ??
|
|
2642
|
-
(typeof rawTeamSettings.reply_footer === 'boolean'
|
|
2643
|
-
? rawTeamSettings.reply_footer
|
|
2644
|
-
: true)
|
|
2645
|
-
}
|
|
2646
|
-
currentInjectSender={
|
|
2647
|
-
data.config.injectSender ??
|
|
2648
|
-
(typeof rawTeamSettings.inject_sender === 'boolean'
|
|
2649
|
-
? rawTeamSettings.inject_sender
|
|
2650
|
-
: false)
|
|
2651
|
-
}
|
|
2652
|
-
currentManagedSources={currentManagedSources}
|
|
2653
|
-
currentDisabledCommands={currentDisabledCommands}
|
|
2654
|
-
currentPlatformAllowFrom={currentPlatformAllowFrom}
|
|
2655
|
-
currentProviderRefs={data.providerRefs ?? []}
|
|
2656
|
-
globalProviders={data.globalProviders ?? []}
|
|
2657
|
-
currentMembers={membersWithLiveBranches.filter((m) => !isLeadMember(m))}
|
|
2658
|
-
leadMember={membersWithLiveBranches.find((m) => isLeadMember(m)) ?? null}
|
|
2659
|
-
resolvedMemberColorMap={resolvedMemberColorMap}
|
|
2660
|
-
isTeamAlive={data.isAlive && !isTeamProvisioning}
|
|
2661
|
-
isTeamProvisioning={isTeamProvisioning}
|
|
2662
|
-
projectPath={data.config.projectPath}
|
|
2663
|
-
savedLaunchRequest={savedLaunchRequest}
|
|
2664
|
-
onClose={() => setEditDialogOpen(false)}
|
|
2665
|
-
onSaved={() => {
|
|
2666
|
-
void fetchTeams();
|
|
2667
|
-
void selectTeam(teamName);
|
|
2668
|
-
}}
|
|
2669
|
-
onDeleteTeam={
|
|
2670
|
-
teamName !== 'default' && teamName !== 'my-project' ? handleDeleteTeam : undefined
|
|
2671
|
-
}
|
|
2672
|
-
onRestartTeam={handleRestartTeamFromEdit}
|
|
2673
|
-
/>
|
|
2674
|
-
|
|
2675
2583
|
<Dialog open={envDialogOpen} onOpenChange={setEnvDialogOpen}>
|
|
2676
2584
|
<DialogContent className="max-h-[80vh] max-w-lg overflow-y-auto">
|
|
2677
2585
|
<DialogHeader>
|
|
@@ -2863,6 +2771,14 @@ export const TeamDetailView = ({
|
|
|
2863
2771
|
{teamAgentRuntimeWatcher}
|
|
2864
2772
|
{leadContextWatcher}
|
|
2865
2773
|
{renderBody()}
|
|
2774
|
+
<EditTeamDialog
|
|
2775
|
+
open={editDialogOpen}
|
|
2776
|
+
teamName={teamName}
|
|
2777
|
+
onClose={() => setEditDialogOpen(false)}
|
|
2778
|
+
onDeleteTeam={
|
|
2779
|
+
teamName !== 'default' && teamName !== 'my-project' ? handleDeleteTeam : undefined
|
|
2780
|
+
}
|
|
2781
|
+
/>
|
|
2866
2782
|
</>
|
|
2867
2783
|
);
|
|
2868
2784
|
};
|
|
@@ -79,10 +79,6 @@ export const TeamListFilterPopover = ({
|
|
|
79
79
|
() => teams.filter((t) => aliveSet.has(t.teamName)).length,
|
|
80
80
|
[teams, aliveSet]
|
|
81
81
|
);
|
|
82
|
-
const offlineCount = useMemo(
|
|
83
|
-
() => teams.filter((t) => !aliveSet.has(t.teamName)).length,
|
|
84
|
-
[teams, aliveSet]
|
|
85
|
-
);
|
|
86
82
|
|
|
87
83
|
return (
|
|
88
84
|
<Popover>
|
|
@@ -125,18 +121,6 @@ export const TeamListFilterPopover = ({
|
|
|
125
121
|
<span className="text-[var(--color-text-muted)]">({runningCount})</span>
|
|
126
122
|
</span>
|
|
127
123
|
</label>
|
|
128
|
-
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control -- Radix Checkbox renders a button, not a native input */}
|
|
129
|
-
<label className="flex cursor-pointer items-center gap-2 rounded-md px-1 py-0.5 text-xs text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-raised)]">
|
|
130
|
-
<Checkbox
|
|
131
|
-
checked={filter.selectedStatuses.has('offline')}
|
|
132
|
-
onCheckedChange={() => handleStatusToggle('offline')}
|
|
133
|
-
/>
|
|
134
|
-
<span className="flex items-center gap-1.5">
|
|
135
|
-
<span className="size-1.5 rounded-full bg-zinc-500" />
|
|
136
|
-
离线
|
|
137
|
-
<span className="text-[var(--color-text-muted)]">({offlineCount})</span>
|
|
138
|
-
</span>
|
|
139
|
-
</label>
|
|
140
124
|
</div>
|
|
141
125
|
</div>
|
|
142
126
|
|
|
@@ -85,7 +85,7 @@ function generateUniqueName(sourceName: string, existingNames: string[]): string
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
type TeamStatus = 'active' | 'idle' | 'provisioning'
|
|
88
|
+
type TeamStatus = 'active' | 'idle' | 'provisioning';
|
|
89
89
|
|
|
90
90
|
function getRecentProjects(team: TeamSummary): string[] {
|
|
91
91
|
const history = team.projectPathHistory;
|
|
@@ -162,7 +162,7 @@ function renderMemberChips(members: TeamSummaryMember[], isLight: boolean): Reac
|
|
|
162
162
|
|
|
163
163
|
function renderTeamRecentPaths(
|
|
164
164
|
team: TeamSummary,
|
|
165
|
-
status: TeamStatus,
|
|
165
|
+
status: TeamStatus | null,
|
|
166
166
|
matchesCurrentProject: boolean,
|
|
167
167
|
isLight: boolean
|
|
168
168
|
): React.JSX.Element | null {
|
|
@@ -211,7 +211,7 @@ function resolveTeamStatus(
|
|
|
211
211
|
aliveTeams: string[],
|
|
212
212
|
currentProgress: ReturnType<typeof getCurrentProvisioningProgressForTeam>,
|
|
213
213
|
leadActivityByTeam: Record<string, string>
|
|
214
|
-
): TeamStatus {
|
|
214
|
+
): TeamStatus | null {
|
|
215
215
|
if (aliveTeams.includes(teamName)) {
|
|
216
216
|
return leadActivityByTeam[teamName] === 'active' ? 'active' : 'idle';
|
|
217
217
|
}
|
|
@@ -223,10 +223,11 @@ function resolveTeamStatus(
|
|
|
223
223
|
) {
|
|
224
224
|
return 'provisioning';
|
|
225
225
|
}
|
|
226
|
-
return
|
|
226
|
+
return null;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
const StatusBadge = ({ status }: { status: TeamStatus }): React.JSX.Element => {
|
|
229
|
+
const StatusBadge = ({ status }: { status: TeamStatus | null }): React.JSX.Element | null => {
|
|
230
|
+
if (!status) return null;
|
|
230
231
|
switch (status) {
|
|
231
232
|
case 'active':
|
|
232
233
|
return (
|
|
@@ -249,13 +250,6 @@ const StatusBadge = ({ status }: { status: TeamStatus }): React.JSX.Element => {
|
|
|
249
250
|
启动中...
|
|
250
251
|
</span>
|
|
251
252
|
);
|
|
252
|
-
case 'offline':
|
|
253
|
-
return (
|
|
254
|
-
<span className="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full bg-zinc-500/15 px-2 py-0.5 text-[10px] font-medium text-zinc-500">
|
|
255
|
-
<span className="size-1.5 rounded-full bg-zinc-500" />
|
|
256
|
-
离线
|
|
257
|
-
</span>
|
|
258
|
-
);
|
|
259
253
|
}
|
|
260
254
|
};
|
|
261
255
|
|
|
@@ -436,9 +430,8 @@ export const TeamListView = (): React.JSX.Element => {
|
|
|
436
430
|
getCurrentProvisioningProgressForTeam(provisioningState, t.teamName),
|
|
437
431
|
leadActivityByTeam
|
|
438
432
|
);
|
|
439
|
-
const isRunning = status !==
|
|
433
|
+
const isRunning = status !== null;
|
|
440
434
|
if (filter.selectedStatuses.has('running') && isRunning) return true;
|
|
441
|
-
if (filter.selectedStatuses.has('offline') && !isRunning) return true;
|
|
442
435
|
return false;
|
|
443
436
|
});
|
|
444
437
|
}
|
|
@@ -1154,24 +1147,6 @@ export const TeamListView = (): React.JSX.Element => {
|
|
|
1154
1147
|
})()}
|
|
1155
1148
|
</div>
|
|
1156
1149
|
<div className="flex shrink-0 gap-1">
|
|
1157
|
-
{status === 'offline' && team.projectPath && (
|
|
1158
|
-
<Tooltip>
|
|
1159
|
-
<TooltipTrigger asChild>
|
|
1160
|
-
<button
|
|
1161
|
-
type="button"
|
|
1162
|
-
className="shrink-0 rounded p-1 text-[var(--color-text-muted)] opacity-0 transition-opacity hover:bg-emerald-500/10 hover:text-emerald-300 disabled:opacity-50 group-hover:opacity-100"
|
|
1163
|
-
onClick={(e) => handleLaunchTeam(team.teamName, team.projectPath, e)}
|
|
1164
|
-
disabled={launchingTeamName === team.teamName}
|
|
1165
|
-
aria-label="启动团队"
|
|
1166
|
-
>
|
|
1167
|
-
<Play size={14} fill="currentColor" />
|
|
1168
|
-
</button>
|
|
1169
|
-
</TooltipTrigger>
|
|
1170
|
-
<TooltipContent side="bottom">
|
|
1171
|
-
{launchingTeamName === team.teamName ? '启动中…' : '启动团队'}
|
|
1172
|
-
</TooltipContent>
|
|
1173
|
-
</Tooltip>
|
|
1174
|
-
)}
|
|
1175
1150
|
{!team.pendingCreate && (
|
|
1176
1151
|
<Tooltip>
|
|
1177
1152
|
<TooltipTrigger asChild>
|