Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import '@fontsource/inter/600.css';
import '@fontsource/inter/700.css';
import '@fontsource/inter/800.css';
import type { Preview } from '@storybook/react-vite';
import { Toaster } from 'sonner';
import { Toaster } from '../src/components/ui/sonner';
import '../src/style/index.css';
import './storybook.css'; // Storybook-specific overrides

Expand Down
6 changes: 3 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
// limitations under the License.
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========

import { Toaster } from '@/components/ui/sonner';
import { queryClient } from '@/lib/queryClient';
import AppRoutes from '@/routers/index';
import { stackClientApp } from '@/stack/client';
import { StackProvider, StackTheme } from '@stackframe/react';
import { QueryClientProvider } from '@tanstack/react-query';
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Toaster } from 'sonner';
import { useBackgroundTaskProcessor } from './hooks/useBackgroundTaskProcessor';
import { useExecutionSubscription } from './hooks/useExecutionSubscription';
import { useTriggerTaskExecutor } from './hooks/useTriggerTaskExecutor';
Expand Down Expand Up @@ -88,14 +88,14 @@ function App() {
return (
<StackProvider app={stackClientApp}>
<StackTheme>{content}</StackTheme>
<Toaster style={{ zIndex: '999999 !important', position: 'fixed' }} />
<Toaster />
</StackProvider>
);
}
return (
<>
{content}
<Toaster style={{ zIndex: '999999 !important', position: 'fixed' }} />
<Toaster />
</>
);
};
Expand Down
52 changes: 28 additions & 24 deletions src/components/AddWorker/ToolSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const ToolSelect = forwardRef<
const [installed, setInstalled] = useState<{ [id: number]: boolean }>({});
const [installing, setInstalling] = useState<{ [id: number]: boolean }>({});
const [installedIds, setInstalledIds] = useState<number[]>([]);
const [userMcpsHydrated, setUserMcpsHydrated] = useState(false);
const { email } = useAuthStore();
// add: integration service list
const [integrations, setIntegrations] = useState<any[]>([]);
Expand Down Expand Up @@ -357,22 +358,22 @@ const ToolSelect = forwardRef<
console.error('Error fetching installed MCPs:', error);
setInstalledIds([]);
setCustomMcpList([]);
});
})
.finally(() => setUserMcpsHydrated(true));
}, []);

// only surface installed MCPs from the market list
useEffect(() => {
// Add defensive check and fix logic: should filter when installedIds has items
if (!userMcpsHydrated) return;
if (Array.isArray(allMcpList) && installedIds.length > 0) {
const filtered = allMcpList.filter((item) =>
installedIds.includes(item.id)
);
setMcpList(filtered);
} else if (Array.isArray(allMcpList)) {
// If no installed IDs, show empty list instead of all
setMcpList([]);
}
}, [allMcpList, installedIds]);
}, [allMcpList, installedIds, userMcpsHydrated]);

// public save env/config logic
const saveEnvAndConfig = async (
Expand Down Expand Up @@ -705,6 +706,7 @@ const ToolSelect = forwardRef<
};

const getInstallButtonText = (itemId: number) => {
if (!userMcpsHydrated) return t('setting.loading');
if (installedIds.includes(itemId)) return t('layout.installed');
if (installing[itemId]) return t('layout.installing');
if (installed[itemId]) return t('layout.installed');
Expand Down Expand Up @@ -757,12 +759,12 @@ const ToolSelect = forwardRef<
{(initialSelectedTools || []).map((item: any) => (
<Badge
key={item.id + item.key + (item.isLocal + '')}
className="flex h-5 w-auto flex-shrink-0 items-center gap-1 bg-button-tertiery-fill-default px-xs"
className="h-5 gap-1 bg-button-tertiery-fill-default px-xs flex w-auto flex-shrink-0 items-center"
>
{item.name || item.mcp_name || item.key || `tool_${item.id}`}
<div className="flex items-center justify-center rounded-sm bg-button-secondary-fill-disabled">
<div className="rounded-sm bg-button-secondary-fill-disabled flex items-center justify-center">
<X
className="h-4 w-4 cursor-pointer text-button-secondary-icon-disabled"
className="h-4 w-4 text-button-secondary-icon-disabled cursor-pointer"
onClick={() => removeOption(item)}
/>
</div>
Expand All @@ -775,7 +777,7 @@ const ToolSelect = forwardRef<
<div
key={item.id}
onClick={() => {
// check if already installed
if (!userMcpsHydrated) return;
const isAlreadyInstalled =
installedIds.includes(item.id) || installed[item.id];

Expand All @@ -788,21 +790,21 @@ const ToolSelect = forwardRef<
checkEnv(item.id);
}
}}
className="flex cursor-pointer justify-between px-3 py-2 hover:bg-surface-hover-subtle"
className="px-3 py-2 hover:bg-surface-hover-subtle flex cursor-pointer justify-between"
>
<div className="flex items-center gap-1">
<div className="gap-1 flex items-center">
{getCategoryIcon(item.category?.name)}
<div className="line-clamp-1 overflow-hidden text-ellipsis break-words text-sm font-bold leading-17 text-text-action">
<div className="text-sm font-bold leading-17 text-text-action line-clamp-1 overflow-hidden break-words text-ellipsis">
{item.name}
</div>
<TooltipSimple content={item.description}>
<CircleAlert
className="h-4 w-4 cursor-pointer text-icon-primary"
className="h-4 w-4 text-icon-primary cursor-pointer"
onClick={(e) => e.stopPropagation()}
/>
</TooltipSimple>
</div>
<div className="flex items-center gap-1">
<div className="gap-1 flex items-center">
{getGithubRepoName(item.home_page) && (
<div className="flex items-center">
<img
Expand All @@ -816,15 +818,17 @@ const ToolSelect = forwardRef<
verticalAlign: 'middle',
}}
/>
<span className="line-clamp-1 items-center justify-center self-stretch overflow-hidden text-ellipsis break-words text-xs font-medium leading-3">
<span className="text-xs font-medium leading-3 line-clamp-1 items-center justify-center self-stretch overflow-hidden break-words text-ellipsis">
{getGithubRepoName(item.home_page)}
</span>
</div>
)}
<Button
variant="primary"
size="sm"
rounded="full"
disabled={
!userMcpsHydrated ||
installed[item.id] ||
installing[item.id] ||
installedIds.includes(item.id)
Expand All @@ -847,21 +851,21 @@ const ToolSelect = forwardRef<
addOption(item);
setKeyword('');
}}
className="flex cursor-pointer justify-between px-3 py-2 hover:bg-surface-hover-subtle"
className="px-3 py-2 hover:bg-surface-hover-subtle flex cursor-pointer justify-between"
>
<div className="flex items-center gap-1">
<div className="gap-1 flex items-center">
{/* {getCategoryIcon(item.category?.name)} */}
<div className="line-clamp-1 overflow-hidden text-ellipsis break-words text-sm font-bold leading-17 text-text-action">
<div className="text-sm font-bold leading-17 text-text-action line-clamp-1 overflow-hidden break-words text-ellipsis">
{item.mcp_name}
</div>
<TooltipSimple content={item.mcp_desc}>
<CircleAlert
className="h-4 w-4 cursor-pointer text-icon-primary"
className="h-4 w-4 text-icon-primary cursor-pointer"
onClick={(e) => e.stopPropagation()}
/>
</TooltipSimple>
</div>
<div className="flex items-center gap-1">
<div className="gap-1 flex items-center">
<Button
className="h-6 rounded-md bg-button-secondary-fill-default px-sm py-xs text-xs font-bold leading-17 text-button-secondary-text-default shadow-sm hover:bg-button-tertiery-text-default"
disabled={true}
Expand All @@ -873,8 +877,8 @@ const ToolSelect = forwardRef<
);
return (
<div className="relative w-full" ref={containerRef}>
<div className="bg-white flex min-h-[40px] flex-wrap gap-1.5 rounded-lg border">
<div className="flex items-center gap-1 text-sm font-bold leading-normal text-text-body">
<div className="bg-white gap-1.5 rounded-lg flex min-h-[40px] flex-wrap border">
<div className="gap-1 text-sm font-bold leading-normal text-text-body flex items-center">
{t('workforce.agent-tool')}
<TooltipSimple content={t('workforce.agent-tool-tooltip')}>
<CircleAlert size={16} className="text-icon-primary" />
Expand All @@ -885,7 +889,7 @@ const ToolSelect = forwardRef<
inputRef.current?.focus();
setIsOpen(true);
}}
className="flex max-h-[120px] min-h-[60px] w-full flex-wrap justify-start gap-1 overflow-y-auto rounded-lg border border-solid border-input-border-default bg-input-bg-default px-[6px] py-1"
className="gap-1 rounded-lg border-input-border-default bg-input-bg-default py-1 flex max-h-[120px] min-h-[60px] w-full flex-wrap justify-start overflow-y-auto border border-solid px-[6px]"
>
{renderSelectedItems()}
<Textarea
Expand All @@ -894,14 +898,14 @@ const ToolSelect = forwardRef<
onChange={(e) => setKeyword(e.target.value)}
onFocus={() => setIsOpen(true)}
ref={inputRef}
className="!h-[20px] w-auto resize-none border-none bg-transparent p-0 text-sm leading-normal !shadow-none !ring-0 !ring-offset-0"
className="p-0 text-sm leading-normal !h-[20px] w-auto resize-none border-none bg-transparent !shadow-none !ring-0 !ring-offset-0"
/>
</div>
</div>

{/* floating dropdown */}
{isOpen && (
<div className="absolute left-0 right-0 top-full z-50 mt-1 overflow-y-auto rounded-lg border border-solid border-input-border-default bg-dropdown-bg">
<div className="left-0 right-0 mt-1 rounded-lg border-input-border-default bg-dropdown-bg absolute top-full z-50 overflow-y-auto border border-solid">
<div className="max-h-[192px] overflow-y-auto">
<IntegrationList
variant="select"
Expand Down
30 changes: 16 additions & 14 deletions src/components/AddWorker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,8 @@ export function AddWorker({
{showEnvConfig ? (
// environment configuration interface
<>
<DialogContentSection className="flex flex-col gap-3 bg-white-100% p-md">
<div className="flex items-center gap-md">
<DialogContentSection className="gap-3 bg-white-100% p-md flex flex-col">
<div className="gap-md flex items-center">
{getCategoryIcon(activeMcp?.category?.name)}
<div>
<div className="text-base font-bold leading-9 text-text-action">
Expand All @@ -490,15 +490,15 @@ export function AddWorker({
verticalAlign: 'middle',
}}
/>
<span className="line-clamp-1 items-center justify-center self-stretch overflow-hidden text-ellipsis break-words text-xs font-medium leading-normal">
<span className="text-xs font-medium leading-normal line-clamp-1 items-center justify-center self-stretch overflow-hidden break-words text-ellipsis">
{getGithubRepoName(activeMcp?.home_page)}
</span>
</div>
)}
</div>
</div>
</div>
<div className="flex flex-col gap-sm">
<div className="gap-sm flex flex-col">
{Object.keys(activeMcp?.install_command?.env || {}).map(
(key) => (
<div key={key}>
Expand Down Expand Up @@ -553,7 +553,9 @@ export function AddWorker({
onCancel={handleCloseMcpEnvSetting}
onConfirm={handleConfigureMcpEnvSetting}
cancelButtonVariant="ghost"
cancelButtonRounded="full"
confirmButtonVariant="primary"
confirmButtonRounded="full"
></DialogFooter>
{/* hidden but keep rendering ToolSelect component */}
<div style={{ display: 'none' }}>
Expand All @@ -568,10 +570,10 @@ export function AddWorker({
) : (
// default add interface
<>
<DialogContentSection className="flex flex-col gap-3 bg-white-100% p-md">
<div className="flex flex-col gap-4">
<div className="flex items-center gap-sm">
<div className="flex h-16 w-16 items-center justify-center">
<DialogContentSection className="gap-3 bg-white-100% p-md flex flex-col">
<div className="gap-4 flex flex-col">
<div className="gap-sm flex items-center">
<div className="h-16 w-16 flex items-center justify-center">
<Bot size={32} className="text-icon-primary" />
</div>
<Input
Expand Down Expand Up @@ -608,10 +610,10 @@ export function AddWorker({
/>

{/* Model Configuration Section */}
<div className="mt-2 flex flex-col gap-2">
<div className="mt-2 gap-2 flex flex-col">
<button
type="button"
className="flex items-center gap-1 text-sm text-text-body hover:text-text-action"
className="gap-1 text-sm text-text-body hover:text-text-action flex items-center"
onClick={() => setShowModelConfig(!showModelConfig)}
>
{showModelConfig ? (
Expand All @@ -623,8 +625,8 @@ export function AddWorker({
</button>

{showModelConfig && (
<div className="flex flex-col gap-3 rounded-lg bg-surface-tertiary-subtle p-3">
<label className="flex items-center gap-2 text-sm">
<div className="gap-3 rounded-lg bg-surface-tertiary-subtle p-3 flex flex-col">
<label className="gap-2 text-sm flex items-center">
<input
type="checkbox"
checked={useCustomModel}
Expand All @@ -636,7 +638,7 @@ export function AddWorker({

{useCustomModel && (
<>
<div className="flex flex-col gap-1">
<div className="gap-1 flex flex-col">
<label className="text-xs text-text-body">
{t('workforce.model-platform')}
</label>
Expand All @@ -662,7 +664,7 @@ export function AddWorker({
</Select>
</div>

<div className="flex flex-col gap-1">
<div className="gap-1 flex flex-col">
<label className="text-xs text-text-body">
{t('workforce.model-type')}
</label>
Expand Down
Loading
Loading