mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-15 05:45:20 +00:00
Add skeletons to filter panel when search is streaming
This commit is contained in:
parent
b09def9ddd
commit
74376c022a
3 changed files with 36 additions and 20 deletions
|
|
@ -5,6 +5,7 @@ import { compareEntries, Entry } from "./entry";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import Fuse from "fuse.js";
|
import Fuse from "fuse.js";
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
|
|
||||||
interface FilterProps {
|
interface FilterProps {
|
||||||
title: string,
|
title: string,
|
||||||
|
|
@ -12,6 +13,7 @@ interface FilterProps {
|
||||||
entries: Entry[],
|
entries: Entry[],
|
||||||
onEntryClicked: (key: string) => void,
|
onEntryClicked: (key: string) => void,
|
||||||
className?: string,
|
className?: string,
|
||||||
|
isStreaming: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Filter = ({
|
export const Filter = ({
|
||||||
|
|
@ -20,6 +22,7 @@ export const Filter = ({
|
||||||
entries,
|
entries,
|
||||||
onEntryClicked,
|
onEntryClicked,
|
||||||
className,
|
className,
|
||||||
|
isStreaming,
|
||||||
}: FilterProps) => {
|
}: FilterProps) => {
|
||||||
const [searchFilter, setSearchFilter] = useState<string>("");
|
const [searchFilter, setSearchFilter] = useState<string>("");
|
||||||
|
|
||||||
|
|
@ -43,27 +46,34 @@ export const Filter = ({
|
||||||
className
|
className
|
||||||
)}>
|
)}>
|
||||||
<h2 className="text-sm font-semibold">{title}</h2>
|
<h2 className="text-sm font-semibold">{title}</h2>
|
||||||
<div className="pr-1">
|
{(isStreaming && entries.length === 0) ? (
|
||||||
<Input
|
<Skeleton className="h-12 w-full" />
|
||||||
placeholder={searchPlaceholder}
|
) : (
|
||||||
className="h-8"
|
<>
|
||||||
onChange={(event) => setSearchFilter(event.target.value)}
|
<div className="pr-1">
|
||||||
/>
|
<Input
|
||||||
</div>
|
placeholder={searchPlaceholder}
|
||||||
|
className="h-8"
|
||||||
<div
|
onChange={(event) => setSearchFilter(event.target.value)}
|
||||||
className="flex flex-col gap-0.5 text-sm overflow-scroll no-scrollbar"
|
|
||||||
>
|
|
||||||
{filteredEntries
|
|
||||||
.sort((entryA, entryB) => compareEntries(entryB, entryA))
|
|
||||||
.map((entry) => (
|
|
||||||
<Entry
|
|
||||||
key={entry.key}
|
|
||||||
entry={entry}
|
|
||||||
onClicked={() => onEntryClicked(entry.key)}
|
|
||||||
/>
|
/>
|
||||||
))}
|
</div>
|
||||||
</div>
|
|
||||||
|
<div
|
||||||
|
className="flex flex-col gap-0.5 text-sm overflow-scroll no-scrollbar"
|
||||||
|
>
|
||||||
|
{filteredEntries
|
||||||
|
.sort((entryA, entryB) => compareEntries(entryB, entryA))
|
||||||
|
.map((entry) => (
|
||||||
|
<Entry
|
||||||
|
key={entry.key}
|
||||||
|
entry={entry}
|
||||||
|
onClicked={() => onEntryClicked(entry.key)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ interface FilePanelProps {
|
||||||
matches: SearchResultFile[];
|
matches: SearchResultFile[];
|
||||||
repoInfo: Record<number, RepositoryInfo>;
|
repoInfo: Record<number, RepositoryInfo>;
|
||||||
onFilterChange?: () => void;
|
onFilterChange?: () => void;
|
||||||
|
isStreaming: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -33,11 +34,13 @@ interface FilePanelProps {
|
||||||
* @param matches - Array of search result files to filter
|
* @param matches - Array of search result files to filter
|
||||||
* @param repoInfo - Information about repositories including their display names and icons
|
* @param repoInfo - Information about repositories including their display names and icons
|
||||||
* @param onFilterChange - Optional callback that is called whenever a filter is applied or removed
|
* @param onFilterChange - Optional callback that is called whenever a filter is applied or removed
|
||||||
|
* @param isStreaming - Whether the search is streaming
|
||||||
*/
|
*/
|
||||||
export const FilterPanel = ({
|
export const FilterPanel = ({
|
||||||
matches,
|
matches,
|
||||||
repoInfo,
|
repoInfo,
|
||||||
onFilterChange,
|
onFilterChange,
|
||||||
|
isStreaming,
|
||||||
}: FilePanelProps) => {
|
}: FilePanelProps) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
@ -155,6 +158,7 @@ export const FilterPanel = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="max-h-[50%]"
|
className="max-h-[50%]"
|
||||||
|
isStreaming={isStreaming}
|
||||||
/>
|
/>
|
||||||
<Filter
|
<Filter
|
||||||
title="Filter By Language"
|
title="Filter By Language"
|
||||||
|
|
@ -178,6 +182,7 @@ export const FilterPanel = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="overflow-auto"
|
className="overflow-auto"
|
||||||
|
isStreaming={isStreaming}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,7 @@ const PanelGroup = ({
|
||||||
<FilterPanel
|
<FilterPanel
|
||||||
matches={fileMatches}
|
matches={fileMatches}
|
||||||
repoInfo={repoInfo}
|
repoInfo={repoInfo}
|
||||||
|
isStreaming={isStreaming}
|
||||||
onFilterChange={() => {
|
onFilterChange={() => {
|
||||||
searchResultsPanelRef.current?.resetScroll();
|
searchResultsPanelRef.current?.resetScroll();
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue