fix: lint errors + redundant css

This commit is contained in:
Siddhant Rai committed 2026-03-28 15:02:16 +05:30
1 parent 174dee0fe6
commit 193ca6fd63
65 files changed
+561 -543

No files matched your search

+1 -1
View File
@@ -44,7 +44,7 @@ export default function Hero({
<button
key={key}
onClick={() => handleQuestion({ question: demo.query })}
className={`border-border text-foreground hover:bg-muted dark:hover:bg-muted/50 bg-card dark:bg-transparent w-full rounded-[66px] border px-6 py-3.5 text-left transition-colors ${key >= 2 ? 'hidden md:block' : ''}`}
className={`border-border text-foreground hover:bg-muted dark:hover:bg-muted/50 bg-card w-full rounded-[66px] border px-6 py-3.5 text-left transition-colors dark:bg-transparent ${key >= 2 ? 'hidden md:block' : ''}`}
>
<p className="text-black-1000 dark:text-foreground mb-2 font-semibold">
{demo.header}
+8 -12
View File
@@ -394,7 +394,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
</NavLink>
<div
id="conversationsMainDiv"
className="mb-auto h-[78vh] overflow-x-hidden overflow-y-auto scrollbar-overlay dark:text-white"
className="scrollbar-overlay mb-auto h-[78vh] overflow-x-hidden overflow-y-auto dark:text-white"
>
{conversations?.loading && !isDeletingConversation && (
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transform">
@@ -540,7 +540,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
}}
to="/settings"
className={({ isActive }) =>
`mx-4 my-auto flex h-9 cursor-pointer items-center gap-4 rounded-3xl hover:bg-sidebar-accent ${
`hover:bg-sidebar-accent mx-4 my-auto flex h-9 cursor-pointer items-center gap-4 rounded-3xl ${
isActive ? 'bg-sidebar-accent' : ''
}`
}
@@ -565,9 +565,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
<NavLink
target="_blank"
to={'https://discord.gg/vN7YFfdMpj'}
className={
'rounded-full hover:bg-sidebar-accent'
}
className={'hover:bg-sidebar-accent rounded-full'}
>
<img
src={Discord}
@@ -580,9 +578,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
<NavLink
target="_blank"
to={'https://x.com/docsgptai'}
className={
'rounded-full hover:bg-sidebar-accent'
}
className={'hover:bg-sidebar-accent rounded-full'}
>
<img
src={Twitter}
@@ -595,9 +591,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
<NavLink
target="_blank"
to={'https://github.com/arc53/docsgpt'}
className={
'rounded-full hover:bg-sidebar-accent'
}
className={'hover:bg-sidebar-accent rounded-full'}
>
<img
src={Github}
@@ -624,7 +618,9 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
className="w-7 filter dark:invert"
/>
</button>
<div className="text-muted-foreground text-[20px] font-medium">DocsGPT</div>
<div className="text-muted-foreground text-[20px] font-medium">
DocsGPT
</div>
</div>
</div>
<DeleteConvModal
+1 -1
View File
@@ -6,7 +6,7 @@ export default function PageNotFound() {
return (
<div className="bg-background grid min-h-screen">
<p className="text-foreground mx-auto my-auto mt-20 flex w-full max-w-6xl flex-col place-items-center gap-6 rounded-3xl bg-gray-100 p-6 lg:p-10 xl:p-16 dark:bg-card">
<p className="text-foreground dark:bg-card mx-auto my-auto mt-20 flex w-full max-w-6xl flex-col place-items-center gap-6 rounded-3xl bg-gray-100 p-6 lg:p-10 xl:p-16">
<h1>{t('pageNotFound.title')}</h1>
<p>{t('pageNotFound.message')}</p>
<button className="pointer-cursor bg-blue-1000 hover:bg-blue-3000 mr-4 flex cursor-pointer items-center justify-center rounded-full px-4 py-2 text-white transition-colors duration-100">
+5 -5
View File
@@ -251,7 +251,7 @@ export default function AgentCard({
};
return (
<div
className={`relative flex h-44 flex-col justify-between rounded-[1.2rem] bg-muted px-4 py-5 hover:bg-accent sm:w-48 sm:px-6 ${agent.status === 'published' && 'cursor-pointer'}`}
className={`bg-muted hover:bg-accent relative flex h-44 flex-col justify-between rounded-[1.2rem] px-4 py-5 sm:w-48 sm:px-6 ${agent.status === 'published' && 'cursor-pointer'}`}
onClick={(e) => {
e.stopPropagation();
handleClick();
@@ -283,17 +283,17 @@ export default function AgentCard({
className="h-7 w-7 rounded-full object-contain"
/>
{agent.status === 'draft' && (
<p className="text-xs text-foreground opacity-50">{`(Draft)`}</p>
<p className="text-foreground text-xs opacity-50">{`(Draft)`}</p>
)}
</div>
<div className="mt-2">
<p
title={agent.name}
className="truncate px-1 text-[13px] leading-relaxed font-semibold text-foreground capitalize"
className="text-foreground truncate px-1 text-[13px] leading-relaxed font-semibold capitalize"
>
{agent.name}
</p>
<p className="dark:text-muted-foreground mt-1 h-20 overflow-auto px-1 text-[12px] leading-relaxed text-muted-foreground">
<p className="dark:text-muted-foreground text-muted-foreground mt-1 h-20 overflow-auto px-1 text-[12px] leading-relaxed">
{agent.description}
</p>
</div>
@@ -320,4 +320,4 @@ export default function AgentCard({
/>
</div>
);
}
}
+2 -2
View File
@@ -41,7 +41,7 @@ export default function AgentLogs() {
<div className="p-4 md:p-12">
<div className="flex items-center gap-3 px-4">
<button
className="rounded-full border border-border p-3 text-sm text-muted-foreground hover:bg-accent"
className="border-border text-muted-foreground hover:bg-accent rounded-full border p-3 text-sm"
onClick={() => navigate('/agents')}
>
<img src={ArrowLeft} alt="left-arrow" className="h-3 w-3" />
@@ -59,7 +59,7 @@ export default function AgentLogs() {
{agent && (
<div className="flex flex-col gap-1">
<p className="text-foreground">{agent.name}</p>
<p className="text-xs text-muted-foreground">
<p className="text-muted-foreground text-xs">
{agent.last_used_at
? t('agents.logs.lastUsedAt') +
' ' +
+12 -12
View File
@@ -162,7 +162,7 @@ export default function AgentsList() {
<h1 className="text-foreground mb-0 text-[32px] font-bold lg:text-[40px]">
{t('agents.title')}
</h1>
<p className="mt-5 text-[15px] leading-6 text-muted-foreground">
<p className="text-muted-foreground mt-5 text-[15px] leading-6">
{t('agents.description')}
</p>
@@ -178,7 +178,7 @@ export default function AgentsList() {
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder={t('agents.searchPlaceholder')}
className="h-11 w-full rounded-full border border-border bg-card py-2 pr-5 pl-11 text-sm text-foreground shadow-[0_1px_4px_rgba(0,0,0,0.06)] transition-shadow outline-none placeholder:text-muted-foreground focus:shadow-[0_2px_8px_rgba(0,0,0,0.1)] dark:shadow-none"
className="border-border bg-card text-foreground placeholder:text-muted-foreground h-11 w-full rounded-full border py-2 pr-5 pl-11 text-sm shadow-[0_1px_4px_rgba(0,0,0,0.06)] transition-shadow outline-none focus:shadow-[0_2px_8px_rgba(0,0,0,0.1)] dark:shadow-none"
/>
</div>
@@ -190,7 +190,7 @@ export default function AgentsList() {
className={`rounded-full px-4 py-2 text-sm transition-colors ${
activeFilter === tab.id
? 'bg-border text-foreground dark:bg-accent dark:text-white'
: 'dark:text-gray bg-transparent text-muted-foreground hover:bg-accent/50'
: 'dark:text-gray text-muted-foreground hover:bg-accent/50 bg-transparent'
}`}
>
{t(tab.labelKey)}
@@ -224,7 +224,7 @@ export default function AgentsList() {
))}
{showSearchEmptyState && (
<div className="mt-12 flex flex-col items-center justify-center gap-2 text-muted-foreground">
<div className="text-muted-foreground mt-12 flex flex-col items-center justify-center gap-2">
<p className="text-lg">{t('agents.noSearchResults')}</p>
<p className="text-sm">{t('agents.tryDifferentSearch')}</p>
</div>
@@ -399,7 +399,7 @@ function AgentSection({
if (isFilteredView && isSearchingWithNoResults) {
return (
<div className="mt-12 flex flex-col items-center justify-center gap-2 text-muted-foreground">
<div className="text-muted-foreground mt-12 flex flex-col items-center justify-center gap-2">
<p className="text-lg">{t('agents.noSearchResults')}</p>
<p className="text-sm">{t('agents.tryDifferentSearch')}</p>
</div>
@@ -408,7 +408,7 @@ function AgentSection({
if (isFilteredView && hasNoAgentsAtAll) {
return (
<div className="mt-12 flex flex-col items-center justify-center gap-3 text-muted-foreground">
<div className="text-muted-foreground mt-12 flex flex-col items-center justify-center gap-3">
<p>{t(`agents.sections.${config.id}.emptyState`)}</p>
{config.showNewAgentButton && (
<button
@@ -456,7 +456,7 @@ function AgentSection({
<div className="mt-8 flex flex-col gap-4">
<div className="flex w-full flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div className="flex flex-col gap-2">
<h2 className="flex flex-wrap items-center gap-2 text-[18px] font-semibold text-foreground">
<h2 className="text-foreground flex flex-wrap items-center gap-2 text-[18px] font-semibold">
{config.id === 'user' && folderPath.length > 0 ? (
<>
<button
@@ -485,7 +485,7 @@ function AgentSection({
t(`agents.sections.${config.id}.title`)
)}
</h2>
<p className="text-[13px] text-muted-foreground">
<p className="text-muted-foreground text-[13px]">
{t(`agents.sections.${config.id}.description`)}
</p>
</div>
@@ -513,12 +513,12 @@ function AgentSection({
}
}}
placeholder={t('agents.folders.newFolder')}
className="w-28 rounded-full border border-border bg-card px-4 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground sm:w-auto"
className="border-border bg-card text-foreground placeholder:text-muted-foreground w-28 rounded-full border px-4 py-2 text-sm outline-none sm:w-auto"
autoFocus
/>
) : (
<button
className="shrink-0 rounded-full border border-border bg-card px-4 py-2 text-sm whitespace-nowrap text-foreground hover:bg-accent"
className="border-border bg-card text-foreground hover:bg-accent shrink-0 rounded-full border px-4 py-2 text-sm whitespace-nowrap"
onClick={() => {
setIsCreatingFolder(true);
setTimeout(() => newFolderInputRef.current?.focus(), 0);
@@ -579,7 +579,7 @@ function AgentSection({
))}
</div>
) : hasNoAgentsAtAll && currentLevelFolders.length === 0 ? (
<div className="flex h-40 w-full flex-col items-center justify-center gap-3 text-muted-foreground">
<div className="text-muted-foreground flex h-40 w-full flex-col items-center justify-center gap-3">
<p>
{currentFolderId
? t('agents.folders.empty')
@@ -603,4 +603,4 @@ function AgentSection({
</div>
</div>
);
}
}
+3 -5
View File
@@ -70,17 +70,15 @@ export default function FolderCard({
<>
<div
className={`relative flex cursor-pointer items-center justify-between rounded-[1.2rem] px-4 py-3 sm:w-48 ${
isExpanded
? 'bg-accent'
: 'bg-muted hover:bg-accent'
isExpanded ? 'bg-accent' : 'bg-muted hover:bg-accent'
}`}
onClick={() => onToggleExpand(folder.id)}
>
<div className="flex items-center gap-2 overflow-hidden">
<span className="truncate text-sm font-medium text-foreground">
<span className="text-foreground truncate text-sm font-medium">
{folder.name}
</span>
<span className="shrink-0 text-xs text-muted-foreground">
<span className="text-muted-foreground shrink-0 text-xs">
({agentCount})
</span>
</div>
+1 -1
View File
@@ -143,7 +143,7 @@ export default function SharedAgent() {
alt="No agent found"
className="mx-auto mb-6 h-32 w-32"
/>
<p className="text-center text-lg text-muted-foreground">
<p className="text-muted-foreground text-center text-lg">
{t('agents.shared.notFound')}
</p>
</div>
+2 -2
View File
@@ -21,7 +21,7 @@ export default function SharedAgentCard({ agent }: { agent: Agent }) {
<h2 className="text-foreground text-base font-semibold sm:text-lg">
{agent.name}
</h2>
<p className="overflow-y-auto text-xs text-wrap break-all text-muted-foreground sm:text-sm">
<p className="text-muted-foreground overflow-y-auto text-xs text-wrap break-all sm:text-sm">
{agent.description}
</p>
</div>
@@ -34,7 +34,7 @@ export default function SharedAgentCard({ agent }: { agent: Agent }) {
</p>
)}
{agent.shared_metadata?.shared_at && (
<p className="text-xs font-light text-muted-foreground sm:text-sm">
<p className="text-muted-foreground text-xs font-light sm:text-sm">
Shared on{' '}
{new Date(agent.shared_metadata.shared_at).toLocaleString(
'en-US',
+27 -30
View File
@@ -575,12 +575,12 @@ function WorkflowBuilderInner() {
]);
return (
<div className="flex h-screen w-full flex-col bg-background">
<div className="flex items-center justify-between border-b border-border bg-card px-6 py-4">
<div className="bg-background flex h-screen w-full flex-col">
<div className="border-border bg-card flex items-center justify-between border-b px-6 py-4">
<div className="flex items-center gap-4">
<button
onClick={() => navigate('/agents')}
className="rounded-full border border-border p-3 text-sm text-muted-foreground hover:bg-accent"
className="border-border text-muted-foreground hover:bg-accent rounded-full border p-3 text-sm"
>
<img src={ArrowLeft} alt="left-arrow" className="h-3 w-3" />
</button>
@@ -609,7 +609,7 @@ function WorkflowBuilderInner() {
{showWorkflowSettings && (
<div
ref={workflowSettingsRef}
className="absolute top-full left-0 z-50 mt-2 w-80 rounded-xl border border-border bg-card p-4 shadow-lg"
className="border-border bg-card absolute top-full left-0 z-50 mt-2 w-80 rounded-xl border p-4 shadow-lg"
>
<div className="mb-3">
<label className="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">
@@ -619,7 +619,7 @@ function WorkflowBuilderInner() {
type="text"
value={workflowName}
onChange={(e) => setWorkflowName(e.target.value)}
className="w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-lg border px-3 py-2 text-sm outline-none focus:ring-2"
placeholder="Enter workflow name"
/>
</div>
@@ -630,14 +630,14 @@ function WorkflowBuilderInner() {
<textarea
value={workflowDescription}
onChange={(e) => setWorkflowDescription(e.target.value)}
className="w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-lg border px-3 py-2 text-sm outline-none focus:ring-2"
rows={3}
placeholder="Describe what this workflow does"
/>
</div>
<button
onClick={() => setShowWorkflowSettings(false)}
className="w-full rounded-lg bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90"
className="bg-primary text-primary-foreground hover:bg-primary/90 w-full rounded-lg px-3 py-2 text-sm font-medium"
>
Done
</button>
@@ -656,7 +656,7 @@ function WorkflowBuilderInner() {
}
setShowPreview(true);
}}
className="flex items-center gap-2 rounded-full border border-border bg-card px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-accent"
className="border-border bg-card text-foreground hover:bg-accent flex items-center gap-2 rounded-full border px-4 py-2 text-sm font-medium transition-colors"
>
<Play size={16} />
Preview
@@ -664,7 +664,7 @@ function WorkflowBuilderInner() {
<button
onClick={handlePublish}
disabled={isPublishing}
className="rounded-full bg-primary px-6 py-2 text-sm font-medium text-primary-foreground shadow-sm transition-colors hover:bg-primary/90 disabled:opacity-50"
className="bg-primary text-primary-foreground hover:bg-primary/90 rounded-full px-6 py-2 text-sm font-medium shadow-sm transition-colors disabled:opacity-50"
>
{isPublishing ? 'Publishing...' : 'Publish'}
</button>
@@ -701,20 +701,20 @@ function WorkflowBuilderInner() {
)}
<div className="flex flex-1 overflow-hidden">
<div className="flex w-64 flex-col gap-6 border-r border-border bg-muted p-4">
<div className="border-border bg-muted flex w-64 flex-col gap-6 border-r p-4">
<div>
<h3 className="mb-3 text-xs font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400">
Core Nodes
</h3>
<div className="flex flex-col gap-2">
<div
className="group flex cursor-move items-center gap-3 rounded-full border border-border bg-card px-4 py-3 shadow-sm transition-all hover:bg-accent hover:shadow-md"
className="group border-border bg-card hover:bg-accent flex cursor-move items-center gap-3 rounded-full border px-4 py-3 shadow-sm transition-all hover:shadow-md"
draggable
onDragStart={(e) =>
e.dataTransfer.setData('application/reactflow', 'agent')
}
>
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary transition-colors group-hover:bg-primary group-hover:text-primary-foreground">
<div className="bg-primary/10 text-primary group-hover:bg-primary group-hover:text-primary-foreground flex h-8 w-8 shrink-0 items-center justify-center rounded-full transition-colors">
<Bot size={18} />
</div>
<span className="text-sm font-medium text-gray-700 dark:text-gray-200">
@@ -722,7 +722,7 @@ function WorkflowBuilderInner() {
</span>
</div>
<div
className="group flex cursor-move items-center gap-3 rounded-full border border-border bg-card px-4 py-3 shadow-sm transition-all hover:bg-accent hover:shadow-md"
className="group border-border bg-card hover:bg-accent flex cursor-move items-center gap-3 rounded-full border px-4 py-3 shadow-sm transition-all hover:shadow-md"
draggable
onDragStart={(e) =>
e.dataTransfer.setData('application/reactflow', 'end')
@@ -736,7 +736,7 @@ function WorkflowBuilderInner() {
</span>
</div>
<div
className="group flex cursor-move items-center gap-3 rounded-full border border-border bg-card px-4 py-3 shadow-sm transition-all hover:bg-accent hover:shadow-md"
className="group border-border bg-card hover:bg-accent flex cursor-move items-center gap-3 rounded-full border px-4 py-3 shadow-sm transition-all hover:shadow-md"
draggable
onDragStart={(e) =>
e.dataTransfer.setData('application/reactflow', 'note')
@@ -758,7 +758,7 @@ function WorkflowBuilderInner() {
</h3>
<div className="flex flex-col gap-2">
<div
className="group flex cursor-move items-center gap-3 rounded-full border border-border bg-card px-4 py-3 shadow-sm transition-all hover:bg-accent hover:shadow-md"
className="group border-border bg-card hover:bg-accent flex cursor-move items-center gap-3 rounded-full border px-4 py-3 shadow-sm transition-all hover:shadow-md"
draggable
onDragStart={(e) =>
e.dataTransfer.setData('application/reactflow', 'state')
@@ -780,10 +780,7 @@ function WorkflowBuilderInner() {
</div>
</div>
<div
ref={reactFlowWrapper}
className="relative flex-1 bg-muted"
>
<div ref={reactFlowWrapper} className="bg-muted relative flex-1">
<ReactFlow
nodes={nodes}
edges={edges}
@@ -803,9 +800,9 @@ function WorkflowBuilderInner() {
{showNodeConfig && selectedNode && (
<div
ref={configPanelRef}
className="absolute top-4 right-4 w-96 rounded-2xl border border-border bg-card shadow-[0px_4px_40px_-3px_#0000001A]"
className="border-border bg-card absolute top-4 right-4 w-96 rounded-2xl border shadow-[0px_4px_40px_-3px_#0000001A]"
>
<div className="flex items-center justify-between border-b border-border p-4">
<div className="border-border flex items-center justify-between border-b p-4">
<h3 className="font-semibold text-gray-900 dark:text-white">
{selectedNode.type === 'start' && 'Start Node'}
{selectedNode.type === 'end' && 'End Node'}
@@ -823,7 +820,7 @@ function WorkflowBuilderInner() {
<div className="max-h-[calc(100vh-200px)] overflow-y-auto p-4">
<div className="mb-4 flex flex-col gap-2">
<div className="rounded-lg bg-muted p-3">
<div className="bg-muted rounded-lg p-3">
<div className="mb-1 text-xs text-gray-500 dark:text-gray-400">
Node ID
</div>
@@ -852,7 +849,7 @@ function WorkflowBuilderInner() {
label: e.target.value,
})
}
className="w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground transition-all outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-xl border px-3 py-2 text-sm transition-all outline-none focus:ring-2"
placeholder="Enter node title"
/>
</div>
@@ -936,7 +933,7 @@ function WorkflowBuilderInner() {
},
})
}
className="w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground transition-all outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-xl border px-3 py-2 text-sm transition-all outline-none focus:ring-2"
rows={3}
placeholder="System prompt for the agent"
/>
@@ -958,7 +955,7 @@ function WorkflowBuilderInner() {
},
})
}
className="w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground transition-all outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-xl border px-3 py-2 text-sm transition-all outline-none focus:ring-2"
rows={4}
placeholder="Use {{variable}} for dynamic content"
/>
@@ -981,7 +978,7 @@ function WorkflowBuilderInner() {
},
})
}
className="w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground transition-all outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-xl border px-3 py-2 text-sm transition-all outline-none focus:ring-2"
placeholder="Variable name for output"
/>
</div>
@@ -1048,7 +1045,7 @@ function WorkflowBuilderInner() {
content: e.target.value,
})
}
className="w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground transition-all outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-xl border px-3 py-2 text-sm transition-all outline-none focus:ring-2"
rows={4}
placeholder="Enter note content"
/>
@@ -1069,7 +1066,7 @@ function WorkflowBuilderInner() {
variable: e.target.value,
})
}
className="w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground transition-all outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-xl border px-3 py-2 text-sm transition-all outline-none focus:ring-2"
placeholder="e.g. analysis_type"
/>
</div>
@@ -1085,7 +1082,7 @@ function WorkflowBuilderInner() {
value: e.target.value,
})
}
className="w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground transition-all outline-none focus:ring-2 focus:ring-ring"
className="border-border bg-card text-foreground focus:ring-ring w-full rounded-xl border px-3 py-2 text-sm transition-all outline-none focus:ring-2"
placeholder="e.g. price_check"
/>
</div>
@@ -1116,7 +1113,7 @@ function WorkflowBuilderInner() {
<SheetContent
side="right"
showCloseButton={false}
className="w-full max-w-none border-border bg-card p-0 sm:max-w-[600px] md:max-w-[700px] lg:max-w-[800px]"
className="border-border bg-card w-full max-w-none p-0 sm:max-w-[600px] md:max-w-[700px] lg:max-w-[800px]"
>
<WorkflowPreview
workflowData={{
+1 -1
View File
@@ -41,4 +41,4 @@ export const agentSectionsConfig = [
selectData: selectSharedAgents,
updateAction: setSharedAgents,
},
];
];
@@ -33,7 +33,7 @@ export default function AgentTypeModal({
onClick={onClose}
>
<div
className="relative w-full max-w-lg rounded-xl bg-card p-8 shadow-2xl"
className="bg-card relative w-full max-w-lg rounded-xl p-8 shadow-2xl"
onClick={(e) => e.stopPropagation()}
>
<button
@@ -53,7 +53,7 @@ export default function AgentTypeModal({
<div className="flex flex-col gap-4">
<button
onClick={() => handleSelect('normal')}
className="hover:border-primary hover:bg-primary/5 dark:hover:border-primary dark:hover:bg-primary/10 group flex items-start gap-5 rounded-xl border-2 border-gray-200 p-5 text-left transition-all dark:border-border"
className="hover:border-primary hover:bg-primary/5 dark:hover:border-primary dark:hover:bg-primary/10 group dark:border-border flex items-start gap-5 rounded-xl border-2 border-gray-200 p-5 text-left transition-all"
>
<div className="dark:bg-primary/20 bg-primary/10 text-primary group-hover:bg-primary/90 flex h-14 w-14 shrink-0 items-center justify-center rounded-xl transition-colors group-hover:text-white dark:text-purple-300">
<Bot size={28} />
@@ -71,7 +71,7 @@ export default function AgentTypeModal({
<button
onClick={() => handleSelect('workflow')}
className="hover:border-primary hover:bg-primary/5 dark:hover:border-primary dark:hover:bg-primary/10 group flex items-start gap-5 rounded-xl border-2 border-gray-200 p-5 text-left transition-all dark:border-border"
className="hover:border-primary hover:bg-primary/5 dark:hover:border-primary dark:hover:bg-primary/10 group dark:border-border flex items-start gap-5 rounded-xl border-2 border-gray-200 p-5 text-left transition-all"
>
<div className="dark:bg-primary/20 bg-primary/10 text-primary group-hover:bg-primary flex h-14 w-14 shrink-0 items-center justify-center rounded-xl transition-colors group-hover:text-white dark:text-purple-300">
<Workflow size={28} />
+1 -1
View File
@@ -18,4 +18,4 @@ export default function Agents() {
<Route path="/workflow/edit/:agentId" element={<WorkflowBuilder />} />
</Routes>
);
}
}
+7 -1
View File
@@ -1,4 +1,10 @@
export type NodeType = 'start' | 'end' | 'agent' | 'note' | 'state' | 'condition';
export type NodeType =
| 'start'
| 'end'
| 'agent'
| 'note'
| 'state'
| 'condition';
export interface ConditionCase {
name?: string;
@@ -1428,7 +1428,7 @@ function WorkflowBuilderInner() {
]}
className="border-border rounded-lg border-2 border-dashed p-3 text-center transition-colors"
/>
<p className="mt-1 text-[11px] text-muted-foreground">
<p className="text-muted-foreground mt-1 text-[11px]">
Image updates are included the next time you save.
</p>
</div>
@@ -1608,10 +1608,10 @@ function WorkflowBuilderInner() {
<Database size={18} />
</div>
<div className="flex flex-col">
<span className="text-sm font-medium text-foreground">
<span className="text-foreground text-sm font-medium">
Set State
</span>
<span className="text-[10px] text-muted-foreground">
<span className="text-muted-foreground text-[10px]">
Modify workflow variables
</span>
</div>
@@ -1625,10 +1625,10 @@ function WorkflowBuilderInner() {
<GitBranch size={18} />
</div>
<div className="flex flex-col">
<span className="text-sm font-medium text-foreground">
<span className="text-foreground text-sm font-medium">
If / Else
</span>
<span className="text-[10px] text-muted-foreground">
<span className="text-muted-foreground text-[10px]">
Conditional branching
</span>
</div>
@@ -2041,7 +2041,7 @@ function WorkflowBuilderInner() {
rows={2}
placeholder="input.foo + 1"
/>
<p className="mb-3 text-[10px] text-muted-foreground">
<p className="text-muted-foreground mb-3 text-[10px]">
Use Common Expression Language to create
a custom expression.{' '}
<a
@@ -2376,7 +2376,7 @@ function WorkflowBuilderInner() {
rows={2}
placeholder="Enter condition, e.g. input == 5"
/>
<p className="mt-1 text-[10px] text-muted-foreground">
<p className="text-muted-foreground mt-1 text-[10px]">
Use Common Expression Language to
create a custom expression.{' '}
<a
@@ -150,7 +150,7 @@ function ExecutionDetails({
ref={(el) => {
if (el && stepRefs) stepRefs.current.set(step.nodeId, el);
}}
className="rounded-xl bg-muted p-3 dark:bg-accent"
className="bg-muted dark:bg-accent rounded-xl p-3"
>
<div className="flex items-center gap-2 text-sm">
<span className="flex h-5 w-5 shrink-0 items-center justify-center text-xs font-medium text-gray-500 dark:text-gray-400">
@@ -181,7 +181,7 @@ function ExecutionDetails({
{(hasOutput || step.error || stateVars.length > 0) && (
<div className="mt-3 space-y-2 text-sm">
{hasOutput && (
<div className="rounded-lg bg-muted p-2">
<div className="bg-muted rounded-lg p-2">
<span className="font-medium text-gray-600 dark:text-gray-400">
Output:{' '}
</span>
@@ -205,7 +205,7 @@ function ExecutionDetails({
{stateVars.map(([key, value]) => (
<span
key={key}
className="inline-flex items-center rounded-lg bg-muted px-2 py-1 text-xs"
className="bg-muted inline-flex items-center rounded-lg px-2 py-1 text-xs"
>
<span className="max-w-[100px] truncate font-medium text-gray-600 dark:text-gray-400">
{key}:
@@ -487,10 +487,10 @@ export default function WorkflowPreview({
queries.length > 0 ? queries[queries.length - 1].executionSteps || [] : [];
return (
<div className="flex h-full flex-col bg-card">
<div className="bg-card flex h-full flex-col">
<div className="border-border flex h-[77px] items-center justify-between border-b px-6">
<div className="flex items-center gap-3">
<div className="flex items-center justify-center rounded-full bg-muted p-3 text-gray-600 dark:text-gray-300">
<div className="bg-muted flex items-center justify-center rounded-full p-3 text-gray-600 dark:text-gray-300">
<Play className="h-4 w-4" />
</div>
<div>
@@ -512,7 +512,7 @@ export default function WorkflowPreview({
</div>
<div className="flex min-h-0 flex-1">
<div className="flex w-64 shrink-0 flex-col border-r border-border">
<div className="border-border flex w-64 shrink-0 flex-col border-r">
<div className="flex items-center justify-between px-4 py-3">
<h3 className="text-xs font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400">
Workflow
@@ -537,7 +537,7 @@ export default function WorkflowPreview({
>
{queries.length === 0 ? (
<div className="flex h-full flex-col items-center justify-center">
<div className="mb-2 flex size-14 shrink-0 items-center justify-center rounded-xl bg-muted">
<div className="bg-muted mb-2 flex size-14 shrink-0 items-center justify-center rounded-xl">
<MessageSquare className="size-6 text-gray-600 dark:text-gray-300" />
</div>
<p className="text-xl font-semibold text-gray-700 dark:text-gray-200">
@@ -618,7 +618,7 @@ export default function WorkflowPreview({
</div>
)}
</div>
<div className="absolute right-0 bottom-0 left-0 flex w-full flex-col gap-2 bg-card px-4 pt-2 pb-4">
<div className="bg-card absolute right-0 bottom-0 left-0 flex w-full flex-col gap-2 px-4 pt-2 pb-4">
<MessageInput
onSubmit={(text) => handleQuestionSubmission(text)}
loading={status === 'loading'}
@@ -6,10 +6,10 @@ export default function MobileBlocker() {
<div className="bg-primary/10 dark:bg-primary/20 mb-6 flex h-20 w-20 items-center justify-center rounded-2xl">
<Monitor className="text-primary h-10 w-10" />
</div>
<h2 className="mb-2 text-xl font-bold text-foreground">
<h2 className="text-foreground mb-2 text-xl font-bold">
Desktop Required
</h2>
<p className="max-w-sm text-sm leading-relaxed text-muted-foreground">
<p className="text-muted-foreground max-w-sm text-sm leading-relaxed">
The Workflow Builder requires a larger screen for the best experience.
Please open this page on a desktop or laptop computer.
</p>
@@ -222,7 +222,7 @@ function VariableListWithSearch({
return (
<div className="flex w-full flex-col overflow-hidden">
<div className="flex items-center gap-2 border-b border-border px-3 py-2">
<div className="border-border flex items-center gap-2 border-b px-3 py-2">
<Search className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
<input
type="text"
@@ -252,7 +252,7 @@ function VariableListWithSearch({
e.stopPropagation();
onSelect(v.templatePath);
}}
className="flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-sm transition-colors hover:bg-accent"
className="hover:bg-accent flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-sm transition-colors"
>
<Braces className="text-primary h-3.5 w-3.5 shrink-0" />
<span className="truncate font-medium text-gray-800 dark:text-gray-200">
@@ -412,7 +412,7 @@ export default function PromptTextArea({
)}
<div
ref={wrapperRef}
className="border-border focus-within:ring-ring relative rounded-xl border bg-card transition-all focus-within:ring-2"
className="border-border focus-within:ring-ring bg-card relative rounded-xl border transition-all focus-within:ring-2"
>
<div
ref={overlayRef}
@@ -472,7 +472,7 @@ export default function PromptTextArea({
<PopoverContent
align="end"
side="top"
className="w-60 rounded-xl border border-border bg-card p-0 shadow-lg"
className="border-border bg-card w-60 rounded-xl border p-0 shadow-lg"
onOpenAutoFocus={(e) => e.preventDefault()}
>
<VariableListWithSearch
@@ -486,7 +486,7 @@ export default function PromptTextArea({
{showDropdown && filtered.length > 0 && (
<div
ref={dropdownRef}
className="absolute z-50 w-64 rounded-xl border border-border bg-card shadow-lg"
className="border-border bg-card absolute z-50 w-64 rounded-xl border shadow-lg"
style={{ top: dropdownPos.top, left: dropdownPos.left }}
>
<VariableListWithSearch
@@ -27,8 +27,7 @@ export const BaseNode: React.FC<BaseNodeProps> = ({
let iconColor = 'text-gray-600 dark:text-gray-400';
if (selected) {
borderColor =
'border-primary ring-2 ring-primary';
borderColor = 'border-primary ring-2 ring-primary';
}
if (type === 'start') {
@@ -56,7 +55,7 @@ export const BaseNode: React.FC<BaseNodeProps> = ({
type="target"
position={Position.Left}
isConnectable={true}
className="hover:bg-primary/90! -left-1! h-3! w-3! rounded-full! border-2! border-card! bg-gray-400! transition-colors!"
className="hover:bg-primary/90! border-card! -left-1! h-3! w-3! rounded-full! border-2! bg-gray-400! transition-colors!"
/>
)}
@@ -86,7 +85,7 @@ export const BaseNode: React.FC<BaseNodeProps> = ({
type="source"
position={Position.Right}
isConnectable={true}
className="hover:bg-primary/90! -right-1! h-3! w-3! rounded-full! border-2! border-card! bg-gray-400! transition-colors!"
className="hover:bg-primary/90! border-card! -right-1! h-3! w-3! rounded-full! border-2! bg-gray-400! transition-colors!"
/>
)}
</div>
@@ -36,7 +36,7 @@ const ConditionNode = ({ data, selected }: NodeProps<ConditionNodeData>) => {
return (
<div
className={`relative rounded-2xl border bg-card shadow-md transition-all ${
className={`bg-card relative rounded-2xl border shadow-md transition-all ${
selected
? 'border-primary dark:ring-primary scale-105 ring-2 ring-purple-300'
: 'border-border hover:shadow-lg'
@@ -47,7 +47,7 @@ const ConditionNode = ({ data, selected }: NodeProps<ConditionNodeData>) => {
type="target"
position={Position.Left}
isConnectable
className="hover:bg-primary/90! top-1/2! -left-1! h-3! w-3! rounded-full! border-2! border-card! bg-gray-400! transition-colors!"
className="hover:bg-primary/90! border-card! top-1/2! -left-1! h-3! w-3! rounded-full! border-2! bg-gray-400! transition-colors!"
/>
<div className="flex items-center gap-3 px-3 py-2">
@@ -100,7 +100,7 @@ const ConditionNode = ({ data, selected }: NodeProps<ConditionNodeData>) => {
id={c.sourceHandle}
isConnectable
style={{ top: getHandleTop(i, totalOutputs) }}
className="hover:bg-primary/90! -right-1! h-3! w-3! rounded-full! border-2! border-white! bg-orange-400! transition-colors dark:border-border!"
className="hover:bg-primary/90! dark:border-border! -right-1! h-3! w-3! rounded-full! border-2! border-white! bg-orange-400! transition-colors"
/>
))}
<Handle
@@ -109,7 +109,7 @@ const ConditionNode = ({ data, selected }: NodeProps<ConditionNodeData>) => {
id="else"
isConnectable
style={{ top: getHandleTop(cases.length, totalOutputs) }}
className="hover:bg-primary/90! -right-1! h-3! w-3! rounded-full! border-2! border-card! bg-gray-400! transition-colors!"
className="hover:bg-primary/90! border-card! -right-1! h-3! w-3! rounded-full! border-2! bg-gray-400! transition-colors!"
/>
</div>
);
+2 -2
View File
@@ -53,7 +53,7 @@ export default function ActionButtons({
<button
title={t('actionButtons.openNewChat')}
onClick={newChat}
className="hover:bg-accent flex items-center gap-1 rounded-full p-2 lg:hidden dark:hover:bg-accent"
className="hover:bg-accent dark:hover:bg-accent flex items-center gap-1 rounded-full p-2 lg:hidden"
>
<img
className="filter dark:invert"
@@ -70,7 +70,7 @@ export default function ActionButtons({
<button
title={t('actionButtons.share')}
onClick={() => setShareModalState(true)}
className="hover:bg-accent rounded-full p-2 dark:hover:bg-accent"
className="hover:bg-accent dark:hover:bg-accent rounded-full p-2"
>
<img
className="filter dark:invert"
+3 -3
View File
@@ -547,7 +547,7 @@ const Chunks: React.FC<ChunksProps> = ({
<>
<div className="mb-3 flex flex-col items-start justify-between gap-3 sm:flex-row sm:items-center">
<div className="border-border dark:border-border flex h-[38px] w-full flex-1 items-center overflow-hidden rounded-md border">
<div className="flex h-full items-center px-4 font-medium whitespace-nowrap text-gray-700 dark:text-foreground">
<div className="dark:text-foreground flex h-full items-center px-4 font-medium whitespace-nowrap text-gray-700">
{totalChunks > 999999
? `${(totalChunks / 1000000).toFixed(2)}M`
: totalChunks > 999
@@ -606,7 +606,7 @@ const Chunks: React.FC<ChunksProps> = ({
>
<div className="w-full">
<div className="border-border bg-muted dark:border-border dark:bg-card flex w-full items-center justify-between border-b px-4 py-3">
<div className="text-sm text-[#59636E] dark:text-muted-foreground">
<div className="dark:text-muted-foreground text-sm text-[#59636E]">
{chunk.metadata.token_count
? chunk.metadata.token_count.toLocaleString()
: '-'}{' '}
@@ -641,7 +641,7 @@ const Chunks: React.FC<ChunksProps> = ({
<div className="w-full">
<div className="border-border dark:border-border relative flex w-full flex-col overflow-hidden rounded-[5.86px] border">
<div className="border-border bg-muted dark:border-border dark:bg-card flex w-full items-center justify-between border-b px-4 py-3">
<div className="text-sm text-[#59636E] dark:text-muted-foreground">
<div className="dark:text-muted-foreground text-sm text-[#59636E]">
{editingChunk.metadata.token_count
? editingChunk.metadata.token_count.toLocaleString()
: '-'}{' '}
+11 -11
View File
@@ -68,9 +68,7 @@ export default function ConfigFields({
<div key={key} className="flex flex-col gap-1.5">
<Label htmlFor={key}>
{spec.label || key}
{spec.required && (
<span className="text-red-500">*</span>
)}
{spec.required && <span className="text-red-500">*</span>}
</Label>
<Select
value={value || spec.default || ''}
@@ -82,7 +80,8 @@ export default function ConfigFields({
size="lg"
className={cn(
'w-full rounded-xl',
hasError && 'border-destructive aria-invalid:ring-destructive/20',
hasError &&
'border-destructive aria-invalid:ring-destructive/20',
)}
>
<SelectValue placeholder={spec.label || key} />
@@ -90,13 +89,14 @@ export default function ConfigFields({
<SelectContent>
{spec.enum.map((v) => (
<SelectItem key={v} value={v}>
{v.charAt(0).toUpperCase() + v.slice(1).replace(/_/g, ' ')}
{v.charAt(0).toUpperCase() +
v.slice(1).replace(/_/g, ' ')}
</SelectItem>
))}
</SelectContent>
</Select>
{hasError && (
<p className="text-xs text-destructive">{errors[key]}</p>
<p className="text-destructive text-xs">{errors[key]}</p>
)}
</div>
);
@@ -106,9 +106,7 @@ export default function ConfigFields({
<div key={key} className="flex flex-col gap-1.5">
<Label htmlFor={key}>
{spec.label || key}
{spec.required && (
<span className="text-red-500">*</span>
)}
{spec.required && <span className="text-red-500">*</span>}
</Label>
<Input
id={key}
@@ -134,12 +132,14 @@ export default function ConfigFields({
}}
placeholder={placeholder || spec.description || ''}
min={spec.type === 'number' ? 1 : undefined}
max={spec.type === 'number' && key === 'timeout' ? 300 : undefined}
max={
spec.type === 'number' && key === 'timeout' ? 300 : undefined
}
aria-invalid={hasError || undefined}
className={cn('rounded-xl', hasError && 'border-destructive')}
/>
{hasError && (
<p className="text-xs text-destructive">{errors[key]}</p>
<p className="text-destructive text-xs">{errors[key]}</p>
)}
</div>
);
+1 -2
View File
@@ -39,8 +39,7 @@ export default function CopyButton({
'flex items-center justify-center rounded-full transition-colors duration-150 ease-in-out',
padding,
{
[`bg-transparent hover:bg-muted`]:
!isCopied,
[`bg-transparent hover:bg-muted`]: !isCopied,
'bg-green-100 dark:bg-green-900 hover:bg-green-100 dark:hover:bg-green-900':
isCopied,
},
@@ -61,12 +61,12 @@ const Pagination: React.FC<PaginationProps> = ({
<div className="relative">
<button
onClick={toggleDropdown}
className="dark:bg-card dark:text-foreground rounded border px-3 py-1 hover:bg-accent dark:hover:bg-accent"
className="dark:bg-card dark:text-foreground hover:bg-accent dark:hover:bg-accent rounded border px-3 py-1"
>
{rowsPerPage}
</button>
<div
className={`ring-opacity-5 dark:bg-card absolute right-0 z-50 mt-1 w-28 transform bg-card shadow-lg ring-1 ring-black transition-all duration-200 ease-in-out ${
className={`ring-opacity-5 dark:bg-card bg-card absolute right-0 z-50 mt-1 w-28 transform shadow-lg ring-1 ring-black transition-all duration-200 ease-in-out ${
isDropdownOpen
? 'block scale-100 opacity-100'
: 'hidden scale-95 opacity-0'
@@ -76,7 +76,7 @@ const Pagination: React.FC<PaginationProps> = ({
<div
key={option}
onClick={() => handleSelectRowsPerPage(option)}
className={`cursor-pointer px-4 py-2 text-xs hover:bg-accent dark:hover:bg-accent ${
className={`hover:bg-accent dark:hover:bg-accent cursor-pointer px-4 py-2 text-xs ${
rowsPerPage === option
? 'dark:text-foreground bg-gray-100 dark:bg-neutral-700'
: 'bg-card dark:text-foreground'
+15 -14
View File
@@ -110,7 +110,7 @@ function Dropdown<T extends DropdownOption>({
<button
type="button"
onClick={() => setOpen((v) => !v)}
className={`flex w-full cursor-pointer items-center justify-between border border-border bg-card px-5 py-3 text-foreground ${open ? radiusTop : radius}`}
className={`border-border bg-card text-foreground flex w-full cursor-pointer items-center justify-between border px-5 py-3 ${open ? radiusTop : radius}`}
>
<span
className={`truncate ${contentSize} ${displayValue ? '' : 'text-muted-foreground'}`}
@@ -118,24 +118,24 @@ function Dropdown<T extends DropdownOption>({
{displayValue ?? placeholder}
</span>
<ChevronDown
className={`ml-2 h-4 w-4 shrink-0 text-muted-foreground transition-transform ${open ? 'rotate-180' : ''}`}
className={`text-muted-foreground ml-2 h-4 w-4 shrink-0 transition-transform ${open ? 'rotate-180' : ''}`}
/>
</button>
{open && (
<div
className={`absolute inset-x-0 z-20 -mt-px overflow-hidden border border-t-0 border-border bg-card shadow-lg ${radiusBottom}`}
className={`border-border bg-card absolute inset-x-0 z-20 -mt-px overflow-hidden border border-t-0 shadow-lg ${radiusBottom}`}
>
{searchable && (
<div className="flex items-center border-b border-border px-3 py-2">
<Search className="mr-2 h-4 w-4 shrink-0 text-muted-foreground" />
<div className="border-border flex items-center border-b px-3 py-2">
<Search className="text-muted-foreground mr-2 h-4 w-4 shrink-0" />
<input
ref={searchRef}
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
className="w-full bg-transparent text-sm text-foreground placeholder:text-muted-foreground focus:outline-none"
className="text-foreground placeholder:text-muted-foreground w-full bg-transparent text-sm focus:outline-none"
onClick={(e) => e.stopPropagation()}
/>
</div>
@@ -143,7 +143,7 @@ function Dropdown<T extends DropdownOption>({
<div className="max-h-48 overflow-y-auto">
{filtered.length === 0 ? (
<div className="px-4 py-3 text-center text-sm text-muted-foreground">
<div className="text-muted-foreground px-4 py-3 text-center text-sm">
No results found
</div>
) : (
@@ -157,7 +157,7 @@ function Dropdown<T extends DropdownOption>({
return (
<div
key={i}
className={`flex cursor-pointer items-center justify-between hover:bg-accent ${active ? 'bg-accent' : ''}`}
className={`hover:bg-accent flex cursor-pointer items-center justify-between ${active ? 'bg-accent' : ''}`}
>
<span
onClick={() => {
@@ -165,7 +165,7 @@ function Dropdown<T extends DropdownOption>({
setOpen(false);
setQuery('');
}}
className={`flex-1 truncate px-4 py-2.5 text-foreground ${contentSize}`}
className={`text-foreground flex-1 truncate px-4 py-2.5 ${contentSize}`}
>
{getOptionText(option)}
</span>
@@ -185,9 +185,9 @@ function Dropdown<T extends DropdownOption>({
setOpen(false);
setQuery('');
}}
className="mr-1 rounded p-1 hover:bg-accent"
className="hover:bg-accent mr-1 rounded p-1"
>
<Pencil className="h-3.5 w-3.5 text-muted-foreground" />
<Pencil className="text-muted-foreground h-3.5 w-3.5" />
</button>
)}
@@ -202,13 +202,14 @@ function Dropdown<T extends DropdownOption>({
: ((optObj?.id as string) ?? ''),
);
}}
className={`mr-1 rounded p-1 hover:bg-accent ${
typeof showDelete === 'function' && !showDelete(option)
className={`hover:bg-accent mr-1 rounded p-1 ${
typeof showDelete === 'function' &&
!showDelete(option)
? 'hidden'
: ''
} ${optObj?.type === 'public' ? 'pointer-events-none opacity-30' : ''}`}
>
<Trash2 className="h-3.5 w-3.5 text-muted-foreground" />
<Trash2 className="text-muted-foreground h-3.5 w-3.5" />
</button>
)}
</div>
+3 -5
View File
@@ -88,7 +88,7 @@ export default function DropdownMenu({
onClick={(e) => e.stopPropagation()}
>
<div
className={`w-28 transform rounded-md border border-border bg-card shadow-lg transition-all duration-200 ease-in-out ${className}`}
className={`border-border bg-card w-28 transform rounded-md border shadow-lg transition-all duration-200 ease-in-out ${className}`}
>
<div
role="menu"
@@ -99,10 +99,8 @@ export default function DropdownMenu({
{options.map((option, idx) => (
<div
id={`option-${idx}`}
className={`dark:text-foreground cursor-pointer px-4 py-2 text-xs hover:bg-muted ${
selectedOption.value === option.value
? 'bg-muted'
: 'bg-card'
className={`dark:text-foreground hover:bg-muted cursor-pointer px-4 py-2 text-xs ${
selectedOption.value === option.value ? 'bg-muted' : 'bg-card'
}`}
role="menuitem"
key={option.value}
+3 -1
View File
@@ -128,7 +128,9 @@ export default function DropdownModel() {
))
) : (
<div className="border-border/30 flex h-10 w-full items-center border-t">
<p className="pl-5 text-sm text-muted-foreground">No models available</p>
<p className="text-muted-foreground pl-5 text-sm">
No models available
</p>
</div>
)}
</div>
+14 -19
View File
@@ -93,9 +93,7 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
const [isConnected, setIsConnected] = useState(false);
const [userEmail, setUserEmail] = useState<string>('');
const [allowsSharedContent, setAllowsSharedContent] = useState(false);
const [activeTab, setActiveTab] = useState<'my_files' | 'shared'>(
'my_files',
);
const [activeTab, setActiveTab] = useState<'my_files' | 'shared'>('my_files');
const scrollContainerRef = useRef<HTMLDivElement>(null);
const searchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
@@ -214,9 +212,7 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
setIsConnected(true);
setAuthError('');
if (provider === 'share_point') {
setAllowsSharedContent(
validateData.allows_shared_content ?? false,
);
setAllowsSharedContent(validateData.allows_shared_content ?? false);
}
setFiles([]);
@@ -369,9 +365,7 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
{
id: null,
name:
tab === 'shared'
? 'Shared'
: getProviderConfig(provider).rootName,
tab === 'shared' ? 'Shared' : getProviderConfig(provider).rootName,
},
]);
const sessionToken = getSessionToken(provider);
@@ -380,8 +374,6 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
}
};
const handleFileSelect = (fileId: string, isFolder: boolean) => {
if (isFolder) {
const newSelectedFolders = selectedFolders.includes(fileId)
@@ -459,10 +451,10 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
/>
{isConnected && (
<div className="mt-3 overflow-hidden rounded-lg border border-border dark:border-border">
<div className="rounded-t-lg border-border dark:border-border">
<div className="border-border dark:border-border mt-3 overflow-hidden rounded-lg border">
<div className="border-border dark:border-border rounded-t-lg">
{provider === 'share_point' && allowsSharedContent && (
<div className="flex border-b border-border dark:border-border">
<div className="border-border dark:border-border flex border-b">
<button
onClick={() => handleTabChange('my_files')}
className={`px-4 py-2 text-sm font-medium ${
@@ -485,7 +477,7 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
</button>
</div>
)}
<div className="rounded-t-lg bg-[#EEE6FF78] px-4 pt-4 dark:bg-muted">
<div className="dark:bg-muted rounded-t-lg bg-[#EEE6FF78] px-4 pt-4">
<div className="mb-2 flex items-center gap-1">
{folderPath.map((path, index) => (
<div
@@ -531,7 +523,7 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
</div>
</div>
<div className="h-72 border-t border-border dark:border-border">
<div className="border-border dark:border-border h-72 border-t">
<TableContainer
ref={scrollContainerRef}
height="288px"
@@ -586,7 +578,7 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
>
<TableCell width="40px" align="center">
<div
className="mx-auto flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center border border-border p-[0.5px] text-sm dark:border-border"
className="border-border dark:border-border mx-auto flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center border p-[0.5px] text-sm"
onClick={(e) => {
e.stopPropagation();
handleFileSelect(file.id, isFolder(file));
@@ -615,7 +607,9 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
className="h-6 w-6"
/>
</div>
<span className="truncate">{file.name}</span>
<span className="truncate">
{file.name}
</span>
</div>
</TableCell>
<TableCell className="text-xs">
@@ -626,7 +620,8 @@ export const FilePicker: React.FC<CloudFilePickerProps> = ({
</TableCell>
</TableRow>
))}
{isLoading && files.length > 0 &&
{isLoading &&
files.length > 0 &&
Array.from({ length: 3 }).map((_, i) => (
<TableRow key={`load-more-skeleton-${i}`}>
<TableCell width="40px" align="center">
@@ -1,5 +1,5 @@
const FilesSectionSkeleton = () => (
<div className="rounded-lg border border-border dark:border-border">
<div className="border-border dark:border-border rounded-lg border">
<div className="p-4">
<div className="mb-4 flex items-center justify-between">
<div className="h-5 w-24 animate-pulse rounded bg-gray-200 dark:bg-gray-700"></div>
+6 -6
View File
@@ -599,7 +599,7 @@ const FileTree: React.FC<FileTreeProps> = ({
<div ref={menuRef} className="relative">
<button
onClick={(e) => handleMenuClick(e, itemId)}
className="inline-flex h-[35px] w-[24px] shrink-0 items-center justify-center rounded-md font-medium transition-colors hover:bg-[#EBEBEB] dark:hover:bg-muted"
className="dark:hover:bg-muted inline-flex h-[35px] w-[24px] shrink-0 items-center justify-center rounded-md font-medium transition-colors hover:bg-[#EBEBEB]"
aria-label={t('settings.sources.menuAlt')}
>
<img
@@ -656,7 +656,7 @@ const FileTree: React.FC<FileTreeProps> = ({
<div ref={menuRef} className="relative">
<button
onClick={(e) => handleMenuClick(e, itemId)}
className="inline-flex h-[35px] w-[24px] shrink-0 items-center justify-center rounded-md font-medium transition-colors hover:bg-[#EBEBEB] dark:hover:bg-muted"
className="dark:hover:bg-muted inline-flex h-[35px] w-[24px] shrink-0 items-center justify-center rounded-md font-medium transition-colors hover:bg-[#EBEBEB]"
aria-label={t('settings.sources.menuAlt')}
>
<img
@@ -754,11 +754,11 @@ const FileTree: React.FC<FileTreeProps> = ({
}
}}
placeholder={t('settings.sources.searchFiles')}
className={`h-[38px] w-full border border-border px-4 py-2 dark:border-border ${searchQuery ? 'rounded-t-[24px]' : 'rounded-[24px]'} bg-transparent focus:outline-none`}
className={`border-border dark:border-border h-[38px] w-full border px-4 py-2 ${searchQuery ? 'rounded-t-[24px]' : 'rounded-[24px]'} bg-transparent focus:outline-none`}
/>
{searchQuery && (
<div className="absolute top-full right-0 left-0 z-10 max-h-[calc(100vh-200px)] w-full overflow-hidden rounded-b-[12px] border border-t-0 border-border bg-card shadow-lg transition-all duration-200 dark:border-border dark:bg-card">
<div className="border-border bg-card dark:border-border dark:bg-card absolute top-full right-0 left-0 z-10 max-h-[calc(100vh-200px)] w-full overflow-hidden rounded-b-[12px] border border-t-0 shadow-lg transition-all duration-200">
<div className="max-h-[calc(100vh-200px)] overflow-x-hidden overflow-y-auto overscroll-contain">
{searchResults.length === 0 ? (
<div className="py-2 text-center text-sm text-gray-500 dark:text-gray-400">
@@ -770,9 +770,9 @@ const FileTree: React.FC<FileTreeProps> = ({
key={index}
onClick={() => handleSearchSelect(result)}
title={result.path}
className={`flex min-w-0 cursor-pointer items-center px-3 py-2 hover:bg-muted dark:hover:bg-muted ${
className={`hover:bg-muted dark:hover:bg-muted flex min-w-0 cursor-pointer items-center px-3 py-2 ${
index !== searchResults.length - 1
? 'border-b border-border dark:border-border'
? 'border-border dark:border-border border-b'
: ''
}`}
>
@@ -262,7 +262,7 @@ const GoogleDrivePicker: React.FC<GoogleDrivePickerProps> = ({
/>
{isConnected && (
<div className="rounded-lg border border-border dark:border-border">
<div className="border-border dark:border-border rounded-lg border">
<div className="p-4">
<div className="mb-4 flex items-center justify-between">
<h3 className="text-sm font-medium">
+4 -4
View File
@@ -36,20 +36,20 @@ const Help = () => {
<button
ref={buttonRef}
onClick={toggleDropdown}
className="mx-4 my-auto flex h-9 w-full items-center gap-4 rounded-3xl hover:bg-sidebar-accent"
className="hover:bg-sidebar-accent mx-4 my-auto flex h-9 w-full items-center gap-4 rounded-3xl"
>
<img src={Info} alt="info" className="ml-2 w-5 filter dark:invert" />
{t('help')}
</button>
{isOpen && (
<div
className={`dark:bg-card absolute z-10 w-48 translate-x-4 -translate-y-28 rounded-xl bg-card shadow-lg`}
className={`dark:bg-card bg-card absolute z-10 w-48 translate-x-4 -translate-y-28 rounded-xl shadow-lg`}
>
<a
href="https://docs.docsgpt.cloud/"
target="_blank"
rel="noopener noreferrer"
className="hover:bg-muted flex items-start gap-4 rounded-t-xl px-4 py-2 text-foreground"
className="hover:bg-muted text-foreground flex items-start gap-4 rounded-t-xl px-4 py-2"
>
<img
src={PageIcon}
@@ -61,7 +61,7 @@ const Help = () => {
</a>
<a
href="mailto:support@docsgpt.cloud"
className="hover:bg-muted flex items-start gap-4 rounded-b-xl px-4 py-2 text-foreground"
className="hover:bg-muted text-foreground flex items-start gap-4 rounded-b-xl px-4 py-2"
>
<img
src={EmailIcon}
+2 -2
View File
@@ -1438,7 +1438,7 @@ export default function MessageInput({
onChange={handleVoiceFileAttachment}
/>
<div className="border-border bg-card dark:bg-transparent relative flex w-full flex-col rounded-[23px] border">
<div className="border-border bg-card relative flex w-full flex-col rounded-[23px] border dark:bg-transparent">
<div className="flex flex-wrap gap-1.5 px-2 py-2 sm:gap-2 sm:px-3">
{attachments.map((attachment) => {
return (
@@ -1620,7 +1620,7 @@ export default function MessageInput({
className={`xs:px-3 xs:py-1.5 dark:border-purple-taupe flex items-center rounded-[32px] border px-2 py-1 transition-colors ${
recordingState === 'recording'
? 'border-[#B42318] bg-[#FEE4E2] text-[#B42318] dark:bg-[#4A2323]'
: 'border-border hover:bg-gray-100 dark:hover:bg-accent'
: 'border-border dark:hover:bg-accent hover:bg-gray-100'
} ${
loading || recordingState === 'transcribing'
? 'cursor-not-allowed opacity-60'
+3 -3
View File
@@ -212,7 +212,7 @@ export default function MultiSelectPopup({
<div className="h-6 w-6 animate-spin rounded-full border-b-2 border-gray-900 dark:border-white"></div>
</div>
) : (
<div className="h-full overflow-y-auto scrollbar-overlay">
<div className="scrollbar-overlay h-full overflow-y-auto">
{filteredOptions.length === 0 ? (
<div className="flex h-full flex-col items-center justify-center px-4 py-8 text-center">
<img
@@ -233,7 +233,7 @@ export default function MultiSelectPopup({
<div
key={option.id}
onClick={() => handleOptionClick(option.id)}
className="dark:border-border dark:hover:bg-accent flex cursor-pointer items-center justify-between border-b border-[#D9D9D9] p-3 last:border-b-0 hover:bg-accent"
className="dark:border-border dark:hover:bg-accent hover:bg-accent flex cursor-pointer items-center justify-between border-b border-[#D9D9D9] p-3 last:border-b-0"
role="option"
aria-selected={isSelected}
>
@@ -248,7 +248,7 @@ export default function MultiSelectPopup({
</div>
<div className="shrink-0">
<div
className={`flex h-4 w-4 items-center justify-center rounded-xs border-2 border-border bg-card`}
className={`border-border bg-card flex h-4 w-4 items-center justify-center rounded-xs border-2`}
aria-hidden="true"
>
{isSelected && (
+2 -2
View File
@@ -87,7 +87,7 @@ export default function Notification({
))}
</div>
<p className="text-white relative z-10 text-xs leading-6 font-semibold xl:text-sm xl:leading-7">
<p className="relative z-10 text-xs leading-6 font-semibold text-white xl:text-sm xl:leading-7">
{notificationText}
</p>
<span className="relative z-10 flex items-center">
@@ -132,4 +132,4 @@ export default function Notification({
</a>
</>
);
}
}
+2 -2
View File
@@ -60,7 +60,7 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
<div className="z-10 md:hidden">
<button
onClick={() => scrollTabs(-1)}
className="flex h-6 w-6 items-center justify-center rounded-full transition-all hover:bg-muted dark:hover:bg-accent"
className="hover:bg-muted dark:hover:bg-accent flex h-6 w-6 items-center justify-center rounded-full transition-all"
aria-label={t('settings.scrollTabsLeft')}
>
<img src={ArrowLeft} alt="left-arrow" className="h-3" />
@@ -93,7 +93,7 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
<div className="z-10 md:hidden">
<button
onClick={() => scrollTabs(1)}
className="flex h-6 w-6 items-center justify-center rounded-full hover:bg-muted dark:hover:bg-accent"
className="hover:bg-muted dark:hover:bg-accent flex h-6 w-6 items-center justify-center rounded-full"
aria-label={t('settings.scrollTabsRight')}
>
<img src={ArrowRight} alt="right-arrow" className="h-3" />
+1 -1
View File
@@ -33,7 +33,7 @@ export default function Sidebar({
return (
<div ref={sidebarRef} className="h-vh relative">
<div
className={`fixed top-0 right-0 z-50 h-full w-64 transform bg-card shadow-xl transition-all duration-300 sm:w-80 ${
className={`bg-card fixed top-0 right-0 z-50 h-full w-64 transform shadow-xl transition-all duration-300 sm:w-80 ${
isOpen ? 'translate-x-[10px]' : 'translate-x-full'
} border-l border-[#9ca3af]/10`}
>
+5 -8
View File
@@ -97,7 +97,7 @@ const SkeletonLoader: React.FC<SkeletonLoaderProps> = ({
{[...Array(8)].map((_, idx) => (
<div
key={idx}
className="dark:hover:bg-accent flex w-full items-start p-2 hover:bg-muted"
className="dark:hover:bg-accent hover:bg-muted flex w-full items-start p-2"
>
<div className="flex w-full items-center gap-2">
<div className="h-3 w-3 rounded-lg bg-gray-300 dark:bg-gray-600"></div>
@@ -154,10 +154,7 @@ const SkeletonLoader: React.FC<SkeletonLoaderProps> = ({
const renderAnalysis = () => (
<>
{[...Array(skeletonCount)].map((_, idx) => (
<div
key={idx}
className="bg-card w-full animate-pulse rounded-3xl p-6"
>
<div key={idx} className="bg-card w-full animate-pulse rounded-3xl p-6">
<div className="space-y-6">
<div className="space-y-2">
<div className="mb-4 h-4 w-1/3 rounded-sm bg-gray-300 dark:bg-gray-600"></div>
@@ -189,10 +186,10 @@ const SkeletonLoader: React.FC<SkeletonLoaderProps> = ({
{Array.from({ length: count }).map((_, index) => (
<div
key={`chunk-skel-${index}`}
className="relative flex h-[197px] w-full max-w-[487px] animate-pulse flex-col overflow-hidden rounded-[5.86px] border border-border dark:border-border"
className="border-border dark:border-border relative flex h-[197px] w-full max-w-[487px] animate-pulse flex-col overflow-hidden rounded-[5.86px] border"
>
<div className="w-full">
<div className="flex w-full items-center justify-between border-b border-border bg-muted px-4 py-3 dark:border-border dark:bg-card">
<div className="border-border bg-muted dark:border-border dark:bg-card flex w-full items-center justify-between border-b px-4 py-3">
<div className="h-4 w-20 rounded bg-gray-300 dark:bg-gray-600"></div>
</div>
<div className="space-y-3 px-4 pt-4 pb-6">
@@ -214,7 +211,7 @@ const SkeletonLoader: React.FC<SkeletonLoaderProps> = ({
{Array.from({ length: count }).map((_, idx) => (
<div
key={`source-skel-${idx}`}
className="flex h-[130px] w-full animate-pulse flex-col rounded-2xl bg-muted p-3 dark:bg-accent"
className="bg-muted dark:bg-accent flex h-[130px] w-full animate-pulse flex-col rounded-2xl p-3"
>
<div className="w-full flex-1">
<div className="flex w-full items-center justify-between gap-2">
+3 -3
View File
@@ -139,7 +139,7 @@ export default function SourcesPopup({
/>
</div>
<div className="dark:border-border mx-4 grow overflow-y-auto rounded-md border border-[#D9D9D9] scrollbar-overlay">
<div className="dark:border-border scrollbar-overlay mx-4 grow overflow-y-auto rounded-md border border-[#D9D9D9]">
{options ? (
<>
{filteredOptions?.map((option: any, index: number) => {
@@ -154,7 +154,7 @@ export default function SourcesPopup({
return (
<div
key={index}
className="border-opacity-80 dark:border-border flex cursor-pointer items-center border-b border-[#D9D9D9] p-3 transition-colors hover:bg-muted dark:text-[14px]"
className="border-opacity-80 dark:border-border hover:bg-muted flex cursor-pointer items-center border-b border-[#D9D9D9] p-3 transition-colors dark:text-[14px]"
onClick={() => {
if (isSelected) {
const updatedDocs =
@@ -190,7 +190,7 @@ export default function SourcesPopup({
{option.name}
</span>
<div
className={`flex h-4 w-4 shrink-0 items-center justify-center rounded-xs border-2 border-[#C6C6C6] p-[0.5px] dark:border-border`}
className={`dark:border-border flex h-4 w-4 shrink-0 items-center justify-center rounded-xs border-2 border-[#C6C6C6] p-[0.5px]`}
>
{isSelected && (
<img
+2 -2
View File
@@ -46,7 +46,7 @@ const TableContainer = React.forwardRef<HTMLDivElement, TableContainerProps>(
<div className={`relative rounded-[6px] ${className}`}>
<div
ref={ref}
className={`w-full overflow-x-auto rounded-[6px] bg-transparent ${bordered ? 'border border-border dark:border-border' : ''}`}
className={`w-full overflow-x-auto rounded-[6px] bg-transparent ${bordered ? 'border-border dark:border-border border' : ''}`}
style={{
maxHeight: height === 'auto' ? undefined : height,
overflowY: height === 'auto' ? 'hidden' : 'auto',
@@ -75,7 +75,7 @@ const Table: React.FC<TableProps> = ({
const TableHead: React.FC<TableHeadProps> = ({ children, className = '' }) => {
return (
<thead
className={`sticky top-0 z-10 bg-gray-100 dark:bg-card ${className} `}
className={`dark:bg-card sticky top-0 z-10 bg-gray-100 ${className} `}
>
{children}
</thead>
@@ -176,9 +176,7 @@ export default function SpeakButton({ text }: { text: string }) {
<button
type="button"
className={`flex cursor-pointer items-center justify-center rounded-full p-2 ${
isSpeaking || isLoading
? 'bg-accent'
: 'bg-transparent hover:bg-accent'
isSpeaking || isLoading ? 'bg-accent' : 'hover:bg-accent bg-transparent'
}`}
onClick={handleSpeakClick}
aria-label={
+3 -3
View File
@@ -175,7 +175,7 @@ export default function ToolsPopup({
</div>
) : (
<div className="dark:border-border mx-4 grow overflow-hidden rounded-md border border-[#D9D9D9]">
<div className="h-full overflow-y-auto scrollbar-overlay">
<div className="scrollbar-overlay h-full overflow-y-auto">
{filteredTools.length === 0 ? (
<div className="flex h-full flex-col items-center justify-center py-8">
<img
@@ -192,7 +192,7 @@ export default function ToolsPopup({
<div
key={tool.id}
onClick={() => updateToolStatus(tool.id, !tool.status)}
className="dark:border-border dark:hover:bg-accent flex items-center justify-between border-b border-[#D9D9D9] p-3 hover:bg-accent"
className="dark:border-border dark:hover:bg-accent hover:bg-accent flex items-center justify-between border-b border-[#D9D9D9] p-3"
>
<div className="mr-3 flex grow items-center">
<img
@@ -208,7 +208,7 @@ export default function ToolsPopup({
</div>
<div className="flex shrink-0 items-center">
<div
className={`flex h-4 w-4 items-center justify-center rounded-xs border-2 border-[#C6C6C6] p-[0.5px] dark:border-border`}
className={`dark:border-border flex h-4 w-4 items-center justify-center rounded-xs border-2 border-[#C6C6C6] p-[0.5px]`}
>
{tool.status && (
<img
+2 -2
View File
@@ -70,7 +70,7 @@ export function MultiSelect({
role="combobox"
aria-expanded={open}
className={cn(
'w-full justify-between border-border bg-card hover:bg-accent',
'border-border bg-card hover:bg-accent w-full justify-between',
!selected.length && 'text-gray-500 dark:text-gray-400',
className,
)}
@@ -124,7 +124,7 @@ export function MultiSelect({
</Button>
</PopoverTrigger>
<PopoverContent
className="w-(--radix-popover-trigger-width) border-border bg-card p-0"
className="border-border bg-card w-(--radix-popover-trigger-width) p-0"
align="start"
>
<Command className="bg-transparent">
+3 -3
View File
@@ -37,11 +37,11 @@ function SelectTrigger({
data-slot="select-trigger"
data-size={size}
className={cn(
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex w-fit items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 data-[size=lg]:h-[42px] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-gray-600 dark:[&_svg:not([class*='text-'])]:text-gray-400",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex w-fit items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=lg]:h-[42px] data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-gray-600 dark:[&_svg:not([class*='text-'])]:text-gray-400",
variant === 'default' &&
'border-border bg-card focus-visible:ring-ring/50 hover:bg-accent data-placeholder:text-muted-foreground',
variant === 'ghost' &&
'border-border bg-transparent focus-visible:ring-ring/50 hover:bg-accent data-[state=open]:bg-muted data-placeholder:text-muted-foreground dark:border-border dark:hover:bg-accent dark:data-[state=open]:bg-muted',
'border-border focus-visible:ring-ring/50 hover:bg-accent data-[state=open]:bg-muted data-placeholder:text-muted-foreground dark:border-border dark:hover:bg-accent dark:data-[state=open]:bg-muted bg-transparent',
className,
)}
{...props}
@@ -113,7 +113,7 @@ function SelectItem({
<SelectPrimitive.Item
data-slot="select-item"
className={cn(
"[&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none hover:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
"[&_svg:not([class*='text-'])]:text-muted-foreground hover:bg-muted relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
className,
)}
{...props}
+36 -36
View File
@@ -1,29 +1,29 @@
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { XIcon } from "lucide-react"
import * as React from 'react';
import * as SheetPrimitive from '@radix-ui/react-dialog';
import { XIcon } from 'lucide-react';
import { cn } from "@/lib/utils"
import { cn } from '@/lib/utils';
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
return <SheetPrimitive.Root data-slot="sheet" {...props} />
return <SheetPrimitive.Root data-slot="sheet" {...props} />;
}
function SheetTrigger({
...props
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
}
function SheetClose({
...props
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
}
function SheetPortal({
...props
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
}
function SheetOverlay({
@@ -34,23 +34,23 @@ function SheetOverlay({
<SheetPrimitive.Overlay
data-slot="sheet-overlay"
className={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
className
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
className,
)}
{...props}
/>
)
);
}
function SheetContent({
className,
children,
side = "right",
side = 'right',
showCloseButton = true,
...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
side?: "top" | "right" | "bottom" | "left"
showCloseButton?: boolean
side?: 'top' | 'right' | 'bottom' | 'left';
showCloseButton?: boolean;
}) {
return (
<SheetPortal>
@@ -58,16 +58,16 @@ function SheetContent({
<SheetPrimitive.Content
data-slot="sheet-content"
className={cn(
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
side === "right" &&
"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
side === "left" &&
"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
side === "top" &&
"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
side === "bottom" &&
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
className
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
side === 'right' &&
'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
side === 'left' &&
'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
side === 'top' &&
'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
side === 'bottom' &&
'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
className,
)}
{...props}
>
@@ -80,27 +80,27 @@ function SheetContent({
)}
</SheetPrimitive.Content>
</SheetPortal>
)
);
}
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="sheet-header"
className={cn("flex flex-col gap-1.5 p-4", className)}
className={cn('flex flex-col gap-1.5 p-4', className)}
{...props}
/>
)
);
}
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
function SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="sheet-footer"
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
className={cn('mt-auto flex flex-col gap-2 p-4', className)}
{...props}
/>
)
);
}
function SheetTitle({
@@ -110,10 +110,10 @@ function SheetTitle({
return (
<SheetPrimitive.Title
data-slot="sheet-title"
className={cn("text-foreground font-semibold", className)}
className={cn('text-foreground font-semibold', className)}
{...props}
/>
)
);
}
function SheetDescription({
@@ -123,10 +123,10 @@ function SheetDescription({
return (
<SheetPrimitive.Description
data-slot="sheet-description"
className={cn("text-muted-foreground text-sm", className)}
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
)
);
}
export {
@@ -138,4 +138,4 @@ export {
SheetFooter,
SheetTitle,
SheetDescription,
}
};
+103 -103
View File
@@ -137,7 +137,7 @@ const ConversationBubble = forwardRef<
<div
key={index}
title={file.fileName}
className="dark:text-foreground flex items-center rounded-xl bg-[#EFF3F4] p-2 text-[14px] text-[#5D5D5D] dark:bg-accent"
className="dark:text-foreground dark:bg-accent flex items-center rounded-xl bg-[#EFF3F4] p-2 text-[14px] text-[#5D5D5D]"
>
<div className="bg-primary mr-2 items-center justify-center rounded-lg p-[5.5px]">
<img
@@ -198,7 +198,7 @@ const ConversationBubble = forwardRef<
setIsEditClicked(true);
setEditInputBox(message ?? '');
}}
className={`hover:bg-accent mt-3 flex h-fit shrink-0 cursor-pointer items-center rounded-full p-2 pt-1.5 pl-1.5 dark:hover:bg-accent ${isEditClicked ? 'visible' : 'invisible group-hover:visible'}`}
className={`hover:bg-accent dark:hover:bg-accent mt-3 flex h-fit shrink-0 cursor-pointer items-center rounded-full p-2 pt-1.5 pl-1.5 ${isEditClicked ? 'visible' : 'invisible group-hover:visible'}`}
>
<img src={Edit} alt="Edit" className="cursor-pointer" />
</button>
@@ -227,7 +227,7 @@ const ConversationBubble = forwardRef<
/>
<div className="flex items-center justify-end gap-2">
<button
className="text-primary hover:bg-muted hover:text-foreground dark:hover:bg-accent rounded-full px-4 py-2 text-sm font-semibold transition-colors dark:hover:text-foreground"
className="text-primary hover:bg-muted hover:text-foreground dark:hover:bg-accent dark:hover:text-foreground rounded-full px-4 py-2 text-sm font-semibold transition-colors"
onClick={() => setIsEditClicked(false)}
>
{t('conversation.edit.cancel')}
@@ -322,7 +322,7 @@ const ConversationBubble = forwardRef<
{sources?.slice(0, 3)?.map((source, index) => (
<div key={index} className="relative">
<div
className="bg-muted dark:bg-answer-bubble h-28 cursor-pointer rounded-4xl p-4 hover:bg-muted dark:hover:bg-muted"
className="bg-muted hover:bg-accent dark:bg-answer-bubble dark:hover:bg-muted h-28 cursor-pointer rounded-4xl p-4"
onMouseOver={() => setActiveTooltip(index)}
onMouseOut={() => setActiveTooltip(null)}
>
@@ -379,7 +379,7 @@ const ConversationBubble = forwardRef<
))}
{(sources?.length ?? 0) > 3 && (
<div
className="bg-muted text-primary dark:bg-answer-bubble flex h-28 cursor-pointer flex-col-reverse rounded-4xl p-4 hover:bg-muted hover:text-primary dark:hover:bg-muted dark:hover:text-primary"
className="bg-muted text-primary hover:bg-accent hover:text-primary dark:bg-answer-bubble dark:hover:bg-muted dark:hover:text-primary flex h-28 cursor-pointer flex-col-reverse rounded-4xl p-4"
onClick={() => setIsSidebarOpen(true)}
>
<p className="ellipsis-text h-22 text-xs">
@@ -458,7 +458,7 @@ const ConversationBubble = forwardRef<
<div
className={`fade-in-bubble bg-answer-bubble mr-5 flex max-w-full rounded-[18px] px-6 py-4.5 ${
type === 'ERROR'
? 'text-destructive/80 dark:border-destructive relative flex-row items-center rounded-full border border-transparent bg-[#FFE7E7] p-2 py-5 text-sm font-normal dark:bg-destructive/15 dark:text-white'
? 'text-destructive/80 dark:border-destructive dark:bg-destructive/15 relative flex-row items-center rounded-full border border-transparent bg-[#FFE7E7] p-2 py-5 text-sm font-normal dark:text-white'
: 'flex-col rounded-3xl'
}`}
>
@@ -551,14 +551,14 @@ const ConversationBubble = forwardRef<
},
thead({ children }) {
return (
<thead className="bg-muted text-xs text-foreground uppercase">
<thead className="bg-muted text-foreground text-xs uppercase">
{children}
</thead>
);
},
tr({ children }) {
return (
<tr className="border-b border-border odd:bg-card even:bg-muted">
<tr className="border-border odd:bg-card even:bg-muted border-b">
{children}
</tr>
);
@@ -657,7 +657,7 @@ const ConversationBubble = forwardRef<
<div className="relative mr-2 flex items-center justify-center">
<button
type="button"
className="bg-transparent hover:bg-accent flex cursor-pointer items-center justify-center rounded-full p-2"
className="hover:bg-accent flex cursor-pointer items-center justify-center rounded-full bg-transparent p-2"
onClick={() => {
if (feedback === 'LIKE') {
handleFeedback?.(null);
@@ -670,7 +670,7 @@ const ConversationBubble = forwardRef<
}
>
<Like
className={`${feedback === 'LIKE' ? 'fill-white stroke-primary dark:fill-transparent' : 'stroke-muted-foreground fill-none'}`}
className={`${feedback === 'LIKE' ? 'stroke-primary fill-white dark:fill-transparent' : 'stroke-muted-foreground fill-none'}`}
></Like>
</button>
</div>
@@ -678,7 +678,7 @@ const ConversationBubble = forwardRef<
<div className="relative mr-2 flex items-center justify-center">
<button
type="button"
className="bg-transparent hover:bg-accent flex cursor-pointer items-center justify-center rounded-full p-2"
className="hover:bg-accent flex cursor-pointer items-center justify-center rounded-full bg-transparent p-2"
onClick={() => {
if (feedback === 'DISLIKE') {
handleFeedback?.(null);
@@ -693,7 +693,7 @@ const ConversationBubble = forwardRef<
}
>
<Dislike
className={`${feedback === 'DISLIKE' ? 'fill-white stroke-destructive dark:fill-transparent' : 'stroke-muted-foreground fill-none'}`}
className={`${feedback === 'DISLIKE' ? 'stroke-destructive fill-white dark:fill-transparent' : 'stroke-muted-foreground fill-none'}`}
></Dislike>
</button>
</div>
@@ -746,7 +746,7 @@ function AllSources(sources: AllSourcesProps) {
return (
<div
key={index}
className={`group/card bg-muted relative w-full rounded-4xl p-4 transition-colors hover:bg-muted dark:bg-card dark:hover:bg-muted ${
className={`group/card bg-muted hover:bg-accent dark:bg-card dark:hover:bg-muted relative w-full rounded-4xl p-4 transition-colors ${
isExternalSource ? 'cursor-pointer' : ''
}`}
onClick={() =>
@@ -790,105 +790,105 @@ function ToolCalls({ toolCalls }: { toolCalls: ToolCallsType[] }) {
const [isToolCallsOpen, setIsToolCallsOpen] = useState(false);
return (
<div className="mb-4 flex w-full flex-col flex-wrap items-start self-start lg:flex-nowrap">
<div className="my-2 flex flex-row items-center justify-center gap-3">
<Avatar
className="h-[26px] w-[30px] text-xl"
avatar={
<img
src={Sources}
alt={'ToolCalls'}
className="h-full w-full object-fill"
/>
}
/>
<button
className="flex flex-row items-center gap-2"
onClick={() => setIsToolCallsOpen(!isToolCallsOpen)}
>
<p className="text-base font-semibold">Tool Calls</p>
<div className="mb-4 flex w-full flex-col flex-wrap items-start self-start lg:flex-nowrap">
<div className="my-2 flex flex-row items-center justify-center gap-3">
<Avatar
className="h-[26px] w-[30px] text-xl"
avatar={
<img
src={ChevronDown}
alt="ChevronDown"
className={`h-4 w-4 transform transition-transform duration-200 dark:invert ${isToolCallsOpen ? 'rotate-180' : ''}`}
src={Sources}
alt={'ToolCalls'}
className="h-full w-full object-fill"
/>
</button>
</div>
{isToolCallsOpen && (
<div className="fade-in mr-5 ml-3 w-[90vw] md:w-[70vw] lg:w-full">
<div className="grid grid-cols-1 gap-2">
{toolCalls.map((toolCall, index) => (
<Accordion
key={`tool-call-${index}`}
title={`${toolCall.tool_name} - ${toolCall.action_name.substring(0, toolCall.action_name.lastIndexOf('_'))}`}
className="bg-muted dark:bg-answer-bubble w-full rounded-4xl"
titleClassName="px-6 py-2 text-sm font-semibold"
>
<div className="flex flex-col gap-1">
<div className="border-border flex flex-col rounded-2xl border">
<p className="dark:bg-background flex flex-row items-center justify-between rounded-t-2xl bg-black/10 px-2 py-1 text-sm font-semibold wrap-break-word">
<span style={{ fontFamily: 'IBMPlexMono-Medium' }}>
Arguments
</span>{' '}
<CopyButton
textToCopy={JSON.stringify(toolCall.arguments, null, 2)}
/>
</p>
}
/>
<button
className="flex flex-row items-center gap-2"
onClick={() => setIsToolCallsOpen(!isToolCallsOpen)}
>
<p className="text-base font-semibold">Tool Calls</p>
<img
src={ChevronDown}
alt="ChevronDown"
className={`h-4 w-4 transform transition-transform duration-200 dark:invert ${isToolCallsOpen ? 'rotate-180' : ''}`}
/>
</button>
</div>
{isToolCallsOpen && (
<div className="fade-in mr-5 ml-3 w-[90vw] md:w-[70vw] lg:w-full">
<div className="grid grid-cols-1 gap-2">
{toolCalls.map((toolCall, index) => (
<Accordion
key={`tool-call-${index}`}
title={`${toolCall.tool_name} - ${toolCall.action_name.substring(0, toolCall.action_name.lastIndexOf('_'))}`}
className="bg-muted dark:bg-answer-bubble w-full rounded-4xl"
titleClassName="px-6 py-2 text-sm font-semibold"
>
<div className="flex flex-col gap-1">
<div className="border-border flex flex-col rounded-2xl border">
<p className="dark:bg-background flex flex-row items-center justify-between rounded-t-2xl bg-black/10 px-2 py-1 text-sm font-semibold wrap-break-word">
<span style={{ fontFamily: 'IBMPlexMono-Medium' }}>
Arguments
</span>{' '}
<CopyButton
textToCopy={JSON.stringify(toolCall.arguments, null, 2)}
/>
</p>
<p className="dark:bg-card rounded-b-2xl p-2 font-mono text-sm wrap-break-word">
<span
className="dark:text-muted-foreground leading-[23px] text-black"
style={{ fontFamily: 'IBMPlexMono-Medium' }}
>
{JSON.stringify(toolCall.arguments, null, 2)}
</span>
</p>
</div>
<div className="border-border flex flex-col rounded-2xl border">
<p className="dark:bg-background flex flex-row items-center justify-between rounded-t-2xl bg-black/10 px-2 py-1 text-sm font-semibold wrap-break-word">
<span style={{ fontFamily: 'IBMPlexMono-Medium' }}>
Response
</span>{' '}
<CopyButton
textToCopy={
toolCall.status === 'error'
? toolCall.error || 'Unknown error'
: JSON.stringify(toolCall.result, null, 2)
}
/>
</p>
{toolCall.status === 'pending' && (
<span className="dark:bg-card flex w-full items-center justify-center rounded-b-2xl p-2">
<Spinner size="small" />
</span>
)}
{toolCall.status === 'completed' && (
<p className="dark:bg-card rounded-b-2xl p-2 font-mono text-sm wrap-break-word">
<span
className="leading-[23px] text-black dark:text-muted-foreground"
className="dark:text-muted-foreground leading-[23px] text-black"
style={{ fontFamily: 'IBMPlexMono-Medium' }}
>
{JSON.stringify(toolCall.arguments, null, 2)}
{JSON.stringify(toolCall.result, null, 2)}
</span>
</p>
</div>
<div className="border-border flex flex-col rounded-2xl border">
<p className="dark:bg-background flex flex-row items-center justify-between rounded-t-2xl bg-black/10 px-2 py-1 text-sm font-semibold wrap-break-word">
<span style={{ fontFamily: 'IBMPlexMono-Medium' }}>
Response
</span>{' '}
<CopyButton
textToCopy={
toolCall.status === 'error'
? toolCall.error || 'Unknown error'
: JSON.stringify(toolCall.result, null, 2)
}
/>
</p>
{toolCall.status === 'pending' && (
<span className="dark:bg-card flex w-full items-center justify-center rounded-b-2xl p-2">
<Spinner size="small" />
)}
{toolCall.status === 'error' && (
<p className="dark:bg-card rounded-b-2xl p-2 font-mono text-sm wrap-break-word">
<span
className="leading-[23px] text-red-500 dark:text-red-400"
style={{ fontFamily: 'IBMPlexMono-Medium' }}
>
{toolCall.error}
</span>
)}
{toolCall.status === 'completed' && (
<p className="dark:bg-card rounded-b-2xl p-2 font-mono text-sm wrap-break-word">
<span
className="leading-[23px] text-black dark:text-muted-foreground"
style={{ fontFamily: 'IBMPlexMono-Medium' }}
>
{JSON.stringify(toolCall.result, null, 2)}
</span>
</p>
)}
{toolCall.status === 'error' && (
<p className="dark:bg-card rounded-b-2xl p-2 font-mono text-sm wrap-break-word">
<span
className="leading-[23px] text-red-500 dark:text-red-400"
style={{ fontFamily: 'IBMPlexMono-Medium' }}
>
{toolCall.error}
</span>
</p>
)}
</div>
</p>
)}
</div>
</Accordion>
))}
</div>
</div>
</Accordion>
))}
</div>
)}
</div>
</div>
)}
</div>
);
}
@@ -998,14 +998,14 @@ function Thought({
},
thead({ children }) {
return (
<thead className="bg-muted text-xs text-foreground uppercase">
<thead className="bg-muted text-foreground text-xs uppercase">
{children}
</thead>
);
},
tr({ children }) {
return (
<tr className="border-b border-border odd:bg-card even:bg-muted">
<tr className="border-border odd:bg-card even:bg-muted border-b">
{children}
</tr>
);
@@ -240,7 +240,7 @@ export default function ConversationMessages({
scrollConversationToBottom();
}}
aria-label={t('Scroll to bottom') || 'Scroll to bottom'}
className="border-border fixed right-14 bottom-40 z-10 flex h-7 w-7 items-center justify-center rounded-full border bg-card md:h-9 md:w-9"
className="border-border bg-card fixed right-14 bottom-40 z-10 flex h-7 w-7 items-center justify-center rounded-full border md:h-9 md:w-9"
>
<img
src={ArrowDown}
@@ -203,7 +203,7 @@ export default function ConversationTile({
<input
autoFocus
type="text"
className="h-6 w-full bg-transparent px-1 text-sm leading-6 rounded-2xl font-normal outline-none"
className="h-6 w-full rounded-2xl bg-transparent px-1 text-sm leading-6 font-normal outline-none"
value={conversationName}
onChange={(e) => setConversationsName(e.target.value)}
onKeyDown={handleRenameKeyDown}
@@ -215,7 +215,10 @@ export default function ConversationTile({
)}
</div>
{(conversationId === conversation.id || isHovered || isOpen) && (
<div className="dark:text-muted-foreground flex text-white" ref={menuRef}>
<div
className="dark:text-muted-foreground flex text-white"
ref={menuRef}
>
{isEdit ? (
<div className="flex gap-1">
<img
@@ -248,7 +251,7 @@ export default function ConversationTile({
event.stopPropagation();
setOpen(!isOpen);
}}
className="mr-2 flex h-6 w-6 items-center justify-center rounded-full transition-colors duration-200 hover:bg-accent dark:hover:bg-accent"
className="hover:bg-accent dark:hover:bg-accent mr-2 flex h-6 w-6 items-center justify-center rounded-full transition-colors duration-200"
>
<img src={threeDots} width={8} alt="menu" />
</button>
+1 -1
View File
@@ -80,7 +80,7 @@ export default function AddActionModal({
setModalState('INACTIVE');
setActionName('');
}}
className="dark:text-foreground cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium hover:bg-accent dark:hover:bg-accent"
className="dark:text-foreground hover:bg-accent dark:hover:bg-accent cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium"
>
{t('modals.configTool.closeButton')}
</button>
+1 -1
View File
@@ -131,7 +131,7 @@ export default function AddToolModal({
role="button"
tabIndex={0}
key={index}
className="border-border bg-card flex h-52 w-full cursor-pointer flex-col justify-between rounded-2xl border p-6 hover:bg-accent hover:border-border/80"
className="border-border bg-card hover:bg-accent hover:border-border/80 flex h-52 w-full cursor-pointer flex-col justify-between rounded-2xl border p-6"
onClick={() => {
setSelectedTool(tool);
handleAddTool(tool);
+10 -8
View File
@@ -140,19 +140,21 @@ export default function ConfigToolModal({
/>
</div>
{hasConfig && <ConfigFields
configRequirements={configRequirements}
values={configValues}
onChange={handleFieldChange}
errors={errors}
/>}
{hasConfig && (
<ConfigFields
configRequirements={configRequirements}
values={configValues}
onChange={handleFieldChange}
errors={errors}
/>
)}
</div>
<div className="mt-8 flex flex-row-reverse gap-2">
<button
onClick={handleAddTool}
disabled={saving}
className="bg-primary hover:bg-primary/90 disabled:opacity-60 rounded-full px-5 py-2 text-sm font-medium text-white transition-colors"
className="bg-primary hover:bg-primary/90 rounded-full px-5 py-2 text-sm font-medium text-white transition-colors disabled:opacity-60"
>
{saving
? t('modals.configTool.addButton') + '…'
@@ -160,7 +162,7 @@ export default function ConfigToolModal({
</button>
<button
onClick={handleClose}
className="dark:text-foreground cursor-pointer rounded-full px-5 py-2 text-sm font-medium hover:bg-accent dark:hover:bg-accent"
className="dark:text-foreground hover:bg-accent dark:hover:bg-accent cursor-pointer rounded-full px-5 py-2 text-sm font-medium"
>
{t('modals.configTool.closeButton')}
</button>
@@ -59,7 +59,7 @@ export default function FolderNameModal({
onKeyDown={handleKeyDown}
placeholder={t('agents.folders.folderName')}
autoFocus
className="w-full rounded-lg border border-border bg-card px-3 py-2 text-sm outline-none dark:text-white"
className="border-border bg-card w-full rounded-lg border px-3 py-2 text-sm outline-none dark:text-white"
/>
<div className="mt-6 flex justify-end gap-2">
<button
@@ -67,7 +67,7 @@ export default function FolderNameModal({
setModalState('INACTIVE');
setName('');
}}
className="dark:text-foreground cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium hover:bg-accent dark:hover:bg-accent"
className="dark:text-foreground hover:bg-accent dark:hover:bg-accent cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium"
>
{t('cancel')}
</button>
+5 -5
View File
@@ -206,7 +206,7 @@ export default function ImportSpecModal({
</div>
) : (
<div className="flex flex-col gap-4">
<div className="rounded-xl bg-muted p-4">
<div className="bg-muted rounded-xl p-4">
<h3 className="text-foreground dark:text-foreground font-medium">
{parsedResult.metadata.title}
</h3>
@@ -215,7 +215,7 @@ export default function ImportSpecModal({
{parsedResult.metadata.description}
</p>
)}
<p className="mt-2 text-xs text-muted-foreground">
<p className="text-muted-foreground mt-2 text-xs">
{t('modals.importSpec.version')}:{' '}
{parsedResult.metadata.version}
</p>
@@ -227,7 +227,7 @@ export default function ImportSpecModal({
type="text"
value={baseUrl}
onChange={(e) => setBaseUrl(e.target.value)}
className="border-border dark:border-border text-foreground dark:text-foreground w-full rounded-lg border bg-card px-3 py-2 text-sm outline-hidden"
className="border-border dark:border-border text-foreground dark:text-foreground bg-card w-full rounded-lg border px-3 py-2 text-sm outline-hidden"
placeholder={
parsedResult.metadata.base_url || 'https://api.example.com'
}
@@ -255,7 +255,7 @@ export default function ImportSpecModal({
{parsedResult.actions.map((action, index) => (
<label
key={index}
className="border-border dark:border-border flex cursor-pointer items-start gap-3 rounded-xl border p-3 transition-colors hover:bg-muted dark:hover:bg-muted"
className="border-border dark:border-border hover:bg-muted dark:hover:bg-muted flex cursor-pointer items-start gap-3 rounded-xl border p-3 transition-colors"
>
<input
type="checkbox"
@@ -310,7 +310,7 @@ export default function ImportSpecModal({
)}
<button
onClick={handleClose}
className="dark:text-foreground cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium hover:bg-accent dark:hover:bg-accent"
className="dark:text-foreground hover:bg-accent dark:hover:bg-accent cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium"
>
{t('modals.importSpec.cancel')}
</button>
+2 -2
View File
@@ -753,7 +753,7 @@ export default function MCPServerModal({
<button
onClick={testConnection}
disabled={testing}
className="border-border dark:border-border dark:text-foreground w-full rounded-3xl border px-6 py-2 text-sm font-medium transition-all hover:bg-accent disabled:opacity-50 sm:w-auto dark:hover:bg-muted/50"
className="border-border dark:border-border dark:text-foreground hover:bg-accent dark:hover:bg-muted/50 w-full rounded-3xl border px-6 py-2 text-sm font-medium transition-all disabled:opacity-50 sm:w-auto"
>
{testing ? (
<div className="flex items-center justify-center">
@@ -773,7 +773,7 @@ export default function MCPServerModal({
setModalState('INACTIVE');
resetForm();
}}
className="dark:text-foreground w-full cursor-pointer rounded-3xl px-6 py-2 text-sm font-medium hover:bg-accent sm:w-auto dark:hover:bg-muted/50"
className="dark:text-foreground hover:bg-accent dark:hover:bg-muted/50 w-full cursor-pointer rounded-3xl px-6 py-2 text-sm font-medium sm:w-auto"
>
{t('settings.tools.mcp.cancel')}
</button>
+11 -11
View File
@@ -151,7 +151,7 @@ export default function MoveToFolderModal({
</h2>
</div>
<div
className="flex items-center gap-1 bg-muted px-8 py-2 text-xs font-semibold text-[#59636E] dark:bg-muted dark:text-gray-400"
className="bg-muted dark:bg-muted flex items-center gap-1 px-8 py-2 text-xs font-semibold text-[#59636E] dark:text-gray-400"
style={{ fontFamily: "'Segoe UI', sans-serif" }}
>
<button
@@ -180,7 +180,7 @@ export default function MoveToFolderModal({
) : (
<button
onClick={() => handleNavigateToPath(index)}
className="opacity-70 hover:text-foreground dark:hover:text-white"
className="hover:text-foreground opacity-70 dark:hover:text-white"
>
{item.name}
</button>
@@ -188,10 +188,10 @@ export default function MoveToFolderModal({
</span>
))}
</div>
<div className="max-h-60 min-h-[200px] overflow-y-auto border-t border-gray-200 dark:border-border">
<div className="dark:border-border max-h-60 min-h-[200px] overflow-y-auto border-t border-gray-200">
{isLoading ? (
<div className="flex h-[200px] items-center justify-center">
<span className="text-[14px] text-muted-foreground">
<span className="text-muted-foreground text-[14px]">
{t('loading')}...
</span>
</div>
@@ -204,7 +204,7 @@ export default function MoveToFolderModal({
e.stopPropagation();
setSelectedFolderId(null);
}}
className={`flex w-full items-center gap-2 border-b border-gray-200 dark:border-border px-8 py-2 text-left text-[14px] ${
className={`dark:border-border flex w-full items-center gap-2 border-b border-gray-200 px-8 py-2 text-left text-[14px] ${
selectedFolderId === null
? 'bg-[#7D54D1] text-white'
: 'bg-muted hover:bg-accent dark:bg-muted'
@@ -226,7 +226,7 @@ export default function MoveToFolderModal({
<button
key={folder.id}
onClick={() => setSelectedFolderId(folder.id)}
className={`flex w-full cursor-pointer items-center justify-between border-b border-gray-200 dark:border-border px-8 py-2 text-left text-[14px] ${
className={`dark:border-border flex w-full cursor-pointer items-center justify-between border-b border-gray-200 px-8 py-2 text-left text-[14px] ${
selectedFolderId === folder.id
? 'bg-[#7D54D1] text-white'
: 'bg-muted hover:bg-accent dark:bg-muted'
@@ -271,14 +271,14 @@ export default function MoveToFolderModal({
</button>
))}
{currentLevelFolders.length === 0 && folderPath.length > 0 && (
<div className="flex h-[200px] items-center justify-center text-sm text-muted-foreground">
<div className="text-muted-foreground flex h-[200px] items-center justify-center text-sm">
{t('agents.folders.noSubfolders')}
</div>
)}
{currentLevelFolders.length === 0 &&
folderPath.length === 0 &&
!currentFolderId && (
<div className="flex h-[200px] items-center justify-center text-sm text-muted-foreground">
<div className="text-muted-foreground flex h-[200px] items-center justify-center text-sm">
{t('agents.folders.noFolders')}
</div>
)}
@@ -286,7 +286,7 @@ export default function MoveToFolderModal({
)}
</div>
<div className="flex items-center justify-between border-t border-gray-200 dark:border-border px-8 py-4">
<div className="dark:border-border flex items-center justify-between border-t border-gray-200 px-8 py-4">
{isCreatingFolder ? (
<input
ref={newFolderInputRef}
@@ -309,7 +309,7 @@ export default function MoveToFolderModal({
}
}}
placeholder={t('agents.folders.newFolder')}
className="rounded-full border border-[#7D54D1] bg-transparent px-6 py-2 text-sm font-medium text-[#7D54D1] outline-none placeholder:text-[#7D54D1]/60 dark:text-primary dark:placeholder:text-[#B794F4]/60"
className="dark:text-primary rounded-full border border-[#7D54D1] bg-transparent px-6 py-2 text-sm font-medium text-[#7D54D1] outline-none placeholder:text-[#7D54D1]/60 dark:placeholder:text-[#B794F4]/60"
autoFocus
/>
) : (
@@ -336,7 +336,7 @@ export default function MoveToFolderModal({
setModalState('INACTIVE');
}
}}
className="dark:text-foreground cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium hover:bg-accent dark:hover:bg-accent"
className="dark:text-foreground hover:bg-accent dark:hover:bg-accent cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium"
>
{t('cancel')}
</button>
+3 -4
View File
@@ -32,8 +32,7 @@ export default function WrapperModal({
)
return;
if (document.querySelector('[data-radix-select-content]')) return;
if (modalRef.current && !modalRef.current.contains(target))
close();
if (modalRef.current && !modalRef.current.contains(target)) close();
};
const handleEscapePress = (event: KeyboardEvent) => {
@@ -61,7 +60,7 @@ export default function WrapperModal({
/>
<div
ref={modalRef}
className={`relative rounded-2xl bg-card p-8 shadow-[0px_4px_40px_-3px_#0000001A] dark:bg-card ${className}`}
className={`bg-card dark:bg-card relative rounded-2xl p-8 shadow-[0px_4px_40px_-3px_#0000001A] ${className}`}
>
{!isPerformingTask && (
<button
@@ -72,7 +71,7 @@ export default function WrapperModal({
</button>
)}
<div
className={`no-scrollbar overflow-y-auto text-foreground dark:text-foreground ${contentClassName}`}
className={`no-scrollbar text-foreground dark:text-foreground overflow-y-auto ${contentClassName}`}
>
{children}
</div>
+8 -8
View File
@@ -120,7 +120,7 @@ function PromptTextarea({
return (
<>
<div
className="pointer-events-none absolute inset-0 z-0 overflow-hidden rounded bg-card px-3 py-2"
className="bg-card pointer-events-none absolute inset-0 z-0 overflow-hidden rounded px-3 py-2"
aria-hidden="true"
>
<div
@@ -239,7 +239,7 @@ function AddPrompt({
<p className="mb-1 text-xl font-semibold text-[#2B2B2B] dark:text-white">
{t('modals.prompts.addPrompt')}
</p>
<p className="mb-6 text-sm text-[#6B6B6B] dark:text-muted-foreground">
<p className="dark:text-muted-foreground mb-6 text-sm text-[#6B6B6B]">
{t('modals.prompts.addDescription')}
</p>
<div>
@@ -266,7 +266,7 @@ function AddPrompt({
htmlFor="new-prompt-content"
className={`absolute z-20 select-none ${
newPromptContent ? '-top-2.5 left-3 text-xs' : ''
} text-muted-foreground pointer-events-none max-w-[calc(100%-24px)] cursor-none overflow-hidden bg-card px-2 text-ellipsis whitespace-nowrap transition-all peer-placeholder-shown:top-2.5 peer-placeholder-shown:left-3 peer-placeholder-shown:text-base peer-focus:-top-2.5 peer-focus:left-3 peer-focus:text-xs`}
} text-muted-foreground bg-card pointer-events-none max-w-[calc(100%-24px)] cursor-none overflow-hidden px-2 text-ellipsis whitespace-nowrap transition-all peer-placeholder-shown:top-2.5 peer-placeholder-shown:left-3 peer-placeholder-shown:text-base peer-focus:-top-2.5 peer-focus:left-3 peer-focus:text-xs`}
>
{t('modals.prompts.promptText')}
</label>
@@ -278,7 +278,7 @@ function AddPrompt({
<span className="font-bold">
{t('modals.prompts.variablesLabel')}
</span>
<span className="text-xs text-[10px] font-medium text-muted-foreground">
<span className="text-muted-foreground text-xs text-[10px] font-medium">
{t('modals.prompts.variablesDescription')}
</span>
</p>
@@ -446,7 +446,7 @@ function EditPrompt({
<p className="mb-1 text-xl font-semibold text-[#2B2B2B] dark:text-white">
{t('modals.prompts.editPrompt')}
</p>
<p className="mb-6 text-sm text-[#6B6B6B] dark:text-muted-foreground">
<p className="dark:text-muted-foreground mb-6 text-sm text-[#6B6B6B]">
{t('modals.prompts.editDescription')}
</p>
<div>
@@ -473,7 +473,7 @@ function EditPrompt({
htmlFor="edit-prompt-content"
className={`absolute z-20 select-none ${
editPromptContent ? '-top-2.5 left-3 text-xs' : ''
} text-muted-foreground pointer-events-none max-w-[calc(100%-24px)] cursor-none overflow-hidden bg-card px-2 text-ellipsis whitespace-nowrap transition-all peer-placeholder-shown:top-2.5 peer-placeholder-shown:left-3 peer-placeholder-shown:text-base peer-focus:-top-2.5 peer-focus:left-3 peer-focus:text-xs`}
} text-muted-foreground bg-card pointer-events-none max-w-[calc(100%-24px)] cursor-none overflow-hidden px-2 text-ellipsis whitespace-nowrap transition-all peer-placeholder-shown:top-2.5 peer-placeholder-shown:left-3 peer-placeholder-shown:text-base peer-focus:-top-2.5 peer-focus:left-3 peer-focus:text-xs`}
>
{t('modals.prompts.promptText')}
</label>
@@ -485,7 +485,7 @@ function EditPrompt({
<span className="font-bold">
{t('modals.prompts.variablesLabel')}
</span>
<span className="text-xs text-[10px] font-medium text-muted-foreground">
<span className="text-muted-foreground text-xs text-[10px] font-medium">
{t('modals.prompts.variablesDescription')}
</span>
</p>
@@ -759,7 +759,7 @@ export default function PromptsModal({
setNewPromptContent('');
}
}}
className="mx-4 mt-16 w-[95vw] max-w-[650px] rounded-2xl bg-card px-4 py-4 sm:px-6 sm:py-6 md:max-w-[860px] md:px-8 md:py-6 lg:max-w-[980px] dark:bg-card"
className="bg-card dark:bg-card mx-4 mt-16 w-[95vw] max-w-[650px] rounded-2xl px-4 py-4 sm:px-6 sm:py-6 md:max-w-[860px] md:px-8 md:py-6 lg:max-w-[980px]"
contentClassName="!overflow-visible"
>
{view}
+1 -1
View File
@@ -175,7 +175,7 @@ export default function Analytics({ agentId }: AnalyticsProps) {
}, [agentId, feedbackFilter]);
return (
<div className="mt-8">
<p className="mb-5 text-[15px] leading-6 text-muted-foreground">
<p className="text-muted-foreground mb-5 text-[15px] leading-6">
{t('settings.analytics.subtitle')}
</p>
{/* Messages Analytics */}
+7 -7
View File
@@ -58,7 +58,7 @@ export default function Logs({ agentId, tableHeader }: LogsProps) {
}, [page, agentId]);
return (
<div className="mt-8">
<p className="mb-5 text-[15px] leading-6 text-muted-foreground">
<p className="text-muted-foreground mb-5 text-[15px] leading-6">
{t('settings.logs.subtitle')}
</p>
<div>
@@ -117,9 +117,9 @@ function LogsTable({ logs, setPage, loading, tableHeader }: LogsTableProps) {
}, []);
return (
<div className="logs-table border-border h-[55vh] w-full overflow-hidden rounded-xl border bg-card dark:bg-black">
<div className="logs-table border-border bg-card h-[55vh] w-full overflow-hidden rounded-xl border dark:bg-black">
<div className="flex h-8 flex-col items-start justify-center bg-black/10 dark:bg-white/5">
<p className="px-3 text-xs text-muted-foreground">
<p className="text-muted-foreground px-3 text-xs">
{tableHeader ? tableHeader : t('settings.logs.tableHeader')}
</p>
</div>
@@ -168,11 +168,11 @@ function Log({
const { id, action, timestamp, ...filteredLog } = log;
return (
<div className="group dark:hover:bg-accent w-full rounded-xl bg-transparent hover:bg-muted">
<div className="group dark:hover:bg-accent hover:bg-muted w-full rounded-xl bg-transparent">
<div
onClick={() => onToggle(log.id)}
className={`flex cursor-pointer flex-row items-start gap-2 p-2 px-4 py-3 text-foreground ${
isOpen ? 'rounded-t-xl bg-[#F1F1F1] dark:bg-background' : ''
className={`text-foreground flex cursor-pointer flex-row items-start gap-2 p-2 px-4 py-3 ${
isOpen ? 'dark:bg-background rounded-t-xl bg-[#F1F1F1]' : ''
}`}
>
<img
@@ -193,7 +193,7 @@ function Log({
</span>
</div>
{isOpen && (
<div className="rounded-b-xl bg-[#F1F1F1] px-4 py-3 dark:bg-background">
<div className="dark:bg-background rounded-b-xl bg-[#F1F1F1] px-4 py-3">
<div className="scrollbar-overlay overflow-y-auto">
<pre className="px-2 font-mono text-xs leading-relaxed wrap-break-word whitespace-pre-wrap text-gray-700 dark:text-gray-400">
{JSON.stringify(filteredLog, null, 2)}
+13 -13
View File
@@ -362,7 +362,7 @@ export default function Sources({
) : (
<div className="mt-8 flex w-full max-w-full flex-col overflow-hidden">
<div className="relative flex grow flex-col">
<p className="mb-5 text-[15px] leading-6 text-muted-foreground">
<p className="text-muted-foreground mb-5 text-[15px] leading-6">
{t('settings.sources.subtitle')}
</p>
<div className="mb-6 flex flex-col items-start justify-between gap-3 sm:flex-row sm:items-center">
@@ -371,7 +371,11 @@ export default function Sources({
{t('settings.sources.searchPlaceholder')}
</label>
<div className="relative w-full max-w-md">
<img src={SearchIcon} alt="" className="absolute top-1/2 left-4 h-5 w-5 -translate-y-1/2 opacity-40" />
<img
src={SearchIcon}
alt=""
className="absolute top-1/2 left-4 h-5 w-5 -translate-y-1/2 opacity-40"
/>
<input
maxLength={256}
placeholder={t('settings.sources.searchPlaceholder')}
@@ -383,7 +387,7 @@ export default function Sources({
setSearchTerm(e.target.value);
setCurrentPage(1);
}}
className="h-11 w-full rounded-full border border-border bg-card py-2 pr-5 pl-11 text-sm text-foreground shadow-[0_1px_4px_rgba(0,0,0,0.06)] outline-none transition-shadow placeholder:text-muted-foreground focus:shadow-[0_2px_8px_rgba(0,0,0,0.1)] dark:shadow-none"
className="border-border bg-card text-foreground placeholder:text-muted-foreground h-11 w-full rounded-full border py-2 pr-5 pl-11 text-sm shadow-[0_1px_4px_rgba(0,0,0,0.06)] transition-shadow outline-none focus:shadow-[0_2px_8px_rgba(0,0,0,0.1)] dark:shadow-none"
/>
</div>
</div>
@@ -422,7 +426,7 @@ export default function Sources({
return (
<div key={docId} className="relative">
<div
className={`flex h-[130px] w-full flex-col rounded-2xl bg-muted p-3 transition-all duration-200 dark:bg-accent ${
className={`bg-muted dark:bg-accent flex h-[130px] w-full flex-col rounded-2xl p-3 transition-all duration-200 ${
activeMenuId === docId || syncMenuState.docId === docId
? 'scale-[1.05]'
: 'hover:scale-[1.05]'
@@ -431,7 +435,7 @@ export default function Sources({
<div className="w-full flex-1">
<div className="flex w-full items-center justify-between gap-2">
<h3
className="font-inter dark:text-foreground line-clamp-3 text-[13px] leading-[18px] font-semibold wrap-break-word text-foreground"
className="font-inter dark:text-foreground text-foreground line-clamp-3 text-[13px] leading-[18px] font-semibold wrap-break-word"
title={document.name}
>
{document.name}
@@ -472,7 +476,7 @@ export default function Sources({
e.stopPropagation();
handleMenuClick(e, docId);
}}
className="inline-flex h-[35px] w-6 shrink-0 items-center justify-center rounded-md transition-colors hover:bg-[#EBEBEB] dark:hover:bg-muted"
className="dark:hover:bg-muted inline-flex h-[35px] w-6 shrink-0 items-center justify-center rounded-md transition-colors hover:bg-[#EBEBEB]"
aria-label={t('settings.sources.menuAlt')}
data-testid={`menu-button-${docId}`}
>
@@ -493,17 +497,13 @@ export default function Sources({
alt=""
className="h-3.5 w-3.5"
/>
<span className="font-inter text-[12px] leading-[18px] font-medium text-muted-foreground">
<span className="font-inter text-muted-foreground text-[12px] leading-[18px] font-medium">
{document.date ? formatDate(document.date) : ''}
</span>
</div>
<div className="flex items-center gap-2">
<img
src={DiscIcon}
alt=""
className="h-3.5 w-3.5"
/>
<span className="font-inter text-[12px] leading-[18px] font-medium text-muted-foreground">
<img src={DiscIcon} alt="" className="h-3.5 w-3.5" />
<span className="font-inter text-muted-foreground text-[12px] leading-[18px] font-medium">
{document.tokens
? formatTokens(+document.tokens)
: ''}
+27 -7
View File
@@ -332,7 +332,7 @@ export default function ToolConfig({
<div className="mb-4 flex items-center justify-between">
<div className="text-foreground dark:text-foreground flex items-center gap-3 text-sm">
<button
className="rounded-full border border-border p-3 text-sm text-muted-foreground hover:bg-accent"
className="border-border text-muted-foreground hover:bg-accent rounded-full border p-3 text-sm"
onClick={handleBackClick}
>
<img src={ArrowLeft} alt="left-arrow" className="h-3 w-3" />
@@ -434,13 +434,23 @@ export default function ToolConfig({
{'actions' in tool && tool.actions && tool.actions.length > 0 ? (
<>
<div className="relative">
<svg className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor"><circle cx="11" cy="11" r="8"/><path strokeLinecap="round" d="m21 21-4.35-4.35"/></svg>
<svg
className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={2}
stroke="currentColor"
>
<circle cx="11" cy="11" r="8" />
<path strokeLinecap="round" d="m21 21-4.35-4.35" />
</svg>
<input
type="text"
value={userActionsSearch}
onChange={(e) => setUserActionsSearch(e.target.value)}
placeholder={t('settings.tools.searchActions')}
className="h-10 w-full rounded-full border border-border bg-transparent pl-10 pr-4 text-sm text-foreground outline-none placeholder:text-muted-foreground"
className="border-border text-foreground placeholder:text-muted-foreground h-10 w-full rounded-full border bg-transparent pr-4 pl-10 text-sm outline-none"
/>
</div>
@@ -843,13 +853,23 @@ function APIToolConfig({
return (
<div className="scrollbar-overlay flex flex-col gap-4">
<div className="relative">
<svg className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor"><circle cx="11" cy="11" r="8"/><path strokeLinecap="round" d="m21 21-4.35-4.35"/></svg>
<svg
className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={2}
stroke="currentColor"
>
<circle cx="11" cy="11" r="8" />
<path strokeLinecap="round" d="m21 21-4.35-4.35" />
</svg>
<input
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder={t('settings.tools.searchActions')}
className="h-10 w-full rounded-full border border-border bg-transparent pl-10 pr-4 text-sm text-foreground outline-none placeholder:text-muted-foreground"
className="border-border text-foreground placeholder:text-muted-foreground h-10 w-full rounded-full border bg-transparent pr-4 pl-10 text-sm outline-none"
/>
</div>
@@ -945,7 +965,7 @@ function APIToolConfig({
</div>
<div className="mt-4 px-5 py-2">
<div className="relative w-full">
<span className="text-muted-foreground absolute -top-2 left-5 z-10 bg-card px-2 text-xs">
<span className="text-muted-foreground bg-card absolute -top-2 left-5 z-10 px-2 text-xs">
{t('settings.tools.method')}
</span>
<Dropdown
@@ -1024,7 +1044,7 @@ function APIToolConfig({
action.method === 'OPTIONS') && (
<div className="mt-4 px-5 py-2">
<div className="relative w-full">
<span className="text-muted-foreground absolute -top-2 left-5 z-10 bg-card px-2 text-xs">
<span className="text-muted-foreground bg-card absolute -top-2 left-5 z-10 px-2 text-xs">
{t('settings.tools.bodyContentType')}
</span>
<Dropdown
+119 -111
View File
@@ -210,12 +210,16 @@ export default function Tools() {
) : (
<div className="mt-8">
<div className="relative flex flex-col">
<p className="mb-5 text-[15px] leading-6 text-muted-foreground">
<p className="text-muted-foreground mb-5 text-[15px] leading-6">
{t('settings.tools.subtitle')}
</p>
<div className="my-3 flex flex-col items-start gap-3 sm:flex-row sm:items-center sm:justify-between">
<div className="relative w-full max-w-md">
<img src={SearchIcon} alt="" className="absolute top-1/2 left-4 h-5 w-5 -translate-y-1/2 opacity-40" />
<img
src={SearchIcon}
alt=""
className="absolute top-1/2 left-4 h-5 w-5 -translate-y-1/2 opacity-40"
/>
<input
maxLength={256}
placeholder={t('settings.tools.searchPlaceholder')}
@@ -224,7 +228,7 @@ export default function Tools() {
id="tool-search-input"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="h-11 w-full rounded-full border border-border bg-card py-2 pr-5 pl-11 text-sm text-foreground shadow-[0_1px_4px_rgba(0,0,0,0.06)] outline-none transition-shadow placeholder:text-muted-foreground focus:shadow-[0_2px_8px_rgba(0,0,0,0.1)] dark:shadow-none"
className="border-border bg-card text-foreground placeholder:text-muted-foreground h-11 w-full rounded-full border py-2 pr-5 pl-11 text-sm shadow-[0_1px_4px_rgba(0,0,0,0.06)] transition-shadow outline-none focus:shadow-[0_2px_8px_rgba(0,0,0,0.1)] dark:shadow-none"
/>
</div>
<button
@@ -256,115 +260,119 @@ export default function Tools() {
{t('settings.tools.noToolsFound')}
</p>
</div>
) : (() => {
const filtered = userTools.filter((tool) =>
(tool.customName || tool.displayName)
.toLowerCase()
.includes(searchTerm.toLowerCase()),
);
return filtered.length === 0 ? (
<div className="flex w-full flex-col items-center justify-center py-12">
<img
src={isDarkTheme ? NoFilesDarkIcon : NoFilesIcon}
alt={t('settings.tools.noToolsFound')}
className="mx-auto mb-6 h-32 w-32"
/>
<p className="text-center text-lg text-gray-500 dark:text-gray-400">
{t('settings.tools.noToolsFound')}
</p>
</div>
) : (
filtered.map((tool, index) => (
<div
key={index}
className="relative flex h-52 w-[300px] flex-col justify-between overflow-hidden rounded-2xl bg-muted p-6 hover:bg-accent"
>
<div
ref={menuRefs.current[tool.id]}
onClick={(e) => {
e.stopPropagation();
setActiveMenuId(
activeMenuId === tool.id ? null : tool.id,
);
}}
className="absolute top-4 right-4 z-10 cursor-pointer"
>
<img
src={ThreeDotsIcon}
alt={t('settings.tools.settingsIconAlt')}
className="h-[19px] w-[19px]"
/>
<ContextMenu
isOpen={activeMenuId === tool.id}
setIsOpen={(isOpen) => {
setActiveMenuId(isOpen ? tool.id : null);
}}
options={getMenuOptions(tool)}
anchorRef={menuRefs.current[tool.id]}
position="bottom-right"
offset={{ x: 0, y: 0 }}
/>
</div>
<div className="w-full">
<div className="flex w-full items-center gap-2 px-1">
<img
src={`/toolIcons/tool_${tool.name}.svg`}
alt={`${tool.displayName} icon`}
className="h-6 w-6"
/>
{tool.name === 'mcp_tool' &&
mcpStatuses[tool.id] && (
<span
className={`inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium leading-none ${
mcpStatuses[tool.id] === 'connected'
? 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300'
: mcpStatuses[tool.id] === 'needs_auth'
? 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300'
: 'bg-gray-100 text-gray-600 dark:bg-gray-700/40 dark:text-gray-300'
}`}
>
{mcpStatuses[tool.id] === 'connected'
? t('settings.tools.authStatus.connected')
: mcpStatuses[tool.id] === 'needs_auth'
? t('settings.tools.authStatus.needsAuth')
: t(
'settings.tools.authStatus.configured',
)}
</span>
)}
</div>
<div className="mt-[9px]">
<p
title={tool.customName || tool.displayName}
className="text-foreground dark:text-foreground truncate px-1 text-[13px] leading-relaxed font-semibold capitalize"
>
{tool.customName || tool.displayName}
</p>
<p
className="text-muted-foreground mt-1 line-clamp-4 max-h-24 overflow-hidden px-1 text-[12px] leading-relaxed break-all"
title={tool.description}
>
{tool.description}
</p>
</div>
</div>
<div className="absolute right-4 bottom-4">
<ToggleSwitch
checked={tool.status}
onChange={(checked) =>
updateToolStatus(tool.id, checked)
}
size="small"
id={`toolToggle-${index}`}
ariaLabel={t('settings.tools.toggleToolAria', {
toolName: tool.customName || tool.displayName,
})}
/>
</div>
) : (
(() => {
const filtered = userTools.filter((tool) =>
(tool.customName || tool.displayName)
.toLowerCase()
.includes(searchTerm.toLowerCase()),
);
return filtered.length === 0 ? (
<div className="flex w-full flex-col items-center justify-center py-12">
<img
src={isDarkTheme ? NoFilesDarkIcon : NoFilesIcon}
alt={t('settings.tools.noToolsFound')}
className="mx-auto mb-6 h-32 w-32"
/>
<p className="text-center text-lg text-gray-500 dark:text-gray-400">
{t('settings.tools.noToolsFound')}
</p>
</div>
))
);
})()}
) : (
filtered.map((tool, index) => (
<div
key={index}
className="bg-muted hover:bg-accent relative flex h-52 w-[300px] flex-col justify-between overflow-hidden rounded-2xl p-6"
>
<div
ref={menuRefs.current[tool.id]}
onClick={(e) => {
e.stopPropagation();
setActiveMenuId(
activeMenuId === tool.id ? null : tool.id,
);
}}
className="absolute top-4 right-4 z-10 cursor-pointer"
>
<img
src={ThreeDotsIcon}
alt={t('settings.tools.settingsIconAlt')}
className="h-[19px] w-[19px]"
/>
<ContextMenu
isOpen={activeMenuId === tool.id}
setIsOpen={(isOpen) => {
setActiveMenuId(isOpen ? tool.id : null);
}}
options={getMenuOptions(tool)}
anchorRef={menuRefs.current[tool.id]}
position="bottom-right"
offset={{ x: 0, y: 0 }}
/>
</div>
<div className="w-full">
<div className="flex w-full items-center gap-2 px-1">
<img
src={`/toolIcons/tool_${tool.name}.svg`}
alt={`${tool.displayName} icon`}
className="h-6 w-6"
/>
{tool.name === 'mcp_tool' &&
mcpStatuses[tool.id] && (
<span
className={`inline-flex items-center rounded-full px-2 py-0.5 text-[10px] leading-none font-medium ${
mcpStatuses[tool.id] === 'connected'
? 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300'
: mcpStatuses[tool.id] === 'needs_auth'
? 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300'
: 'bg-gray-100 text-gray-600 dark:bg-gray-700/40 dark:text-gray-300'
}`}
>
{mcpStatuses[tool.id] === 'connected'
? t('settings.tools.authStatus.connected')
: mcpStatuses[tool.id] === 'needs_auth'
? t(
'settings.tools.authStatus.needsAuth',
)
: t(
'settings.tools.authStatus.configured',
)}
</span>
)}
</div>
<div className="mt-[9px]">
<p
title={tool.customName || tool.displayName}
className="text-foreground dark:text-foreground truncate px-1 text-[13px] leading-relaxed font-semibold capitalize"
>
{tool.customName || tool.displayName}
</p>
<p
className="text-muted-foreground mt-1 line-clamp-4 max-h-24 overflow-hidden px-1 text-[12px] leading-relaxed break-all"
title={tool.description}
>
{tool.description}
</p>
</div>
</div>
<div className="absolute right-4 bottom-4">
<ToggleSwitch
checked={tool.status}
onChange={(checked) =>
updateToolStatus(tool.id, checked)
}
size="small"
id={`toolToggle-${index}`}
ariaLabel={t('settings.tools.toggleToolAria', {
toolName: tool.customName || tool.displayName,
})}
/>
</div>
</div>
))
);
})()
)}
</div>
)}
</div>
+1 -1
View File
@@ -78,4 +78,4 @@ export default store;
// TODO : use https://redux-toolkit.js.org/tutorials/typescript#define-typed-hooks everywere instead of direct useDispatch
// TODO : streamline async state management
// TODO : streamline async state management
+5 -5
View File
@@ -203,7 +203,7 @@ function Upload({
{files.map((file) => (
<p
key={file.name}
className="truncate overflow-hidden text-ellipsis text-muted-foreground"
className="text-muted-foreground truncate overflow-hidden text-ellipsis"
title={file.name}
>
{file.name}
@@ -812,7 +812,7 @@ function Upload({
className={`relative mx-auto flex h-[91.2px] w-full cursor-pointer flex-col justify-between gap-2 rounded-2xl border border-solid pt-[21.1px] pr-[21px] pb-[15px] pl-[21px] transition-colors duration-300 ease-out ${
ingestor.type === option.value
? 'border-[#7D54D1] bg-[#7D54D1] text-white'
: 'border-border bg-transparent transition-shadow duration-300 hover:bg-accent/30 hover:shadow-[0_0_15px_0_#00000026] dark:border-border/30'
: 'border-border hover:bg-accent/30 dark:border-border/30 bg-transparent transition-shadow duration-300 hover:shadow-[0_0_15px_0_#00000026]'
}`}
onClick={() =>
handleIngestorTypeChange(option.value as IngestorType)
@@ -843,7 +843,7 @@ function Upload({
>
<div className="flex w-full flex-col gap-6">
{!ingestor.type && (
<p className="font-inter text-left text-[20px] leading-7 font-semibold tracking-[0.15px] text-foreground dark:text-foreground">
<p className="font-inter text-foreground dark:text-foreground text-left text-[20px] leading-7 font-semibold tracking-[0.15px]">
{t('modals.uploadDoc.selectSource')}
</p>
)}
@@ -865,7 +865,7 @@ function Upload({
<span>{t('modals.uploadDoc.back')}</span>
</button>
<h2 className="font-inter text-[22px] leading-7 font-semibold tracking-[0.15px] text-foreground">
<h2 className="font-inter text-foreground text-[22px] leading-7 font-semibold tracking-[0.15px]">
{ingestor.type &&
t(`modals.uploadDoc.ingestors.${ingestor.type}.heading`)}
</h2>
@@ -913,7 +913,7 @@ function Upload({
disabled={isUploadDisabled()}
className={`rounded-3xl px-4 py-2 text-[14px] font-medium ${
isUploadDisabled()
? 'cursor-not-allowed bg-gray-300 text-gray-500 dark:bg-muted dark:text-muted-foreground'
? 'dark:bg-muted dark:text-muted-foreground cursor-not-allowed bg-gray-300 text-gray-500'
: 'bg-primary hover:bg-primary/90 cursor-pointer text-white'
}`}
>