Skip to content
Open
Show file tree
Hide file tree
Changes from all 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