mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-14 21:35:25 +00:00
fix: Fix repo carousel thrashing (#294)
This commit is contained in:
parent
eb10d599f3
commit
b280e2ddbb
3 changed files with 45 additions and 17 deletions
|
|
@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixes bug with repos not being visible in the homepage carousel when re-indexing. [#294](https://github.com/sourcebot-dev/sourcebot/pull/294)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Added special `*` value for `rev:` to allow searching across all branches. [#281](https://github.com/sourcebot-dev/sourcebot/pull/281)
|
- Added special `*` value for `rev:` to allow searching across all branches. [#281](https://github.com/sourcebot-dev/sourcebot/pull/281)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,24 @@ import {
|
||||||
} from "@/components/ui/carousel";
|
} from "@/components/ui/carousel";
|
||||||
import { RepoIndexingStatus } from "@sourcebot/db";
|
import { RepoIndexingStatus } from "@sourcebot/db";
|
||||||
import { SymbolIcon } from "@radix-ui/react-icons";
|
import { SymbolIcon } from "@radix-ui/react-icons";
|
||||||
|
import { RepositoryQuery } from "@/lib/types";
|
||||||
|
|
||||||
export function RepositorySnapshot({ authEnabled }: { authEnabled: boolean }) {
|
interface RepositorySnapshotProps {
|
||||||
|
authEnabled: boolean;
|
||||||
|
repos: RepositoryQuery[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RepositorySnapshot({
|
||||||
|
authEnabled,
|
||||||
|
repos: initialRepos,
|
||||||
|
}: RepositorySnapshotProps) {
|
||||||
const domain = useDomain();
|
const domain = useDomain();
|
||||||
|
|
||||||
const { data: repos, isPending, isError } = useQuery({
|
const { data: repos, isPending, isError } = useQuery({
|
||||||
queryKey: ['repos', domain],
|
queryKey: ['repos', domain],
|
||||||
queryFn: () => unwrapServiceError(getRepos(domain)),
|
queryFn: () => unwrapServiceError(getRepos(domain)),
|
||||||
refetchInterval: env.NEXT_PUBLIC_POLLING_INTERVAL_MS,
|
refetchInterval: env.NEXT_PUBLIC_POLLING_INTERVAL_MS,
|
||||||
|
placeholderData: initialRepos,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isPending || isError || !repos) {
|
if (isPending || isError || !repos) {
|
||||||
|
|
@ -33,22 +43,30 @@ export function RepositorySnapshot({ authEnabled }: { authEnabled: boolean }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const numIndexedRepos = repos.filter((repo) => repo.repoIndexingStatus === RepoIndexingStatus.INDEXED).length;
|
// Use `indexedAt` to determine if a repo has __ever__ been indexed.
|
||||||
const numIndexingRepos = repos.filter((repo) => repo.repoIndexingStatus === RepoIndexingStatus.INDEXING || repo.repoIndexingStatus === RepoIndexingStatus.IN_INDEX_QUEUE).length;
|
// The repo indexing status only tells us the repo's current indexing status.
|
||||||
if (numIndexedRepos === 0 && numIndexingRepos > 0) {
|
const indexedRepos = repos.filter((repo) => repo.indexedAt !== undefined);
|
||||||
return (
|
|
||||||
<div className="flex flex-row items-center gap-3">
|
// If there are no indexed repos...
|
||||||
<SymbolIcon className="h-4 w-4 animate-spin" />
|
if (indexedRepos.length === 0) {
|
||||||
<span className="text-sm">indexing in progress...</span>
|
|
||||||
</div>
|
// ... show a loading state if repos are being indexed now
|
||||||
)
|
if (repos.some((repo) => repo.repoIndexingStatus === RepoIndexingStatus.INDEXING || repo.repoIndexingStatus === RepoIndexingStatus.IN_INDEX_QUEUE)) {
|
||||||
} else if (numIndexedRepos == 0) {
|
return (
|
||||||
return (
|
<div className="flex flex-row items-center gap-3">
|
||||||
<EmptyRepoState domain={domain} authEnabled={authEnabled} />
|
<SymbolIcon className="h-4 w-4 animate-spin" />
|
||||||
)
|
<span className="text-sm">indexing in progress...</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
// ... otherwise, show the empty state.
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<EmptyRepoState domain={domain} authEnabled={authEnabled} />
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const indexedRepos = repos.filter((repo) => repo.repoIndexingStatus === RepoIndexingStatus.INDEXED);
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center gap-3">
|
<div className="flex flex-col items-center gap-3">
|
||||||
<span className="text-sm">
|
<span className="text-sm">
|
||||||
|
|
@ -57,7 +75,7 @@ export function RepositorySnapshot({ authEnabled }: { authEnabled: boolean }) {
|
||||||
href={`${domain}/repos`}
|
href={`${domain}/repos`}
|
||||||
className="text-blue-500"
|
className="text-blue-500"
|
||||||
>
|
>
|
||||||
{repos.length > 1 ? 'repositories' : 'repository'}
|
{indexedRepos.length > 1 ? 'repositories' : 'repository'}
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
<RepositoryCarousel repos={indexedRepos} />
|
<RepositoryCarousel repos={indexedRepos} />
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import { SourcebotLogo } from "../components/sourcebotLogo";
|
||||||
import { RepositorySnapshot } from "./components/repositorySnapshot";
|
import { RepositorySnapshot } from "./components/repositorySnapshot";
|
||||||
import { SyntaxReferenceGuideHint } from "./components/syntaxReferenceGuideHint";
|
import { SyntaxReferenceGuideHint } from "./components/syntaxReferenceGuideHint";
|
||||||
import { env } from '@/env.mjs';
|
import { env } from '@/env.mjs';
|
||||||
|
import { getRepos } from "@/actions";
|
||||||
|
import { isServiceError } from "@/lib/utils";
|
||||||
|
|
||||||
export default async function Home({ params: { domain } }: { params: { domain: string } }) {
|
export default async function Home({ params: { domain } }: { params: { domain: string } }) {
|
||||||
const org = await getOrgFromDomain(domain);
|
const org = await getOrgFromDomain(domain);
|
||||||
|
|
@ -17,6 +19,8 @@ export default async function Home({ params: { domain } }: { params: { domain: s
|
||||||
return <PageNotFound />
|
return <PageNotFound />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const repos = await getRepos(domain);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center overflow-hidden min-h-screen">
|
<div className="flex flex-col items-center overflow-hidden min-h-screen">
|
||||||
<NavigationMenu
|
<NavigationMenu
|
||||||
|
|
@ -34,7 +38,10 @@ export default async function Home({ params: { domain } }: { params: { domain: s
|
||||||
className="mt-4 w-full max-w-[800px]"
|
className="mt-4 w-full max-w-[800px]"
|
||||||
/>
|
/>
|
||||||
<div className="mt-8">
|
<div className="mt-8">
|
||||||
<RepositorySnapshot authEnabled={env.SOURCEBOT_AUTH_ENABLED === 'true'} />
|
<RepositorySnapshot
|
||||||
|
authEnabled={env.SOURCEBOT_AUTH_ENABLED === 'true'}
|
||||||
|
repos={isServiceError(repos) ? [] : repos}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center w-fit gap-6">
|
<div className="flex flex-col items-center w-fit gap-6">
|
||||||
<Separator className="mt-5" />
|
<Separator className="mt-5" />
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue