Joshenlim/fe 4383 consolidate tablerow no search result state (#50389)

### Context

Just some housekeeping/consolidate refactors. There's a number of places
where we render the same "no result" empty state for tables. So this PR
just consolidates that into a reusable component `TableRowNoResults` to
reduce duplication.

Opting to save this under `components/ui` instead of the `ui` package as
this is more of a derivation of `TableRow` than a primitive

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **UI Improvements**
- Standardized empty search-result messages across database, functions,
storage, and vector bucket tables.
- Search terms now appear consistently when no matching records are
found.
  - Added an accessible label to the vector bucket row actions menu.
- Improved the storage explorer loading layout so content expands to use
available vertical space.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Joshen Lim authored and GitHub committed 2026-09-16 16:35:26 +08:00
1 parent 32b1a0f492
commit ee3fbc4e61
19 files changed
+137 -181

No files matched your search

@@ -30,6 +30,7 @@ import { AlertError } from '@/components/ui/AlertError'
import { DocsButton } from '@/components/ui/DocsButton'
import { SchemaSelector } from '@/components/ui/SchemaSelector'
import { Shortcut } from '@/components/ui/Shortcut'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useEnumeratedTypeDeleteMutation } from '@/data/enumerated-types/enumerated-type-delete-mutation'
import { useEnumeratedTypesQuery } from '@/data/enumerated-types/enumerated-types-query'
import { useQuerySchemaState } from '@/hooks/misc/useSchemaQueryState'
@@ -217,14 +218,7 @@ export const EnumeratedTypes = () => {
</TableRow>
)}
{filteredEnumeratedTypes.length === 0 && search.length > 0 && (
<TableRow>
<TableCell colSpan={4}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{search}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults colSpan={4} search={search} />
)}
{filteredEnumeratedTypes.length > 0 &&
filteredEnumeratedTypes.map((type) => (
@@ -24,6 +24,7 @@ import { stripInArgModePrefixes } from '../Functions.utils'
import { getDatabaseTriggersHref, getFilteredFunctions } from './FunctionList.utils'
import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import {
useDatabaseFunctionsQuery,
type SavedDatabaseFunction,
@@ -91,16 +92,7 @@ export const FunctionList = ({
}
if (_functions.length === 0 && filterString.length > 0) {
return (
<TableRow key={schema}>
<TableCell colSpan={5}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{filterString}" did not return any results
</p>
</TableCell>
</TableRow>
)
return <TableRowNoResults key={schema} colSpan={5} search={filterString} />
}
return (
@@ -28,6 +28,7 @@ import { AlertError } from '@/components/ui/AlertError'
import { CodeEditor } from '@/components/ui/CodeEditor/CodeEditor'
import { SchemaSelector } from '@/components/ui/SchemaSelector'
import { Shortcut } from '@/components/ui/Shortcut'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useDatabaseIndexDeleteMutation } from '@/data/database-indexes/index-delete-mutation'
import { useIndexesQuery, type DatabaseIndex } from '@/data/database-indexes/indexes-query'
import { useSchemasQuery } from '@/data/database/schemas-query'
@@ -240,14 +241,7 @@ export const Indexes = () => {
</TableRow>
)}
{indexes.length === 0 && search.length > 0 && (
<TableRow>
<TableCell colSpan={4}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{search}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults colSpan={4} search={search} />
)}
{indexes.length > 0 &&
indexes.map((index) => (
@@ -25,6 +25,7 @@ import { MigrationsEmptyState } from './MigrationsEmptyState'
import { SupportLink } from '@/components/interfaces/Support/SupportLink'
import { CodeEditor } from '@/components/ui/CodeEditor/CodeEditor'
import { InlineLink } from '@/components/ui/InlineLink'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { DatabaseMigration, useMigrationsQuery } from '@/data/database/migrations-query'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { DOCS_URL } from '@/lib/constants'
@@ -184,14 +185,7 @@ export const Migrations = () => {
)
})
) : (
<TableRow>
<TableCell colSpan={3}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{search}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults colSpan={3} search={search} />
)}
</TableBody>
</Table>
@@ -15,7 +15,6 @@ import {
DropdownMenuTrigger,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableHeadSort,
@@ -42,6 +41,7 @@ import {
import { useRedirectLegacyReadReplicaDestination } from './useRedirectLegacyReadReplicaDestination'
import { AlertError } from '@/components/ui/AlertError'
import { Shortcut } from '@/components/ui/Shortcut'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useReplicationDestinationsQuery } from '@/data/replication/destinations-query'
import { replicationKeys } from '@/data/replication/keys'
import {
@@ -404,16 +404,7 @@ export const Destinations = () => {
{!isDestinationsLoading &&
filteredDestinations.length === 0 &&
hasDestinations && (
<TableRow>
<TableCell colSpan={6}>
<p>No results found</p>
<p className="text-foreground-light">
Your search for “{filterString}” did not return any results.
</p>
</TableCell>
</TableRow>
)}
hasDestinations && <TableRowNoResults colSpan={6} search={filterString} />}
</TableBody>
</Table>
</CardContent>
@@ -54,6 +54,7 @@ import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip
import { EntityTypeIcon } from '@/components/ui/EntityTypeIcon'
import { SchemaSelector } from '@/components/ui/SchemaSelector'
import { Shortcut } from '@/components/ui/Shortcut'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useDatabasePublicationsQuery } from '@/data/database-publications/database-publications-query'
import { ENTITY_TYPE } from '@/data/entity-types/entity-type-constants'
import { useForeignTablesQuery } from '@/data/foreign-tables/foreign-tables-query'
@@ -429,14 +430,7 @@ export const TableList = ({
</TableRow>
)}
{entities.length === 0 && filterString.length > 0 && (
<TableRow key={selectedSchema}>
<TableCell colSpan={7}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{filterString}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults key={selectedSchema} colSpan={7} search={filterString} />
)}
{entities.length > 0 &&
entities.map((x) => (
@@ -19,6 +19,7 @@ import type { EventTrigger } from './EventTriggerList.utils'
import { SUPABASE_ROLES } from '@/components/interfaces/Database/Roles/Roles.constants'
import { getDatabaseFunctionsHref } from '@/components/interfaces/Database/Triggers/TriggersList/TriggerList.utils'
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
interface EventTriggerListProps {
filterString: string
@@ -64,32 +65,8 @@ export const EventTriggerList = ({
return sortBy(filteredEventTriggers, (trigger) => trigger.name.toLocaleLowerCase())
}, [eventTriggers, ownerFilter, filterString])
if (orderedTriggers.length === 0 && filterString.length === 0 && ownerFilter.length === 0) {
return (
<TableRow>
<TableCell colSpan={6}>
<p className="text-sm text-foreground">No event triggers created yet</p>
<p className="text-sm text-foreground-light">
There are no event triggers configured for this database
</p>
</TableCell>
</TableRow>
)
}
if (orderedTriggers.length === 0 && (filterString.length > 0 || ownerFilter.length > 0)) {
return (
<TableRow>
<TableCell colSpan={6}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
{filterString.length > 0
? `Your search for "${filterString}" did not return any results`
: 'No event triggers match the current filters'}
</p>
</TableCell>
</TableRow>
)
return <TableRowNoResults colSpan={6} search={filterString} />
}
return (
@@ -27,6 +27,7 @@ import {
import { selectFilterSchema } from '@/components/interfaces/Reports/v2/ReportsSelectFilter'
import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useDatabaseTriggersQuery } from '@/data/database-triggers/database-triggers-query'
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
import { useQuerySchemaState } from '@/hooks/misc/useSchemaQueryState'
@@ -92,16 +93,7 @@ export const TriggerList = ({ editTrigger, duplicateTrigger, deleteTrigger }: Tr
}
if (_triggers.length === 0 && filterString.length > 0) {
return (
<TableRow key={schema}>
<TableCell colSpan={7}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{filterString}" did not return any results
</p>
</TableCell>
</TableRow>
)
return <TableRowNoResults key={schema} colSpan={7} search={filterString} />
}
return (
@@ -20,6 +20,7 @@ import { EditSecretSheet } from './EditSecretSheet'
import { AlertError } from '@/components/ui/AlertError'
import { DocsButton } from '@/components/ui/DocsButton'
import { NoPermission } from '@/components/ui/NoPermission'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useSecretsDeleteMutation } from '@/data/secrets/secrets-delete-mutation'
import { useSecretsQuery } from '@/data/secrets/secrets-query'
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
@@ -181,14 +182,11 @@ export const EdgeFunctionSecrets = () => {
</TableCell>
</TableRow>
) : (
<TableRow className="[&>td]:hover:bg-inherit">
<TableCell colSpan={headers.length}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{searchString}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={headers.length}
search={searchString}
/>
)}
</TableBody>
</Table>
@@ -27,6 +27,7 @@ import { CreateBucketButton } from '../NewBucketButton'
import { CreateAnalyticsBucketModal } from './CreateAnalyticsBucketModal'
import { AlertError } from '@/components/ui/AlertError'
import { AlphaNotice } from '@/components/ui/AlphaNotice'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useProjectStorageConfigQuery } from '@/data/config/project-storage-config-query'
import { useAnalyticsBucketsQuery } from '@/data/storage/analytics-buckets-query'
import { createNavigationHandler } from '@/lib/navigation'
@@ -136,14 +137,11 @@ export const AnalyticsBuckets = () => {
</TableHeader>
<TableBody>
{analyticsBuckets.length === 0 && filterString.length > 0 && (
<TableRow className="[&>td]:hover:bg-inherit">
<TableCell colSpan={3}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{filterString}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={3}
search={filterString}
/>
)}
{analyticsBuckets.map((bucket) => {
const handleBucketNavigation = createNavigationHandler(
@@ -12,27 +12,6 @@ import { formatBytes } from '@/lib/helpers'
type BucketTableMode = 'standard' | 'virtualized'
type BucketTableEmptyStateProps = {
mode: BucketTableMode
filterString: string
}
export const BucketTableEmptyState = ({ mode, filterString }: BucketTableEmptyStateProps) => {
const BucketTableRow = mode === 'standard' ? TableRow : VirtualizedTableRow
const BucketTableCell = mode === 'standard' ? TableCell : VirtualizedTableCell
return (
<BucketTableRow className="[&>td]:hover:bg-inherit">
<BucketTableCell colSpan={5}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-lighter">
Your search for “{filterString}” did not return any results
</p>
</BucketTableCell>
</BucketTableRow>
)
}
type BucketTableRowProps = {
mode: BucketTableMode
bucket: Bucket
@@ -3,8 +3,9 @@ import { Table, TableBody } from 'ui'
import { LoadMoreRow } from './BucketsTable.LoadMoreRow'
import { BucketTableHeader } from './BucketTableHeader'
import { BucketTableEmptyState, BucketTableRow } from './BucketTableRow'
import { BucketTableRow } from './BucketTableRow'
import type { AllowedBucketType, BucketsTablePaginationProps } from './types'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { VirtualizedTable, VirtualizedTableBody } from '@/components/ui/VirtualizedTable'
import { type Bucket } from '@/data/storage/buckets-query'
@@ -47,7 +48,11 @@ const BucketsTableUnvirtualized = ({
<BucketTableHeader mode="standard" hasBuckets={buckets.length > 0} />
<TableBody>
{showSearchEmptyState ? (
<BucketTableEmptyState mode="standard" filterString={filterString} />
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={5}
search={filterString}
/>
) : (
buckets.map((bucket) => (
<BucketTableRow
@@ -95,7 +100,11 @@ const BucketsTableVirtualized = ({
paddingColSpan={5}
emptyContent={
showSearchEmptyState ? (
<BucketTableEmptyState mode="virtualized" filterString={filterString} />
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={5}
search={filterString}
/>
) : undefined
}
trailingContent={
@@ -14,6 +14,7 @@ import {
import { PUBLIC_BUCKET_TOOLTIP } from '@/components/interfaces/Storage/Storage.constants'
import { useBucketPolicyCount } from '@/components/interfaces/Storage/useBucketPolicyCount'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import {
VirtualizedTableCell,
VirtualizedTableHead,
@@ -64,19 +65,22 @@ type BucketTableEmptyStateProps = {
}
export const BucketTableEmptyState = ({ mode, filterString }: BucketTableEmptyStateProps) => {
const BucketTableRow = mode === 'standard' ? TableRow : VirtualizedTableRow
const BucketTableCell = mode === 'standard' ? TableCell : VirtualizedTableCell
return (
<BucketTableRow className="[&>td]:hover:bg-inherit">
<BucketTableCell colSpan={5}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-lighter">
Your search for “{filterString}” did not return any results
</p>
</BucketTableCell>
</BucketTableRow>
)
if (mode === 'standard') {
return (
<TableRowNoResults className="[&>td]:hover:bg-inherit" colSpan={5} search={filterString} />
)
} else {
return (
<VirtualizedTableRow className="[&>td]:hover:bg-inherit">
<VirtualizedTableCell colSpan={5}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-lighter">
Your search for “{filterString}” did not return any results
</p>
</VirtualizedTableCell>
</VirtualizedTableRow>
)
}
}
type BucketTableRowProps = {
@@ -3,7 +3,8 @@ import { Table, TableBody } from 'ui'
import { LoadMoreRow } from './BucketsTable.LoadMoreRow'
import type { BucketsTablePaginationProps } from './BucketsTable.types'
import { BucketTableEmptyState, BucketTableHeader, BucketTableRow } from './BucketTable'
import { BucketTableHeader, BucketTableRow } from './BucketTable'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { VirtualizedTable, VirtualizedTableBody } from '@/components/ui/VirtualizedTable'
import { Bucket } from '@/data/storage/buckets-query'
@@ -15,8 +16,16 @@ type BucketsTableProps = {
pagination: BucketsTablePaginationProps
}
// [Joshen] To investigate: There's a lot of duplicate logic + components between
// this FilesBuckets/BucketsTable and BucketsPickerDialog/BucketsTable. Check separately
// if they can be cleaned up and consolidated. The latter should take precedence as it aims to
// reduce footprint on the giant StorageExplorerState.
export const BucketsTable = (props: BucketsTableProps) => {
// [Joshen] To investigate: Can't we just default to virtualized?
// Do we need to dynamically decide whether to use a virtualized or unvirtualized one?
const isVirtualized = props.buckets.length > 50
return isVirtualized ? (
<BucketsTableVirtualized {...props} />
) : (
@@ -43,7 +52,11 @@ const BucketsTableUnvirtualized = ({
<BucketTableHeader mode="standard" hasBuckets={buckets.length > 0} />
<TableBody>
{showSearchEmptyState ? (
<BucketTableEmptyState mode="standard" filterString={filterString} />
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={5}
search={filterString}
/>
) : (
buckets.map((bucket) => (
<BucketTableRow
@@ -89,7 +102,11 @@ const BucketsTableVirtualized = ({
paddingColSpan={5}
emptyContent={
showSearchEmptyState ? (
<BucketTableEmptyState mode="virtualized" filterString={filterString} />
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={5}
search={filterString}
/>
) : undefined
}
trailingContent={
@@ -269,7 +269,7 @@ export const FileExplorerColumn = ({
<div
className={`
${fullWidth ? 'w-full' : 'w-64 border-r border-default'}
px-2 py-1 my-1 flex shrink-0 flex-col space-y-2 overflow-auto
px-2 py-1 my-1 flex flex-grow shrink-0 flex-col space-y-2 overflow-auto
`}
>
<ShimmeringLoader />
@@ -45,6 +45,7 @@ import {
ScaffoldSectionTitle,
} from '@/components/layouts/Scaffold'
import { AlertError } from '@/components/ui/AlertError'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useVectorBucketQuery } from '@/data/storage/vector-bucket-query'
import { useVectorBucketsIndexesQuery } from '@/data/storage/vector-buckets-indexes-query'
@@ -182,25 +183,20 @@ export const VectorBucketDetails = () => {
</TableHeader>
<TableBody>
{filteredList.length === 0 ? (
<TableRow className="[&>td]:hover:bg-inherit">
<TableCell colSpan={3}>
{filterString.length > 0 ? (
<>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-lighter">
Your search for "{filterString}" did not return any results
</p>
</>
) : (
<>
<p className="text-sm text-foreground">No tables yet</p>
<p className="text-sm text-foreground-lighter">
Create your first table to get started
</p>
</>
)}
</TableCell>
</TableRow>
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={3}
search={filterString}
>
{filterString.length === 0 ? (
<>
<p className="text-sm text-foreground">No tables yet</p>
<p className="text-sm text-foreground-lighter">
Create your first table to get started
</p>
</>
) : undefined}
</TableRowNoResults>
) : (
filteredList.map((index, idx: number) => {
const id = `index-${idx}`
@@ -225,6 +221,7 @@ export const VectorBucketDetails = () => {
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
aria-label="More options"
className="w-7"
icon={<MoreVertical />}
onClick={(e) => e.stopPropagation()}
@@ -16,6 +16,7 @@ import { CreateBucketButton } from '../NewBucketButton'
import { CreateVectorBucketDialog } from './CreateVectorBucketDialog'
import { VectorBucketsErrorState } from './VectorBucketsErrorState'
import { AlphaNotice } from '@/components/ui/AlphaNotice'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useVectorBucketsQuery } from '@/data/storage/vector-buckets-query'
import { createNavigationHandler } from '@/lib/navigation'
@@ -107,14 +108,11 @@ export const VectorsBuckets = () => {
</TableHeader>
<TableBody>
{filteredBuckets.length === 0 && filterString.length > 0 && (
<TableRow className="[&>td]:hover:bg-inherit">
<TableCell colSpan={3}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-lighter">
Your search for "{filterString}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults
className="[&>td]:hover:bg-inherit"
colSpan={3}
search={filterString}
/>
)}
{filteredBuckets.map((bucket, idx: number) => {
const id = `bucket-${idx}`
@@ -0,0 +1,30 @@
import { type PropsWithChildren } from 'react'
import { TableCell, TableRow } from 'ui'
interface TableRowNoResultsProps {
className?: string
colSpan: number
search?: string
}
export const TableRowNoResults = ({
className,
colSpan,
search,
children,
}: PropsWithChildren<TableRowNoResultsProps>) => {
return (
<TableRow className={className}>
<TableCell colSpan={colSpan}>
{children ?? (
<>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{search}" did not return any results
</p>
</>
)}
</TableCell>
</TableRow>
)
}
@@ -3,7 +3,7 @@ import { ExternalLink, RefreshCw, Search, X } from 'lucide-react'
import { useRouter } from 'next/router'
import { parseAsString, parseAsStringLiteral, useQueryState } from 'nuqs'
import React, { useMemo, useRef, type PropsWithChildren } from 'react'
import { Button, Card, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from 'ui'
import { Button, Card, Table, TableBody, TableHead, TableHeader, TableRow } from 'ui'
import { Admonition } from 'ui-patterns/Admonition'
import { Input } from 'ui-patterns/DataInputs/Input'
import { PageContainer } from 'ui-patterns/PageContainer'
@@ -35,6 +35,7 @@ import EdgeFunctionsLayout from '@/components/layouts/EdgeFunctionsLayout/EdgeFu
import { AlertError } from '@/components/ui/AlertError'
import { DocsButton } from '@/components/ui/DocsButton'
import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip'
import { TableRowNoResults } from '@/components/ui/TableRowNoResults'
import { useEdgeFunctionsQuery } from '@/data/edge-functions/edge-functions-query'
import { useIsProjectActive } from '@/hooks/misc/useSelectedProject'
import { DOCS_URL, IS_PLATFORM } from '@/lib/constants'
@@ -145,6 +146,7 @@ const EdgeFunctionsPage: NextPageWithLayout = () => {
actions={[
search && (
<Button
aria-label="Clear search"
key="clear"
size="tiny"
variant="text"
@@ -200,14 +202,10 @@ const EdgeFunctionsPage: NextPageWithLayout = () => {
<EdgeFunctionsListItem key={item.id} function={item} />
))
) : (
<TableRow>
<TableCell colSpan={showLastHourStats ? 8 : 6}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{search}" did not return any results
</p>
</TableCell>
</TableRow>
<TableRowNoResults
colSpan={showLastHourStats ? 8 : 6}
search={search}
/>
)}
</>
</TableBody>