mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
chore: dashboard header alignments (#42769)
Align borders to match header heights. <img width="2904" height="1734" alt="shot_2026-02-04_at_08 42 21z_2x" src="https://github.com/user-attachments/assets/0538f8eb-64a5-4329-94fb-3ea4feed847d" />
This commit is contained in:
1 parent
17dbcc91e4
commit
bd9e78b209
26 files changed
+97
-101
No files matched your search
@@ -4,8 +4,8 @@ import { keepPreviousData, useQueryClient } from '@tanstack/react-query'
|
||||
import AwesomeDebouncePromise from 'awesome-debounce-promise'
|
||||
import { LOCAL_STORAGE_KEYS, useFlag, useParams } from 'common'
|
||||
import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import { APIDocsButton } from 'components/ui/APIDocsButton'
|
||||
import { AlertError } from 'components/ui/AlertError'
|
||||
import { APIDocsButton } from 'components/ui/APIDocsButton'
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
import { FilterPopover } from 'components/ui/FilterPopover'
|
||||
import { FormHeader } from 'components/ui/Forms/FormHeader'
|
||||
@@ -39,23 +39,23 @@ import { UIEvent, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import DataGrid, { Column, DataGridHandle, Row } from 'react-data-grid'
|
||||
import { toast } from 'sonner'
|
||||
import {
|
||||
Alert_Shadcn_,
|
||||
AlertDescription_Shadcn_,
|
||||
AlertTitle_Shadcn_,
|
||||
Alert_Shadcn_,
|
||||
Button,
|
||||
cn,
|
||||
LoadingLine,
|
||||
ResizablePanel,
|
||||
ResizablePanelGroup,
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
SelectGroup_Shadcn_,
|
||||
SelectItem_Shadcn_,
|
||||
SelectTrigger_Shadcn_,
|
||||
SelectValue_Shadcn_,
|
||||
Select_Shadcn_,
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
cn,
|
||||
} from 'ui'
|
||||
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
|
||||
@@ -482,10 +482,10 @@ export const UsersV2 = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="h-full flex flex-col">
|
||||
<FormHeader className="py-4 px-6 !mb-0" title="Users" />
|
||||
<FormHeader className="py-4 px-6 !mb-0 border-b" title="Users" />
|
||||
|
||||
{showImprovedSearchOptIn && (
|
||||
<Alert_Shadcn_ className="rounded-none mb-0 border-0 border-t relative">
|
||||
<Alert_Shadcn_ className="rounded-none mb-0 border-0 relative">
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
onClick={() => setImprovedSearchDismissed(true)}
|
||||
@@ -535,7 +535,7 @@ export const UsersV2 = () => {
|
||||
</Alert_Shadcn_>
|
||||
)}
|
||||
|
||||
<div className="bg-surface-200 py-3 px-4 md:px-6 flex flex-col lg:flex-row lg:items-start justify-between gap-2 border-t">
|
||||
<div className="bg-surface-200 py-3 px-4 md:px-6 flex flex-col lg:flex-row lg:items-start justify-between gap-2">
|
||||
{selectedUsers.size > 0 ? (
|
||||
<div className="flex items-center gap-x-2">
|
||||
<Button type="default" icon={<Trash />} onClick={() => setShowDeleteModal(true)}>
|
||||
|
||||
@@ -203,7 +203,7 @@ export const SchemaGraph = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center justify-between p-4 border-b border-muted">
|
||||
<div className="flex items-center justify-between p-4 border-b border-muted h-[var(--header-height)]">
|
||||
{isLoadingSchemas && (
|
||||
<div className="h-[34px] w-[260px] bg-foreground-lighter rounded shimmering-loader" />
|
||||
)}
|
||||
@@ -328,10 +328,6 @@ export const SchemaGraph = () => {
|
||||
type: 'smoothstep',
|
||||
animated: true,
|
||||
deletable: false,
|
||||
style: {
|
||||
stroke: 'hsl(var(--border-stronger))',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
}}
|
||||
nodeTypes={nodeTypes}
|
||||
fitView
|
||||
|
||||
@@ -4,6 +4,7 @@ import Link from 'next/link'
|
||||
import { useAiAssistantStateSnapshot } from 'state/ai-assistant-state'
|
||||
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
|
||||
import { AiIconAnimation, Button, Card, cn } from 'ui'
|
||||
|
||||
import { AnimatedCursors } from './AnimatedCursors'
|
||||
|
||||
/**
|
||||
@@ -22,7 +23,7 @@ export const EmptyRealtime = ({ projectRef }: { projectRef: string }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex grow items-center justify-center p-12 border-t @container">
|
||||
<div className="flex grow items-center justify-center p-12 @container">
|
||||
<div className="w-full max-w-4xl flex flex-col items-center gap-0">
|
||||
<div className="text-center mb-12">
|
||||
<AnimatedCursors />
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PlayCircle, StopCircle } from 'lucide-react'
|
||||
import { Dispatch, SetStateAction } from 'react'
|
||||
|
||||
import { IS_PLATFORM, useParams } from 'common'
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
import { getTemporaryAPIKey } from 'data/api-keys/temp-api-keys-query'
|
||||
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
|
||||
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
|
||||
import { PlayCircle, StopCircle } from 'lucide-react'
|
||||
import { Dispatch, SetStateAction } from 'react'
|
||||
|
||||
import { ChooseChannelPopover } from './ChooseChannelPopover'
|
||||
import { RealtimeFilterPopover } from './RealtimeFilterPopover'
|
||||
import { RealtimeTokensPopover } from './RealtimeTokensPopover'
|
||||
@@ -29,7 +29,7 @@ export const Header = ({ config, onChangeConfig }: HeaderProps) => {
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="flex flex-row h-14 gap-2.5 items-center px-4">
|
||||
<div className="flex flex-row min-h-14 md:min-h-[var(--header-height)] gap-2.5 items-center px-4 border-b ">
|
||||
<div className="flex flex-row">
|
||||
<ChooseChannelPopover config={config} onChangeConfig={onChangeConfig} />
|
||||
<RealtimeTokensPopover config={config} onChangeConfig={onChangeConfig} />
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { X } from 'lucide-react'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import CopyButton from 'components/ui/CopyButton'
|
||||
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
|
||||
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
|
||||
import { X } from 'lucide-react'
|
||||
import { useMemo } from 'react'
|
||||
import { Button, cn } from 'ui'
|
||||
|
||||
import type { LogData } from './Messages.types'
|
||||
import { SelectedRealtimeMessagePanel } from './SelectedRealtimeMessagePanel'
|
||||
|
||||
@@ -25,9 +25,7 @@ const MessageSelection = ({ log, onClose }: MessageSelectionProps) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'relative flex h-full flex-grow flex-col border-l border-t-2 overflow-y-scroll bg-200'
|
||||
)}
|
||||
className={cn('relative flex h-full flex-grow flex-col border-l overflow-y-scroll bg-200')}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { isEqual } from 'lodash'
|
||||
import { ExternalLink, Loader2, Megaphone } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useEffect, useState } from 'react'
|
||||
import DataGrid, { Row } from 'react-data-grid'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { DocsButton } from 'components/ui/DocsButton'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
@@ -13,10 +7,16 @@ import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
|
||||
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
|
||||
import { DOCS_URL } from 'lib/constants'
|
||||
import { Button, IconBroadcast, IconDatabaseChanges, IconPresence, cn } from 'ui'
|
||||
import { isEqual } from 'lodash'
|
||||
import { ExternalLink, Loader2, Megaphone } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useEffect, useState } from 'react'
|
||||
import DataGrid, { Row } from 'react-data-grid'
|
||||
import { Button, cn, IconBroadcast, IconDatabaseChanges, IconPresence } from 'ui'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns'
|
||||
import MessageSelection from './MessageSelection'
|
||||
|
||||
import type { LogData } from './Messages.types'
|
||||
import MessageSelection from './MessageSelection'
|
||||
import NoChannelEmptyState from './NoChannelEmptyState'
|
||||
import { ColumnRenderer } from './RealtimeMessageColumnRenderer'
|
||||
|
||||
@@ -140,12 +140,12 @@ const MessagesTable = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="flex w-full flex-col" style={{ maxHeight: 'calc(100vh - 42px - 3rem)' }}>
|
||||
<section className="flex w-full flex-col md:max-h-[calc(100vh-var(--header-height)-3rem)]">
|
||||
<ShimmerLine active={enabled} />
|
||||
<div className={cn('flex h-full flex-row', enabled ? 'border-brand-400' : null)}>
|
||||
<div className="flex flex-grow flex-col">
|
||||
{enabled && (
|
||||
<div className="w-full h-9 px-4 bg-surface-100 border-b items-center inline-flex justify-between text-foreground-light">
|
||||
<div className="w-full h-9 px-4 bg-surface-100 items-center inline-flex justify-between text-foreground-light">
|
||||
<div className="inline-flex gap-2.5 text-xs">
|
||||
<Loader2 size="16" className="animate-spin" />
|
||||
<div>Listening</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useParams } from 'common'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { useDatabasePublicationsQuery } from 'data/database-publications/database-publications-query'
|
||||
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
|
||||
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { EmptyRealtime } from './EmptyRealtime'
|
||||
import { Header } from './Header'
|
||||
import MessagesTable from './MessagesTable'
|
||||
|
||||
+3
-2
@@ -13,6 +13,7 @@ import {
|
||||
Separator,
|
||||
} from 'ui'
|
||||
import { TimestampInfo } from 'ui-patterns'
|
||||
|
||||
import { ErrorCodeDialog } from '../ErrorCodeDialog'
|
||||
import type { LogSearchCallback, PreviewLogData } from '../Logs.types'
|
||||
import { ResponseCodeFormatter } from '../LogsFormatters'
|
||||
@@ -131,14 +132,14 @@ const PropertyRow = ({
|
||||
<DropdownMenuTrigger className="group w-full" data-testid={dataTestId}>
|
||||
<div className="rounded-md w-full overflow-hidden">
|
||||
<div
|
||||
className={cn('flex h-10 w-full', {
|
||||
className={cn('flex h-[var(--header-height)] w-full', {
|
||||
'flex-col gap-1.5 h-auto': isExpanded,
|
||||
'items-center group-hover:bg-surface-300 gap-4': !isExpanded,
|
||||
})}
|
||||
>
|
||||
<h3
|
||||
className={cn('pl-3 text-foreground-lighter text-sm text-left', {
|
||||
'h-10 flex items-center': isExpanded,
|
||||
'h-[var(--header-height)] flex items-center': isExpanded,
|
||||
})}
|
||||
>
|
||||
{keyName}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import dayjs from 'dayjs'
|
||||
import { Rewind } from 'lucide-react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { PropsWithChildren, useEffect, useState } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import PreviewFilterPanel from 'components/interfaces/Settings/Logs/PreviewFilterPanel'
|
||||
import LoadingOpacity from 'components/ui/LoadingOpacity'
|
||||
import ShimmerLine from 'components/ui/ShimmerLine'
|
||||
import { useReadReplicasQuery } from 'data/read-replicas/replicas-query'
|
||||
import dayjs from 'dayjs'
|
||||
import useLogsPreview from 'hooks/analytics/useLogsPreview'
|
||||
import { useLogsUrlState } from 'hooks/analytics/useLogsUrlState'
|
||||
import { useSelectedLog } from 'hooks/analytics/useSelectedLog'
|
||||
@@ -15,19 +11,23 @@ import useSingleLog from 'hooks/analytics/useSingleLog'
|
||||
import { useCheckEntitlements } from 'hooks/misc/useCheckEntitlements'
|
||||
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
|
||||
import { useUpgradePrompt } from 'hooks/misc/useUpgradePrompt'
|
||||
import { Rewind } from 'lucide-react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { PropsWithChildren, useEffect, useState } from 'react'
|
||||
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
|
||||
import { Button } from 'ui'
|
||||
import { LogsBarChart } from 'ui-patterns/LogsBarChart'
|
||||
import LogTable from './LogTable'
|
||||
import { DatePickerValue } from './Logs.DatePickers'
|
||||
|
||||
import {
|
||||
LOGS_TABLES,
|
||||
LOG_ROUTES_WITH_REPLICA_SUPPORT,
|
||||
LOGS_TABLES,
|
||||
LogsTableName,
|
||||
PREVIEWER_DATEPICKER_HELPERS,
|
||||
} from './Logs.constants'
|
||||
import { DatePickerValue } from './Logs.DatePickers'
|
||||
import type { Filters, LogSearchCallback, LogTemplate, QueryType } from './Logs.types'
|
||||
import { maybeShowUpgradePromptIfNotEntitled } from './Logs.utils'
|
||||
import LogTable from './LogTable'
|
||||
import UpgradePrompt from './UpgradePrompt'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { BookOpen, Check, ChevronDown, Copy, ExternalLink, X } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { ReactNode, useEffect, useState } from 'react'
|
||||
|
||||
import { IS_PLATFORM } from 'common'
|
||||
import Table from 'components/to-be-cleaned/Table'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import { DOCS_URL } from 'lib/constants'
|
||||
import { BookOpen, Check, ChevronDown, Copy, ExternalLink, X } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { ReactNode, useEffect, useState } from 'react'
|
||||
import { logConstants } from 'shared-data'
|
||||
import {
|
||||
Badge,
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from 'ui'
|
||||
|
||||
import {
|
||||
EXPLORER_DATEPICKER_HELPERS,
|
||||
LOGS_SOURCE_DESCRIPTION,
|
||||
@@ -81,7 +81,7 @@ const LogsQueryPanel = ({
|
||||
}, [value.from, value.to, value.text, value.isHelper])
|
||||
|
||||
return (
|
||||
<div className="border-b bg-surface-100">
|
||||
<div className="flex items-center border-b bg-surface-100 h-[var(--header-height)]">
|
||||
<div className="flex w-full items-center justify-between px-4 md:px-5 py-2 overflow-x-scroll no-scrollbar">
|
||||
<div className="flex w-full flex-row items-center justify-between gap-x-4">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { Eye, EyeOff, RefreshCw, Search, Terminal, X } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
import { DatabaseSelector } from 'components/ui/DatabaseSelector'
|
||||
import { DownloadResultsButton } from 'components/ui/DownloadResultsButton'
|
||||
import { useLoadBalancersQuery } from 'data/read-replicas/load-balancers-query'
|
||||
import { IS_PLATFORM } from 'lib/constants'
|
||||
import { Button, Input, Tooltip, TooltipContent, TooltipTrigger, cn } from 'ui'
|
||||
import { DatePickerValue, LogsDatePicker } from './Logs.DatePickers'
|
||||
import { Eye, EyeOff, RefreshCw, Search, Terminal, X } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Button, cn, Input, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
|
||||
|
||||
import {
|
||||
FILTER_OPTIONS,
|
||||
LOG_ROUTES_WITH_REPLICA_SUPPORT,
|
||||
LogsTableName,
|
||||
PREVIEWER_DATEPICKER_HELPERS,
|
||||
} from './Logs.constants'
|
||||
import { DatePickerValue, LogsDatePicker } from './Logs.DatePickers'
|
||||
import type { Filters, LogSearchCallback, LogTemplate } from './Logs.types'
|
||||
import LogsFilterPopover from './LogsFilterPopover'
|
||||
|
||||
@@ -94,7 +94,7 @@ const PreviewFilterPanel = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex w-full items-center justify-between overflow-x-scroll no-scrollbar',
|
||||
'flex w-full items-center justify-between overflow-x-scroll no-scrollbar h-[calc(var(--header-height)-1px)]',
|
||||
condensedLayout ? ' p-3' : '',
|
||||
className
|
||||
)}
|
||||
|
||||
@@ -18,10 +18,7 @@ const ProductMenuBar = ({ title, children, className }: PropsWithChildren<Produc
|
||||
'hide-scrollbar bg-dash-sidebar border-default'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="border-default flex max-h-12 items-center border-b px-6"
|
||||
style={{ minHeight: '3rem' }}
|
||||
>
|
||||
<div className="border-default flex min-h-[var(--header-height)] items-center border-b px-6">
|
||||
<h4 className="text-lg">{title}</h4>
|
||||
</div>
|
||||
<div className={cn('flex-grow overflow-y-auto', className)}>{children}</div>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useBreakpoint } from 'common'
|
||||
import { PanelLeftClose, PanelLeftOpen } from 'lucide-react'
|
||||
|
||||
import { useAppStateSnapshot } from 'state/app-state'
|
||||
import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
|
||||
import { useBreakpoint } from 'common'
|
||||
|
||||
export function CollapseButton({ hideTabs }: { hideTabs: boolean }) {
|
||||
const { showSidebar, setShowSidebar, mobileMenuOpen, setMobileMenuOpen } = useAppStateSnapshot()
|
||||
@@ -21,7 +20,7 @@ export function CollapseButton({ hideTabs }: { hideTabs: boolean }) {
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
className={cn(
|
||||
'hidden md:flex items-center justify-center w-10 h-10 hover:bg-surface-100 shrink-0',
|
||||
'hidden md:flex items-center justify-center w-10 h-[var(--header-height)] hover:bg-surface-100 shrink-0',
|
||||
!hideTabs && 'border-b border-b-default'
|
||||
)}
|
||||
onClick={handleToggle}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { EntityTypeIcon } from 'components/ui/EntityTypeIcon'
|
||||
import { AnimatePresence, motion } from 'framer-motion'
|
||||
import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState'
|
||||
import { X } from 'lucide-react'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { EntityTypeIcon } from 'components/ui/EntityTypeIcon'
|
||||
import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState'
|
||||
import { useTabsStateSnapshot, type Tab } from 'state/tabs'
|
||||
import { cn, TabsTrigger_Shadcn_ } from 'ui'
|
||||
|
||||
import { useEditorType } from '../editors/EditorsLayout.hooks'
|
||||
|
||||
/**
|
||||
@@ -60,7 +60,7 @@ export const SortableTab = ({
|
||||
layoutId={tab.id}
|
||||
transition={{ duration: 0.045 }}
|
||||
animate={{ opacity: isDragging ? 0 : 1 }}
|
||||
className={cn('flex items-center h-10 first-of-type:border-l')}
|
||||
className={cn('flex items-center h-[var(--header-height)] first-of-type:border-l')}
|
||||
>
|
||||
<TabsTrigger_Shadcn_
|
||||
value={tab.id}
|
||||
|
||||
@@ -7,13 +7,12 @@ import {
|
||||
useSensors,
|
||||
} from '@dnd-kit/core'
|
||||
import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable'
|
||||
import { useParams } from 'common'
|
||||
import { AnimatePresence, motion } from 'framer-motion'
|
||||
import { useDashboardHistory } from 'hooks/misc/useDashboardHistory'
|
||||
import { Plus, X } from 'lucide-react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { useDashboardHistory } from 'hooks/misc/useDashboardHistory'
|
||||
import { editorEntityTypes, useTabsStateSnapshot, type Tab } from 'state/tabs'
|
||||
import {
|
||||
cn,
|
||||
@@ -25,6 +24,7 @@ import {
|
||||
TabsList_Shadcn_,
|
||||
TabsTrigger_Shadcn_,
|
||||
} from 'ui'
|
||||
|
||||
import { useEditorType } from '../editors/EditorsLayout.hooks'
|
||||
import { CollapseButton } from './CollapseButton'
|
||||
import { SortableTab } from './SortableTab'
|
||||
@@ -147,7 +147,7 @@ export const EditorTabs = () => {
|
||||
<TabsList_Shadcn_
|
||||
ref={tabsListRef}
|
||||
className={cn(
|
||||
'rounded-b-none gap-0 h-10 flex items-center w-full z-[1]',
|
||||
'rounded-b-none gap-0 min-h-[var(--header-height)] flex items-center w-full z-[1]',
|
||||
'bg-surface-200 dark:bg-alternative border-none overflow-clip overflow-x-auto'
|
||||
)}
|
||||
>
|
||||
@@ -226,7 +226,7 @@ export const EditorTabs = () => {
|
||||
<AnimatePresence initial={false}>
|
||||
{!hasNewTab && (
|
||||
<motion.button
|
||||
className="flex items-center justify-center w-10 h-10 hover:bg-surface-100 shrink-0 border-b"
|
||||
className="flex items-center justify-center w-10 min-h-[var(--header-height)] hover:bg-surface-100 shrink-0 border-b"
|
||||
onClick={() =>
|
||||
router.push(
|
||||
`/project/${router.query.ref}/${editor === 'table' ? 'editor' : 'sql'}/new?skip=true`
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useParams } from 'common'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { ComponentProps, ReactNode } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { useTabsStateSnapshot } from 'state/tabs'
|
||||
import { cn } from 'ui'
|
||||
|
||||
import { ProjectLayoutWithAuth } from '../ProjectLayout'
|
||||
import { CollapseButton } from '../Tabs/CollapseButton'
|
||||
import { EditorTabs } from '../Tabs/Tabs'
|
||||
@@ -44,7 +44,7 @@ export const EditorBaseLayout = ({
|
||||
<div className="flex flex-col h-full">
|
||||
<div
|
||||
className={cn(
|
||||
'h-10 flex items-center',
|
||||
'h-10 md:min-h-[var(--header-height)] flex items-center',
|
||||
!hideTabs ? 'bg-surface-200 dark:bg-alternative' : 'bg-surface-100'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Plus, Settings, X } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { AiIconAnimation, Button } from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
|
||||
import { ButtonTooltip } from '../ButtonTooltip'
|
||||
import { AIAssistantChatSelector } from './AIAssistantChatSelector'
|
||||
import { AIOptInModal } from './AIOptInModal'
|
||||
@@ -29,7 +29,7 @@ export const AIAssistantHeader = ({
|
||||
const [isOptInModalOpen, setIsOptInModalOpen] = useState(false)
|
||||
return (
|
||||
<div className="z-30 sticky top-0">
|
||||
<div className="border-b border-b-muted flex items-center bg gap-x-4 pl-4 pr-3 h-[46px]">
|
||||
<div className="border-b border-b-muted flex items-center bg gap-x-4 pl-4 pr-3 min-h-[var(--header-height)]">
|
||||
<div className="text-sm flex-1 flex items-center">
|
||||
<AiIconAnimation size={20} allowHoverEffect={false} />
|
||||
<span className="text-border-stronger dark:text-border-strong ml-3">
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { X } from 'lucide-react'
|
||||
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
import { FilterPopover } from 'components/ui/FilterPopover'
|
||||
import { X } from 'lucide-react'
|
||||
import { AdvisorSeverity, AdvisorTab } from 'state/advisor-state'
|
||||
import { TabsList_Shadcn_, TabsTrigger_Shadcn_, Tabs_Shadcn_ } from 'ui'
|
||||
import { Tabs_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_ } from 'ui'
|
||||
|
||||
const severityOptions = [
|
||||
{ label: 'Critical', value: 'critical' },
|
||||
@@ -39,7 +38,7 @@ export const AdvisorFilters = ({
|
||||
}: AdvisorFiltersProps) => {
|
||||
return (
|
||||
<div className="border-b overflow-x-auto">
|
||||
<div className="flex items-center justify-between gap-x-4 h-[46px]">
|
||||
<div className="flex items-center justify-between gap-x-4 h-[calc(var(--header-height)-1px)]">
|
||||
<Tabs_Shadcn_ value={activeTab} onValueChange={onTabChange} className="h-full pl-4">
|
||||
<TabsList_Shadcn_ className="border-b-0 gap-4 h-full">
|
||||
<TabsTrigger_Shadcn_ value="all" className="h-full text-xs">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ChevronLeft, X } from 'lucide-react'
|
||||
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
import { ChevronLeft, X } from 'lucide-react'
|
||||
import { Badge } from 'ui'
|
||||
|
||||
import type { AdvisorItem } from './AdvisorPanel.types'
|
||||
import {
|
||||
formatItemDate,
|
||||
|
||||
@@ -22,22 +22,22 @@ import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
|
||||
import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
|
||||
import {
|
||||
Button,
|
||||
cn,
|
||||
CodeBlock,
|
||||
Command_Shadcn_,
|
||||
CommandEmpty_Shadcn_,
|
||||
CommandGroup_Shadcn_,
|
||||
CommandInput_Shadcn_,
|
||||
CommandItem_Shadcn_,
|
||||
CommandList_Shadcn_,
|
||||
Command_Shadcn_,
|
||||
HoverCard_Shadcn_,
|
||||
HoverCardContent_Shadcn_,
|
||||
HoverCardTrigger_Shadcn_,
|
||||
HoverCard_Shadcn_,
|
||||
KeyboardShortcut,
|
||||
Popover_Shadcn_,
|
||||
PopoverContent_Shadcn_,
|
||||
PopoverTrigger_Shadcn_,
|
||||
Popover_Shadcn_,
|
||||
SQL_ICON,
|
||||
cn,
|
||||
} from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
|
||||
@@ -155,7 +155,7 @@ export const EditorPanel = () => {
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col bg-background">
|
||||
<div className="border-b border-b-muted flex items-center justify-between gap-x-4 pl-4 pr-3 h-[46px]">
|
||||
<div className="border-b border-b-muted flex items-center justify-between gap-x-4 pl-4 pr-3 h-[var(--header-height)]">
|
||||
<div className="text-xs">{label}</div>
|
||||
<div className="flex items-center">
|
||||
{templates.length > 0 && (
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ReactNode } from 'react'
|
||||
import { cn } from 'ui'
|
||||
|
||||
import { DocsButton } from '../DocsButton'
|
||||
|
||||
export const FormHeader = ({
|
||||
@@ -18,7 +19,7 @@ export const FormHeader = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
`w-full mb-6 flex flex-col sm:flex-row md:items-center justify-between gap-4 ${className}`
|
||||
`w-full mb-6 flex flex-col sm:flex-row md:items-center justify-between gap-4 md:h-[var(--header-height)] ${className}`
|
||||
)}
|
||||
>
|
||||
<div className="space-y-1">
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
const ShimmerLine = ({ active }: { active: boolean }) => {
|
||||
return active ? <div className="logs-shimmering-loader w-full h-0.5"></div> : null
|
||||
import { cn } from 'ui'
|
||||
|
||||
const ShimmerLine = ({ active, className }: { active: boolean; className?: string }) => {
|
||||
return active ? (
|
||||
<div className={cn('logs-shimmering-loader w-full h-0.5', className)}></div>
|
||||
) : null
|
||||
}
|
||||
|
||||
export default ShimmerLine
|
||||
@@ -1,18 +1,17 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import LintPageTabs from 'components/interfaces/Linter/LintPageTabs'
|
||||
import { LINTER_LEVELS } from 'components/interfaces/Linter/Linter.constants'
|
||||
import { lintInfoMap } from 'components/interfaces/Linter/Linter.utils'
|
||||
import LinterDataGrid from 'components/interfaces/Linter/LinterDataGrid'
|
||||
import LinterFilters from 'components/interfaces/Linter/LinterFilters'
|
||||
import { LinterPageFooter } from 'components/interfaces/Linter/LinterPageFooter'
|
||||
import LintPageTabs from 'components/interfaces/Linter/LintPageTabs'
|
||||
import AdvisorsLayout from 'components/layouts/AdvisorsLayout/AdvisorsLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { FormHeader } from 'components/ui/Forms/FormHeader'
|
||||
import { Lint, useProjectLintsQuery } from 'data/lint/lint-query'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL } from 'lib/constants'
|
||||
import { useMemo, useState } from 'react'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
import { LoadingLine } from 'ui'
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import LintPageTabs from 'components/interfaces/Linter/LintPageTabs'
|
||||
import { LINTER_LEVELS } from 'components/interfaces/Linter/Linter.constants'
|
||||
import { lintInfoMap } from 'components/interfaces/Linter/Linter.utils'
|
||||
import LinterDataGrid from 'components/interfaces/Linter/LinterDataGrid'
|
||||
import LinterFilters from 'components/interfaces/Linter/LinterFilters'
|
||||
import { LinterPageFooter } from 'components/interfaces/Linter/LinterPageFooter'
|
||||
import LintPageTabs from 'components/interfaces/Linter/LintPageTabs'
|
||||
import AdvisorsLayout from 'components/layouts/AdvisorsLayout/AdvisorsLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { FormHeader } from 'components/ui/Forms/FormHeader'
|
||||
import { Lint, useProjectLintsQuery } from 'data/lint/lint-query'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL } from 'lib/constants'
|
||||
import { useMemo, useState } from 'react'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
import { LoadingLine } from 'ui'
|
||||
|
||||
@@ -66,7 +65,7 @@ const ProjectLints: NextPageWithLayout = () => {
|
||||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
<FormHeader
|
||||
className="py-4 px-6 !mb-0"
|
||||
className="py-4 px-6 !-mb-px"
|
||||
title="Security Advisor"
|
||||
docsUrl={`${DOCS_URL}/guides/database/database-linter`}
|
||||
/>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
--sidebar-accent-foreground: var(--foreground-default);
|
||||
--sidebar-border: var(--border-default);
|
||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||
--header-height: 3rem;
|
||||
}
|
||||
|
||||
[data-theme='deep-dark'],
|
||||
|
||||
@@ -867,8 +867,9 @@ export default {
|
||||
shadow-xl
|
||||
`,
|
||||
header: `
|
||||
flex items-center
|
||||
space-y-1 py-4 px-4 bg-dash-sidebar sm:px-6
|
||||
border-b
|
||||
border-b h-[var(--header-height)]
|
||||
`,
|
||||
contents: `
|
||||
relative
|
||||
|
||||
Reference in new issue
Block a user