Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 47 additions & 44 deletions web-app/src/routes/hub/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useVirtualizer } from '@tanstack/react-virtual'
import { createFileRoute, useNavigate, useSearch } from '@tanstack/react-router'
import { route } from '@/constants/routes'
import { useModelSources } from '@/hooks/useModelSources'
import { cn } from '@/lib/utils'
import {

Check warning on line 7 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

2-7 lines are not covered with tests
useState,
useMemo,
useEffect,
Expand All @@ -12,39 +12,39 @@
useCallback,
useRef,
} from 'react'
import { Button } from '@/components/ui/button'
import { useModelProvider } from '@/hooks/useModelProvider'
import { Card, CardItem } from '@/containers/Card'
import { RenderMarkdown } from '@/containers/RenderMarkdown'
import { extractModelName, extractDescription } from '@/lib/models'
import {

Check warning on line 20 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

15-20 lines are not covered with tests
IconDownload,
IconFileCode,
IconSearch,
IconTool,
} from '@tabler/icons-react'
import { Switch } from '@/components/ui/switch'
import Joyride, { CallBackProps, STATUS } from 'react-joyride'
import { CustomTooltipJoyRide } from '@/containers/CustomeTooltipJoyRide'
import {

Check warning on line 29 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

26-29 lines are not covered with tests
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import {

Check warning on line 35 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

35 line is not covered with tests
CatalogModel,
pullModel,
fetchHuggingFaceRepo,
convertHfRepoToCatalogModel,
} from '@/services/models'
import { useDownloadStore } from '@/hooks/useDownloadStore'
import { Progress } from '@/components/ui/progress'
import HeaderPage from '@/containers/HeaderPage'
import { Loader } from 'lucide-react'
import { useTranslation } from '@/i18n/react-i18next-compat'
import Fuse from 'fuse.js'
import { useGeneralSetting } from '@/hooks/useGeneralSetting'

Check warning on line 47 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

41-47 lines are not covered with tests

type ModelProps = {
model: CatalogModel
Expand All @@ -52,31 +52,31 @@
type SearchParams = {
repo: string
}
const defaultModelQuantizations = ['iq4_xs', 'q4_k_m']

Check warning on line 55 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

55 line is not covered with tests

export const Route = createFileRoute(route.hub.index as any)({
component: Hub,
validateSearch: (search: Record<string, unknown>): SearchParams => ({
repo: search.repo as SearchParams['repo'],
}),
})

Check warning on line 62 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

57-62 lines are not covered with tests

function Hub() {
const parentRef = useRef(null)
const { huggingfaceToken } = useGeneralSetting()

Check warning on line 66 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

64-66 lines are not covered with tests

const { t } = useTranslation()
const sortOptions = [
{ value: 'newest', name: t('hub:sortNewest') },
{ value: 'most-downloaded', name: t('hub:sortMostDownloaded') },
]
const searchOptions = useMemo(() => {
return {
includeScore: true,

Check warning on line 75 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

68-75 lines are not covered with tests
// Search in `author` and in `tags` array
keys: ['model_name', 'quants.model_id'],
}
}, [])

Check warning on line 79 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

77-79 lines are not covered with tests

const { sources, fetchSources, loading } = useModelSources()

Expand Down Expand Up @@ -146,14 +146,16 @@
}
// Apply downloaded filter
if (showOnlyDownloaded) {
filtered = filtered?.map((model) => ({
...model,
quants: model.quants.filter((variant) =>
llamaProvider?.models.some(
(m: { id: string }) => m.id === variant.model_id
)
)
})).filter((model) => model.quants.length > 0)
filtered = filtered
?.map((model) => ({
...model,
quants: model.quants.filter((variant) =>
llamaProvider?.models.some(
(m: { id: string }) => m.id === variant.model_id
)
),
}))
.filter((model) => model.quants.length > 0)
}
// Add HuggingFace repo at the beginning if available
if (huggingFaceRepo) {
Expand Down Expand Up @@ -428,43 +430,44 @@
const isLastStep = currentStepIndex === steps.length - 1

const renderFilter = () => {
return (
<>
<DropdownMenu>
<DropdownMenuTrigger>
<span className="flex cursor-pointer items-center gap-1 px-2 py-1 rounded-sm bg-main-view-fg/15 text-sm outline-none text-main-view-fg font-medium">
{
sortOptions.find((option) => option.value === sortSelected)
?.name
}
if (searchValue.length === 0)
return (
<>
<DropdownMenu>
<DropdownMenuTrigger>
<span className="flex cursor-pointer items-center gap-1 px-2 py-1 rounded-sm bg-main-view-fg/15 text-sm outline-none text-main-view-fg font-medium">
{
sortOptions.find((option) => option.value === sortSelected)
?.name
}
</span>
</DropdownMenuTrigger>
<DropdownMenuContent side="bottom" align="end">
{sortOptions.map((option) => (
<DropdownMenuItem
className={cn(
'cursor-pointer my-0.5',
sortSelected === option.value && 'bg-main-view-fg/5'
)}
key={option.value}
onClick={() => setSortSelected(option.value)}
>
{option.name}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
<div className="flex items-center gap-2">
<Switch
checked={showOnlyDownloaded}
onCheckedChange={setShowOnlyDownloaded}
/>
<span className="text-xs text-main-view-fg/70 font-medium whitespace-nowrap">
{t('hub:downloaded')}
</span>
</DropdownMenuTrigger>
<DropdownMenuContent side="bottom" align="end">
{sortOptions.map((option) => (
<DropdownMenuItem
className={cn(
'cursor-pointer my-0.5',
sortSelected === option.value && 'bg-main-view-fg/5'
)}
key={option.value}
onClick={() => setSortSelected(option.value)}
>
{option.name}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
<div className="flex items-center gap-2">
<Switch
checked={showOnlyDownloaded}
onCheckedChange={setShowOnlyDownloaded}
/>
<span className="text-xs text-main-view-fg/70 font-medium whitespace-nowrap">
{t('hub:downloaded')}
</span>
</div>
</>
)
</div>
</>
)
}

return (
Expand Down
Loading