Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions apps/docs/content/guides/local-development.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ Develop locally while running the Supabase stack on your machine.
pnpm add supabase --save-dev --allow-build=supabase
```

<Admonition type="note">

The `--allow-build=supabase` flag is required on pnpm version 10 or higher. If you're using an older version of pnpm, omit this flag.

</Admonition>

</TabPanel><TabPanel id="brew" label="brew">

```sh
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { LOCAL_STORAGE_KEYS } from 'common'

export const FEATURE_PREVIEWS = [
{
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS,
name: 'New Logs Interface',
discussionsUrl: 'https://github.com/orgs/supabase/discussions/37234',
isNew: true,
isPlatformOnly: true,
},
{
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0,
name: 'Branching 2.0',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ export const useIsInlineEditorEnabled = () => {
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_INLINE_EDITOR]
}

export const useUnifiedLogsPreview = () => {
const { flags, onUpdateFlag } = useFeaturePreviewContext()
const isEnabled = flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS]
const enable = () => onUpdateFlag(LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS, true)
const disable = () => onUpdateFlag(LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS, false)
return { isEnabled, enable, disable }
}

export const useIsRealtimeSettingsEnabled = () => {
const { flags } = useFeaturePreviewContext()
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS]
Expand All @@ -111,6 +119,7 @@ export const useFeaturePreviewModal = () => {
const isRealtimeSettingsEnabled = useIsRealtimeSettingsFFEnabled()
const gitlessBranchingEnabled = useFlag('gitlessBranching')
const advisorRulesEnabled = useFlag('advisorRules')
const isUnifiedLogsPreviewAvailable = useFlag('unifiedLogs')

const selectedFeatureKeyFromQuery = featurePreviewModal?.trim() ?? null
const showFeaturePreviewModal = selectedFeatureKeyFromQuery !== null
Expand All @@ -125,19 +134,28 @@ export const useFeaturePreviewModal = () => {
return gitlessBranchingEnabled
case 'supabase-ui-advisor-rules':
return advisorRulesEnabled
case 'supabase-ui-preview-unified-logs':
return isUnifiedLogsPreviewAvailable
default:
return true
}
},
[isRealtimeSettingsEnabled, gitlessBranchingEnabled, advisorRulesEnabled]
[
isRealtimeSettingsEnabled,
gitlessBranchingEnabled,
advisorRulesEnabled,
isUnifiedLogsPreviewAvailable,
]
)

const selectedFeatureKey = !selectedFeatureKeyFromQuery
? FEATURE_PREVIEWS.filter((feature) => isFeaturePreviewReleasedToPublic(feature))[0].key
: selectedFeatureKeyFromQuery
const selectedFeatureKey = (
!selectedFeatureKeyFromQuery
? FEATURE_PREVIEWS.filter((feature) => isFeaturePreviewReleasedToPublic(feature))[0].key
: selectedFeatureKeyFromQuery
) as (typeof FEATURE_PREVIEWS)[number]['key']

const selectFeaturePreview = useCallback(
(featureKey: string) => {
(featureKey: (typeof FEATURE_PREVIEWS)[number]['key']) => {
setFeaturePreviewModal(featureKey)
},
[setFeaturePreviewModal]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { FEATURE_PREVIEWS } from './FeaturePreview.constants'
import { useFeaturePreviewContext, useFeaturePreviewModal } from './FeaturePreviewContext'
import { InlineEditorPreview } from './InlineEditorPreview'
import { RealtimeSettingsPreview } from './RealtimeSettingsPreview'
import { UnifiedLogsPreview } from './UnifiedLogsPreview'

const FEATURE_PREVIEW_KEY_TO_CONTENT: {
[key: string]: ReactNode
Expand All @@ -25,6 +26,7 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: {
[LOCAL_STORAGE_KEYS.UI_PREVIEW_INLINE_EDITOR]: <InlineEditorPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]: <APISidePanelPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS]: <CLSPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS]: <UnifiedLogsPreview />,
}

const FeaturePreviewModal = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useParams } from 'common'
import { InlineLink } from 'components/ui/InlineLink'
import { BASE_PATH } from 'lib/constants'
import Image from 'next/image'

export const UnifiedLogsPreview = () => {
const { ref } = useParams()

return (
<div className="space-y-2">
<Image
alt="new-logs-preview"
src={`${BASE_PATH}/img/previews/new-logs-preview.png`}
width={1296}
height={900}
className="rounded border mb-4"
/>
<p className="text-foreground-light text-sm mb-4">
Experience our enhanced logs interface with improved filtering, real-time updates, and a
unified view across all your services. Built for better performance and easier debugging.
</p>
<div className="space-y-2 !mt-4">
<p className="text-sm">Enabling this preview will:</p>
<ul className="list-disc pl-6 text-sm text-foreground-light space-y-1">
<li>
Replace the current logs interface on the{' '}
<InlineLink href={`/project/${ref}/logs`}>logs page</InlineLink> with a unified view
</li>
<li>Provide enhanced filtering capabilities and real-time log streaming</li>
<li>Improve performance with optimized data loading and virtualization</li>
<li>Offer a more modern interface with better search and navigation</li>
</ul>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,13 @@ interface NewOrgFormProps {
onPlanSelected: (plan: string) => void
}

const plans = ['FREE', 'PRO', 'TEAM'] as const

const formSchema = z.object({
plan: z
.string()
.transform((val) => val.toUpperCase())
.pipe(z.enum(['FREE', 'PRO', 'TEAM', 'ENTERPRISE'] as const)),
.pipe(z.enum(plans)),
name: z.string().min(1),
kind: z
.string()
Expand Down Expand Up @@ -149,9 +151,10 @@ const NewOrgForm = ({ onPaymentMethodReset, setupIntent, onPlanSelected }: NewOr

if (typeof name === 'string') updateForm('name', name)
if (typeof kind === 'string') updateForm('kind', kind)
if (typeof plan === 'string') {
updateForm('plan', plan)
onPlanSelected(plan)
if (typeof plan === 'string' && plans.includes(plan.toUpperCase() as (typeof plans)[number])) {
const uppercasedPlan = plan.toUpperCase() as (typeof plans)[number]
updateForm('plan', uppercasedPlan)
onPlanSelected(uppercasedPlan)
}
if (typeof size === 'string') updateForm('size', size)
if (typeof spend_cap === 'string') updateForm('spend_cap', spend_cap === 'true')
Expand Down Expand Up @@ -251,8 +254,7 @@ const NewOrgForm = ({ onPaymentMethodReset, setupIntent, onPlanSelected }: NewOr
| 'tier_payg'
| 'tier_pro'
| 'tier_free'
| 'tier_team'
| 'tier_enterprise',
| 'tier_team',
...(formState.kind == 'COMPANY' ? { size: formState.size } : {}),
payment_method: paymentMethodId,
billing_name: dbTier === 'FREE' ? undefined : customerData?.billing_name,
Expand Down
3 changes: 1 addition & 2 deletions apps/studio/components/interfaces/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ const ProjectLinks = () => {
const { securityLints, errorLints } = useLints()

const showWarehouse = useFlag('warehouse')
const showUnifiedLogs = useFlag('unifiedLogs')

const activeRoute = router.pathname.split('/')[3]

Expand All @@ -247,7 +246,7 @@ const ProjectLinks = () => {
storage: storageEnabled,
realtime: realtimeEnabled,
})
const otherRoutes = generateOtherRoutes(ref, project, { unifiedLogs: showUnifiedLogs })
const otherRoutes = generateOtherRoutes(ref, project)
const settingsRoutes = generateSettingsRoutes(ref, project)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { User } from 'lucide-react'

import { LEVELS } from 'components/ui/DataTable/DataTable.constants'
import { DataTableFilterField, Option } from 'components/ui/DataTable/DataTable.types'
import { getLevelColor, getStatusColor } from 'components/ui/DataTable/DataTable.utils'
import { getLevelColor } from 'components/ui/DataTable/DataTable.utils'
import { cn } from 'ui'
import { LOG_TYPES, METHODS, STATUS_CODE_LABELS } from './UnifiedLogs.constants'
import { ColumnSchema } from './UnifiedLogs.schema'
Expand Down Expand Up @@ -41,22 +41,15 @@ export const filterFields = [
value: 'status',
type: 'checkbox',
defaultOpen: true,
options: [
{ label: '2xx', value: 200 },
{ label: '4xx', value: 400 },
{ label: '4xx', value: 500 },
], // REMINDER: this is a placeholder to set the type in the client.tsx
options: [],
hasDynamicOptions: true,
component: (props: Option) => {
if (typeof props.value === 'boolean') return null
if (typeof props.value === 'undefined') return null

const statusValue = String(props.value)
const statusLabel = STATUS_CODE_LABELS[statusValue as keyof typeof STATUS_CODE_LABELS]

// Convert string status codes to numbers for HTTP status styling
const statusCode = typeof props.value === 'string' ? parseInt(props.value, 10) : props.value
const isHttpStatus = !isNaN(statusCode) && statusCode >= 100 && statusCode < 600

return (
<div className="flex items-center gap-2 w-full min-w-0">
<span className="flex-shrink-0 text-foreground">{statusValue}</span>
Expand Down Expand Up @@ -110,7 +103,9 @@ export const filterFields = [
value: 'host',
type: 'checkbox',
defaultOpen: false,
options: [], // Will be populated dynamically from facets
options: [],
hasDynamicOptions: true,
hasAsyncSearch: true,
component: (props: Option) => {
return (
<span className="truncate block text-[0.75rem]" title={props.value as string}>
Expand All @@ -123,8 +118,10 @@ export const filterFields = [
label: 'Pathname',
value: 'pathname',
type: 'checkbox',
defaultOpen: true,
options: [], // Will be populated dynamically from facets
defaultOpen: false,
options: [],
hasDynamicOptions: true,
hasAsyncSearch: true,
component: (props: Option) => {
return (
<span className="truncate block w-full text-[0.75rem]" title={props.value as string}>
Expand All @@ -138,7 +135,9 @@ export const filterFields = [
value: 'auth_user',
type: 'checkbox',
defaultOpen: false,
options: [], // Will be populated dynamically from facets
options: [],
hasDynamicOptions: true,
hasAsyncSearch: true,
component: (props: Option) => {
return (
<div className="flex items-center gap-2 min-w-0">
Expand Down
Loading
Loading