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
2 changes: 1 addition & 1 deletion apps/docs/content/guides/auth/sessions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Otherwise sessions are progressively deleted from the database 24 hours after th

### What are recommended values for access token (JWT) expiration?

Most applications should use the default expiration time of 1 hour. This can be customized in your project's [Auth settings](/dashboard/project/_/settings/jwt) in the Advanced Settings section.
Most applications should use the default expiration time of 1 hour. This can be customized in your [project's settings](/dashboard/project/_/settings/jwt/legacy) in the JWT Keys > Legacy JWT Secret section.

Setting a value over 1 hour is generally discouraged for security reasons, but it may make sense in certain situations.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ You can update scopes of your OAuth app at any time, but existing OAuth app user
| `Rest` | `Write` | Update a project's PostgREST configuration |
| `Secrets` | `Read` | Retrieve a project's API keys<br/>Retrieve a project's secrets<br/>Retrieve a project's pgsodium config |
| `Secrets` | `Write` | Create or update a project's secrets<br/>Update a project's pgsodium configuration |
| `Storage` | `Read` | Retrieve a project's storage buckets. |
| |
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Usage is shown as "Log Drain Hours" on your invoice.

### Pricing

Log Drains are available as a project Add-On for all Team and Enterprise users. Each Log Drain costs <Price price="0.0822" /> per hour (<Price price="60" /> per month).
Log Drains are available as a project Add-On for all Pro, Team and Enterprise users. Each Log Drain costs <Price price="0.0822" /> per hour (<Price price="60" /> per month).

## Log Drain Events

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/guides/telemetry/log-drains.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: 'Log Drains'
description: 'Getting started with Supabase Log Drains'
---

Log drains will send all logs of the Supabase stack to one or more desired destinations. It is only available for customers on Team and Enterprise Plans. Log drains is available in the dashboard under [Project Settings > Log Drains](/dashboard/project/_/settings/log-drains).
Log drains send all logs of the Supabase stack to one or more desired destinations. It is only available for customers on Pro, Team and Enterprise Plans. Log drains are available in the dashboard under [Project Settings > Log Drains](/dashboard/project/_/settings/log-drains).

You can read about the initial announcement [here](/blog/log-drains) and vote for your preferred drains in [this discussion](https://github.com/orgs/supabase/discussions/28324?sort=top).

Expand Down
3 changes: 3 additions & 0 deletions apps/docs/public/humans.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Supabase is 100% remote.

Aaron Byrne
Ada Wong
Adam Mohammed
Adam Mokan
AJ Matias
Akash Manimaran
Expand Down Expand Up @@ -82,6 +83,7 @@ Francesco Sansalvadore
Garrett Crowell
Gerardo Estaba
Gildas Garcia
Giuseppe Mandato
Greg Kress
Greg P
Greg Richardson
Expand Down Expand Up @@ -109,6 +111,7 @@ Jim Brodeur
Jim Chanco Jr
Joakim Ahrlin
Joel Low
Joel Martin
John Pena
John Schaeffer
Jon M
Expand Down
15 changes: 9 additions & 6 deletions apps/studio/components/grid/components/editor/TimeEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import type { RenderEditCellProps } from 'react-data-grid'
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import * as React from 'react'
import type { RenderEditCellProps } from 'react-data-grid'

dayjs.extend(customParseFormat)

Expand Down Expand Up @@ -29,23 +29,26 @@ function BaseEditor<TRow, TSummaryRow = unknown>({
onClose,
}: TimeEditorProps<TRow, TSummaryRow>) {
const value = row[column.key as keyof TRow] as unknown as string
const timeValue = value ? dayjs(value, format).format(INPUT_TIME_FORMAT) : value

function onChange(event: React.ChangeEvent<HTMLInputElement>) {
const _value = event.target.value

if (_value == '') {
onRowChange({ ...row, [column.key]: null })
} else {
const _timeValue = dayjs(_value, INPUT_TIME_FORMAT).format(format)
onRowChange({ ...row, [column.key]: _timeValue })
const dayJsValue = dayjs(_value, format)
if (dayJsValue.isValid()) {
const _timeValue = dayJsValue.format(format)
onRowChange({ ...row, [column.key]: _timeValue })
}
}
}

return (
<input
className="sb-grid-time-editor"
ref={autoFocusAndSelect}
value={timeValue ?? ''}
defaultValue={value ?? ''}
onChange={onChange}
onBlur={() => onClose(true)}
type="time"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { QueueOperationsPreview } from './QueueOperationsPreview'
import { TableFilterBarPreview } from './TableFilterBarPreview'
import { UnifiedLogsPreview } from './UnifiedLogsPreview'
import { useFeaturePreviews } from './useFeaturePreviews'
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'

const FEATURE_PREVIEW_KEY_TO_CONTENT: {
[key: string]: ReactNode
Expand Down Expand Up @@ -56,6 +57,11 @@ export const FeaturePreviewModal = () => {
const featurePreviewContext = useFeaturePreviewContext()
const { mutate: sendEvent } = useSendEventMutation()

const [isDismissedTableFilterBar, setIsDismissedTableFilterBar] = useLocalStorageQuery(
LOCAL_STORAGE_KEYS.TABLE_EDITOR_NEW_FILTER_BANNER_DISMISSED(ref ?? ''),
false
)

const { flags, onUpdateFlag } = featurePreviewContext
const selectedFeature =
featurePreviews.find((preview) => preview.key === selectedFeatureKey) ?? featurePreviews[0]
Expand All @@ -72,6 +78,13 @@ export const FeaturePreviewModal = () => {
properties: { feature: selectedFeature.key },
groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
})

if (
selectedFeature.key === LOCAL_STORAGE_KEYS.UI_PREVIEW_TABLE_FILTER_BAR &&
!isDismissedTableFilterBar
) {
setIsDismissedTableFilterBar(true)
}
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,23 +236,9 @@ export const ProjectPausedState = ({ product }: ProjectPausedStateProps) => {

{isPauseStatusSuccess && !isRestoreDisabled && (
<CardFooter className="flex justify-end items-center gap-x-2">
{isFreePlan ? (
<Button asChild type="default">
<Link
href={`/org/${orgSlug}/billing?panel=subscriptionPlan&source=projectPausedStateRestore`}
>
Upgrade to Pro
</Link>
</Button>
) : (
<Button asChild type="default">
<Link href={`/project/${ref}/settings/general`}>View project settings</Link>
</Button>
)}

<ButtonTooltip
size="tiny"
type="primary"
type="default"
disabled={!canResumeProject}
onClick={onSelectRestore}
tooltip={{
Expand All @@ -266,6 +252,20 @@ export const ProjectPausedState = ({ product }: ProjectPausedStateProps) => {
>
Resume project
</ButtonTooltip>

{isFreePlan ? (
<Button asChild type="primary">
<Link
href={`/org/${orgSlug}/billing?panel=subscriptionPlan&source=projectPausedStateRestore`}
>
Upgrade to Pro
</Link>
</Button>
) : (
<Button asChild type="default">
<Link href={`/project/${ref}/settings/general`}>View project settings</Link>
</Button>
)}
</CardFooter>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { PropsWithChildren, useEffect } from 'react'

import { ProjectLayoutWithAuth } from '../ProjectLayout'
import { SaveQueueActionBar } from '@/components/grid/components/footer/operations/SaveQueueActionBar'
import { useIsTableFilterBarEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { BannerTableEditorFilter } from '@/components/ui/BannerStack/Banners/BannerTableEditorFilter'
import { useBannerStack } from '@/components/ui/BannerStack/BannerStackProvider'
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
Expand All @@ -15,6 +16,7 @@ const TABLE_EDITOR_NEW_FILTER_BANNER_ID = 'table-editor-new-filter-banner'
export const TableEditorLayout = ({ children }: PropsWithChildren<{}>) => {
const { ref } = useParams()
const { addBanner, dismissBanner } = useBannerStack()
const isTableFilterBarEnabled = useIsTableFilterBarEnabled()

const [isTableEditorNewFilterBannerDismissed] = useLocalStorageQuery(
LOCAL_STORAGE_KEYS.TABLE_EDITOR_NEW_FILTER_BANNER_DISMISSED(ref ?? ''),
Expand All @@ -29,7 +31,7 @@ export const TableEditorLayout = ({ children }: PropsWithChildren<{}>) => {
useEffect(() => {
if (!isPermissionsLoaded) return

if (canReadTables && !isTableEditorNewFilterBannerDismissed) {
if (canReadTables && !isTableEditorNewFilterBannerDismissed && !isTableFilterBarEnabled) {
addBanner({
id: TABLE_EDITOR_NEW_FILTER_BANNER_ID,
priority: 2,
Expand All @@ -49,6 +51,7 @@ export const TableEditorLayout = ({ children }: PropsWithChildren<{}>) => {
canReadTables,
isPermissionsLoaded,
isTableEditorNewFilterBannerDismissed,
isTableFilterBarEnabled,
])

if (isPermissionsLoaded && !canReadTables) {
Expand Down
11 changes: 7 additions & 4 deletions apps/studio/data/auth/user-update-mutation.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'

import { handleError, patch } from 'data/fetchers'
import { toast } from 'sonner'
import type { ResponseError, UseCustomMutationOptions } from 'types'

import { authKeys } from './keys'

export type UserUpdateVariables = {
Expand Down Expand Up @@ -37,8 +37,11 @@ export const useUserUpdateMutation = ({
return useMutation<UserUpdateData, ResponseError, UserUpdateVariables>({
mutationFn: (vars) => updateUser(vars),
async onSuccess(data, variables, context) {
const { projectRef } = variables
await queryClient.invalidateQueries({ queryKey: authKeys.usersInfinite(projectRef) })
const { projectRef, userId } = variables
await Promise.all([
queryClient.invalidateQueries({ queryKey: authKeys.usersInfinite(projectRef) }),
queryClient.invalidateQueries({ queryKey: authKeys.user(projectRef, userId) }),
])
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
Expand Down
34 changes: 34 additions & 0 deletions apps/www/_go/events/stripe-exec-dinner-thank-you.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { GoPageInput } from 'marketing'
import Link from 'next/link'
import { Button } from 'ui'

const page: GoPageInput = {
template: 'thank-you',
slug: 'stripe/exec-dinner/thank-you',
metadata: {
title: "You're confirmed | Supabase Executive Dinner",
description:
'Your RSVP for the Supabase executive dinner at Spruce on April 29, 2026 has been confirmed.',
},
hero: {
title: "You're confirmed",
description:
"We'll send details and directions closer to the date. We look forward to seeing you at Spruce on April 29.",
},
sections: [
{
type: 'single-column',
title: 'In the meantime',
description: 'Learn more about what we are building at Supabase.',
children: (
<div className="flex items-center justify-center gap-4">
<Button asChild type="default" size="small">
<Link href="https://supabase.com">Visit supabase.com</Link>
</Button>
</div>
),
},
],
}

export default page
Loading
Loading