diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f0ea6190..d939995c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Added counts to members, requets, and invites tabs in the members settings. [#621](https://github.com/sourcebot-dev/sourcebot/pull/621) + ### Fixed - Fixed spurious infinite loads with explore panel, file tree, and file search command. [#617](https://github.com/sourcebot-dev/sourcebot/pull/617) - Wipe search context on init if entitlement no longer exists [#618](https://github.com/sourcebot-dev/sourcebot/pull/618) diff --git a/packages/web/src/app/[domain]/components/navigationMenu/index.tsx b/packages/web/src/app/[domain]/components/navigationMenu/index.tsx index 34fb014b4..952279630 100644 --- a/packages/web/src/app/[domain]/components/navigationMenu/index.tsx +++ b/packages/web/src/app/[domain]/components/navigationMenu/index.tsx @@ -1,4 +1,4 @@ -import { getConnectionStats, getRepos, getReposStats } from "@/actions"; +import { getConnectionStats, getCurrentUserRole, getOrgAccountRequests, getRepos, getReposStats } from "@/actions"; import { SourcebotLogo } from "@/app/components/sourcebotLogo"; import { auth } from "@/auth"; import { Button } from "@/components/ui/button"; @@ -10,7 +10,7 @@ import { env } from "@sourcebot/shared"; import { ServiceErrorException } from "@/lib/serviceError"; import { isServiceError } from "@/lib/utils"; import { DiscordLogoIcon, GitHubLogoIcon } from "@radix-ui/react-icons"; -import { RepoIndexingJobStatus, RepoIndexingJobType } from "@sourcebot/db"; +import { OrgRole, RepoIndexingJobStatus, RepoIndexingJobType } from "@sourcebot/db"; import Link from "next/link"; import { redirect } from "next/navigation"; import { OrgSelector } from "../orgSelector"; @@ -39,11 +39,32 @@ export const NavigationMenu = async ({ throw new ServiceErrorException(repoStats); } - const connectionStats = isAuthenticated ? await getConnectionStats() : null; - if (isServiceError(connectionStats)) { - throw new ServiceErrorException(connectionStats); + const role = isAuthenticated ? await getCurrentUserRole(domain) : null; + if (isServiceError(role)) { + throw new ServiceErrorException(role); } + const stats = await (async () => { + if (!isAuthenticated || role !== OrgRole.OWNER) { + return null; + } + + const joinRequests = await getOrgAccountRequests(domain); + if (isServiceError(joinRequests)) { + throw new ServiceErrorException(joinRequests); + } + + const connectionStats = await getConnectionStats(); + if (isServiceError(connectionStats)) { + throw new ServiceErrorException(connectionStats); + } + + return { + numJoinRequests: joinRequests.length, + connectionStats, + }; + })(); + const sampleRepos = await getRepos({ where: { jobs: { @@ -100,9 +121,10 @@ export const NavigationMenu = async ({ numberOfRepos={numberOfRepos} isReposButtonNotificationDotVisible={numberOfReposWithFirstTimeIndexingJobsInProgress > 0} isSettingsButtonNotificationDotVisible={ - connectionStats ? - connectionStats.numberOfConnectionsWithFirstTimeSyncJobsInProgress > 0 : - false + stats ? ( + stats.connectionStats.numberOfConnectionsWithFirstTimeSyncJobsInProgress > 0 || + stats.numJoinRequests > 0 + ) : false } isAuthenticated={isAuthenticated} /> diff --git a/packages/web/src/app/[domain]/settings/layout.tsx b/packages/web/src/app/[domain]/settings/layout.tsx index 0b508903a..63ac7e4a3 100644 --- a/packages/web/src/app/[domain]/settings/layout.tsx +++ b/packages/web/src/app/[domain]/settings/layout.tsx @@ -69,7 +69,7 @@ export default async function SettingsLayout( throw new ServiceErrorException(connectionStats); } - const hasPermissionSyncingEntitlement = await hasEntitlement("permission-syncing"); + const hasPermissionSyncingEntitlement = hasEntitlement("permission-syncing"); const sidebarNavItems: SidebarNavItem[] = [ { @@ -89,16 +89,8 @@ export default async function SettingsLayout( } ] : []), ...(userRoleInOrg === OrgRole.OWNER ? [{ - title: ( -