Skip to content

Commit 93ab165

Browse files
ivicacclaude
andcommitted
4000 KnowledgeBase - client - Address remaining PR review comments
- Use Icon suffix for all lucide imports (SearchIcon, DatabaseIcon, etc.) - Simplify useKnowledgeBaseDropdownMenu to return one-liners - Replace nested ternary with renderTrigger function in EditKnowledgeBaseDialog - Use fieldset for semantic form grouping - Replace cn() with twMerge() in UploadKnowledgeBaseDocumentDialog - Use useMemo instead of IIFE for resultsWithChunkIndex calculation - Extract renderSearchResults function in KnowledgeBaseSearchInterface - Use descriptive variable names (event, selectedFile, unitIndex, etc.) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent efe6e9a commit 93ab165

File tree

8 files changed

+203
-189
lines changed

8 files changed

+203
-189
lines changed

client/src/pages/automation/knowledge-base/components/EditKnowledgeBaseDialog.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,25 @@ const EditKnowledgeBaseDialog = ({
4343
open,
4444
} = useEditKnowledgeBaseDialog({knowledgeBase, onOpenChange, open: controlledOpen});
4545

46-
return (
47-
<Dialog onOpenChange={handleOpenChange} open={open}>
48-
{trigger !== undefined ? (
49-
<DialogTrigger asChild>{trigger}</DialogTrigger>
50-
) : controlledOpen === undefined ? (
46+
const renderTrigger = () => {
47+
if (trigger !== undefined) {
48+
return <DialogTrigger asChild>{trigger}</DialogTrigger>;
49+
}
50+
51+
if (controlledOpen === undefined) {
52+
return (
5153
<DialogTrigger asChild>
5254
<Button icon={<EditIcon />} size="icon" variant="ghost" />
5355
</DialogTrigger>
54-
) : null}
56+
);
57+
}
58+
59+
return null;
60+
};
61+
62+
return (
63+
<Dialog onOpenChange={handleOpenChange} open={open}>
64+
{renderTrigger()}
5565

5666
<DialogContent className="sm:max-w-[500px]">
5767
<DialogHeader className="flex flex-row items-center justify-between space-y-0">
@@ -64,7 +74,7 @@ const EditKnowledgeBaseDialog = ({
6474
<DialogCloseButton />
6575
</DialogHeader>
6676

67-
<div className="space-y-4 py-4">
77+
<fieldset className="space-y-4 border-0 py-4">
6878
<div className="space-y-2">
6979
<Label htmlFor="kb-name">Name</Label>
7080

@@ -87,7 +97,7 @@ const EditKnowledgeBaseDialog = ({
8797
value={description}
8898
/>
8999
</div>
90-
</div>
100+
</fieldset>
91101

92102
<DialogFooter>
93103
<Button onClick={handleCancel} variant="ghost">

client/src/pages/automation/knowledge-base/components/KnowledgeBaseHeader.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Button from '@/components/Button/Button';
22
import Header from '@/shared/layout/Header';
3-
import {ArrowLeft} from 'lucide-react';
3+
import {ArrowLeftIcon} from 'lucide-react';
44

55
interface KnowledgeBaseHeaderProps {
66
knowledgeBaseName: string | undefined;
@@ -10,13 +10,13 @@ interface KnowledgeBaseHeaderProps {
1010
const KnowledgeBaseHeader = ({knowledgeBaseName, onBackClick}: KnowledgeBaseHeaderProps) => {
1111
return (
1212
<Header
13-
centerTitle={true}
13+
centerTitle
1414
position="main"
1515
title={
1616
<div className="flex items-center space-x-2">
1717
<Button
1818
aria-label="Back"
19-
icon={<ArrowLeft className="size-5" />}
19+
icon={<ArrowLeftIcon className="size-5" />}
2020
onClick={onBackClick}
2121
size="icon"
2222
variant="ghost"

client/src/pages/automation/knowledge-base/components/KnowledgeBaseInfoCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import KnowledgeBaseDropdownMenu from '@/pages/automation/knowledge-base/components/KnowledgeBaseDropdownMenu';
22
import {KnowledgeBase, KnowledgeBaseDocument} from '@/shared/middleware/graphql';
3-
import {Database} from 'lucide-react';
3+
import {DatabaseIcon} from 'lucide-react';
44

55
interface KnowledgeBaseInfoCardProps {
66
knowledgeBase: KnowledgeBase & {documents: KnowledgeBaseDocument[]};
@@ -11,7 +11,7 @@ const KnowledgeBaseInfoCard = ({knowledgeBase}: KnowledgeBaseInfoCardProps) => {
1111
<div className="mb-4 rounded-lg border border-gray-200 bg-white p-4">
1212
<div className="flex items-center justify-between">
1313
<div className="flex items-center space-x-2">
14-
<Database className="size-5 text-gray-400" />
14+
<DatabaseIcon className="size-5 text-gray-400" />
1515

1616
<h2 className="text-lg font-semibold">{knowledgeBase.name}</h2>
1717
</div>

client/src/pages/automation/knowledge-base/components/KnowledgeBaseSearchInterface.tsx

Lines changed: 100 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import Button from '@/components/Button/Button';
22
import {Input} from '@/components/ui/input';
33
import {Label} from '@/components/ui/label';
44
import useKnowledgeBaseSearchInterface from '@/pages/automation/knowledge-base/components/hooks/useKnowledgeBaseSearchInterface';
5-
import {Search} from 'lucide-react';
5+
import {SearchIcon} from 'lucide-react';
6+
import {useMemo} from 'react';
67

78
interface KnowledgeBaseSearchInterfaceProps {
89
knowledgeBaseId: string;
@@ -22,39 +23,111 @@ const KnowledgeBaseSearchInterface = ({knowledgeBaseId}: KnowledgeBaseSearchInte
2223
setQuery,
2324
} = useKnowledgeBaseSearchInterface({knowledgeBaseId});
2425

25-
return (
26-
<div className="space-y-4">
27-
<form className="space-y-4 rounded-lg border border-gray-200 bg-white p-4" onSubmit={handleSearch}>
28-
<div className="space-y-2">
29-
<Label htmlFor="query">Search Query</Label>
26+
const resultsWithChunkIndex = useMemo(() => {
27+
const documentChunkCounts: Record<string, number> = {};
3028

31-
<div className="flex space-x-2">
32-
<Input
33-
id="query"
34-
onChange={(e) => setQuery(e.target.value)}
35-
placeholder="Enter your search query..."
36-
value={query}
37-
/>
29+
return results.map((result, index) => {
30+
const documentName = String((result.metadata as Record<string, unknown>)?.file_name ?? 'Unknown');
3831

39-
<Button disabled={isLoading || !canSearch} type="submit">
40-
<Search className="mr-2 size-4" />
32+
documentChunkCounts[documentName] = (documentChunkCounts[documentName] ?? 0) + 1;
4133

42-
{isLoading ? 'Searching...' : 'Search'}
43-
</Button>
44-
</div>
34+
return {
35+
chunkIndex: documentChunkCounts[documentName],
36+
documentName,
37+
index,
38+
result,
39+
};
40+
});
41+
}, [results]);
42+
43+
const renderSearchResults = () => {
44+
if (results.length === 0) {
45+
return (
46+
<div className="rounded-lg border border-gray-200 bg-gray-50 p-8 text-center">
47+
<p className="text-gray-500">No results found for your query.</p>
4548
</div>
49+
);
50+
}
4651

47-
<div className="space-y-2">
48-
<Label htmlFor="filters">Metadata Filters (JSON, optional)</Label>
52+
return resultsWithChunkIndex.map(({chunkIndex, documentName, index, result}) => (
53+
<div
54+
className="rounded-lg border border-gray-200 bg-white p-4 transition-shadow hover:shadow-md"
55+
key={result.id}
56+
>
57+
<div className="mb-2 flex items-center justify-between">
58+
<div className="flex items-center space-x-2 text-sm text-gray-500">
59+
<span className="font-medium">Result {index + 1}</span>
4960

50-
<Input
51-
id="filters"
52-
onChange={(e) => setMetadataFilters(e.target.value)}
53-
placeholder='{"category": "documentation"}'
54-
value={metadataFilters}
55-
/>
61+
<span></span>
62+
63+
<span className="font-medium">{documentName}</span>
64+
65+
<span></span>
66+
67+
<span>Chunk {chunkIndex}</span>
68+
69+
{result.score != null && (
70+
<>
71+
<span></span>
72+
73+
<span className="font-medium text-blue-600">
74+
Score: {(result.score * 100).toFixed(1)}%
75+
</span>
76+
</>
77+
)}
78+
</div>
5679
</div>
5780

81+
<p className="text-sm leading-relaxed text-gray-700">{result.content}</p>
82+
83+
{result.metadata && (
84+
<div className="mt-3 rounded-md bg-gray-50 p-2 text-xs text-gray-600">
85+
<span className="font-medium">Metadata: </span>
86+
87+
<pre className="mt-1 overflow-x-auto">
88+
<code>{JSON.stringify(result.metadata, null, 2)}</code>
89+
</pre>
90+
</div>
91+
)}
92+
</div>
93+
));
94+
};
95+
96+
return (
97+
<div className="space-y-4">
98+
<form className="space-y-4 rounded-lg border border-gray-200 bg-white p-4" onSubmit={handleSearch}>
99+
<fieldset className="space-y-4 border-0">
100+
<div className="space-y-2">
101+
<Label htmlFor="query">Search Query</Label>
102+
103+
<div className="flex space-x-2">
104+
<Input
105+
id="query"
106+
onChange={(event) => setQuery(event.target.value)}
107+
placeholder="Enter your search query..."
108+
value={query}
109+
/>
110+
111+
<Button disabled={isLoading || !canSearch} type="submit">
112+
<SearchIcon className="mr-2 size-4" />
113+
114+
{isLoading ? 'Searching...' : 'Search'}
115+
</Button>
116+
</div>
117+
</div>
118+
119+
<div className="space-y-2">
120+
<Label htmlFor="filters">Metadata Filters (JSON, optional)</Label>
121+
122+
<Input
123+
id="filters"
124+
onChange={(event) => setMetadataFilters(event.target.value)}
125+
placeholder='{"category": "documentation"}'
126+
value={metadataFilters}
127+
/>
128+
</div>
129+
</fieldset>
130+
58131
{searchQuery && (
59132
<div className="flex items-center justify-between border-t border-gray-200 pt-4">
60133
<p className="text-sm text-gray-500">
@@ -68,71 +141,7 @@ const KnowledgeBaseSearchInterface = ({knowledgeBaseId}: KnowledgeBaseSearchInte
68141
)}
69142
</form>
70143

71-
{searchQuery && (
72-
<div className="space-y-2">
73-
{results.length === 0 ? (
74-
<div className="rounded-lg border border-gray-200 bg-gray-50 p-8 text-center">
75-
<p className="text-gray-500">No results found for your query.</p>
76-
</div>
77-
) : (
78-
(() => {
79-
const documentChunkCounts: Record<string, number> = {};
80-
81-
return results.map((result, index) => {
82-
const documentName = String(
83-
(result.metadata as Record<string, unknown>)?.file_name ?? 'Unknown'
84-
);
85-
86-
documentChunkCounts[documentName] = (documentChunkCounts[documentName] ?? 0) + 1;
87-
const chunkIndex = documentChunkCounts[documentName];
88-
89-
return (
90-
<div
91-
className="rounded-lg border border-gray-200 bg-white p-4 transition-shadow hover:shadow-md"
92-
key={result.id}
93-
>
94-
<div className="mb-2 flex items-center justify-between">
95-
<div className="flex items-center space-x-2 text-sm text-gray-500">
96-
<span className="font-medium">Result {index + 1}</span>
97-
98-
<span></span>
99-
100-
<span className="font-medium">{documentName}</span>
101-
102-
<span></span>
103-
104-
<span>Chunk {chunkIndex}</span>
105-
106-
{result.score != null && (
107-
<>
108-
<span></span>
109-
110-
<span className="font-medium text-blue-600">
111-
Score: {(result.score * 100).toFixed(1)}%
112-
</span>
113-
</>
114-
)}
115-
</div>
116-
</div>
117-
118-
<p className="text-sm leading-relaxed text-gray-700">{result.content}</p>
119-
120-
{result.metadata && (
121-
<div className="mt-3 rounded-md bg-gray-50 p-2 text-xs text-gray-600">
122-
<span className="font-medium">Metadata: </span>
123-
124-
<pre className="mt-1 overflow-x-auto">
125-
<code>{JSON.stringify(result.metadata, null, 2)}</code>
126-
</pre>
127-
</div>
128-
)}
129-
</div>
130-
);
131-
});
132-
})()
133-
)}
134-
</div>
135-
)}
144+
{searchQuery && <div className="space-y-2">{renderSearchResults()}</div>}
136145
</div>
137146
);
138147
};

client/src/pages/automation/knowledge-base/components/KnowledgeBaseTabs.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import KnowledgeBaseSearchInterface from '@/pages/automation/knowledge-base/comp
33
import UploadKnowledgeBaseDocumentDialog from '@/pages/automation/knowledge-base/components/UploadKnowledgeBaseDocumentDialog';
44
import KnowledgeBaseDocumentList from '@/pages/automation/knowledge-base/components/knowledge-base-document-list/KnowledgeBaseDocumentList';
55
import {KnowledgeBaseDocument} from '@/shared/middleware/graphql';
6-
import {FileTextIcon, Search} from 'lucide-react';
6+
import {FileTextIcon, SearchIcon} from 'lucide-react';
77

88
interface KnowledgeBaseTabsProps {
99
documents: KnowledgeBaseDocument[];
@@ -21,7 +21,7 @@ const KnowledgeBaseTabs = ({documents, knowledgeBaseId}: KnowledgeBaseTabsProps)
2121
</TabsTrigger>
2222

2323
<TabsTrigger value="search">
24-
<Search className="mr-2 size-4" />
24+
<SearchIcon className="mr-2 size-4" />
2525
Search
2626
</TabsTrigger>
2727
</TabsList>

0 commit comments

Comments
 (0)